WIP: Almost
This commit is contained in:
parent
e8f73d19b1
commit
fea9082dd7
|
|
@ -1,11 +1,19 @@
|
|||
package org.adde0109.ambassador.forge;
|
||||
|
||||
import com.velocitypowered.api.event.Continuation;
|
||||
import com.velocitypowered.api.util.UuidUtils;
|
||||
import com.velocitypowered.proxy.Velocity;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
|
@ -14,7 +22,12 @@ import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnectionPhase {
|
||||
private boolean isResettable;
|
||||
|
|
@ -23,15 +36,15 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
|
|||
public byte[] modListData;
|
||||
|
||||
private final ArrayList<Integer> listenerList = new ArrayList();
|
||||
private Continuation whenComplete;
|
||||
private Runnable whenComplete;
|
||||
@Override
|
||||
public void handleLogin(ConnectedPlayer player,ForgeHandshakeUtils.CachedServerHandshake handshake, Continuation continuation) {
|
||||
this.whenComplete = continuation;
|
||||
this.whenComplete = continuation::resume;
|
||||
final MinecraftConnection connection = player.getConnection();
|
||||
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player);
|
||||
if(handshake == null) {
|
||||
connection.delayedWrite(new LoginPluginMessage(98,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateResetPacket())));
|
||||
listenerList.add(98);
|
||||
connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateEmptyModlist())));
|
||||
listenerList.add(1);
|
||||
} else {
|
||||
connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
|
||||
listenerList.add(1);
|
||||
|
|
@ -59,9 +72,22 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
|
|||
}
|
||||
modListData = ByteBufUtil.getBytes(packet.content());
|
||||
}
|
||||
if (listenerList.isEmpty()) {
|
||||
whenComplete.resume();
|
||||
if (listenerList.isEmpty() && whenComplete != null) {
|
||||
whenComplete.run();
|
||||
whenComplete = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public void reset(ConnectedPlayer player,MinecraftConnection connection, List<byte[]> messages, Runnable whenComplete) {
|
||||
this.whenComplete = whenComplete;
|
||||
connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player));
|
||||
connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
|
||||
listenerList.add(98);
|
||||
connection.setState(StateRegistry.LOGIN);
|
||||
for (int i = 0;i<messages.size();i++) {
|
||||
connection.delayedWrite(new LoginPluginMessage(i+2,"fml:loginwrapper", Unpooled.wrappedBuffer(messages.get(i))));
|
||||
listenerList.add(i+2);
|
||||
}
|
||||
connection.flush();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
|||
import com.velocitypowered.proxy.connection.ConnectionType;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
||||
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
||||
import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase;
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ public class ForgeFML2ConnectionType implements ConnectionType {
|
|||
|
||||
@Override
|
||||
public BackendConnectionPhase getInitialBackendPhase() {
|
||||
return new VelocityForgeBackendConnectionPhase();
|
||||
return BackendConnectionPhases.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -8,7 +8,16 @@ import com.velocitypowered.api.proxy.server.ServerPing;
|
|||
import com.velocitypowered.api.util.ModInfo;
|
||||
import java.util.*;
|
||||
|
||||
import com.velocitypowered.api.util.UuidUtils;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
|
@ -73,11 +82,46 @@ public class ForgeHandshakeUtils {
|
|||
stream.write(dataAndPacketId);
|
||||
return stream.toByteArray();
|
||||
}
|
||||
public static byte[] generatePluginResetPacket() {
|
||||
ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput();
|
||||
writeVarInt(dataAndPacketIdStream,98);
|
||||
return dataAndPacketIdStream.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] generateEmptyModlist() {
|
||||
ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput();
|
||||
writeVarInt(dataAndPacketIdStream,1);
|
||||
writeVarInt(dataAndPacketIdStream,0);
|
||||
writeVarInt(dataAndPacketIdStream,0);
|
||||
writeVarInt(dataAndPacketIdStream,0);
|
||||
|
||||
ByteArrayDataOutput stream = ByteStreams.newDataOutput();
|
||||
byte[] dataAndPacketId = dataAndPacketIdStream.toByteArray();
|
||||
writeUtf(stream,"fml:handshake");
|
||||
writeVarInt(stream,dataAndPacketId.length);
|
||||
stream.write(dataAndPacketId);
|
||||
return stream.toByteArray();
|
||||
}
|
||||
|
||||
static public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) {
|
||||
VelocityConfiguration configuration = (VelocityConfiguration) server.getConfiguration();
|
||||
UUID playerUniqueId = player.getUniqueId();
|
||||
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) {
|
||||
playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername());
|
||||
}
|
||||
ServerLoginSuccess success = new ServerLoginSuccess();
|
||||
success.setUsername(player.getUsername());
|
||||
success.setUuid(playerUniqueId);
|
||||
connection.write(success);
|
||||
|
||||
connection.setState(StateRegistry.PLAY);
|
||||
connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal());
|
||||
}
|
||||
|
||||
public static final byte[] ACKPacket = generateACKPacket();
|
||||
private static byte[] generateACKPacket() {
|
||||
ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput();
|
||||
writeVarInt(dataAndPacketIdStream,4);
|
||||
writeVarInt(dataAndPacketIdStream,99);
|
||||
|
||||
ByteArrayDataOutput stream = ByteStreams.newDataOutput();
|
||||
byte[] dataAndPacketId = dataAndPacketIdStream.toByteArray();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.velocitypowered.api.event.Continuation;
|
|||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
|
||||
import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
|
|
@ -11,6 +12,7 @@ import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
|||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
||||
|
|
@ -54,11 +56,14 @@ public class VelocityEventHandler {
|
|||
continuation.resumeWithException(new NullPointerException());
|
||||
return;
|
||||
}
|
||||
serverCon.setConnectionPhase(new VelocityForgeBackendConnectionPhase());
|
||||
connection.setType(new ForgeFML2ConnectionType());
|
||||
MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon);
|
||||
connection.setSessionHandler(sessionHandler);
|
||||
sessionHandler.handle(new LoginPluginMessage(event.getSequenceId(),event.getIdentifier().getId(), Unpooled.wrappedBuffer(event.getContents())));
|
||||
continuation.resume();
|
||||
connection.eventLoop().submit(() -> {
|
||||
connection.setType(new ForgeFML2ConnectionType());
|
||||
serverCon.setConnectionPhase(new VelocityForgeBackendConnectionPhase(ambassador));
|
||||
byte[] response = ((VelocityForgeBackendConnectionPhase)serverCon.getPhase()).generateResponse(serverCon.getPlayer(), Unpooled.wrappedBuffer(event.getContents()));
|
||||
event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(response));
|
||||
continuation.resume();
|
||||
MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon);
|
||||
connection.setSessionHandler(sessionHandler);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
|||
public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHandler {
|
||||
private final MinecraftSessionHandler original;
|
||||
private final ConnectedPlayer player;
|
||||
|
||||
public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, ConnectedPlayer player) {
|
||||
this.original = original;
|
||||
this.player = player;
|
||||
|
|
@ -37,4 +38,8 @@ public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHan
|
|||
public void disconnected() {
|
||||
original.disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
public MinecraftSessionHandler getOriginal() {
|
||||
return this.original;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,43 @@
|
|||
package org.adde0109.ambassador.velocity.backend;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
||||
import org.adde0109.ambassador.forge.ForgeHandshakeUtils;
|
||||
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
|
||||
|
||||
public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) {
|
||||
if (!message.getChannel().equals("fml:loginwrapper") || !(player.getPhase() instanceof VelocityForgeClientConnectionPhase)) {
|
||||
return false;
|
||||
}
|
||||
MinecraftConnection connection = server.getConnection();
|
||||
if (connection == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
private final Ambassador ambassador;
|
||||
private final List<byte[]> handshakeMessages = new ArrayList<>();
|
||||
|
||||
ByteBuf content = message.content();
|
||||
public VelocityForgeBackendConnectionPhase(Ambassador ambassador) {
|
||||
this.ambassador = ambassador;
|
||||
}
|
||||
|
||||
public void handleSuccess(VelocityServerConnection serverCon) {
|
||||
((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()).reset(serverCon.getPlayer(),serverCon.getPlayer().getConnection(), handshakeMessages,
|
||||
() -> ForgeHandshakeUtils.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection()));
|
||||
}
|
||||
|
||||
public byte[] generateResponse(ConnectedPlayer player, ByteBuf content) {
|
||||
content.readBytes(14); //Channel Identifier
|
||||
ProtocolUtils.readVarInt(content); //Length
|
||||
int packetID = ProtocolUtils.readVarInt(content);
|
||||
|
|
@ -38,14 +47,23 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha
|
|||
|
||||
case 1:
|
||||
final byte[] data = ((ForgeFML2ClientConnectionPhase) player.getPhase()).modListData;
|
||||
connection.write(new LoginPluginResponse(message.getId(),true, Unpooled.wrappedBuffer(data)));
|
||||
break;
|
||||
return data;
|
||||
|
||||
default:
|
||||
connection.write(new LoginPluginResponse(message.getId(),true,Unpooled.wrappedBuffer(ForgeHandshakeUtils.ACKPacket)));
|
||||
break;
|
||||
return ForgeHandshakeUtils.ACKPacket;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) {
|
||||
if (!message.getChannel().equals("fml:loginwrapper") || !(player.getPhase() instanceof VelocityForgeClientConnectionPhase)) {
|
||||
return false;
|
||||
}
|
||||
MinecraftConnection connection = server.getConnection();
|
||||
if (connection == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
connection.write(new LoginPluginResponse(message.getId(),true, Unpooled.wrappedBuffer(generateResponse(player,message.content()))));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSes
|
|||
|
||||
@Override
|
||||
public boolean handle(ServerLoginSuccess packet) {
|
||||
return original.handle(packet);
|
||||
original.handle(packet);
|
||||
((VelocityForgeBackendConnectionPhase) serverCon.getPhase()).handleSuccess(serverCon);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user