WIP: Works but NEEDS CLEANUP

This commit is contained in:
Adrian Bergqvist 2022-09-20 22:34:05 +02:00
parent fea9082dd7
commit d6dcb9a814
No known key found for this signature in database
GPG Key ID: FAE7D8EDE225E686
7 changed files with 115 additions and 38 deletions

View File

@ -4,7 +4,7 @@ plugins {
}
group 'org.adde0109'
version '0.4.0-reset'
version '1.0.0-alpha'
repositories {
maven {

View File

@ -28,7 +28,7 @@ import org.slf4j.Logger;
import java.nio.file.Path;
@Plugin(id = "ambassador", name = "Ambassador", version = "0.4.0-reset", authors = {"adde0109"})
@Plugin(id = "ambassador", name = "Ambassador", version = "1.0.0-alpha", authors = {"adde0109"})
public class Ambassador {
public ProxyServer server;

View File

@ -1,6 +1,7 @@
package org.adde0109.ambassador.forge;
import com.velocitypowered.api.event.Continuation;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.util.UuidUtils;
import com.velocitypowered.proxy.Velocity;
import com.velocitypowered.proxy.VelocityServer;
@ -19,6 +20,8 @@ import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler;
import org.checkerframework.checker.units.qual.A;
import org.checkerframework.checker.units.qual.C;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -36,21 +39,23 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
public byte[] modListData;
private final ArrayList<Integer> listenerList = new ArrayList();
public ArrayList<LoginPluginMessage> packagesToSendAfterReset = new ArrayList<>();
private Runnable whenComplete;
public boolean isReady = false;
@Override
public void handleLogin(ConnectedPlayer player,ForgeHandshakeUtils.CachedServerHandshake handshake, Continuation continuation) {
this.whenComplete = continuation::resume;
final MinecraftConnection connection = player.getConnection();
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player);
if(handshake == null) {
connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateEmptyModlist())));
listenerList.add(1);
connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateEmptyModlist())));
listenerList.add(0);
} else {
connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
listenerList.add(1);
connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket)));
listenerList.add(0);
for (int i = 0;i<handshake.otherPackets.size();i++) {
connection.delayedWrite(new LoginPluginMessage(i+2,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.otherPackets.get(i))));
listenerList.add(i+2);
connection.delayedWrite(new LoginPluginMessage(i+1,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.otherPackets.get(i))));
listenerList.add(i+1);
}
}
connection.setSessionHandler(sessionHandler);
@ -60,11 +65,16 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
@Override
public boolean handle(ConnectedPlayer player, LoginPluginResponse packet) {
if (!listenerList.removeIf(id -> id.equals(packet.getId()))) {
return false;
player.getConnectionInFlight().getConnection().write(packet.retain());
return true;
}
if (packet.getId() == 98) {
isResettable = packet.isSuccess();
} else if (packet.getId() == 1) {
for (LoginPluginMessage 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();
@ -78,16 +88,23 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec
}
return true;
}
public void reset(ConnectedPlayer player,MinecraftConnection connection, List<byte[]> messages, Runnable whenComplete) {
this.whenComplete = whenComplete;
public void reset(ConnectedPlayer player,MinecraftConnection connection, byte[] serverModlist) {
isReady = false;
if (player.getConnectedServer() != null) {
player.getConnectedServer().disconnect();
}
connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player));
connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
listenerList.add(98);
send(player,new LoginPluginMessage(0,"fml:loginwrapper",Unpooled.wrappedBuffer(serverModlist)));
listenerList.add(0);
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);
}
public void send(ConnectedPlayer player, LoginPluginMessage message) {
if (isReady) {
player.getConnection().write(message);
} else {
packagesToSendAfterReset.add(message);
}
connection.flush();
}
}

View File

@ -12,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 com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.adde0109.ambassador.Ambassador;
@ -57,13 +58,18 @@ public class VelocityEventHandler {
return;
}
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));
if (event.getSequenceId() == 0) {
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));
MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon);
connection.setSessionHandler(sessionHandler);
((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()).reset(serverCon.getPlayer(), serverCon.getPlayer().getConnection(),event.getContents());
} else {
((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()).send(serverCon.getPlayer(), new LoginPluginMessage(event.getSequenceId(),event.getIdentifier().getId(),Unpooled.wrappedBuffer(event.getContents())));
}
continuation.resume();
MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon);
connection.setSessionHandler(sessionHandler);
});
}
}

View File

@ -1,25 +1,20 @@
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;
@ -33,8 +28,9 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha
}
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()));
ForgeHandshakeUtils.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection());
//((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) {
@ -58,11 +54,8 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha
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()))));
message.retain();
((ForgeFML2ClientConnectionPhase) player.getPhase()).send(player,message);
return true;
}

View File

@ -1,18 +1,20 @@
package org.adde0109.ambassador.velocity.backend;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.backend.LoginSessionHandler;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase;
public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSessionHandler {
private final MinecraftSessionHandler original;
private final LoginSessionHandler original;
private final VelocityServerConnection serverCon;
public VelocityForgeBackendHandshakeSessionHandler(MinecraftSessionHandler original, VelocityServerConnection serverCon) {
this.original = original;
this.original = (LoginSessionHandler) original;
this.serverCon = serverCon;
}
@ -21,6 +23,11 @@ public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSes
original.disconnected();
}
@Override
public void handleGeneric(MinecraftPacket packet) {
packet.handle(original);
}
@Override
public void exception(Throwable throwable) {
original.exception(throwable);
@ -37,8 +44,8 @@ public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSes
@Override
public boolean handle(ServerLoginSuccess packet) {
original.handle(packet);
((VelocityForgeBackendConnectionPhase) serverCon.getPhase()).handleSuccess(serverCon);
original.handle(packet);
return true;
}
}

View File

@ -0,0 +1,54 @@
package org.adde0109.ambassador.velocity.backend;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.backend.TransitionSessionHandler;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
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.PluginMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class VelocityForgeBackendTransitionSessionHandler implements MinecraftSessionHandler {
private final TransitionSessionHandler original;
private final VelocityServerConnection serverCon;
public VelocityForgeBackendTransitionSessionHandler(MinecraftSessionHandler original, VelocityServerConnection serverCon) {
this.original = (TransitionSessionHandler) original;
this.serverCon = serverCon;
}
@Override
public boolean beforeHandle() {
return original.beforeHandle();
}
@Override
public void disconnected() {
original.disconnected();
}
@Override
public void handleGeneric(MinecraftPacket packet) {
packet.handle(original);
}
@Override
public boolean handle(PluginMessage packet) {
if (serverCon.getPlayer().getConnection().getState() == StateRegistry.LOGIN) {
//So it can't send when the client is in LOGIN state.
//We can instead use forge's LoginWrapper
ByteBuf wrapped = Unpooled.buffer();
ProtocolUtils.writeString(wrapped,"minecraft:register");
ProtocolUtils.writeVarInt(wrapped, packet.content().readableBytes());
wrapped.writeBytes(packet.content());
serverCon.getPlayer().getConnection().write(new LoginPluginMessage(97,"fml:loginwrapper",wrapped));
} else {
original.handle(packet);
}
return true;
}
}