From 90492940103f2994729c88743273286e7142340a Mon Sep 17 00:00:00 2001 From: SerendipityR <48401197+SerendipityR-2022@users.noreply.github.com> Date: Wed, 24 Aug 2022 01:38:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=8F=E8=AE=AE=E7=89=88?= =?UTF-8?q?=E6=9C=AC754=E5=90=8E=E7=9A=84Forge=E4=BC=AA=E9=80=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EndMinecraftPlusV2.java | 2 +- .../NewVersion/ForgeProtocol/MCForge.java | 124 ++++++++++++++---- .../ForgeProtocol/MCForgeHandShake.java | 1 + .../ForgeProtocol/MCForgeHandShakeV1.java | 57 ++++++++ .../ForgeProtocol/MCForgeHandShakeV2.java | 93 +++++++++++++ .../NewVersion/ForgeProtocol/MCForgeMOTD.java | 1 + 6 files changed, 248 insertions(+), 30 deletions(-) diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/EndMinecraftPlusV2.java b/src/cn/serendipityr/EndMinecraftPlusV2/EndMinecraftPlusV2.java index d945a62..01a6f89 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/EndMinecraftPlusV2.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/EndMinecraftPlusV2.java @@ -8,7 +8,7 @@ import cn.serendipityr.EndMinecraftPlusV2.VersionControl.AttackManager; import cn.serendipityr.EndMinecraftPlusV2.VersionControl.ProtocolLibs; public class EndMinecraftPlusV2 { - public static String ver = "1.2.6"; + public static String ver = "1.2.7"; public static Integer CfgVer = 2; public static void main(String[] args) { diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForge.java b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForge.java index 5571976..3777c05 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForge.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForge.java @@ -1,15 +1,16 @@ package cn.serendipityr.EndMinecraftPlusV2.VersionControl.NewVersion.ForgeProtocol; -import cn.serendipityr.EndMinecraftPlusV2.Tools.LogUtil; +import cn.serendipityr.EndMinecraftPlusV2.VersionControl.ProtocolLibs; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientPluginMessagePacket; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCustomPayloadPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPluginMessagePacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.packet.Packet; import java.lang.reflect.Field; import java.util.Map; -import java.util.Scanner; public class MCForge { private final MCForgeHandShake handshake; @@ -24,44 +25,93 @@ public class MCForge { } public void init() { - this.session.addListener(new SessionListener() { - public void packetReceived(PacketReceivedEvent e) { - if (e.getPacket() instanceof ServerPluginMessagePacket) { - handle(e.getPacket()); - } else if (e.getPacket().getClass().getSimpleName().equals("LoginPluginRequestPacket")) { - handshake.handle(e.getPacket()); + if (ProtocolLibs.adaptAfter754) { + this.session.addListener(new SessionListener() { + public void packetReceived(PacketReceivedEvent e) { + if (e.getPacket() instanceof ClientboundCustomPayloadPacket) { + handle(e.getPacket()); + } else if (e.getPacket().getClass().getSimpleName().equals("ClientboundCustomQueryPacket")) { + handshake.newHandle(e.getPacket()); + } } - } - public void packetReceived(Session session, Packet packet) { + public void packetReceived(Session session, Packet packet) { + if (packet instanceof ClientboundCustomPayloadPacket) { + newHandle((ClientboundCustomPayloadPacket) packet); + } else if (packet.getClass().getSimpleName().equals("ClientboundCustomQueryPacket")) { + handshake.newHandle(packet); + } + } - } + public void packetSending(PacketSendingEvent packetSendingEvent) { - public void packetSending(PacketSendingEvent packetSendingEvent) { + } - } + public void packetSent(Session session, Packet packet) { - public void packetSent(Session session, Packet packet) { + } - } + public void packetError(PacketErrorEvent packetErrorEvent) { - public void packetError(PacketErrorEvent packetErrorEvent) { + } - } + public void packetSent(PacketSentEvent e) { + } - public void packetSent(PacketSentEvent e) { - } + public void connected(ConnectedEvent e) { + modifyHost(); + } - public void connected(ConnectedEvent e) { - modifyHost(); - } + public void disconnecting(DisconnectingEvent e) { + } - public void disconnecting(DisconnectingEvent e) { - } + public void disconnected(DisconnectedEvent e) { + } + }); + } else { + this.session.addListener(new SessionListener() { + public void packetReceived(PacketReceivedEvent e) { + if (e.getPacket() instanceof ServerPluginMessagePacket) { + handle(e.getPacket()); + } else if (e.getPacket().getClass().getSimpleName().equals("LoginPluginRequestPacket")) { + handshake.handle(e.getPacket()); + } + } - public void disconnected(DisconnectedEvent e) { - } - }); + public void packetReceived(Session session, Packet packet) { + if (packet instanceof ServerPluginMessagePacket) { + handle((ServerPluginMessagePacket) packet); + } else if (packet.getClass().getSimpleName().equals("LoginPluginRequestPacket")) { + handshake.handle(packet); + } + } + + public void packetSending(PacketSendingEvent packetSendingEvent) { + + } + + public void packetSent(Session session, Packet packet) { + + } + + public void packetError(PacketErrorEvent packetErrorEvent) { + + } + + public void packetSent(PacketSentEvent e) { + } + + public void connected(ConnectedEvent e) { + modifyHost(); + } + + public void disconnecting(DisconnectingEvent e) { + } + + public void disconnected(DisconnectedEvent e) { + } + }); + } } public void handle(ServerPluginMessagePacket packet) { @@ -70,16 +120,32 @@ public class MCForge { this.handshake.handle(packet); break; case "REGISTER": - case "minecraft:register": // 1.13 + case "minecraft:register": this.session.send(new ClientPluginMessagePacket(packet.getChannel(), packet.getData())); break; case "MC|Brand": - case "minecraft:brand": // 1.13 + case "minecraft:brand": this.session.send(new ClientPluginMessagePacket(packet.getChannel(), "fml,forge".getBytes())); break; } } + public void newHandle(ClientboundCustomPayloadPacket packet) { + switch (packet.getChannel()) { + case "FML|HS": + this.handshake.handle(packet); + break; + case "REGISTER": + case "minecraft:register": + this.session.send(new ServerboundCustomPayloadPacket(packet.getChannel(), packet.getData())); + break; + case "MC|Brand": + case "minecraft:brand": + this.session.send(new ServerboundCustomPayloadPacket(packet.getChannel(), "fml,forge".getBytes())); + break; + } + } + public void modifyHost() { try { Class cls = this.session.getClass().getSuperclass(); diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShake.java b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShake.java index 05b53ea..b3ad5e3 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShake.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShake.java @@ -10,5 +10,6 @@ public abstract class MCForgeHandShake { } public abstract void handle(Packet recvPacket); + public abstract void newHandle(Packet recvPacket); public abstract String getFMLVersion(); } diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV1.java b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV1.java index 960d853..fda37da 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV1.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV1.java @@ -1,7 +1,9 @@ package cn.serendipityr.EndMinecraftPlusV2.VersionControl.NewVersion.ForgeProtocol; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientPluginMessagePacket; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCustomPayloadPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPluginMessagePacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.io.stream.StreamNetOutput; import com.github.steveice10.packetlib.packet.Packet; @@ -65,6 +67,57 @@ public class MCForgeHandShakeV1 extends MCForgeHandShake { } } + public void newHandle(Packet recvPacket) { + ClientboundCustomPayloadPacket packet = (ClientboundCustomPayloadPacket) recvPacket; + Session session = forge.session; + + byte[] data = packet.getData(); + int packetID = data[0]; + + switch (packetID) { + case 0: // Hello + newSendPluginMessage(session, packet.getChannel(), new byte[] { 0x01, 0x02 }); + + // ModList + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + StreamNetOutput out = new StreamNetOutput(buf); + try { + out.writeVarInt(2); + out.writeByte(forge.modList.size()); + forge.modList.forEach((k, v) -> { + try { + out.writeString(k); + out.writeString(v); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } catch (IOException e) { + e.printStackTrace(); + } + newSendPluginMessage(session, packet.getChannel(), buf.toByteArray()); + break; + case 2: // ModList + newSendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x02 }); // ACK(WAITING SERVER DATA) + break; + case 3: // RegistryData + newSendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x03 }); // ACK(WAITING SERVER COMPLETE) + break; + case -1: // HandshakeAck + int ackID = data[1]; + switch (ackID) { + case 2: // WAITING CACK + newSendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x04 }); // PENDING COMPLETE + break; + case 3: // COMPLETE + newSendPluginMessage(session, packet.getChannel(), new byte[] { -0x1, 0x05 }); // COMPLETE + break; + default: + } + default: + } + } + public String getFMLVersion() { return "FML"; } @@ -72,4 +125,8 @@ public class MCForgeHandShakeV1 extends MCForgeHandShake { private void sendPluginMessage(Session session, String channel, byte[] data) { session.send(new ClientPluginMessagePacket(channel, data)); } + + private void newSendPluginMessage(Session session, String channel, byte[] data) { + session.send(new ServerboundCustomPayloadPacket(channel, data)); + } } diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV2.java b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV2.java index d85ab09..31f18ce 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV2.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeHandShakeV2.java @@ -1,7 +1,9 @@ package cn.serendipityr.EndMinecraftPlusV2.VersionControl.NewVersion.ForgeProtocol; import com.github.steveice10.mc.protocol.packet.login.client.LoginPluginResponsePacket; +import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket; import com.github.steveice10.mc.protocol.packet.login.server.LoginPluginRequestPacket; +import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket; import com.github.steveice10.packetlib.io.buffer.ByteBufferNetInput; import com.github.steveice10.packetlib.io.stream.StreamNetOutput; import com.github.steveice10.packetlib.packet.Packet; @@ -112,6 +114,93 @@ public class MCForgeHandShakeV2 extends MCForgeHandShake { } } + public void newHandle(Packet recvPacket) { + ClientboundCustomQueryPacket packet = (ClientboundCustomQueryPacket) recvPacket; + if (!packet.getChannel().equals("fml:loginwrapper")) return; + + try { + LoginWrapper loginWrapper = new LoginWrapper().fromBytes(packet.getData()); + String targetNetworkReceiver = loginWrapper.getTargetNetworkReceiver(); + ByteBufferNetInput in = new ByteBufferNetInput(ByteBuffer.wrap(loginWrapper.getPayload())); + + int packetID = in.readByte(); + switch (packetID) { + case Packet_S2CModList: { + // recv: S2CModList + final List mods = new ArrayList<>(); + int len = in.readVarInt(); + for (int x = 0; x < len; x++) + mods.add(in.readString()); + + final Map channels = new HashMap<>(); + len = in.readVarInt(); + for (int x = 0; x < len; x++) + channels.put(in.readString(), in.readString()); + + final List registries = new ArrayList<>(); + len = in.readVarInt(); + for (int x = 0; x < len; x++) + registries.add(in.readString()); + // send: C2SModListReply + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + StreamNetOutput out = new StreamNetOutput(buf); + + out.writeByte(Packet_C2SModListReply); + + out.writeVarInt(mods.size()); + mods.forEach(m -> { + try { + out.writeString(m); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + out.writeVarInt(channels.size()); + channels.forEach((k, v) -> { + try { + out.writeString(k); + out.writeString(v); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + // TODO: Fill with known hashes, which requires keeping a file cache (FMLHandshakeMessages.java) + out.writeVarInt(0); // empty map + /* + out.writeVarInt(registries.size()); + registries.forEach(r -> { + try { + out.writeString(r); + out.writeString(""); + } catch (IOException e) { + e.printStackTrace(); + } + }); + */ + + newReply(packet.getMessageId(), targetNetworkReceiver, buf.toByteArray()); + break; + } + case Packet_S2CRegistry: + case Packet_S2CConfigData: { + // recv: S2CRegistry + // send: C2SAcknowledge + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + StreamNetOutput out = new StreamNetOutput(buf); + + out.writeByte(Packet_C2SAcknowledge); + + newReply(packet.getMessageId(), targetNetworkReceiver, buf.toByteArray()); + break; + }// recv: S2CConfigData + } + } catch (Exception ex) { + forge.session.disconnect("Failure to handshake", ex); + } + } + public String getFMLVersion() { return "FML2"; } @@ -120,6 +209,10 @@ public class MCForgeHandShakeV2 extends MCForgeHandShake { forge.session.send(new LoginPluginResponsePacket(id, new LoginWrapper(targetNetworkReceiver, payload).toBytes())); } + private void newReply(int id, String targetNetworkReceiver, byte[] payload) throws IOException { + forge.session.send(new ServerboundCustomQueryPacket(id, new LoginWrapper(targetNetworkReceiver, payload).toBytes())); + } + static class LoginWrapper { private String targetNetworkReceiver; private byte[] payload; diff --git a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeMOTD.java b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeMOTD.java index 9457ecc..016cb15 100644 --- a/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeMOTD.java +++ b/src/cn/serendipityr/EndMinecraftPlusV2/VersionControl/NewVersion/ForgeProtocol/MCForgeMOTD.java @@ -51,6 +51,7 @@ public class MCForgeMOTD { if (response.modinfo != null) { for (Response.ModInfo.ModID modid : response.modinfo.modList) { modList.put(modid.modid, modid.version); + LogUtil.doLog(0, modid.modid + " | " + modid.version, "[Debug]"); } } }