Skip to content

Commit e2b6dc2

Browse files
authored
[skipci]Forge Code Cleanup
Optimize code and edit comments
2 parents 86fb4fe + 8be66da commit e2b6dc2

File tree

3 files changed

+70
-91
lines changed

3 files changed

+70
-91
lines changed

MinecraftClient/Protocol/Handlers/Forge/ForgeInfo.cs

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -143,47 +143,40 @@ internal ForgeInfo(Json.JSONData data, FMLVersion fmlVersion)
143143
case FMLVersion.FML3:
144144
// Example ModInfo for Minecraft 1.18 and greater (FML3)
145145

146-
// {
147-
// "enforcesSecureChat": true,
148-
// "forgeData": {
149-
// "channels": [],
150-
// "mods": [],
151-
// "truncated": false, // legacy versions see truncated lists, modern versions ignore this truncated flag (binary data has its own)
152-
// "fmlNetworkVersion": 3,
153-
// "d": "ȳ\u0000\u0000ࠨ㐤獋㙖⹌ᦘ̺⸱恤䒸⡑⛧沮婙㨹牥ఈㄵচ₀沮婙㨹牥ఈㄵচ倠⹡岙㜲獥䋊㷍᭳ႇׇ஌᜘㘴娘▅筳ص䰭宛㘲、\u0000ᠸጋ囗湌夜㘲杩棐䐱ᅱ挃☥ోᤗ㌮ఀ׈䬣 坖ɍ䮌ᤘ\r\n旉䠳ዣ◆䲌㜃瑥廮ⷉࠋ–䁠奚Ҵ㔱摜䂸ᅱ獳ౠᡚ㜷汥戊䂸űဓĠ嵛㖱数嫤Ǎ塰䛶ⶎᮚ㞳晲擞ᖝ″ዣ䘆ఋʂ潦令ඕ爈䖔⺁ᥚ⾹潳棤㦥ᬻ挐؅䅀㠹楬ۨ㣄উ瀀渀嬛㘼扩搢䃀熁挂♥\r\n墋㒺摬牜ࣜ䁠嘗湌孛㜴浩惂䠙熙排٥孁㒰ͮ屢Ӏ䠐⚐䷮ᣛ㊴瑳戚䢸熁匒إ஍᜚ܴ䫜巑፻ᚷؠ䀀ㆃ牵䋨㦥ࠫ㋣䗆䂌㨈慲䫬ᖱᮓᘧ汬尚ㆰ٫屲㣄ᆉ恳ಭ川㤷፫擨妅挫♖乮塘 㖱慰\r\n囆䓩\t"
154-
// },
155-
// "description": {
156-
// "text": "A Minecraft Server"
157-
// },
158-
// "players": {
159-
// "max": 100,
160-
// "online": 0
161-
// },
162-
// "version": {
163-
// "name": "1.20.1",
164-
// "protocol": 763
165-
// }
166-
// }
167-
168-
// All buffer data are encoded and write to forgeData["d"]
146+
// "forgeData": {
147+
// "channels": [],
148+
// "mods": [],
149+
// "truncated": false, // legacy versions see truncated lists, modern versions ignore this truncated flag (binary data has its own)
150+
// "fmlNetworkVersion": 3,
151+
// "d": "ȳ\u0000\u0000ࠨ㐤獋㙖⹌ᦘ̺⸱恤䒸⡑⛧沮婙㨹牥ఈㄵচ₀沮婙㨹牥ఈㄵচ倠⹡岙㜲獥䋊㷍᭳ႇׇ஌᜘㘴娘▅筳ص䰭宛㘲、\u0000ᠸጋ囗湌夜㘲杩棐䐱ᅱ挃☥ోᤗ㌮ఀ׈䬣 坖ɍ䮌ᤘ\r\n旉䠳ዣ◆䲌㜃瑥廮ⷉࠋ–䁠奚Ҵ㔱摜䂸ᅱ獳ౠᡚ㜷汥戊䂸űဓĠ嵛㖱数嫤Ǎ塰䛶ⶎᮚ㞳晲擞ᖝ″ዣ䘆ఋʂ潦令ඕ爈䖔⺁ᥚ⾹潳棤㦥ᬻ挐؅䅀㠹楬ۨ㣄উ瀀渀嬛㘼扩搢䃀熁挂♥\r\n墋㒺摬牜ࣜ䁠嘗湌孛㜴浩惂䠙熙排٥孁㒰ͮ屢Ӏ䠐⚐䷮ᣛ㊴瑳戚䢸熁匒إ஍᜚ܴ䫜巑፻ᚷؠ䀀ㆃ牵䋨㦥ࠫ㋣䗆䂌㨈慲䫬ᖱᮓᘧ汬尚ㆰ٫屲㣄ᆉ恳ಭ川㤷፫擨妅挫♖乮塘 㖱慰\r\n囆䓩\t"
152+
// }
153+
154+
// 1.18 and greater, the mod list and channel list is compressed to forgeData["d"] for efficiency,
155+
// - Here is how forge encode and decode them:
169156
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L264
170-
171-
// 1.18 and greater, the buffer is encoded for efficiency
157+
// - Here is the discussion:
172158
// see https://github.com/MinecraftForge/MinecraftForge/pull/8169
173159

174160
string encodedData = data.Properties["d"].StringValue;
175161
Queue<byte> dataPackage = decodeOptimized(encodedData);
176162
DataTypes dataTypes = new DataTypes(Protocol18Handler.MC_1_18_1_Version);
177163

178164
//
179-
// [truncated][boolean] placeholder for whether we are truncating
180-
// [Mod Size][unsigned short] short so that we can replace it later in case of truncation
165+
// [ Truncated ][ Bool ] // Unused
166+
// [ Mod Size ][ Unsigned short ]
181167
//
182-
bool truncated = dataTypes.ReadNextBool(dataPackage);
168+
dataTypes.ReadNextBool(dataPackage); // truncated: boolean
183169
var modsSize = dataTypes.ReadNextUShort(dataPackage);
184170

185-
Dictionary<string, string> channels = new();
186171
Dictionary<string, string> mods = new();
172+
// Mod Array Definition:
173+
// [ Channel Size And Version Flag ][ VarInt ] // If the value at bit Mask 0x01 is 1, The Mod Version will be ignore.
174+
// // The one-right-shifted int is the Channel List size.
175+
// [ Mod Id ][ String ]
176+
// [ Mod Version ][ Optional String ] // Depends on the Flag above
177+
// [ Channel List ][ Array ] [ Channel Name ][ String ]
178+
// [ Channel Version ][ String ]
179+
// [ Required On Client ][ Bool ]
187180

188181
for (var i = 0; i < modsSize; i++) {
189182
var channelSizeAndVersionFlag = dataTypes.ReadNextVarInt(dataPackage);
@@ -194,38 +187,42 @@ internal ForgeInfo(Json.JSONData data, FMLVersion fmlVersion)
194187

195188
var modId = dataTypes.ReadNextString(dataPackage);
196189

197-
string IGNORESERVERONLY = "";// it was "OHNOES\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31";
190+
string IGNORESERVERONLY = "IGNORED";
198191
var modVersion = isIgnoreServerOnly ? IGNORESERVERONLY : dataTypes.ReadNextString(dataPackage);
199192

200193
for (var i1 = 0; i1 < channelSize; i1++) {
201-
var channelName = dataTypes.ReadNextString(dataPackage);
202-
var channelVersion = dataTypes.ReadNextString(dataPackage);
203-
var requiredOnClient = dataTypes.ReadNextBool(dataPackage);
204-
channels.Add(modId + ":" + channelName, channelVersion + ":" + requiredOnClient);
194+
dataTypes.ReadNextString(dataPackage); // channelName
195+
dataTypes.ReadNextString(dataPackage); // channelVersion
196+
dataTypes.ReadNextBool(dataPackage); // requiredOnClient
205197
}
206198

207199
mods.Add(modId, modVersion);
208200
Mods.Add(new ForgeMod(modId, modVersion));
209201
}
210202

211-
var nonModChannelCount = dataTypes.ReadNextVarInt(dataPackage);
212-
for (var i = 0; i < nonModChannelCount; i++) {
213-
var channelName = dataTypes.ReadNextString(dataPackage);
214-
var channelVersion = dataTypes.ReadNextString(dataPackage);
215-
var requiredOnClient = dataTypes.ReadNextBool(dataPackage);
216-
channels.Add(channelName, channelVersion + ":" + requiredOnClient);
217-
}
203+
// Ignore the left data, which is NonMod Channel List
204+
// [ nonMod Channel Count ][ VarInt ]
205+
// [ nonMod Channel List ][ Array ] [ Channel Name ][ String ]
206+
// [ Channel Version ][ Bool ]
207+
// [ Required On Client ][ Bool ]
218208

