WIP: Almost done
This commit is contained in:
parent
2ab257ffe7
commit
007ff8511a
|
|
@ -4,7 +4,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'org.adde0109'
|
group 'org.adde0109'
|
||||||
version '1.0.0-alpha'
|
version '1.0.2-alpha'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import org.adde0109.ambassador.forge.ForgeConnection;
|
||||||
import org.adde0109.ambassador.forge.ForgeHandshakeHandler;
|
import org.adde0109.ambassador.forge.ForgeHandshakeHandler;
|
||||||
import org.adde0109.ambassador.forge.ForgeHandshakeUtils;
|
import org.adde0109.ambassador.forge.ForgeHandshakeUtils;
|
||||||
import org.adde0109.ambassador.forge.ForgeServerSwitchHandler;
|
import org.adde0109.ambassador.forge.ForgeServerSwitchHandler;
|
||||||
|
import org.adde0109.ambassador.velocity.VelocityBackendChannelInitializer;
|
||||||
import org.adde0109.ambassador.velocity.VelocityServerChannelInitializer;
|
import org.adde0109.ambassador.velocity.VelocityServerChannelInitializer;
|
||||||
import org.adde0109.ambassador.velocity.VelocityEventHandler;
|
import org.adde0109.ambassador.velocity.VelocityEventHandler;
|
||||||
import org.bstats.charts.SingleLineChart;
|
import org.bstats.charts.SingleLineChart;
|
||||||
|
|
@ -28,7 +29,7 @@ import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
@Plugin(id = "ambassador", name = "Ambassador", version = "1.0.0-alpha", authors = {"adde0109"})
|
@Plugin(id = "ambassador", name = "Ambassador", version = "1.0.2-alpha", authors = {"adde0109"})
|
||||||
public class Ambassador {
|
public class Ambassador {
|
||||||
|
|
||||||
public ProxyServer server;
|
public ProxyServer server;
|
||||||
|
|
@ -72,11 +73,12 @@ public class Ambassador {
|
||||||
private void inject() throws ReflectiveOperationException {
|
private void inject() throws ReflectiveOperationException {
|
||||||
Field cmField = VelocityServer.class.getDeclaredField("cm");
|
Field cmField = VelocityServer.class.getDeclaredField("cm");
|
||||||
cmField.setAccessible(true);
|
cmField.setAccessible(true);
|
||||||
Field endpointMap = ConnectionManager.class.getDeclaredField("endpoints");
|
|
||||||
endpointMap.setAccessible(true);
|
|
||||||
|
|
||||||
ChannelInitializer<?> original = ((ConnectionManager) cmField.get(server)).serverChannelInitializer.get();
|
ChannelInitializer<?> original = ((ConnectionManager) cmField.get(server)).serverChannelInitializer.get();
|
||||||
((ConnectionManager) cmField.get(server)).serverChannelInitializer.set(new VelocityServerChannelInitializer(original));
|
((ConnectionManager) cmField.get(server)).serverChannelInitializer.set(new VelocityServerChannelInitializer(original));
|
||||||
|
|
||||||
|
ChannelInitializer<?> originalBackend = ((ConnectionManager) cmField.get(server)).backendChannelInitializer.get();
|
||||||
|
((ConnectionManager) cmField.get(server)).backendChannelInitializer.set(new VelocityBackendChannelInitializer(originalBackend,(VelocityServer) server));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@ package org.adde0109.ambassador.forge;
|
||||||
|
|
||||||
public class ForgeConstants {
|
public class ForgeConstants {
|
||||||
public static final String HANDLER = "Modern Forge handler";
|
public static final String HANDLER = "Modern Forge handler";
|
||||||
|
public static final ForgeFML2ConnectionType ForgeFML2 = new ForgeFML2ConnectionType();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,12 @@ import org.checkerframework.checker.units.qual.A;
|
||||||
import org.checkerframework.checker.units.qual.C;
|
import org.checkerframework.checker.units.qual.C;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnectionPhase {
|
public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnectionPhase {
|
||||||
private boolean isResettable;
|
private boolean isResettable;
|
||||||
|
|
@ -40,24 +39,30 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
|
||||||
public byte[] modListData;
|
public byte[] modListData;
|
||||||
|
|
||||||
private final ArrayList<Integer> listenerList = new ArrayList();
|
private final ArrayList<Integer> listenerList = new ArrayList();
|
||||||
public ArrayList<MinecraftPacket> packagesToSendAfterReset = new ArrayList<>();
|
|
||||||
private Runnable whenComplete;
|
private Runnable whenComplete;
|
||||||
public boolean isReady = false;
|
public ClientPhase clientPhase = ClientPhase.HANDSHAKE;
|
||||||
@Override
|
@Override
|
||||||
public void handleLogin(ConnectedPlayer player,ForgeHandshakeUtils.CachedServerHandshake handshake, Continuation continuation) {
|
public void handleLogin(ConnectedPlayer player,ForgeHandshakeUtils.CachedServerHandshake handshake, Continuation continuation) {
|
||||||
this.whenComplete = continuation::resume;
|
|
||||||
final MinecraftConnection connection = player.getConnection();
|
final MinecraftConnection connection = player.getConnection();
|
||||||
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player);
|
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(), player);
|
||||||
if(handshake == null) {
|
if (handshake == null) {
|
||||||
connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.emptyModlist)));
|
connection.delayedWrite(new LoginPluginMessage(98, "fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateResetPacket())));
|
||||||
listenerList.add(0);
|
listenerList.add(98);
|
||||||
|
this.whenComplete = () -> {
|
||||||
|
this.clientPhase = ClientPhase.VANILLA;
|
||||||
|
continuation.resume();
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
|
connection.delayedWrite(new LoginPluginMessage(0, "fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
|
||||||
listenerList.add(0);
|
listenerList.add(0);
|
||||||
for (int i = 0;i<handshake.otherPackets.size();i++) {
|
for (int i = 0; i < handshake.otherPackets.size(); i++) {
|
||||||
connection.delayedWrite(new LoginPluginMessage(i+1,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.otherPackets.get(i))));
|
connection.delayedWrite(new LoginPluginMessage(i + 1, "fml:loginwrapper", Unpooled.wrappedBuffer(handshake.otherPackets.get(i))));
|
||||||
listenerList.add(i+1);
|
listenerList.add(i + 1);
|
||||||
}
|
}
|
||||||
|
this.whenComplete = () -> {
|
||||||
|
this.clientPhase = ClientPhase.MODDED;
|
||||||
|
continuation.resume();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
connection.setSessionHandler(sessionHandler);
|
connection.setSessionHandler(sessionHandler);
|
||||||
connection.flush();
|
connection.flush();
|
||||||
|
|
@ -65,40 +70,35 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ConnectedPlayer player, LoginPluginResponse packet) {
|
public boolean handle(ConnectedPlayer player, LoginPluginResponse packet) {
|
||||||
|
if (packet.getId() == 98) {
|
||||||
|
this.clientPhase = ClientPhase.HANDSHAKE;
|
||||||
|
this.isResettable = packet.isSuccess();
|
||||||
|
} else if (packet.getId() == 0) {
|
||||||
|
this.clientPhase = ClientPhase.MODLIST;
|
||||||
|
}
|
||||||
if (!listenerList.removeIf(id -> id.equals(packet.getId()))) {
|
if (!listenerList.removeIf(id -> id.equals(packet.getId()))) {
|
||||||
player.getConnectionInFlight().getConnection().write(packet.retain());
|
player.getConnectionInFlight().getConnection().write(packet.retain());
|
||||||
return true;
|
} else if (listenerList.isEmpty() && whenComplete != null) {
|
||||||
}
|
|
||||||
if (packet.getId() == 98) {
|
|
||||||
isReady = true;
|
|
||||||
for (MinecraftPacket packet1 : packagesToSendAfterReset) {
|
|
||||||
player.getConnection().delayedWrite(packet1);
|
|
||||||
}
|
|
||||||
packagesToSendAfterReset = new ArrayList<>();
|
|
||||||
player.getConnection().flush();
|
|
||||||
} else if (packet.getId() == 0) {
|
|
||||||
if (!packet.isSuccess()) {
|
|
||||||
//TODO: Write disconnect message to end user
|
|
||||||
player.getConnection().close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
modListData = ByteBufUtil.getBytes(packet.content());
|
|
||||||
}
|
|
||||||
if (listenerList.isEmpty() && whenComplete != null) {
|
|
||||||
whenComplete.run();
|
whenComplete.run();
|
||||||
whenComplete = null;
|
whenComplete = null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public void reset(ConnectedPlayer player,MinecraftConnection connection) {
|
public void reset(ConnectedPlayer player, Runnable whenComplete) {
|
||||||
isReady = false;
|
this.whenComplete = whenComplete;
|
||||||
if (player.getConnectedServer() != null) {
|
if (player.getConnectedServer() != null) {
|
||||||
player.getConnectedServer().disconnect();
|
player.getConnectedServer().disconnect();
|
||||||
}
|
}
|
||||||
|
MinecraftConnection connection = player.getConnection();
|
||||||
connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player));
|
connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player));
|
||||||
connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
|
if (connection.getState() == StateRegistry.LOGIN) {
|
||||||
|
connection.write(new LoginPluginMessage(98,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateResetPacket())));
|
||||||
|
} else {
|
||||||
|
connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
|
||||||
|
connection.setState(StateRegistry.LOGIN);
|
||||||
|
}
|
||||||
listenerList.add(98);
|
listenerList.add(98);
|
||||||
connection.setState(StateRegistry.LOGIN);
|
this.clientPhase = null;
|
||||||
}
|
}
|
||||||
public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) {
|
public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) {
|
||||||
VelocityConfiguration configuration = (VelocityConfiguration) server.getConfiguration();
|
VelocityConfiguration configuration = (VelocityConfiguration) server.getConfiguration();
|
||||||
|
|
@ -109,16 +109,21 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
|
||||||
ServerLoginSuccess success = new ServerLoginSuccess();
|
ServerLoginSuccess success = new ServerLoginSuccess();
|
||||||
success.setUsername(player.getUsername());
|
success.setUsername(player.getUsername());
|
||||||
success.setUuid(playerUniqueId);
|
success.setUuid(playerUniqueId);
|
||||||
send(player,success);
|
connection.write(success);
|
||||||
|
|
||||||
|
this.clientPhase = this.clientPhase == ClientPhase.MODLIST ? ClientPhase.MODDED : ClientPhase.VANILLA;
|
||||||
|
|
||||||
connection.setState(StateRegistry.PLAY);
|
connection.setState(StateRegistry.PLAY);
|
||||||
connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal());
|
connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal());
|
||||||
}
|
}
|
||||||
public void send(ConnectedPlayer player, MinecraftPacket message) {
|
public void send(ConnectedPlayer player, MinecraftPacket message) {
|
||||||
if (isReady) {
|
|
||||||
player.getConnection().write(message);
|
player.getConnection().write(message);
|
||||||
} else {
|
}
|
||||||
packagesToSendAfterReset.add(message);
|
|
||||||
}
|
public enum ClientPhase {
|
||||||
|
VANILLA,
|
||||||
|
HANDSHAKE,
|
||||||
|
MODLIST,
|
||||||
|
MODDED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public class ForgeFML2ConnectionType implements ConnectionType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BackendConnectionPhase getInitialBackendPhase() {
|
public BackendConnectionPhase getInitialBackendPhase() {
|
||||||
return BackendConnectionPhases.UNKNOWN;
|
return new VelocityForgeBackendConnectionPhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
package org.adde0109.ambassador.velocity;
|
package org.adde0109.ambassador.velocity;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import org.adde0109.ambassador.forge.ForgeConstants;
|
import org.adde0109.ambassador.forge.ForgeConstants;
|
||||||
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
|
||||||
import org.adde0109.ambassador.forge.ForgeFML2ConnectionType;
|
|
||||||
import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler;
|
import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
@ -36,20 +31,8 @@ public class VelocityBackendChannelInitializer extends ChannelInitializer<Channe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(@NotNull Channel ch) throws Exception {
|
protected void initChannel(Channel ch) throws Exception {
|
||||||
INIT_CHANNEL.invoke(original);
|
INIT_CHANNEL.invoke(original,ch);
|
||||||
}
|
ch.pipeline().addLast(ForgeConstants.HANDLER, new VelocityForgeBackendHandshakeHandler(server));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
|
|
||||||
if (ctx.handler() instanceof MinecraftConnection connection) {
|
|
||||||
if (connection.getAssociation() instanceof VelocityServerConnection serverConnection) {
|
|
||||||
if (serverConnection.getPlayer().getPhase() instanceof ForgeFML2ClientConnectionPhase) {
|
|
||||||
connection.setType(new ForgeFML2ConnectionType());
|
|
||||||
ctx.pipeline().addBefore(ctx.name(), ForgeConstants.HANDLER, new VelocityForgeBackendHandshakeHandler(connection, serverConnection, server));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.handlerAdded(ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.Handshake;
|
import com.velocitypowered.proxy.protocol.packet.Handshake;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import org.adde0109.ambassador.forge.ForgeFML2ConnectionType;
|
import org.adde0109.ambassador.forge.ForgeConstants;
|
||||||
|
|
||||||
public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler {
|
public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler {
|
||||||
private final HandshakeSessionHandler original;
|
private final HandshakeSessionHandler original;
|
||||||
|
|
@ -24,7 +24,7 @@ public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler
|
||||||
handshake.handle(original);
|
handshake.handle(original);
|
||||||
if (connection.getType() == ConnectionTypes.VANILLA && connection.getState() == StateRegistry.LOGIN) {
|
if (connection.getType() == ConnectionTypes.VANILLA && connection.getState() == StateRegistry.LOGIN) {
|
||||||
if (handshake.getServerAddress().split("\0")[1].equals("FML2")) {
|
if (handshake.getServerAddress().split("\0")[1].equals("FML2")) {
|
||||||
connection.setType(new ForgeFML2ConnectionType());
|
connection.setType(ForgeConstants.ForgeFML2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,46 @@
|
||||||
package org.adde0109.ambassador.velocity.backend;
|
package org.adde0109.ambassador.velocity.backend;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.Velocity;
|
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
|
||||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
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.LoginPluginMessage;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import org.adde0109.ambassador.Ambassador;
|
|
||||||
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
||||||
import org.adde0109.ambassador.forge.ForgeHandshakeUtils;
|
|
||||||
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
|
public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
|
||||||
|
|
||||||
private final Ambassador ambassador;
|
private final List<LoginPluginMessage> queuedHandshakePackets = new ArrayList<>();
|
||||||
private boolean vanilla = true;
|
|
||||||
|
|
||||||
public VelocityForgeBackendConnectionPhase(Ambassador ambassador) {
|
public VelocityForgeBackendConnectionPhase() {
|
||||||
this.ambassador = ambassador;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleSuccess(VelocityServerConnection serverCon, VelocityServer server) {
|
public void handleSuccess(VelocityServerConnection serverCon, VelocityServer server) {
|
||||||
ForgeFML2ClientConnectionPhase clientPhase = ((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase());
|
ForgeFML2ClientConnectionPhase clientPhase = ((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase());
|
||||||
if (vanilla) {
|
if (clientPhase.clientPhase == ForgeFML2ClientConnectionPhase.ClientPhase.HANDSHAKE || clientPhase.clientPhase == ForgeFML2ClientConnectionPhase.ClientPhase.MODLIST) {
|
||||||
clientPhase.reset(serverCon.getPlayer(),serverCon.getPlayer().getConnection());
|
clientPhase.complete((VelocityServer) server,serverCon.getPlayer(),serverCon.getPlayer().getConnection());
|
||||||
}
|
}
|
||||||
clientPhase.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) {
|
public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) throws Exception {
|
||||||
vanilla = false;
|
ForgeFML2ClientConnectionPhase clientPhase = ((ForgeFML2ClientConnectionPhase) player.getPhase());
|
||||||
message.retain();
|
message.retain();
|
||||||
((ForgeFML2ClientConnectionPhase) player.getPhase()).send(player,message);
|
if (clientPhase.clientPhase == ForgeFML2ClientConnectionPhase.ClientPhase.VANILLA) {
|
||||||
|
clientPhase.reset(player, () -> {
|
||||||
|
for (LoginPluginMessage msg: queuedHandshakePackets) {
|
||||||
|
player.getConnection().delayedWrite(msg);
|
||||||
|
}
|
||||||
|
player.getConnection().flush();
|
||||||
|
});
|
||||||
|
queuedHandshakePackets.add(message);
|
||||||
|
} else if (clientPhase.clientPhase != null) {
|
||||||
|
player.getConnection().write(message);
|
||||||
|
} else {
|
||||||
|
queuedHandshakePackets.add(message);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,34 +3,73 @@ package org.adde0109.ambassador.velocity.backend;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
|
import com.velocitypowered.proxy.network.Connections;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ServerLogin;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.*;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
|
import org.adde0109.ambassador.forge.ForgeConstants;
|
||||||
|
import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase;
|
||||||
|
|
||||||
public class VelocityForgeBackendHandshakeHandler extends ChannelInboundHandlerAdapter {
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
private final MinecraftConnection connection;
|
public class VelocityForgeBackendHandshakeHandler extends ChannelDuplexHandler {
|
||||||
private final VelocityServerConnection serverConnection;
|
|
||||||
|
private VelocityServerConnection serverConnection;
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
|
|
||||||
public VelocityForgeBackendHandshakeHandler(MinecraftConnection connection, VelocityServerConnection serverConnection, VelocityServer server) {
|
public VelocityForgeBackendHandshakeHandler(VelocityServer server) {
|
||||||
this.connection = connection;
|
|
||||||
this.serverConnection = serverConnection;
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||||
|
if ((msg instanceof ServerLogin)) {
|
||||||
|
ChannelHandler handler = ctx.pipeline().get(Connections.HANDLER);
|
||||||
|
if (handler instanceof MinecraftConnection connection) {
|
||||||
|
if (connection.getAssociation() instanceof VelocityServerConnection serverConnection) {
|
||||||
|
if (serverConnection.getPlayer().getPhase() instanceof ForgeFML2ClientConnectionPhase phase) {
|
||||||
|
init(connection,serverConnection);
|
||||||
|
if (phase.clientPhase == ForgeFML2ClientConnectionPhase.ClientPhase.MODDED) {
|
||||||
|
phase.reset(serverConnection.getPlayer(), () -> {
|
||||||
|
ctx.write(msg, promise);
|
||||||
|
ctx.flush();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ctx.write(msg,promise);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.pipeline().remove(this);
|
||||||
|
ctx.write(msg,promise);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Exception("Connection not associated with a server connection");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Exception("Default minecraft packet handler not found");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.write(msg,promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
if (msg instanceof LoginPluginMessage message && message.getChannel().equals("fml:loginwrapper")) {
|
if (msg instanceof LoginPluginMessage message && message.getChannel().equals("fml:loginwrapper")) {
|
||||||
((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handle(serverConnection, serverConnection.getPlayer(), message);
|
((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handle(serverConnection, serverConnection.getPlayer(), message);
|
||||||
ReferenceCountUtil.release(msg);
|
ReferenceCountUtil.release(msg);
|
||||||
} else if (msg instanceof ServerLoginSuccess) {
|
} else if (msg instanceof ServerLoginSuccess) {
|
||||||
((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handleSuccess(serverConnection,server);
|
((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handleSuccess(serverConnection,server);
|
||||||
ReferenceCountUtil.release(msg);
|
ctx.fireChannelRead(msg);
|
||||||
} else {
|
} else {
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void init(MinecraftConnection connection, VelocityServerConnection serverConnection) {
|
||||||
|
this.serverConnection = serverConnection;
|
||||||
|
connection.setType(ForgeConstants.ForgeFML2);
|
||||||
|
serverConnection.setConnectionPhase(connection.getType().getInitialBackendPhase());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user