Interact with forge packets
This commit is contained in:
parent
529d7e7636
commit
d6a89ddec9
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "org.adde0109"
|
||||
version = "1.2.0-beta"
|
||||
version = "1.3.0-beta-rc1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ public class ForgeConstants {
|
|||
public static final String RESET_LISTENER = "ambassador-reset-listener";
|
||||
public static final String SERVER_SUCCESS_LISTENER = "ambassador-server-success-listener";
|
||||
public static final String FORGE_HANDSHAKE_HOLDER = "ambassador-forge-handshake-holder";
|
||||
public static final String FORGE_HANDSHAKE_DECODER = "ambassador-forge-decoder";
|
||||
public static final String FORGE_HANDSHAKE_HANDLER = "ambassador-forge-handler";
|
||||
|
||||
public static final String FML2Marker = "\0FML2\0";
|
||||
public static final String FML3Marker = "\0FML3\0";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ 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 org.adde0109.ambassador.forge.pipeline.ForgeLoginWrapperDecoder;
|
||||
|
||||
public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
|
||||
NOT_STARTED() {
|
||||
|
|
@ -51,6 +52,10 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas
|
|||
VelocityForgeClientConnectionPhase clientPhase = (VelocityForgeClientConnectionPhase) player.getPhase();
|
||||
clientPhase.resetConnectionPhase(player);
|
||||
player.getConnection().write(message.retain());
|
||||
|
||||
ForgeLoginWrapperDecoder decoder = (ForgeLoginWrapperDecoder) player.getConnection()
|
||||
.getChannel().pipeline().get(ForgeConstants.FORGE_HANDSHAKE_DECODER);
|
||||
decoder.registerLoginWrapperID(message.getId());
|
||||
}
|
||||
|
||||
public void onLoginSuccess(VelocityServerConnection serverCon, ConnectedPlayer player) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package org.adde0109.ambassador.forge;
|
||||
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
|
|
@ -8,14 +10,14 @@ import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
|||
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.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
import org.adde0109.ambassador.forge.packet.IForgeLoginWrapperPacket;
|
||||
import org.adde0109.ambassador.forge.packet.ModListReplyPacket;
|
||||
import org.adde0109.ambassador.velocity.client.FML2CRPMResetCompleteDecoder;
|
||||
import org.adde0109.ambassador.velocity.client.OutboundForgeHandshakeHolder;
|
||||
import org.adde0109.ambassador.velocity.client.OutboundSuccessHolder;
|
||||
import org.adde0109.ambassador.velocity.client.VelocityForgeHandshakeSessionHandler;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
|
@ -50,7 +52,7 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
connection.getChannel().pipeline().addBefore(Connections.MINECRAFT_DECODER, ForgeConstants.RESET_LISTENER,new FML2CRPMResetCompleteDecoder());
|
||||
connection.getChannel().pipeline().addAfter(Connections.MINECRAFT_ENCODER, ForgeConstants.FORGE_HANDSHAKE_HOLDER,new OutboundForgeHandshakeHolder());
|
||||
|
||||
player.getConnection().setSessionHandler(new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(),player));
|
||||
//player.getConnection().setSessionHandler(new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(),player));
|
||||
|
||||
connection.write(new PluginMessage("fml:handshake", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket())));
|
||||
|
||||
|
|
@ -77,8 +79,8 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
}, Ambassador.getInstance().config.getResetTimeout(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
@Override
|
||||
public boolean handle(ConnectedPlayer player, LoginPluginResponse response, VelocityServerConnection server) {
|
||||
if (response.getId() == 98) {
|
||||
public boolean handle(ConnectedPlayer player, IForgeLoginWrapperPacket msg, VelocityServerConnection server) {
|
||||
if (msg.getId() == 98) {
|
||||
if (scheduledFuture.cancel(false)) {
|
||||
player.getConnection().getChannel().pipeline().remove(ForgeConstants.RESET_LISTENER);
|
||||
player.getConnection().setState(StateRegistry.LOGIN);
|
||||
|
|
@ -106,10 +108,14 @@ public enum VelocityForgeClientConnectionPhase implements ClientConnectionPhase
|
|||
|
||||
public boolean vanillaMode = true;
|
||||
|
||||
public boolean handle(ConnectedPlayer player, LoginPluginResponse response, VelocityServerConnection server) {
|
||||
public boolean handle(ConnectedPlayer player, IForgeLoginWrapperPacket msg, VelocityServerConnection server) {
|
||||
player.setPhase(nextPhase());
|
||||
|
||||
player.getConnectionInFlight().getConnection().write(response.retain());
|
||||
if (msg instanceof ModListReplyPacket replyPacket) {
|
||||
replyPacket.getChannels().put(MinecraftChannelIdentifier.from("ambassador:commands"),"1");
|
||||
}
|
||||
|
||||
player.getConnectionInFlight().getConnection().write(msg.encode());
|
||||
vanillaMode = false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package org.adde0109.ambassador.forge.packet;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import com.velocitypowered.proxy.protocol.util.DeferredByteBufHolder;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class GenericForgeLoginWrapperPacket extends DeferredByteBufHolder implements IForgeLoginWrapperPacket {
|
||||
private final int id;
|
||||
|
||||
public GenericForgeLoginWrapperPacket(ByteBuf input, int id) {
|
||||
super(input);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginPluginResponse encode() {
|
||||
return new LoginPluginResponse(id, true, content());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package org.adde0109.ambassador.forge.packet;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
|
||||
public interface IForgeLoginWrapperPacket {
|
||||
public LoginPluginResponse encode();
|
||||
public int getId();
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package org.adde0109.ambassador.forge.packet;
|
||||
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ModListReplyPacket implements IForgeLoginWrapperPacket {
|
||||
|
||||
private List<String> mods;
|
||||
private Map<ChannelIdentifier, String> channels;
|
||||
private Map<String, String> registries;
|
||||
|
||||
private final int id;
|
||||
|
||||
private ModListReplyPacket(List<String> mods, Map<ChannelIdentifier,
|
||||
String> channels, Map<String, String> registries, int id) {
|
||||
this.mods = mods;
|
||||
this.channels = channels;
|
||||
this.registries = registries;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static ModListReplyPacket read(LoginPluginResponse msg) {
|
||||
ByteBuf input = msg.content();
|
||||
|
||||
List<String> mods = new ArrayList<>();
|
||||
int len = ProtocolUtils.readVarInt(input);
|
||||
for (int x = 0; x < len; x++)
|
||||
mods.add(ProtocolUtils.readString(input, 0x100));
|
||||
|
||||
Map<ChannelIdentifier, String> channels = new HashMap<>();
|
||||
len = ProtocolUtils.readVarInt(input);
|
||||
for (int x = 0; x < len; x++)
|
||||
channels.put(MinecraftChannelIdentifier.from(ProtocolUtils.readString(input, 32767)),
|
||||
ProtocolUtils.readString(input, 0x100));
|
||||
|
||||
Map<String, String> registries = new HashMap<>();
|
||||
len = ProtocolUtils.readVarInt(input);
|
||||
for (int x = 0; x < len; x++)
|
||||
registries.put(ProtocolUtils.readString(input, 32767), ProtocolUtils.readString(input, 0x100));
|
||||
|
||||
return new ModListReplyPacket(mods, channels, registries, msg.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginPluginResponse encode() {
|
||||
ByteBuf buf = Unpooled.buffer();
|
||||
|
||||
ProtocolUtils.writeVarInt(buf, 2);
|
||||
|
||||
ProtocolUtils.writeVarInt(buf, mods.size());
|
||||
mods.forEach(m -> ProtocolUtils.writeString(buf, m));
|
||||
|
||||
ProtocolUtils.writeVarInt(buf, channels.size());
|
||||
channels.forEach((k, v) -> {
|
||||
ProtocolUtils.writeString(buf,k.getId());
|
||||
ProtocolUtils.writeString(buf,v);
|
||||
});
|
||||
|
||||
ProtocolUtils.writeVarInt(buf, registries.size());
|
||||
registries.forEach((k, v) -> {
|
||||
ProtocolUtils.writeString(buf, k);
|
||||
ProtocolUtils.writeString(buf, v);
|
||||
});
|
||||
|
||||
ByteBuf output = Unpooled.buffer();
|
||||
ProtocolUtils.writeString(output, "fml:handshake");
|
||||
ProtocolUtils.writeVarInt(output, buf.readableBytes());
|
||||
output.writeBytes(buf);
|
||||
|
||||
return new LoginPluginResponse(id,true,output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<String> getMods() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
public Map<ChannelIdentifier, String> getChannels() {
|
||||
return channels;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package org.adde0109.ambassador.forge.pipeline;
|
||||
|
||||
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.handler.codec.MessageToMessageDecoder;
|
||||
import org.adde0109.ambassador.forge.packet.GenericForgeLoginWrapperPacket;
|
||||
import org.adde0109.ambassador.forge.packet.ModListReplyPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ForgeLoginWrapperDecoder extends MessageToMessageDecoder<LoginPluginResponse> {
|
||||
|
||||
private final List<Integer> loginWrapperIDs = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, LoginPluginResponse msg, List<Object> out) throws Exception {
|
||||
ByteBuf buf = msg.content();
|
||||
if (!loginWrapperIDs.remove((Integer) msg.getId())) {
|
||||
out.add(msg.retain());
|
||||
return;
|
||||
}
|
||||
int originalReaderIndex = msg.content().readerIndex();
|
||||
String channel = ProtocolUtils.readString(buf);
|
||||
if (!channel.equals("fml:handshake")) {
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
out.add(new GenericForgeLoginWrapperPacket(buf.retain(), msg.getId()));
|
||||
return;
|
||||
}
|
||||
int length = ProtocolUtils.readVarInt(buf);
|
||||
int packetID = ProtocolUtils.readVarInt(buf);
|
||||
if (packetID == 2) {
|
||||
out.add(ModListReplyPacket.read(msg));
|
||||
} else {
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
out.add(new GenericForgeLoginWrapperPacket(buf.retain(), msg.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
public void registerLoginWrapperID(int loginWrapperID) {
|
||||
this.loginWrapperIDs.add(loginWrapperID);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package org.adde0109.ambassador.forge.pipeline;
|
||||
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.adde0109.ambassador.forge.packet.IForgeLoginWrapperPacket;
|
||||
import org.adde0109.ambassador.forge.VelocityForgeClientConnectionPhase;
|
||||
|
||||
public class ForgeLoginWrapperHandler extends SimpleChannelInboundHandler<IForgeLoginWrapperPacket> {
|
||||
|
||||
private final ConnectedPlayer player;
|
||||
|
||||
|
||||
public ForgeLoginWrapperHandler(ConnectedPlayer player) {
|
||||
super(false);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, IForgeLoginWrapperPacket msg) throws Exception {
|
||||
VelocityForgeClientConnectionPhase phase = (VelocityForgeClientConnectionPhase) player.getPhase();
|
||||
phase.handle(player,msg,player.getConnectionInFlight());
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,13 @@ import com.velocitypowered.api.event.connection.PostLoginEvent;
|
|||
import com.velocitypowered.api.event.player.*;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.network.Connections;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import org.adde0109.ambassador.Ambassador;
|
||||
import org.adde0109.ambassador.forge.ForgeConstants;
|
||||
import org.adde0109.ambassador.forge.VelocityForgeClientConnectionPhase;
|
||||
import org.adde0109.ambassador.velocity.client.VelocityForgeHandshakeSessionHandler;
|
||||
import org.adde0109.ambassador.forge.pipeline.ForgeLoginWrapperDecoder;
|
||||
import org.adde0109.ambassador.forge.pipeline.ForgeLoginWrapperHandler;
|
||||
|
||||
public class VelocityEventHandler {
|
||||
|
||||
|
|
@ -25,7 +28,16 @@ public class VelocityEventHandler {
|
|||
public void onLoginEvent(LoginEvent event, Continuation continuation) {
|
||||
ConnectedPlayer player = (ConnectedPlayer) event.getPlayer();
|
||||
if (player.getPhase() instanceof VelocityForgeClientConnectionPhase) {
|
||||
player.getConnection().eventLoop().submit(() -> player.getConnection().setState(StateRegistry.LOGIN));
|
||||
player.getConnection().eventLoop().submit(() -> {
|
||||
player.getConnection().setState(StateRegistry.LOGIN);
|
||||
|
||||
player.getConnection().getChannel().pipeline().addBefore(
|
||||
Connections.HANDLER,
|
||||
ForgeConstants.FORGE_HANDSHAKE_DECODER, new ForgeLoginWrapperDecoder());
|
||||
player.getConnection().getChannel().pipeline().addAfter(
|
||||
ForgeConstants.FORGE_HANDSHAKE_DECODER,
|
||||
ForgeConstants.FORGE_HANDSHAKE_HANDLER, new ForgeLoginWrapperHandler(player));
|
||||
});
|
||||
}
|
||||
continuation.resume();
|
||||
}
|
||||
|
|
@ -34,8 +46,8 @@ public class VelocityEventHandler {
|
|||
public void onPostLoginEvent(PostLoginEvent event, Continuation continuation) {
|
||||
ConnectedPlayer player = (ConnectedPlayer) event.getPlayer();
|
||||
if (player.getPhase() instanceof VelocityForgeClientConnectionPhase phase) {
|
||||
VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), player);
|
||||
player.getConnection().eventLoop().submit(() -> player.getConnection().setSessionHandler(sessionHandler));
|
||||
//VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), player);
|
||||
//player.getConnection().eventLoop().submit(() -> player.getConnection().setSessionHandler(sessionHandler));
|
||||
}
|
||||
continuation.resume();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ public class ForgeLoginSessionHandler implements MinecraftSessionHandler {
|
|||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
if (!serverConnection.getPlayer().getPhase().consideredComplete()) {
|
||||
//TODO:Change this
|
||||
if (!serverConnection.getPhase().consideredComplete()) {
|
||||
serverConnection.getPlayer().handleConnectionException(serverConnection.getServer(),
|
||||
Disconnect.create(Component.text("Probably mismatched mods"),
|
||||
serverConnection.getPlayer().getProtocolVersion()),false);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import io.netty.buffer.ByteBuf;
|
|||
import org.adde0109.ambassador.forge.VelocityForgeClientConnectionPhase;
|
||||
|
||||
public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHandler {
|
||||
private final MinecraftSessionHandler original;
|
||||
/*private final MinecraftSessionHandler original;
|
||||
private final ConnectedPlayer player;
|
||||
|
||||
public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, ConnectedPlayer player) {
|
||||
|
|
@ -37,4 +37,5 @@ public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHan
|
|||
public MinecraftSessionHandler getOriginal() {
|
||||
return this.original;
|
||||
}
|
||||
*/
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user