From 74151097ff5c935bea125989c0ef139224b1e184 Mon Sep 17 00:00:00 2001 From: ORelio Date: Sat, 8 Aug 2020 22:08:37 +0200 Subject: [PATCH] Implement FML2 mod list in server ping (#1184) --- .../Protocol/Handlers/Forge/ForgeInfo.cs | 64 +++++++++++++++++-- .../Protocol/Handlers/Protocol18Forge.cs | 35 +++++++--- 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Forge/ForgeInfo.cs b/MinecraftClient/Protocol/Handlers/Forge/ForgeInfo.cs index 03180432..088049b8 100755 --- a/MinecraftClient/Protocol/Handlers/Forge/ForgeInfo.cs +++ b/MinecraftClient/Protocol/Handlers/Forge/ForgeInfo.cs @@ -36,9 +36,13 @@ namespace MinecraftClient.Protocol.Handlers.Forge /// Create a new ForgeInfo from the given data. /// /// The modinfo JSON tag. + /// Thrown on missing mod list in JSON data internal ForgeInfo(Json.JSONData data) { - // Example ModInfo (with spacing): + this.Mods = new List(); + bool listFound = false; + + // Example ModInfo for Minecraft 1.12 and lower (FML) // "modinfo": { // "type": "FML", @@ -57,14 +61,62 @@ namespace MinecraftClient.Protocol.Handlers.Forge // }] // } - this.Mods = new List(); - foreach (Json.JSONData mod in data.Properties["modList"].DataArray) + if (data.Properties.ContainsKey("modList") && data.Properties["modList"].Type == Json.JSONData.DataType.Array) { - String modid = mod.Properties["modid"].StringValue; - String version = mod.Properties["version"].StringValue; + listFound = true; - this.Mods.Add(new ForgeMod(modid, version)); + foreach (Json.JSONData mod in data.Properties["modList"].DataArray) + { + String modid = mod.Properties["modid"].StringValue; + String version = mod.Properties["version"].StringValue; + + this.Mods.Add(new ForgeMod(modid, version)); + } } + + // Example ModInfo for Minecraft 1.13 and greater (FML2) + + // "forgeData": { + // "channels": [{ + // "res": "minecraft:unregister", + // "version": "FML2", + // "required": true + // }, { + // "res": "minecraft:register", + // "version": "FML2", + // "required": true + // }], + // "mods": [{ + // "modId": "minecraft", + // "modmarker": "1.15.2" + // }, { + // "modId": "forge", + // "modmarker": "ANY" + // }, { + // "modId": "rats", + // "modmarker": "5.3.2" + // }, { + // "modId": "citadel", + // "modmarker": "1.1.11" + // }], + // "fmlNetworkVersion": 2 + // } + + if (data.Properties.ContainsKey("mods") && data.Properties["mods"].Type == Json.JSONData.DataType.Array) + { + listFound = true; + + foreach (Json.JSONData mod in data.Properties["mods"].DataArray) + { + String modid = mod.Properties["modId"].StringValue; + String version = mod.Properties["modmarker"].StringValue; + + this.Mods.Add(new ForgeMod(modid, version)); + } + } + + if (!listFound) + throw new ArgumentException("Missing mod list", "data"); } } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs index 291944c0..56ab8072 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs @@ -248,30 +248,45 @@ namespace MinecraftClient.Protocol.Handlers /// /// JSON data returned by the server /// ForgeInfo to populate - public static void ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo forgeInfo) + /// True if the server is running Forge + public static bool ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo forgeInfo) { - if (jsonData.Properties.ContainsKey("modinfo") && jsonData.Properties["modinfo"].Type == Json.JSONData.DataType.Object) + return ServerInfoCheckForgeSub(jsonData, ref forgeInfo, "modinfo", "type", "FML") // MC 1.12 and lower + || ServerInfoCheckForgeSub(jsonData, ref forgeInfo, "forgeData", "fmlNetworkVersion", "2"); // MC 1.13 and greater + } + + /// + /// Server Info: Check for For Forge on a Minecraft server Ping result + /// + /// JSON data returned by the server + /// ForgeInfo to populate + /// ForgeData JSON field, e.g. "modinfo" + /// ForgeData version field, e.g. "type" + /// ForgeData version value, e.g. "FML" + /// True if the server is running Forge + private static bool ServerInfoCheckForgeSub(Json.JSONData jsonData, ref ForgeInfo forgeInfo, string forgeDataTag, string versionField, string versionString) + { + if (jsonData.Properties.ContainsKey(forgeDataTag) && jsonData.Properties[forgeDataTag].Type == Json.JSONData.DataType.Object) { - Json.JSONData modData = jsonData.Properties["modinfo"]; - if (modData.Properties.ContainsKey("type") && modData.Properties["type"].StringValue == "FML") + Json.JSONData modData = jsonData.Properties[forgeDataTag]; + if (modData.Properties.ContainsKey(versionField) && modData.Properties[versionField].StringValue == versionString) { forgeInfo = new ForgeInfo(modData); - if (forgeInfo.Mods.Any()) { + ConsoleIO.WriteLineFormatted(String.Format("§8Server is running Forge with {0} mods.", forgeInfo.Mods.Count)); if (Settings.DebugMessages) { - ConsoleIO.WriteLineFormatted("§8Server is running Forge. Mod list:"); + ConsoleIO.WriteLineFormatted("§8Mod list:"); foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) - { ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); - } } - else ConsoleIO.WriteLineFormatted("§8Server is running Forge."); + return true; } - else forgeInfo = null; + else ConsoleIO.WriteLineFormatted("§8Server is running Forge without mods."); } } + return false; } } }