219209
break;
220210
default:
221211
throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!");
222212
}
223213
}
224214

225-
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L361
226-
// Decode binary data ForgeData["d"] to Queue<byte>
215+
/// <summary>
216+
/// Decompress binary data ForgeData["d"] (FML 3)
217+
/// </summary>
218+
/// <param name="encodedData">The encoded data.</param>
219+
/// <returns>Decoded forge data Queue<byte>.</returns>
220+
/// <para>
221+
/// 1.18 and greater, the mod list and channel list is compressed for efficiency
222+
/// The code below is converted from forge source code, see:
223+
/// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L361
224+
/// </para>
227225
private static Queue<byte> decodeOptimized(string encodedData) {
228-
// Console.WriteLine("Got encoded data:" + encodedData + ", decoding...");
229226
int size0 = encodedData[0];
230227
int size1 = encodedData[1];
231228
int size = size0 | (size1 << 15);

MinecraftClient/Protocol/Handlers/Protocol18Forge.cs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -417,21 +417,13 @@ public bool HandleLoginPluginRequest(string channel, Queue<byte> packetData, ref
417417
case 5:
418418
// FML 3
419419
// Server Config: FMLHandshakeMessages.java > S2CModData > decode()
420+
// [ Size ][ VarInt ]
421+
// [ Mod Data List ][ Array ] [ Mod Id ][ String ]
422+
// [ Display Name ][ String ]
423+
// [ Version ][ String ]
420424
//
421425
// We're ignoring this packet in MCC
422426

423-
/*
424-
// Uncomment this code block if needed
425-
var size = dataTypes.ReadNextVarInt(packetData);
426-
Dictionary<string, string> modsData = new();
427-
for (int i = 0; i < size; i++)
428-
{
429-
var modId = dataTypes.ReadNextString(packetData);
430-
var displayName = dataTypes.ReadNextString(packetData);
431-
var version = dataTypes.ReadNextString(packetData);
432-
modsData.Add(modId, displayName + ":" + version);
433-
}
434-
*/
435427
if (Settings.Config.Logging.DebugMessages)
436428
{
437429
ConsoleIO.WriteLineFormatted("§8" + "Received FML3 Server Mod Data List");
@@ -441,20 +433,11 @@ public bool HandleLoginPluginRequest(string channel, Queue<byte> packetData, ref
441433
case 6:
442434
// FML 3
443435
// Server Config: FMLHandshakeMessages.java > S2CChannelMismatchData > decode()
444-
//
436+
// [ Size ][ VarInt ]
437+
// [ Mismatched Mod List ][ Array ] [ Mod Id ][ String ]
438+
// [ Version ][ String ]
445439
// We're ignoring this packet in MCC
446440

447-
/*
448-
// Uncomment this code block if needed
449-
Dictionary<string, string> mismatchedMods = new();
450-
var size0 = dataTypes.ReadNextVarInt(packetData);
451-
for (int i = 0; i < size0; i++)
452-
{
453-
var modId = dataTypes.ReadNextString(packetData);
454-
var version = dataTypes.ReadNextString(packetData);
455-
mismatchedMods.Add(modId, version);
456-
}
457-
*/
458441
if (Settings.Config.Logging.DebugMessages)
459442
{
460443
ConsoleIO.WriteLineFormatted("§8" + "Received FML3 Server Mismatched Mods List");
@@ -523,15 +506,15 @@ public static bool ServerMayForceForge(int protocolVersion)
523506
/// </summary>
524507
/// <param name="protocolVersion">Minecraft protocol version</param>
525508
/// <returns>ForgeInfo item stating that Forge is enabled</returns>
509+
/// <para>
510+
/// 1.18 change the fml version to 3
511+
/// https://github.com/MinecraftForge/MinecraftForge/commit/997d8e0aa28b831edcd712e59a96181d3b2117d4
512+
/// </para>
526513
public static ForgeInfo ServerForceForge(int protocolVersion)
527514
{
528515
if (ServerMayForceForge(protocolVersion))
529-
{
530-
// 1.17 is still FML2
531-
// https://github.com/MinecraftForge/MinecraftForge/blob/50b5414033de82f46be23201db50484f36c37d4f/src/main/java/net/minecraftforge/fmllegacy/network/FMLNetworkConstants.java#L37C29-L37C42
532-
// 1.18 change the constant FMLNETVERSION to 3
533-
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/NetworkConstants.java#L28
534-
if (protocolVersion > ProtocolHandler.MCVer2ProtocolVersion("1.18"))
516+
{
517+
if (protocolVersion >= ProtocolHandler.MCVer2ProtocolVersion("1.18"))
535518
{
536519
return new ForgeInfo(FMLVersion.FML3);
537520
}

MinecraftClient/Protocol/ProfileKey/KeyUtils.cs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using MinecraftClient.Protocol.Handlers;
66
using MinecraftClient.Protocol.Message;
77
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
8-
using Newtonsoft.Json.Linq;
98

109
namespace MinecraftClient.Protocol.ProfileKey
1110
{
@@ -20,7 +19,8 @@ static class KeyUtils
2019
ProxiedWebRequest.Response? response = null;
2120
try
2221
{
23-
if (!isYggdrasil) {
22+
if (!isYggdrasil)
23+
{
2424
var request = new ProxiedWebRequest(certificates)
2525
{
2626
Accept = "application/json"
@@ -37,8 +37,7 @@ static class KeyUtils
3737

3838
// see https://github.com/yushijinhun/authlib-injector/blob/da910956eaa30d2f6c2c457222d188aeb53b0d1f/src/main/java/moe/yushi/authlibinjector/httpd/ProfileKeyFilter.java#L49
3939
// POST to "https://api.minecraftservices.com/player/certificates" with authlib-injector will get a dummy response
40-
string jsonString = isYggdrasil ? MakeDummyResponse() : response!.Body;
41-
Json.JSONData json = Json.ParseJson(jsonString);
40+
Json.JSONData json = isYggdrasil ? MakeDummyResponse() : Json.ParseJson(response!.Body);
4241
// Error here
4342
PublicKey publicKey = new(pemKey: json.Properties["keyPair"].Properties["publicKey"].StringValue,
4443
sig: json.Properties["publicKeySignature"].StringValue,
@@ -236,7 +235,7 @@ public static string EscapeString(string src)
236235
return sb.ToString();
237236
}
238237

239-
public static string MakeDummyResponse()
238+
public static Json.JSONData MakeDummyResponse()
240239
{
241240
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
242241
var mimePublicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
@@ -246,19 +245,19 @@ public static string MakeDummyResponse()
246245
DateTime now = DateTime.UtcNow;
247246
DateTime expiresAt = now.AddHours(48);
248247
DateTime refreshedAfter = now.AddHours(36);
249-
JObject response = new JObject();
250-
JObject keyPairObj = new JObject
251-
{
252-
{ "privateKey", privateKeyPEM },
253-
{ "publicKey", publicKeyPEM }
254-
};
255-
response.Add("keyPair", keyPairObj);
256-
response.Add("publicKeySignature", "AA==");
257-
response.Add("publicKeySignatureV2", "AA==");
248+
Json.JSONData response = new(Json.JSONData.DataType.Object);
249+
Json.JSONData keyPairObj = new(Json.JSONData.DataType.Object);
250+
keyPairObj.Properties["privateKey"] = new(Json.JSONData.DataType.String){ StringValue = privateKeyPEM };
251+
keyPairObj.Properties["publicKey"] = new(Json.JSONData.DataType.String){ StringValue = publicKeyPEM };
252+
253+
response.Properties["keyPair"] = keyPairObj;
254+
response.Properties["publicKeySignature"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
255+
response.Properties["publicKeySignatureV2"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
258256
string format = "yyyy-MM-ddTHH:mm:ss.ffffffZ";
259-
response.Add("expiresAt", expiresAt.ToString(format));
260-
response.Add("refreshedAfter", refreshedAfter.ToString(format));
261-
return response.ToString();
257+
response.Properties["expiresAt"] = new(Json.JSONData.DataType.String){ StringValue = expiresAt.ToString(format) };
258+
response.Properties["refreshedAfter"] = new(Json.JSONData.DataType.String){ StringValue = refreshedAfter.ToString(format) };
259+
260+
return response;
262261
}
263262
}
264263
}

0 commit comments

Comments
 (0)