WIP: Better code
This commit is contained in:
parent
10bfd01324
commit
e6f6ad8dbc
|
|
@ -38,6 +38,8 @@ public class Ambassador {
|
|||
private static final int MAX_DATA_LENGTH = 16000;
|
||||
private static final int PACKET_LENGTH_INDEX = 14;
|
||||
|
||||
private static ForgeHandshakeDataHandler forgeHandshakeDataHandler;
|
||||
|
||||
@Inject
|
||||
public Ambassador(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
|
||||
this.server = server;
|
||||
|
|
@ -60,6 +62,7 @@ public class Ambassador {
|
|||
forgeServer = server.getServer("lobby").orElseThrow(IllegalAccessError::new);
|
||||
loginWrapperChannel = MinecraftChannelIdentifier.create("fml","loginwrapper");
|
||||
|
||||
forgeHandshakeDataHandler = new ForgeHandshakeDataHandler(forgeServer,logger);
|
||||
}
|
||||
|
||||
private int numberOfRecivedParts;
|
||||
|
|
@ -79,11 +82,12 @@ public class Ambassador {
|
|||
}
|
||||
inbound = (LoginPhaseConnection) event.getConnection();
|
||||
|
||||
recivedParts = new byte[2000000];
|
||||
/*recivedParts = new byte[2000000];
|
||||
recivedBytes = 0;
|
||||
numberOfRecivedParts = 0;
|
||||
ping(continuation);
|
||||
|
||||
*/
|
||||
forgeHandshakeDataHandler.onPreLogin(event,continuation);
|
||||
}
|
||||
|
||||
private void ping(Continuation continuation) {
|
||||
|
|
@ -108,26 +112,29 @@ public class Ambassador {
|
|||
|
||||
logger.info("Downloaded part " + String.valueOf(numberOfRecivedParts) + " out of " + String.valueOf(parts));
|
||||
|
||||
|
||||
byte[] temp = pair.getId().getBytes(StandardCharsets.ISO_8859_1);
|
||||
head = (recivedPartNr-1)*MAX_DATA_LENGTH;
|
||||
for(int i = 0;i<temp.length;i++) {
|
||||
recivedParts[head] = temp[i];
|
||||
head++;
|
||||
recivedBytes++;
|
||||
}
|
||||
|
||||
placePartInArray(pair.getId().getBytes(StandardCharsets.ISO_8859_1),recivedPartNr-1);
|
||||
|
||||
if(numberOfRecivedParts >= parts)
|
||||
{
|
||||
sendHandshake(splitPacket(recivedParts,values));
|
||||
sendHandshake(splitPackets(recivedParts,values));
|
||||
continuation.resume();
|
||||
}
|
||||
else {
|
||||
ping(continuation);
|
||||
}
|
||||
}
|
||||
private List<byte[]> splitPacket(byte[] data, int[] startPacketMarkers) {
|
||||
|
||||
private void placePartInArray(byte[] temp, int partNr) {
|
||||
head = partNr*MAX_DATA_LENGTH;
|
||||
for(int i = 0;i<temp.length;i++) {
|
||||
recivedParts[head] = temp[i];
|
||||
head++;
|
||||
recivedBytes++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<byte[]> splitPackets(byte[] data, int[] startPacketMarkers) {
|
||||
List<byte[]> list = new ArrayList<>();
|
||||
for(int i = 0;i<startPacketMarkers.length-1;i++) {
|
||||
list.add(getPacket(data, startPacketMarkers[i],startPacketMarkers[i+1]-1));
|
||||
|
|
@ -176,10 +183,10 @@ public class Ambassador {
|
|||
int packetID = readVarInt(data);
|
||||
|
||||
if(packetID == 1) {
|
||||
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(recivedClientModlist));
|
||||
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(forgeHandshakeDataHandler.recivedClientModlist));
|
||||
}
|
||||
else {
|
||||
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(recivedClientACK));
|
||||
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(forgeHandshakeDataHandler.recivedClientACK));
|
||||
}
|
||||
continuation.resume();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
package org.adde0109.ambassador;
|
||||
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.ModInfo;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ForgeHandshakeDataHandler {
|
||||
|
||||
public handshakeReceiver.CachedServerHandshake cachedServerHandshake;
|
||||
public byte[] recivedClientACK;
|
||||
public byte[] recivedClientModlist;
|
||||
|
||||
private static final int PACKET_LENGTH_INDEX = 14;
|
||||
|
||||
private final Logger logger;
|
||||
private RegisteredServer handshakeServer;
|
||||
|
||||
public ForgeHandshakeDataHandler(RegisteredServer handshakeServer,Logger logger) {
|
||||
this.handshakeServer = handshakeServer;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
public void onPreLogin(PreLoginEvent event, Continuation continuation) {
|
||||
if (cachedServerHandshake == null) {
|
||||
handshakeReceiver receiver = new handshakeReceiver(handshakeServer, logger);
|
||||
receiver.getHandshake().thenAccept((p) -> {
|
||||
sendModlist(p.modListPacket,(LoginPhaseConnection) event.getConnection());
|
||||
sendOther(p.otherPackets,(LoginPhaseConnection) event.getConnection());
|
||||
continuation.resume();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void sendModlist(byte[] modListPacket, LoginPhaseConnection connection) {
|
||||
connection.sendLoginPluginMessage(MinecraftChannelIdentifier.create("fml","loginwrapper"), modListPacket, responseBody -> recivedClientModlist = responseBody);
|
||||
}
|
||||
|
||||
private void sendOther(List<byte[]> otherPackets, LoginPhaseConnection connection) {
|
||||
otherPackets.forEach((packet) -> {
|
||||
connection.sendLoginPluginMessage(MinecraftChannelIdentifier.create("fml","loginwrapper"), packet, responseBody -> recivedClientACK = responseBody);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class handshakeReceiver {
|
||||
|
||||
private static final int MAX_DATA_LENGTH = 16000;
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
private int numberOfRecivedParts;
|
||||
private byte[] recivedParts;
|
||||
private int recivedBytes;
|
||||
private final RegisteredServer forgeServer;
|
||||
|
||||
private handshakeReceiver(RegisteredServer server, Logger logger) {
|
||||
recivedParts = new byte[2000000];
|
||||
|
||||
this.logger = logger;
|
||||
this.forgeServer = server;
|
||||
|
||||
}
|
||||
|
||||
public CompletableFuture<CachedServerHandshake> getHandshake() {
|
||||
CompletableFuture<CachedServerHandshake> future = new CompletableFuture<CachedServerHandshake>();
|
||||
ping(future);
|
||||
return future;
|
||||
}
|
||||
|
||||
private void ping(CompletableFuture<CachedServerHandshake> future) {
|
||||
forgeServer.ping().thenAccept((s) -> onBackendPong(s, future));
|
||||
}
|
||||
|
||||
public void onBackendPong(ServerPing status, CompletableFuture<CachedServerHandshake> future) {
|
||||
numberOfRecivedParts++;
|
||||
if ((!status.getModinfo().isPresent()) || (!Objects.equals(status.getModinfo().get().getType(), "ambassador"))) {
|
||||
future.cancel(true);
|
||||
logger.error("The specified Forge server is not running the Forge-side version of this plugin!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ModInfo.Mod pair = status.getModinfo().orElseThrow(IllegalAccessError::new).getMods().get(0);
|
||||
|
||||
int[] values = Arrays.stream(pair.getVersion().substring(pair.getVersion().indexOf(":") + 1).split(":")).map(Integer::parseInt).mapToInt(x -> x).toArray();
|
||||
|
||||
int parts = Integer.parseInt((pair.getVersion().split(":")[0].split("-"))[1]);
|
||||
int recivedPartNr = Integer.parseInt((pair.getVersion().split(":")[0].split("-"))[0]);
|
||||
|
||||
logger.info("Downloaded part " + String.valueOf(numberOfRecivedParts) + " out of " + String.valueOf(parts));
|
||||
|
||||
placePartInArray(pair.getId().getBytes(StandardCharsets.ISO_8859_1), recivedPartNr - 1);
|
||||
|
||||
if (numberOfRecivedParts >= parts) {
|
||||
List<byte[]> packets = splitPackets(recivedParts,values);
|
||||
future.complete(new CachedServerHandshake("",packets.get(0),packets.subList(1,packets.size()-1)));
|
||||
} else {
|
||||
ping(future);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void placePartInArray(byte[] temp, int partNr) {
|
||||
int head = partNr * MAX_DATA_LENGTH;
|
||||
for (int i = 0; i < temp.length; i++) {
|
||||
recivedParts[head] = temp[i];
|
||||
head++;
|
||||
recivedBytes++;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getPacket(byte[] data, int startByteIndex, int lastByteIndex) {
|
||||
byte[] temp = new byte[lastByteIndex - startByteIndex + 1];
|
||||
|
||||
for (int i = startByteIndex; i <= lastByteIndex; i++) {
|
||||
temp[i - startByteIndex] = data[i];
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
private List<byte[]> splitPackets(byte[] data, int[] startPacketMarkers) {
|
||||
List<byte[]> list = new ArrayList<>();
|
||||
for (int i = 0; i < startPacketMarkers.length - 1; i++) {
|
||||
list.add(getPacket(data, startPacketMarkers[i], startPacketMarkers[i + 1] - 1));
|
||||
}
|
||||
list.add(getPacket(data, startPacketMarkers[startPacketMarkers.length - 1], recivedBytes - 1));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private class CachedServerHandshake {
|
||||
private String sessionID;
|
||||
private byte[] modListPacket;
|
||||
private List<byte[]> otherPackets;
|
||||
|
||||
private CachedServerHandshake(String sessionID,byte[] modListPacket,List<byte[]> otherPackets) {
|
||||
this.sessionID = sessionID;
|
||||
this.modListPacket = modListPacket;
|
||||
this.otherPackets = otherPackets;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user