diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java deleted file mode 100644 index be7058e..0000000 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.adde0109.ambassador; - -import com.google.inject.Inject; -import com.velocitypowered.api.event.PostOrder; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; -import com.velocitypowered.api.plugin.Plugin; -import com.velocitypowered.api.plugin.annotation.DataDirectory; -import com.velocitypowered.api.proxy.ProxyServer; - -import java.lang.reflect.Field; -import java.util.concurrent.Callable; - -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.network.BackendChannelInitializer; -import com.velocitypowered.proxy.network.ConnectionManager; -import com.velocitypowered.proxy.network.ServerChannelInitializer; -import io.netty.channel.ChannelInitializer; -import org.adde0109.ambassador.velocity.VelocityBackendChannelInitializer; -import org.adde0109.ambassador.velocity.VelocityServerChannelInitializer; -import org.adde0109.ambassador.velocity.VelocityEventHandler; -import org.bstats.charts.SingleLineChart; -import org.bstats.velocity.Metrics; -import org.slf4j.Logger; - -import java.nio.file.Path; - -@Plugin(id = "ambassador", name = "Ambassador", version = "1.1.7-alpha", authors = {"adde0109"}) -public class Ambassador { - - public ProxyServer server; - public final Logger logger; - private final Metrics.Factory metricsFactory; - private final Path dataDirectory; - - private static Ambassador instance; - public static Ambassador getInstance() { - return instance; - } - - - @Inject - public Ambassador(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory, Metrics.Factory metricsFactory) { - this.server = server; - this.logger = logger; - this.dataDirectory = dataDirectory; - this.metricsFactory = metricsFactory; - Ambassador.instance = this; - } - - @Subscribe(order = PostOrder.LAST) - public void onProxyInitialization(ProxyInitializeEvent event) throws ReflectiveOperationException { - initMetrics(); - - server.getEventManager().register(this, new VelocityEventHandler(this)); - - inject(); - } - - private void inject() throws ReflectiveOperationException { - Field cmField = VelocityServer.class.getDeclaredField("cm"); - cmField.setAccessible(true); - - ChannelInitializer original = ((ConnectionManager) cmField.get(server)).serverChannelInitializer.get(); - ((ConnectionManager) cmField.get(server)).serverChannelInitializer.set(new VelocityServerChannelInitializer(original,(VelocityServer) server)); - - ChannelInitializer originalBackend = ((ConnectionManager) cmField.get(server)).backendChannelInitializer.get(); - ((ConnectionManager) cmField.get(server)).backendChannelInitializer.set(new VelocityBackendChannelInitializer(originalBackend,(VelocityServer) server)); - } - - private void initMetrics() { - Metrics metrics = metricsFactory.make(this, 15655); - } -} diff --git a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java deleted file mode 100644 index c1a1ddf..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.velocitypowered.api.event.player.KickedFromServerEvent; -import com.velocitypowered.api.proxy.server.RegisteredServer; -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.backend.VelocityServerConnection; -import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.network.Connections; -import com.velocitypowered.proxy.protocol.StateRegistry; -import com.velocitypowered.proxy.protocol.packet.PluginMessage; -import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; -import io.netty.buffer.Unpooled; -import org.adde0109.ambassador.Ambassador; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; -import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler; -import org.adde0109.ambassador.velocity.VelocityLoginPayloadManager; - -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnectionPhase { - - //TODO: Use modData inside ConnectedPlayer instead - public byte[] modListData; - private RegisteredServer backupServer; - - public FML2CRPMClientConnectionPhase(VelocityForgeClientConnectionPhase.ClientPhase clientPhase, VelocityLoginPayloadManager payloadManager) { - super(clientPhase,payloadManager); - } - - public CompletableFuture reset(RegisteredServer server, ConnectedPlayer player) { - CompletableFuture future = new CompletableFuture<>(); - if (player.getConnectedServer() != null) { - backupServer = player.getConnectedServer().getServer(); - player.getConnectedServer().disconnect(); - player.setConnectedServer(null); - } - - MinecraftConnection connection = player.getConnection(); - connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),this)); - - ((VelocityServer) Ambassador.getInstance().server).unregisterConnection(player); - this.clientPhase = null; - - ScheduledFuture scheduledFuture = connection.eventLoop().schedule(()-> { - connection.getChannel().pipeline().remove(ForgeConstants.RESET_LISTENER); - future.complete(false); - },5, TimeUnit.SECONDS); - connection.getChannel().pipeline().addBefore(Connections.MINECRAFT_DECODER, ForgeConstants.RESET_LISTENER,new FML2CRPMResetCompleteDecoder()); - getPayloadManager().listenFor(98).thenAccept(ignore -> { - if (scheduledFuture.cancel(false)) { - connection.getChannel().pipeline().remove(ForgeConstants.RESET_LISTENER); - connection.setState(StateRegistry.LOGIN); - this.clientPhase = ClientPhase.HANDSHAKE; - future.complete(true); - } - }); - connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket()))); - return future; - } - 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); - - this.clientPhase = this.clientPhase == ClientPhase.MODLIST ? ClientPhase.MODDED : ClientPhase.VANILLA; - - connection.setState(StateRegistry.PLAY); - connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal()); - ((VelocityServer) Ambassador.getInstance().server).registerConnection(player); - - backupServer = null; - } - - public void handleKick(KickedFromServerEvent event) { - if (backupServer != null && !(event.getResult() instanceof KickedFromServerEvent.RedirectPlayer)) { - net.kyori.adventure.text.Component reason = event.getServerKickReason().orElse(null); - event.setResult(KickedFromServerEvent.RedirectPlayer.create(backupServer,reason)); - backupServer = null; - } - } - -} diff --git a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMResetCompleteDecoder.java b/src/main/java/org/adde0109/ambassador/forge/FML2CRPMResetCompleteDecoder.java deleted file mode 100644 index 6cee225..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMResetCompleteDecoder.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.velocitypowered.proxy.protocol.MinecraftPacket; -import com.velocitypowered.proxy.protocol.ProtocolUtils; -import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; - -public class FML2CRPMResetCompleteDecoder extends ChannelInboundHandlerAdapter { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) { - if (msg instanceof ByteBuf buf) { - if (!ctx.channel().isActive() || !buf.isReadable()) { - buf.release(); - return; - } - - int originalReaderIndex = buf.readerIndex(); - int packetId = ProtocolUtils.readVarInt(buf); - if (packetId == 0x02 && buf.readableBytes() > 1) { - try { - int id = ProtocolUtils.readVarInt(buf); - boolean success = buf.readBoolean(); - if (id == 98) { - try { - MinecraftPacket packet = new LoginPluginResponse(id,success,buf.readRetainedSlice(buf.readableBytes())); - ctx.fireChannelRead(packet); - } finally { - buf.release(); - } - return; - } - } catch (Exception ignored) {} - } - buf.readerIndex(originalReaderIndex); - } - ctx.fireChannelRead(msg); - } -} diff --git a/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java deleted file mode 100644 index ae297a7..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.velocitypowered.api.event.Continuation; -import com.velocitypowered.api.proxy.server.RegisteredServer; -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.MinecraftConnection; -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.packet.LoginPluginMessage; -import io.netty.buffer.ByteBuf; -import io.netty.util.ReferenceCountUtil; -import net.kyori.adventure.text.Component; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; -import org.apache.commons.collections4.map.PassiveExpiringMap; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhase { - - private static String OUTBOUND_CATCHER_NAME = "ambassador-catcher"; - - private static final PassiveExpiringMap TEMPORARY_FORCED = new PassiveExpiringMap<>(120, TimeUnit.SECONDS); - - private Throwable throwable; - private RegisteredServer triedServer; - private Continuation continuation; - private CompletableFuture onJoinGame; - - private static final Method CONNECT_TO_INITIAL_SERVER; - - static { - Class clazz; - try { - clazz = Class.forName("com.velocitypowered.proxy.connection.client.LoginSessionHandler"); - } catch (ClassNotFoundException ignored){ - try { - clazz = Class.forName("com.velocitypowered.proxy.connection.client.AuthSessionHandler"); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - try { - CONNECT_TO_INITIAL_SERVER = clazz.getDeclaredMethod("connectToInitialServer", ConnectedPlayer.class); - CONNECT_TO_INITIAL_SERVER.setAccessible(true); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - @Override - public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) { - this.continuation = continuation; - final MinecraftConnection connection = player.getConnection(); - - forced = TEMPORARY_FORCED.remove(player.getUsername()); - if (forced != null) { - player.createConnectionRequest(forced).fireAndForget(); - } else { - try { - CONNECT_TO_INITIAL_SERVER.invoke(player.getConnection().getSessionHandler(),player); - } catch (ReflectiveOperationException e) { - continuation.resumeWithException(e); - } - } - } - - @Override - public CompletableFuture reset(RegisteredServer server, ConnectedPlayer player) { - FML2CRPMClientConnectionPhase newPhase = new FML2CRPMClientConnectionPhase(clientPhase,getPayloadManager()); - player.setPhase(newPhase); - CompletableFuture future = newPhase.reset(server,player); - future.thenAccept(success -> { - if (!success) { - TEMPORARY_FORCED.put(player.getUsername(),server); - player.disconnect(Component.text("Please reconnect")); - } - }); - return future; - } - - @Override - public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) { - if (triedServer != null) - player.sendMessage(Component.translatable("velocity.error.connecting-server-error", - Component.text(triedServer.getServerInfo().getName()))); - clientPhase = clientPhase == ClientPhase.MODLIST ? ClientPhase.MODDED : ClientPhase.VANILLA; - internalServerConnection = player.getConnectionInFlight(); - player.resetInFlightConnection(); - this.onJoinGame = new CompletableFuture<>(); - continuation.resume(); - } - - public void handleJoinGame() { - this.onJoinGame.complete(null); - } - - public CompletableFuture awaitJoinGame() { - return this.onJoinGame; - } - - @Override - public void handleForward(VelocityServerConnection serverConnection, LoginPluginMessage payload) { - final ByteBuf buf = payload.content().duplicate(); - ProtocolUtils.readString(buf); //Channel - ProtocolUtils.readVarInt(buf); //Length - if (ProtocolUtils.readVarInt(buf) == 1) { - getPayloadManager().listenFor(payload.getId()).thenAccept(rawResponse -> { - final ByteBuf response = rawResponse.duplicate(); - ProtocolUtils.readString(response); //Channel - ProtocolUtils.readVarInt(response); //Length - if (ProtocolUtils.readVarInt(response) == 2) { - String[] mods = ProtocolUtils.readStringArray(response); - if (Arrays.stream(mods).anyMatch(s -> s.equals("clientresetpacket"))) { - serverConnection.getPlayer().setPhase(new FML2CRPMClientConnectionPhase(clientPhase,getPayloadManager())); - } - } - }); - } - } -} diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java b/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java deleted file mode 100644 index e2300e2..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.velocitypowered.proxy.connection.ConnectionType; - -public class ForgeConstants { - public static final String HANDLER = "Modern Forge handler"; - public static final String OUTBOUND_CATCHER_NAME = "ambassador-catcher"; - public static final String RESET_LISTENER = "ambassador-reset-listener"; - - public static final String FML2Marker = "\0FML2\0"; - public static final String FML3Marker = "\0FML3\0"; - public static final ConnectionType ForgeFML2 = new ForgeFMLConnectionType(2); - public static final ConnectionType ForgeFML3 = new ForgeFMLConnectionType(3); -} diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java b/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java deleted file mode 100644 index 8d6ffe1..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.velocitypowered.api.util.GameProfile; -import com.velocitypowered.proxy.config.PlayerInfoForwarding; -import com.velocitypowered.proxy.connection.ConnectionType; -import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase; -import com.velocitypowered.proxy.connection.client.ClientConnectionPhase; -import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase; - -import java.util.Collections; - -public class ForgeFMLConnectionType implements ConnectionType { - - final int netVersion; - - public ForgeFMLConnectionType(int netVersion) { - this.netVersion = netVersion; - } - - @Override - public ClientConnectionPhase getInitialClientPhase() { - return new FML2ClientConnectionPhase(); - } - - @Override - public BackendConnectionPhase getInitialBackendPhase() { - return new VelocityForgeBackendConnectionPhase(); - } - - @Override - public GameProfile addGameProfileTokensIfRequired(GameProfile original, PlayerInfoForwarding forwardingType) { - if (forwardingType == PlayerInfoForwarding.LEGACY) { - return original.addProperties(Collections.singleton(new GameProfile.Property("extraData", "\1FML" + netVersion + "\1", ""))); - } else { - return original; - } - } -} diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java deleted file mode 100644 index 1da533e..0000000 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.adde0109.ambassador.forge; - -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; -import com.velocitypowered.api.proxy.server.RegisteredServer; -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; -import java.util.concurrent.CompletableFuture; - -public class ForgeHandshakeUtils { - - public static int readVarInt(ByteArrayDataInput stream) { - int i = 0; - int j = 0; - - byte b0; - do { - b0 = stream.readByte(); - i |= (b0 & 127) << j++ * 7; - if (j > 5) { - throw new RuntimeException("VarInt too big"); - } - } while((b0 & 128) == 128); - - return i; - } - - public static void writeVarInt(ByteArrayDataOutput stream,int i) { - while((i & -128) != 0) { - stream.writeByte(i & 127 | 128); - i >>>= 7; - } - - stream.writeByte(i); - } - - public static void writeUtf(ByteArrayDataOutput stream,String p_211400_1_) { - byte[] abyte = p_211400_1_.getBytes(StandardCharsets.UTF_8); - writeVarInt(stream,abyte.length); - stream.write(abyte); - } - - public static byte[] generateTestPacket() { - ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput(); - writeVarInt(dataAndPacketIdStream,4); - writeUtf(dataAndPacketIdStream,"ambassadortestpacket"); - 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(); - } - - public static byte[] generateResetPacket() { - ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput(); - writeVarInt(dataAndPacketIdStream,98); - - ByteArrayDataOutput stream = ByteStreams.newDataOutput(); - byte[] dataAndPacketId = dataAndPacketIdStream.toByteArray(); - writeUtf(stream,"fml:handshake"); - writeVarInt(stream,dataAndPacketId.length); - stream.write(dataAndPacketId); - return stream.toByteArray(); - } - public static byte[] generatePluginResetPacket() { - ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput(); - writeVarInt(dataAndPacketIdStream,98); - return dataAndPacketIdStream.toByteArray(); - } - - public static final byte[] emptyModlist = generateEmptyModlist(); - private 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(); - } - - - public static final byte[] ACKPacket = generateACKPacket(); - private static byte[] generateACKPacket() { - ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput(); - writeVarInt(dataAndPacketIdStream,99); - - ByteArrayDataOutput stream = ByteStreams.newDataOutput(); - byte[] dataAndPacketId = dataAndPacketIdStream.toByteArray(); - writeUtf(stream,"fml:handshake"); - writeVarInt(stream,dataAndPacketId.length); - stream.write(dataAndPacketId); - return stream.toByteArray(); - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java deleted file mode 100644 index 711acda..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.network.BackendChannelInitializer; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; -import org.adde0109.ambassador.forge.ForgeConstants; -import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler; - - -import java.lang.reflect.Method; - -public class VelocityBackendChannelInitializer extends BackendChannelInitializer { - - private static final Method INIT_CHANNEL; - - private final ChannelInitializer delegate; - private final VelocityServer server; - - static { - try { - INIT_CHANNEL = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class); - INIT_CHANNEL.setAccessible(true); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - public VelocityBackendChannelInitializer(ChannelInitializer delegate, VelocityServer server) { - super(server); - this.delegate = delegate; - this.server = server; - } - - @Override - protected void initChannel(Channel ch) { - try { - INIT_CHANNEL.invoke(delegate,ch); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - ch.pipeline().addLast(ForgeConstants.HANDLER, new VelocityForgeBackendHandshakeHandler(server)); - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java deleted file mode 100644 index fd9cfc4..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.api.event.Continuation; -import com.velocitypowered.api.event.PostOrder; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.connection.PostLoginEvent; -import com.velocitypowered.api.event.permission.PermissionsSetupEvent; -import com.velocitypowered.api.event.player.*; -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.protocol.packet.ClientSettings; -import org.adde0109.ambassador.Ambassador; -import org.adde0109.ambassador.forge.FML2CRPMClientConnectionPhase; -import org.adde0109.ambassador.forge.FML2ClientConnectionPhase; -import org.adde0109.ambassador.forge.ForgeConstants; -import org.adde0109.ambassador.forge.ForgeFMLConnectionType; -import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase; - -public class VelocityEventHandler { - - private final Ambassador ambassador; - - public VelocityEventHandler(Ambassador ambassador) { - this.ambassador = ambassador; - } - - @Subscribe - public void onPermissionsSetupEvent(PermissionsSetupEvent event, Continuation continuation) { - if(!(event.getSubject() instanceof ConnectedPlayer player)) { - continuation.resume(); - return; - } - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - player.getConnection().eventLoop().submit(() -> phase.fireLoginEvent(player, (VelocityServer) ambassador.server,continuation)); - } - - @Subscribe(order = PostOrder.LAST) - public void onKickedFromServerEvent(KickedFromServerEvent event, Continuation continuation) { - if (((ConnectedPlayer) event.getPlayer()).getPhase() instanceof FML2CRPMClientConnectionPhase phase) { - phase.handleKick(event); - } - continuation.resume(); - } - - @Subscribe(order = PostOrder.LAST) - public void onServerPreConnectEvent(ServerPreConnectEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - if (phase.internalServerConnection != null) { - event.setResult(ServerPreConnectEvent.ServerResult.denied()); - player.setConnectedServer((VelocityServerConnection) phase.internalServerConnection); - phase.internalServerConnection = null; - } else if (phase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.MODDED) { - player.getConnection().eventLoop().submit(() -> phase.reset(event.getOriginalServer(), (ConnectedPlayer) event.getPlayer()) - .thenAccept((ignored) -> continuation.resume())); - } else { - continuation.resume(); - } - } - - @Subscribe(order = PostOrder.LAST) - public void onPlayerChooseInitialServerEvent(PlayerChooseInitialServerEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - if (event.getInitialServer().isEmpty()) - event.setInitialServer(phase.internalServerConnection.getServer()); - continuation.resume(); - } - - @Subscribe(order = PostOrder.LAST) - public void onServerPostConnectEvent(ServerPostConnectEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - if (phase instanceof FML2ClientConnectionPhase specialPhase) { - specialPhase.handleJoinGame(); - } - //if (((ConnectedPlayer) event.getPlayer()).getConnectedServer() != null && ((ConnectedPlayer) event.getPlayer()).getConnectedServer().getConnection() != null) { - // ((ConnectedPlayer) event.getPlayer()).getConnectedServer().getConnection().write(new ClientSettings("en_GB", (byte) 10, 0, true, (short) 0xFF,1,false,true)); - //} - continuation.resume(); - } - - @Subscribe - public void onLoginEvent(PostLoginEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - - if (phase instanceof FML2ClientConnectionPhase specialPhase) { - specialPhase.awaitJoinGame().thenAcceptAsync((ignored) -> { - player.setConnectedServer(null); - continuation.resume(); - },player.getConnection().eventLoop()); - } - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java deleted file mode 100644 index a7046cd..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.api.event.Continuation; -import com.velocitypowered.api.proxy.ServerConnection; -import com.velocitypowered.api.proxy.server.RegisteredServer; -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.connection.client.ClientConnectionPhase; -import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; - -import java.util.concurrent.CompletableFuture; - -public abstract class VelocityForgeClientConnectionPhase implements ClientConnectionPhase { - //TODO:Make class when PCF is done - - - VelocityLoginPayloadManager payloadManager; - public VelocityForgeClientConnectionPhase.ClientPhase clientPhase = ClientPhase.HANDSHAKE; - - public ServerConnection internalServerConnection; - public RegisteredServer forced; - - protected VelocityForgeClientConnectionPhase(ClientPhase clientPhase, VelocityLoginPayloadManager payloadManager) { - this.clientPhase = clientPhase; - this.payloadManager = payloadManager; - } - protected VelocityForgeClientConnectionPhase() { - } - - public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) { - } - - public CompletableFuture reset(RegisteredServer server, ConnectedPlayer player) { - return CompletableFuture.completedFuture(false); - } - - public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) { - - } - - final void fireLoginEvent(ConnectedPlayer player, VelocityServer server, Continuation continuation) { - payloadManager = new VelocityLoginPayloadManager(player.getConnection()); - handleLogin(player,server,continuation); - - VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), this); - player.getConnection().setSessionHandler(sessionHandler); - } - - public void handleForward(VelocityServerConnection serverConnection, LoginPluginMessage payload) { - } - - final public void forwardPayload(VelocityServerConnection serverConnection, LoginPluginMessage payload) { - handleForward(serverConnection,payload); - if (payloadManager == null) { - payload.release(); - return; - } - payloadManager.sendPayload("fml:loginwrapper",payload.content()).thenAccept((responseData) -> { - //Move this to the backend. Backend should have its own forwarder. - serverConnection.getConnection().write(new LoginPluginResponse(payload.getId(),responseData.isReadable(),responseData.retain())); - }); - clientPhase = ClientPhase.MODLIST; - } - - public final VelocityLoginPayloadManager getPayloadManager() { - return payloadManager; - } - - public enum ClientPhase { - VANILLA, - HANDSHAKE, - MODLIST, - MODDED - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java deleted file mode 100644 index 2c65f0c..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; -import io.netty.buffer.ByteBuf; - -public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHandler { - private final MinecraftSessionHandler original; - private final VelocityForgeClientConnectionPhase phase; - - public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, VelocityForgeClientConnectionPhase phase) { - this.original = original; - this.phase = phase; - } - - @Override - public boolean handle(LoginPluginResponse packet) { - if (phase.getPayloadManager().handlePayload(packet)) { - return true; - } else { - return original.handle(packet); - } - } - @Override - public void handleUnknown(ByteBuf buf) { - original.handleUnknown(buf); - } - - @Override - public void disconnected() { - original.disconnected(); - } - - public MinecraftSessionHandler getOriginal() { - return this.original; - } -} \ No newline at end of file diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java deleted file mode 100644 index 1bc208a..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.proxy.connection.ConnectionTypes; -import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler; -import com.velocitypowered.proxy.protocol.MinecraftPacket; -import com.velocitypowered.proxy.protocol.StateRegistry; -import com.velocitypowered.proxy.protocol.packet.Handshake; -import io.netty.buffer.ByteBuf; -import org.adde0109.ambassador.forge.ForgeConstants; - -public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler { - private final HandshakeSessionHandler original; - private final MinecraftConnection connection; - - public VelocityHandshakeSessionHandler(HandshakeSessionHandler original, MinecraftConnection connection) { - this.original = original; - this.connection = connection; - } - - @Override - public boolean handle(Handshake handshake) { - handshake.handle(original); - if (connection.getType() == ConnectionTypes.VANILLA) { - final String[] markerSplit = handshake.getServerAddress().split("\0"); - if (connection.getState() == StateRegistry.LOGIN && markerSplit.length > 1) { - switch (markerSplit[1]) { - case "FML2" -> connection.setType(ForgeConstants.ForgeFML2); - case "FML3" -> connection.setType(ForgeConstants.ForgeFML3); - } - } - } - return true; - } - - - @Override - public void handleGeneric(MinecraftPacket packet) { - original.handleGeneric(packet); - } - - @Override - public void handleUnknown(ByteBuf buf) { - original.handleUnknown(buf); - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityLoginPayloadManager.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityLoginPayloadManager.java deleted file mode 100644 index 2fe0461..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityLoginPayloadManager.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; -import io.netty.buffer.ByteBuf; - -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -public class VelocityLoginPayloadManager { - private final HashMap> listenerList = new HashMap<>(); - private int counter = 0; - private final MinecraftConnection connection; - - public VelocityLoginPayloadManager(MinecraftConnection connection) { - this.connection = connection; - } - - public CompletableFuture sendPayload(String channel, ByteBuf data) { - connection.write(new LoginPluginMessage(counter,channel,data)); - CompletableFuture future = listenFor(counter); - counter++; - return future; - } - - public CompletableFuture sendPayloads(String channel, List dataList) { - final CompletableFuture callback = new CompletableFuture<>(); - for (ByteBuf data : dataList) { - connection.delayedWrite(new LoginPluginMessage(counter, channel, data)); - listenerList.put(counter,callback); - counter++; - } - connection.flush(); - return callback; - } - - public CompletableFuture listenFor(int id) { - CompletableFuture value = listenerList.get(id); - if (value == null) { - CompletableFuture callback = new CompletableFuture<>(); - listenerList.put(id,callback); - return callback; - } else { - return value; - } - } - - boolean handlePayload(LoginPluginResponse response) { - final CompletableFuture callback = listenerList.get(response.getId()); - if (callback != null) { - listenerList.remove(response.getId()); - if (!listenerList.containsValue(callback)) { - callback.complete(response.content()); - } - return true; - } else { - return false; - } - } - } diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityServerChannelInitializer.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityServerChannelInitializer.java deleted file mode 100644 index 825802a..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityServerChannelInitializer.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.adde0109.ambassador.velocity; - -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler; -import com.velocitypowered.proxy.network.Connections; -import com.velocitypowered.proxy.network.ServerChannelInitializer; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelInitializer; -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Method; - -public class VelocityServerChannelInitializer extends ServerChannelInitializer { - private static final Method INIT_CHANNEL; - - private final ChannelInitializer delegate; - - static { - try { - INIT_CHANNEL = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class); - INIT_CHANNEL.setAccessible(true); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - public VelocityServerChannelInitializer(ChannelInitializer delegate,VelocityServer server) { - super(server); - this.delegate = delegate; - } - - @Override - protected void initChannel(@NotNull Channel ch){ - try { - INIT_CHANNEL.invoke(delegate,ch); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - ChannelHandler handler = ch.pipeline().get(Connections.HANDLER); - if (!(handler instanceof final MinecraftConnection connection)) throw new RuntimeException("plugin conflict"); - HandshakeSessionHandler originalSessionHandler = (HandshakeSessionHandler) connection.getSessionHandler(); - connection.setSessionHandler(new VelocityHandshakeSessionHandler(originalSessionHandler, connection)); - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java deleted file mode 100644 index 5692f26..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.adde0109.ambassador.velocity.backend; - -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.backend.LoginSessionHandler; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.protocol.MinecraftPacket; -import com.velocitypowered.proxy.protocol.packet.Disconnect; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; -import io.netty.buffer.ByteBuf; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextColor; -import org.adde0109.ambassador.forge.ForgeConstants; -import org.adde0109.ambassador.forge.ForgeFMLConnectionType; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; - -public class ForgeHandshakeSessionHandler implements MinecraftSessionHandler { - - private final LoginSessionHandler original; - private final VelocityServerConnection serverConnection; - private final VelocityServer server; - - public ForgeHandshakeSessionHandler(LoginSessionHandler original, VelocityServerConnection serverConnection, VelocityServer server) { - this.original = original; - this.serverConnection = serverConnection; - this.server = server; - } - - @Override - public boolean handle(LoginPluginMessage packet) { - if (packet.getChannel().equals("fml:loginwrapper")) { - if (!(serverConnection.getConnection().getType() instanceof ForgeFMLConnectionType)) { - if (!(serverConnection.getPlayer().getConnection().getType() instanceof ForgeFMLConnectionType clientType)) { - final String reason = "This server has mods that require Forge to be installed on the client. Contact your server admin for more details."; - original.handle(Disconnect.create(Component.text(reason, NamedTextColor.RED),serverConnection.getPlayer().getProtocolVersion())); - return true; - } - serverConnection.getConnection().setType(clientType); - serverConnection.setConnectionPhase(clientType.getInitialBackendPhase()); - } - ((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handle(serverConnection,serverConnection.getPlayer(),packet); - return true; - } - return original.handle(packet); - } - - @Override - public boolean handle(ServerLoginSuccess packet) { - if ((serverConnection.getPlayer().getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - phase.complete(server,serverConnection.getPlayer(),serverConnection.getPlayer().getConnection()); - } - return original.handle(packet); - } - - - @Override - public void disconnected() { - original.disconnected(); - } - - public void handleGeneric(MinecraftPacket packet) { - if (!packet.handle(original)) - original.handleGeneric(packet); - } - - public MinecraftSessionHandler getOriginal() { - return this.original; - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java deleted file mode 100644 index 939f474..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.adde0109.ambassador.velocity.backend; - -import com.velocitypowered.proxy.VelocityServer; -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.packet.LoginPluginMessage; -import io.netty.buffer.ByteBuf; -import io.netty.util.ReferenceCountUtil; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; - -import java.util.ArrayList; -import java.util.List; - -public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase { - - - public VelocityForgeBackendConnectionPhase() { - } - - public void handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) { - VelocityForgeClientConnectionPhase clientPhase = ((VelocityForgeClientConnectionPhase) player.getPhase()); - if (clientPhase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.VANILLA) { - final LoginPluginMessage msg = message; - - msg.content().retain().discardSomeReadBytes(); - - server.getConnection().getChannel().config().setAutoRead(false); - clientPhase.reset(server.getServer(),player).thenAccept((success) -> { - if (success) { - clientPhase.forwardPayload(server,msg); - server.getConnection().getChannel().config().setAutoRead(true); - } else { - msg.release(); - } - }); - } else { - clientPhase.forwardPayload(server, (LoginPluginMessage) message.retain()); - } - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java deleted file mode 100644 index 06328bd..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.adde0109.ambassador.velocity.backend; - -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.config.PlayerInfoForwarding; -import com.velocitypowered.proxy.connection.MinecraftConnection; -import com.velocitypowered.proxy.connection.backend.LoginSessionHandler; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.network.Connections; -import com.velocitypowered.proxy.protocol.packet.Handshake; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; -import io.netty.channel.*; -import io.netty.util.ReferenceCountUtil; -import org.adde0109.ambassador.forge.ForgeConstants; -import org.adde0109.ambassador.forge.ForgeFMLConnectionType; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; -import org.jetbrains.annotations.NotNull; - -public class VelocityForgeBackendHandshakeHandler extends ChannelInboundHandlerAdapter { - - private final VelocityServer server; - - public VelocityForgeBackendHandshakeHandler(VelocityServer server) { - this.server = server; - } - - @Override - public void channelActive(@NotNull ChannelHandlerContext ctx) throws Exception { - MinecraftConnection connection = (MinecraftConnection) ctx.pipeline().get(Connections.HANDLER); - VelocityServerConnection serverConnection = (VelocityServerConnection) connection.getAssociation(); - - if (serverConnection.getPlayer().getConnection().getType() instanceof ForgeFMLConnectionType) { - connection.setSessionHandler(new ForgeHandshakeSessionHandler((LoginSessionHandler) connection.getSessionHandler(),serverConnection,server)); - } - - ctx.pipeline().remove(this); - ctx.pipeline().fireChannelActive(); - } -}