add fabric client
This commit is contained in:
parent
13315e708c
commit
1aabd0f3cf
4 changed files with 117 additions and 27 deletions
|
@ -1,18 +1,45 @@
|
||||||
package eu.e99.svc.client.fabric;
|
package eu.e99.svc.client.fabric;
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.session.Session;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class FabricSimplerVoiceChat implements ClientModInitializer {
|
public class FabricSimplerVoiceChat implements ClientModInitializer {
|
||||||
|
|
||||||
public static final String NAMESPACE = "svc";
|
public static final String NAMESPACE = "svc";
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(NAMESPACE);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
LOGGER.info("Simpler Voice Chat Running");
|
System.out.printf("Simpler Voice Chat loading...%n");
|
||||||
|
|
||||||
|
SSLSocketFactory socketFactory;
|
||||||
|
try {
|
||||||
|
socketFactory = SVCClient.createSocketFactory();
|
||||||
|
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
||||||
|
System.out.printf("Failed to create socket factory:%n");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
Session session = client.getSession();
|
||||||
|
|
||||||
|
|
||||||
|
SVCClient voiceChat = new SVCClient(
|
||||||
|
"localhost",
|
||||||
|
6969,
|
||||||
|
session.getAccessToken(),
|
||||||
|
session.getUsername(),
|
||||||
|
session.getUuidOrNull(),
|
||||||
|
socketFactory
|
||||||
|
);
|
||||||
|
Thread.ofPlatform().start(voiceChat::start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,9 @@ package eu.e99.svc.client.fabric;
|
||||||
import eu.e99.svc.AllTrustManager;
|
import eu.e99.svc.AllTrustManager;
|
||||||
import eu.e99.svc.Connection;
|
import eu.e99.svc.Connection;
|
||||||
import eu.e99.svc.SimplerVoiceChat;
|
import eu.e99.svc.SimplerVoiceChat;
|
||||||
|
import eu.e99.svc.auth.MojangAPI;
|
||||||
import eu.e99.svc.io.BinaryMessage;
|
import eu.e99.svc.io.BinaryMessage;
|
||||||
import eu.e99.svc.packet.AuthRequestPacket;
|
import eu.e99.svc.packet.*;
|
||||||
import eu.e99.svc.packet.AuthResponsePacket;
|
|
||||||
import eu.e99.svc.packet.AuthSuccessPacket;
|
|
||||||
import eu.e99.svc.packet.ClientHelloPacket;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
@ -18,10 +16,11 @@ import java.net.Socket;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SVCClient {
|
public class SVCClient {
|
||||||
|
|
||||||
public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException {
|
public static SSLSocketFactory createSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
|
||||||
TrustManager[] trustManagers = new TrustManager[]{
|
TrustManager[] trustManagers = new TrustManager[]{
|
||||||
new AllTrustManager(),
|
new AllTrustManager(),
|
||||||
};
|
};
|
||||||
|
@ -29,37 +28,58 @@ public class SVCClient {
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(null, trustManagers, new SecureRandom());
|
sslContext.init(null, trustManagers, new SecureRandom());
|
||||||
|
|
||||||
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
|
return sslContext.getSocketFactory();
|
||||||
|
|
||||||
SVCClient voiceChat = new SVCClient("localhost", 6969, socketFactory);
|
|
||||||
voiceChat.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
private final String accessToken;
|
||||||
|
private final String username;
|
||||||
|
private final UUID uuid;
|
||||||
private final SSLSocketFactory socketFactory;
|
private final SSLSocketFactory socketFactory;
|
||||||
|
|
||||||
public SVCClient(String host, int port, SSLSocketFactory socketFactory) {
|
public SVCClient(String host, int port, String accessToken, String username, UUID uuid, SSLSocketFactory socketFactory) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
this.username = username;
|
||||||
|
this.uuid = uuid;
|
||||||
this.socketFactory = socketFactory;
|
this.socketFactory = socketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
// Connect and auth
|
// Connect and auth
|
||||||
|
|
||||||
try (Socket socket = this.socketFactory.createSocket()) {
|
while (true) {
|
||||||
socket.connect(new InetSocketAddress(this.host, this.port));
|
try (Socket socket = this.socketFactory.createSocket()) {
|
||||||
Connection conn = new Connection(socket);
|
System.out.printf("Connecting to %s.%n", this.host);
|
||||||
|
socket.connect(new InetSocketAddress(this.host, this.port));
|
||||||
|
Connection conn = new Connection(socket);
|
||||||
|
System.out.printf("Connected.");
|
||||||
|
|
||||||
this.handleHandshake(conn);
|
boolean ok = this.handleHandshake(conn);
|
||||||
} catch (IOException e) {
|
if (!ok) {
|
||||||
System.out.printf("Failed to connect.%n");
|
System.out.printf("Handshake failed.%n");
|
||||||
e.printStackTrace(System.out);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("Successfully authenticated.%n");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.printf("Failed to connect.%n");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("Disconnected. Attempting reconnection in 30 seconds.%n");
|
||||||
|
try {
|
||||||
|
Thread.sleep(30_000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.printf("Failed to wait:%n");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleHandshake(Connection conn) throws IOException {
|
private boolean handleHandshake(Connection conn) throws IOException {
|
||||||
ClientHelloPacket clientHello = new ClientHelloPacket();
|
ClientHelloPacket clientHello = new ClientHelloPacket();
|
||||||
clientHello.version = SimplerVoiceChat.PROTOCOL_VERSION;
|
clientHello.version = SimplerVoiceChat.PROTOCOL_VERSION;
|
||||||
conn.writePacket(clientHello);
|
conn.writePacket(clientHello);
|
||||||
|
@ -69,18 +89,35 @@ public class SVCClient {
|
||||||
|
|
||||||
switch (packet) {
|
switch (packet) {
|
||||||
case AuthRequestPacket authRequest -> {
|
case AuthRequestPacket authRequest -> {
|
||||||
System.out.printf("Joining fake server to authenticate.%n");
|
System.out.printf("Joining server to authenticate...%n");
|
||||||
|
|
||||||
|
boolean ok;
|
||||||
|
try {
|
||||||
|
ok = MojangAPI.joinServer(this.accessToken, this.uuid, authRequest.serverId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.printf("Failed to join server:%n");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
System.out.printf("Failed to join server.%n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AuthResponsePacket authResponse = new AuthResponsePacket();
|
AuthResponsePacket authResponse = new AuthResponsePacket();
|
||||||
authResponse.username = "Test";
|
authResponse.username = this.username;
|
||||||
conn.writePacket(authResponse);
|
conn.writePacket(authResponse);
|
||||||
}
|
}
|
||||||
case AuthSuccessPacket authComplete -> {
|
case AuthSuccessPacket authComplete -> {
|
||||||
System.out.printf("Successfully authenticated.%n");
|
return true;
|
||||||
return;
|
}
|
||||||
|
case DisconnectPacket disconnect -> {
|
||||||
|
System.out.printf("Disconnected with reason \"%s\".%n", disconnect.reason);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
System.out.printf("Got unexpected packet.%n");
|
System.out.printf("Got unexpected packet %s.%n", packet.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class MojangAPI {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
|
||||||
if (res.statusCode() == 204) {
|
if (res.statusCode() != 200) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,4 +39,29 @@ public class MojangAPI {
|
||||||
return new PlayerProfile(name, uuid);
|
return new PlayerProfile(name, uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean joinServer(String accessToken, UUID uuid, String serverId) throws IOException, InterruptedException {
|
||||||
|
try (HttpClient client = HttpClient.newHttpClient()) {
|
||||||
|
String loc = "https://sessionserver.mojang.com/session/minecraft/join";
|
||||||
|
URI uri = URI.create(loc);
|
||||||
|
|
||||||
|
JsonObject body = new JsonObject();
|
||||||
|
body.addProperty("accessToken", accessToken);
|
||||||
|
body.addProperty("selectedProfile", uuid.toString().replace("-", ""));
|
||||||
|
body.addProperty("serverId", serverId);
|
||||||
|
|
||||||
|
HttpRequest req = HttpRequest.newBuilder()
|
||||||
|
.uri(uri)
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<Void> res = client.send(req, HttpResponse.BodyHandlers.discarding());
|
||||||
|
System.out.printf("%d%n", res.statusCode());
|
||||||
|
if (res.statusCode() != 204) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import eu.e99.svc.auth.PlayerProfile;
|
||||||
import eu.e99.svc.io.BinaryMessage;
|
import eu.e99.svc.io.BinaryMessage;
|
||||||
import eu.e99.svc.packet.*;
|
import eu.e99.svc.packet.*;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
@ -38,7 +39,7 @@ public class Server {
|
||||||
this.socket.notify();
|
this.socket.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.printf("Failed to accept client.%n");
|
System.out.printf("Failed to handle client.%n");
|
||||||
e.printStackTrace(System.out);
|
e.printStackTrace(System.out);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue