From 0cd02fd2da18ad381d8954c9657849f4007caa2d Mon Sep 17 00:00:00 2001 From: iceiix <43691553+iceiix@users.noreply.github.com> Date: Sat, 11 May 2019 18:37:33 -0700 Subject: [PATCH] Forge 1.8.9-1.12.2 handshake protocol support (#144) Adds support for connecting to Forge servers from 1.8.9 up to 1.12.2. (1.7.10 was already supported with #134 #88) Tested on: - 1.8.9 + forge 11.15.1.2318 + ironchest - 1.10.2 + forge 12.18.3.2511 + ironchest - 1.11.2 + forge 13.20.1.2588 + ironchest - 1.12.2 + forge 14.23.5.2837 + ironchest Changes: * Parse and handle FmlHs::RegistryData packet for 1.8+ * Fix RegistryData acknowledgement phase WaitingServerComplete * Fix acknowledgement phase for 1.7.10 ModIdData too, somehow it worked accidentally * Append \0FML\0 to end of server hostname if Forge mods detected https://wiki.vg/Minecraft_Forge_Handshake#Connection_to_a_forge_server --- src/protocol/forge.rs | 24 +++++++++++++++++------- src/server/mod.rs | 14 ++++++++++++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/protocol/forge.rs b/src/protocol/forge.rs index 21d47b3..841df92 100644 --- a/src/protocol/forge.rs +++ b/src/protocol/forge.rs @@ -97,7 +97,6 @@ pub enum FmlHs { ModList { mods: LenPrefixed, }, - /* TODO: 1.8+ https://wiki.vg/Minecraft_Forge_Handshake#Differences_from_Forge_1.7.10 RegistryData { has_more: bool, name: String, @@ -105,7 +104,6 @@ pub enum FmlHs { substitutions: LenPrefixed, dummies: LenPrefixed, }, - */ ModIdData { mappings: LenPrefixed, block_substitutions: LenPrefixed, @@ -145,11 +143,23 @@ impl Serializable for FmlHs { }) }, 3 => { - Ok(FmlHs::ModIdData { - mappings: Serializable::read_from(buf)?, - block_substitutions: Serializable::read_from(buf)?, - item_substitutions: Serializable::read_from(buf)?, - }) + let protocol_version = unsafe { crate::protocol::CURRENT_PROTOCOL_VERSION }; + + if protocol_version >= 47 { + Ok(FmlHs::RegistryData { + has_more: Serializable::read_from(buf)?, + name: Serializable::read_from(buf)?, + ids: Serializable::read_from(buf)?, + substitutions: Serializable::read_from(buf)?, + dummies: Serializable::read_from(buf)?, + }) + } else { + Ok(FmlHs::ModIdData { + mappings: Serializable::read_from(buf)?, + block_substitutions: Serializable::read_from(buf)?, + item_substitutions: Serializable::read_from(buf)?, + }) + } }, 255 => { Ok(FmlHs::HandshakeAck { diff --git a/src/server/mod.rs b/src/server/mod.rs index c2f0a55..9be139a 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -108,7 +108,8 @@ impl Server { pub fn connect(resources: Arc>, profile: mojang::Profile, address: &str, protocol_version: i32, forge_mods: Vec) -> Result { let mut conn = protocol::Conn::new(address, protocol_version)?; - let host = conn.host.clone(); + let tag = if forge_mods.len() != 0 { "\0FML\0" } else { "" }; + let host = conn.host.clone() + tag; let port = conn.port; conn.write_packet(protocol::packet::handshake::serverbound::Handshake { protocol_version: protocol::VarInt(protocol_version), @@ -711,7 +712,16 @@ impl Server { self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerData }); }, ModIdData { mappings: _, block_substitutions: _, item_substitutions: _ } => { - self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerData }); + println!("Received FML|HS ModIdData"); + self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerComplete }); + // TODO: dynamically register mod blocks + }, + RegistryData { has_more, name, ids: _, substitutions: _, dummies: _ } => { + println!("Received FML|HS RegistryData for {}", name); + if !has_more { + self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerComplete }); + } + // TODO: dynamically register mod blocks }, HandshakeAck { phase } => { match phase {