mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
[skipci]Forge Code Cleanup
Optimize code and edit comments
This commit is contained in:
commit
e2b6dc27c8
3 changed files with 69 additions and 90 deletions
|
|
@ -143,32 +143,18 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
case FMLVersion.FML3:
|
||||
// Example ModInfo for Minecraft 1.18 and greater (FML3)
|
||||
|
||||
// {
|
||||
// "enforcesSecureChat": true,
|
||||
// "forgeData": {
|
||||
// "channels": [],
|
||||
// "mods": [],
|
||||
// "truncated": false, // legacy versions see truncated lists, modern versions ignore this truncated flag (binary data has its own)
|
||||
// "fmlNetworkVersion": 3,
|
||||
// "d": "ȳ\u0000\u0000ࠨ㐤獋㙖⹌ᦘ̺⸱恤䒸⡑⛧沮婙㨹牥ఈㄵচ₀沮婙㨹牥ఈㄵচ倠岙㜲獥䋊㷍᭳ႇׇ㘴娘▅筳ص䰭宛㘲、\u0000ᠸጋ囗湌夜㘲杩棐䐱ᅱ挃☥ోᤗ㌮ఀ䬣 坖ɍ䮌ᤘ\r\n旉䠳ዣ◆䲌㜃瑥廮ⷉࠋ–䁠奚Ҵ㔱摜䂸ᅱ獳ౠᡚ㜷汥戊䂸űဓĠ嵛㖱数嫤Ǎ塰䛶ⶎᮚ㞳晲擞ᖝ″ዣ䘆ఋʂ潦令ඕ爈䖔⺁ᥚ⾹潳棤㦥ᬻ挐䅀㠹楬ۨ㣄উ瀀渀嬛㘼扩搢䃀熁挂♥\r\n墋㒺摬牜ࣜ䁠嘗湌孛㜴浩惂䠙熙排٥孁㒰ͮ屢Ӏ䠐⚐䷮ᣛ㊴瑳戚䢸熁匒إܴ䫜巑፻ᚷؠ䀀ㆃ牵䋨㦥ࠫ㋣䗆䂌㨈慲䫬ᖱᮓᘧ汬尚ㆰ٫屲㣄ᆉ恳ಭ川㤷፫擨妅挫♖乮塘 㖱慰\r\n囆䓩\t"
|
||||
// },
|
||||
// "description": {
|
||||
// "text": "A Minecraft Server"
|
||||
// },
|
||||
// "players": {
|
||||
// "max": 100,
|
||||
// "online": 0
|
||||
// },
|
||||
// "version": {
|
||||
// "name": "1.20.1",
|
||||
// "protocol": 763
|
||||
// }
|
||||
// }
|
||||
// "forgeData": {
|
||||
// "channels": [],
|
||||
// "mods": [],
|
||||
// "truncated": false, // legacy versions see truncated lists, modern versions ignore this truncated flag (binary data has its own)
|
||||
// "fmlNetworkVersion": 3,
|
||||
// "d": "ȳ\u0000\u0000ࠨ㐤獋㙖⹌ᦘ̺⸱恤䒸⡑⛧沮婙㨹牥ఈㄵচ₀沮婙㨹牥ఈㄵচ倠岙㜲獥䋊㷍᭳ႇׇ㘴娘▅筳ص䰭宛㘲、\u0000ᠸጋ囗湌夜㘲杩棐䐱ᅱ挃☥ోᤗ㌮ఀ䬣 坖ɍ䮌ᤘ\r\n旉䠳ዣ◆䲌㜃瑥廮ⷉࠋ–䁠奚Ҵ㔱摜䂸ᅱ獳ౠᡚ㜷汥戊䂸űဓĠ嵛㖱数嫤Ǎ塰䛶ⶎᮚ㞳晲擞ᖝ″ዣ䘆ఋʂ潦令ඕ爈䖔⺁ᥚ⾹潳棤㦥ᬻ挐䅀㠹楬ۨ㣄উ瀀渀嬛㘼扩搢䃀熁挂♥\r\n墋㒺摬牜ࣜ䁠嘗湌孛㜴浩惂䠙熙排٥孁㒰ͮ屢Ӏ䠐⚐䷮ᣛ㊴瑳戚䢸熁匒إܴ䫜巑፻ᚷؠ䀀ㆃ牵䋨㦥ࠫ㋣䗆䂌㨈慲䫬ᖱᮓᘧ汬尚ㆰ٫屲㣄ᆉ恳ಭ川㤷፫擨妅挫♖乮塘 㖱慰\r\n囆䓩\t"
|
||||
// }
|
||||
|
||||
// All buffer data are encoded and write to forgeData["d"]
|
||||
// 1.18 and greater, the mod list and channel list is compressed to forgeData["d"] for efficiency,
|
||||
// - Here is how forge encode and decode them:
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L264
|
||||
|
||||
// 1.18 and greater, the buffer is encoded for efficiency
|
||||
// - Here is the discussion:
|
||||
// see https://github.com/MinecraftForge/MinecraftForge/pull/8169
|
||||
|
||||
string encodedData = data.Properties["d"].StringValue;
|
||||
|
|
@ -176,14 +162,21 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
DataTypes dataTypes = new DataTypes(Protocol18Handler.MC_1_18_1_Version);
|
||||
|
||||
//
|
||||
// [truncated][boolean] placeholder for whether we are truncating
|
||||
// [Mod Size][unsigned short] short so that we can replace it later in case of truncation
|
||||
// [ Truncated ][ Bool ] // Unused
|
||||
// [ Mod Size ][ Unsigned short ]
|
||||
//
|
||||
bool truncated = dataTypes.ReadNextBool(dataPackage);
|
||||
dataTypes.ReadNextBool(dataPackage); // truncated: boolean
|
||||
var modsSize = dataTypes.ReadNextUShort(dataPackage);
|
||||
|
||||
Dictionary<string, string> channels = new();
|
||||
Dictionary<string, string> mods = new();
|
||||
// Mod Array Definition:
|
||||
// [ Channel Size And Version Flag ][ VarInt ] // If the value at bit Mask 0x01 is 1, The Mod Version will be ignore.
|
||||
// // The one-right-shifted int is the Channel List size.
|
||||
// [ Mod Id ][ String ]
|
||||
// [ Mod Version ][ Optional String ] // Depends on the Flag above
|
||||
// [ Channel List ][ Array ] [ Channel Name ][ String ]
|
||||
// [ Channel Version ][ String ]
|
||||
// [ Required On Client ][ Bool ]
|
||||
|
||||
for (var i = 0; i < modsSize; i++) {
|
||||
var channelSizeAndVersionFlag = dataTypes.ReadNextVarInt(dataPackage);
|
||||
|
|
@ -194,27 +187,24 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
|
||||
var modId = dataTypes.ReadNextString(dataPackage);
|
||||
|
||||
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";
|
||||
string IGNORESERVERONLY = "IGNORED";
|
||||
var modVersion = isIgnoreServerOnly ? IGNORESERVERONLY : dataTypes.ReadNextString(dataPackage);
|
||||
|
||||
for (var i1 = 0; i1 < channelSize; i1++) {
|
||||
var channelName = dataTypes.ReadNextString(dataPackage);
|
||||
var channelVersion = dataTypes.ReadNextString(dataPackage);
|
||||
var requiredOnClient = dataTypes.ReadNextBool(dataPackage);
|
||||
channels.Add(modId + ":" + channelName, channelVersion + ":" + requiredOnClient);
|
||||
dataTypes.ReadNextString(dataPackage); // channelName
|
||||
dataTypes.ReadNextString(dataPackage); // channelVersion
|
||||
dataTypes.ReadNextBool(dataPackage); // requiredOnClient
|
||||
}
|
||||
|
||||
mods.Add(modId, modVersion);
|
||||
Mods.Add(new ForgeMod(modId, modVersion));
|
||||
}
|
||||
|
||||
var nonModChannelCount = dataTypes.ReadNextVarInt(dataPackage);
|
||||
for (var i = 0; i < nonModChannelCount; i++) {
|
||||
var channelName = dataTypes.ReadNextString(dataPackage);
|
||||
var channelVersion = dataTypes.ReadNextString(dataPackage);
|
||||
var requiredOnClient = dataTypes.ReadNextBool(dataPackage);
|
||||
channels.Add(channelName, channelVersion + ":" + requiredOnClient);
|
||||
}
|
||||
// Ignore the left data, which is NonMod Channel List
|
||||
// [ nonMod Channel Count ][ VarInt ]
|
||||
// [ nonMod Channel List ][ Array ] [ Channel Name ][ String ]
|
||||
// [ Channel Version ][ Bool ]
|
||||
// [ Required On Client ][ Bool ]
|
||||
|
||||
break;
|
||||
default:
|
||||
|
|
@ -222,10 +212,17 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
}
|
||||
}
|
||||
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L361
|
||||
// Decode binary data ForgeData["d"] to Queue<byte>
|
||||
/// <summary>
|
||||
/// Decompress binary data ForgeData["d"] (FML 3)
|
||||
/// </summary>
|
||||
/// <param name="encodedData">The encoded data.</param>
|
||||
/// <returns>Decoded forge data Queue<byte>.</returns>
|
||||
/// <para>
|
||||
/// 1.18 and greater, the mod list and channel list is compressed for efficiency
|
||||
/// The code below is converted from forge source code, see:
|
||||
/// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/ServerStatusPing.java#L361
|
||||
/// </para>
|
||||
private static Queue<byte> decodeOptimized(string encodedData) {
|
||||
// Console.WriteLine("Got encoded data:" + encodedData + ", decoding...");
|
||||
int size0 = encodedData[0];
|
||||
int size1 = encodedData[1];
|
||||
int size = size0 | (size1 << 15);
|
||||
|
|
|
|||
|
|
@ -417,21 +417,13 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 5:
|
||||
// FML 3
|
||||
// Server Config: FMLHandshakeMessages.java > S2CModData > decode()
|
||||
// [ Size ][ VarInt ]
|
||||
// [ Mod Data List ][ Array ] [ Mod Id ][ String ]
|
||||
// [ Display Name ][ String ]
|
||||
// [ Version ][ String ]
|
||||
//
|
||||
// We're ignoring this packet in MCC
|
||||
|
||||
/*
|
||||
// Uncomment this code block if needed
|
||||
var size = dataTypes.ReadNextVarInt(packetData);
|
||||
Dictionary<string, string> modsData = new();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var modId = dataTypes.ReadNextString(packetData);
|
||||
var displayName = dataTypes.ReadNextString(packetData);
|
||||
var version = dataTypes.ReadNextString(packetData);
|
||||
modsData.Add(modId, displayName + ":" + version);
|
||||
}
|
||||
*/
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
{
|
||||
ConsoleIO.WriteLineFormatted("§8" + "Received FML3 Server Mod Data List");
|
||||
|
|
@ -441,20 +433,11 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
case 6:
|
||||
// FML 3
|
||||
// Server Config: FMLHandshakeMessages.java > S2CChannelMismatchData > decode()
|
||||
//
|
||||
// [ Size ][ VarInt ]
|
||||
// [ Mismatched Mod List ][ Array ] [ Mod Id ][ String ]
|
||||
// [ Version ][ String ]
|
||||
// We're ignoring this packet in MCC
|
||||
|
||||
/*
|
||||
// Uncomment this code block if needed
|
||||
Dictionary<string, string> mismatchedMods = new();
|
||||
var size0 = dataTypes.ReadNextVarInt(packetData);
|
||||
for (int i = 0; i < size0; i++)
|
||||
{
|
||||
var modId = dataTypes.ReadNextString(packetData);
|
||||
var version = dataTypes.ReadNextString(packetData);
|
||||
mismatchedMods.Add(modId, version);
|
||||
}
|
||||
*/
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
{
|
||||
ConsoleIO.WriteLineFormatted("§8" + "Received FML3 Server Mismatched Mods List");
|
||||
|
|
@ -523,15 +506,15 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// </summary>
|
||||
/// <param name="protocolVersion">Minecraft protocol version</param>
|
||||
/// <returns>ForgeInfo item stating that Forge is enabled</returns>
|
||||
/// <para>
|
||||
/// 1.18 change the fml version to 3
|
||||
/// https://github.com/MinecraftForge/MinecraftForge/commit/997d8e0aa28b831edcd712e59a96181d3b2117d4
|
||||
/// </para>
|
||||
public static ForgeInfo ServerForceForge(int protocolVersion)
|
||||
{
|
||||
if (ServerMayForceForge(protocolVersion))
|
||||
{
|
||||
// 1.17 is still FML2
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/50b5414033de82f46be23201db50484f36c37d4f/src/main/java/net/minecraftforge/fmllegacy/network/FMLNetworkConstants.java#L37C29-L37C42
|
||||
// 1.18 change the constant FMLNETVERSION to 3
|
||||
// https://github.com/MinecraftForge/MinecraftForge/blob/cb12df41e13da576b781be695f80728b9594c25f/src/main/java/net/minecraftforge/network/NetworkConstants.java#L28
|
||||
if (protocolVersion > ProtocolHandler.MCVer2ProtocolVersion("1.18"))
|
||||
if (protocolVersion >= ProtocolHandler.MCVer2ProtocolVersion("1.18"))
|
||||
{
|
||||
return new ForgeInfo(FMLVersion.FML3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System.Text;
|
|||
using MinecraftClient.Protocol.Handlers;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace MinecraftClient.Protocol.ProfileKey
|
||||
{
|
||||
|
|
@ -20,7 +19,8 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
ProxiedWebRequest.Response? response = null;
|
||||
try
|
||||
{
|
||||
if (!isYggdrasil) {
|
||||
if (!isYggdrasil)
|
||||
{
|
||||
var request = new ProxiedWebRequest(certificates)
|
||||
{
|
||||
Accept = "application/json"
|
||||
|
|
@ -37,8 +37,7 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
|
||||
// see https://github.com/yushijinhun/authlib-injector/blob/da910956eaa30d2f6c2c457222d188aeb53b0d1f/src/main/java/moe/yushi/authlibinjector/httpd/ProfileKeyFilter.java#L49
|
||||
// POST to "https://api.minecraftservices.com/player/certificates" with authlib-injector will get a dummy response
|
||||
string jsonString = isYggdrasil ? MakeDummyResponse() : response!.Body;
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
Json.JSONData json = isYggdrasil ? MakeDummyResponse() : Json.ParseJson(response!.Body);
|
||||
// Error here
|
||||
PublicKey publicKey = new(pemKey: json.Properties["keyPair"].Properties["publicKey"].StringValue,
|
||||
sig: json.Properties["publicKeySignature"].StringValue,
|
||||
|
|
@ -236,7 +235,7 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string MakeDummyResponse()
|
||||
public static Json.JSONData MakeDummyResponse()
|
||||
{
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
|
||||
var mimePublicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
|
||||
|
|
@ -246,19 +245,19 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
DateTime now = DateTime.UtcNow;
|
||||
DateTime expiresAt = now.AddHours(48);
|
||||
DateTime refreshedAfter = now.AddHours(36);
|
||||
JObject response = new JObject();
|
||||
JObject keyPairObj = new JObject
|
||||
{
|
||||
{ "privateKey", privateKeyPEM },
|
||||
{ "publicKey", publicKeyPEM }
|
||||
};
|
||||
response.Add("keyPair", keyPairObj);
|
||||
response.Add("publicKeySignature", "AA==");
|
||||
response.Add("publicKeySignatureV2", "AA==");
|
||||
Json.JSONData response = new(Json.JSONData.DataType.Object);
|
||||
Json.JSONData keyPairObj = new(Json.JSONData.DataType.Object);
|
||||
keyPairObj.Properties["privateKey"] = new(Json.JSONData.DataType.String){ StringValue = privateKeyPEM };
|
||||
keyPairObj.Properties["publicKey"] = new(Json.JSONData.DataType.String){ StringValue = publicKeyPEM };
|
||||
|
||||
response.Properties["keyPair"] = keyPairObj;
|
||||
response.Properties["publicKeySignature"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
|
||||
response.Properties["publicKeySignatureV2"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
|
||||
string format = "yyyy-MM-ddTHH:mm:ss.ffffffZ";
|
||||
response.Add("expiresAt", expiresAt.ToString(format));
|
||||
response.Add("refreshedAfter", refreshedAfter.ToString(format));
|
||||
return response.ToString();
|
||||
response.Properties["expiresAt"] = new(Json.JSONData.DataType.String){ StringValue = expiresAt.ToString(format) };
|
||||
response.Properties["refreshedAfter"] = new(Json.JSONData.DataType.String){ StringValue = refreshedAfter.ToString(format) };
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue