添加支持 Fml3 ,并暂时设置force forge时为fml3

This commit is contained in:
oldkingOK 2024-01-12 13:28:03 +08:00
parent 725510d3ef
commit 22cf7a046b
3 changed files with 152 additions and 6 deletions

View file

@ -7,6 +7,7 @@
enum FMLVersion enum FMLVersion
{ {
FML, FML,
FML2 FML2,
FML3
} }
} }

View file

@ -46,6 +46,13 @@ namespace MinecraftClient.Protocol.Handlers.Forge
}; };
Version = fmlVersion; Version = fmlVersion;
break; break;
case FMLVersion.FML3:
Mods = new List<ForgeMod>
{
new ForgeMod("forge", "ANY")
};
Version = fmlVersion;
break;
default: default:
throw new InvalidOperationException(Translations.error_forgeforce); throw new InvalidOperationException(Translations.error_forgeforce);
} }
@ -133,10 +140,134 @@ namespace MinecraftClient.Protocol.Handlers.Forge
} }
break; break;
case FMLVersion.FML3:
// All buf data are write do forgeData["d"]
// src/main/java/net/minecraftforge/network/ServerStatusPing.java > serialize(ServerStatusPing forgeData)
// src/main/java/net/minecraftforge/network/ServerStatusPing.java > deserializeOptimized(JsonObject forgeData)
// {
// "enforcesSecureChat": true,
// "forgeData": {
// "channels": [],
// "mods": [],
// "truncated": false,
// "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
// }
// }
string encodedData = data.Properties["d"].StringValue;
Queue<byte> dataPackage = decodeOptimized(encodedData);
DataTypes dataTypes = new DataTypes(Protocol18Handler.MC_1_18_2_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
//
// Console.WriteLine("decodedData=");
bool truncated = false;
//Map<ResourceLocation, Pair<String, Boolean>> channels;
truncated = dataTypes.ReadNextBool(dataPackage);
var modsSize = dataTypes.ReadNextUShort(dataPackage);
Dictionary<string, string> channels = new();
Dictionary<string, string> mods = new();
for (var i = 0; i < modsSize; i++) {
var channelSizeAndVersionFlag = dataTypes.ReadNextVarInt(dataPackage);
var channelSize = channelSizeAndVersionFlag >> 1;
int VERSION_FLAG_IGNORESERVERONLY = 0b1;
var isIgnoreServerOnly = (channelSizeAndVersionFlag & VERSION_FLAG_IGNORESERVERONLY) != 0;
var modId = dataTypes.ReadNextString(dataPackage);
string IGNORESERVERONLY = "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";
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);
//channels.Add(new ResourceLocation(modId, channelName), Pair.of(channelVersion, 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);
// channels.put(channelName, Pair.of(channelVersion, requiredOnClient));
}
foreach (var key in channels.Keys) {
//Console.WriteLine("We got channel: " + key + "-" + channels[key]);
}
foreach (var key in mods.Keys) {
//Console.WriteLine("We got mod: " + key + "-" + mods[key]);
}
break;
default: default:
throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!"); throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!");
} }
} }
// decode ForgeData["d"] to Queue<byte>
// see src/main/java/net/minecraftforge/network/ServerStatusPing.java#l361
public static Queue<byte> decodeOptimized(string encodedData) {
// Console.WriteLine("Got encoded data:" + encodedData + ", decoding...");
int size0 = (int)encodedData[0];
int size1 = (int)encodedData[1];
int size = size0 | (size1 << 15);
List<byte> packageData = new();
int stringIndex = 2;
int buffer = 0;
int bitsInBuf = 0;
while (stringIndex < encodedData.Length)
{
while (bitsInBuf >= 8)
{
packageData.Add((byte)buffer);
buffer >>= 8;
bitsInBuf -= 8;
}
char c = encodedData[stringIndex];
buffer |= ((int)c & 0x7FFF) << bitsInBuf;
bitsInBuf += 15;
stringIndex++;
}
while (packageData.Count < size)
{
packageData.Add((byte)buffer);
buffer >>= 8;
bitsInBuf -= 8;
}
return new Queue<byte>(packageData.ToArray());
}
} }
} }

View file

@ -241,7 +241,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <returns>TRUE/FALSE depending on whether the packet was understood or not</returns> /// <returns>TRUE/FALSE depending on whether the packet was understood or not</returns>
public bool HandleLoginPluginRequest(string channel, Queue<byte> packetData, ref List<byte> responseData) public bool HandleLoginPluginRequest(string channel, Queue<byte> packetData, ref List<byte> responseData)
{ {
if (ForgeEnabled() && forgeInfo!.Version == FMLVersion.FML2 && channel == "fml:loginwrapper") if (ForgeEnabled() && (forgeInfo!.Version == FMLVersion.FML2 || forgeInfo!.Version == FMLVersion.FML3) && channel == "fml:loginwrapper")
{ {
// Forge Handshake handler source code used to implement the FML2 packets: // Forge Handshake handler source code used to implement the FML2 packets:
// https://github.com/MinecraftForge/MinecraftForge/blob/master/src/main/java/net/minecraftforge/fml/network/FMLNetworkConstants.java // https://github.com/MinecraftForge/MinecraftForge/blob/master/src/main/java/net/minecraftforge/fml/network/FMLNetworkConstants.java
@ -320,6 +320,14 @@ namespace MinecraftClient.Protocol.Handlers
for (int i = 0; i < registryCount; i++) for (int i = 0; i < registryCount; i++)
registries.Add(dataTypes.ReadNextString(packetData)); registries.Add(dataTypes.ReadNextString(packetData));
List<string> dataPackRegistries = new();
if (forgeInfo!.Version == FMLVersion.FML3 && packetData.Count != 0)
{
int dataPackRegistryCount = dataTypes.ReadNextVarInt(packetData);
for (int i = 0; i < dataPackRegistryCount; i++)
dataPackRegistries.Add(dataTypes.ReadNextString(packetData));
}
// Server Mod List Reply: FMLHandshakeMessages.java > C2SModListReply > encode() // Server Mod List Reply: FMLHandshakeMessages.java > C2SModListReply > encode()
// //
// [ Mod Count ][ VarInt ] // [ Mod Count ][ VarInt ]
@ -375,7 +383,7 @@ namespace MinecraftClient.Protocol.Handlers
string registryName = dataTypes.ReadNextString(packetData); string registryName = dataTypes.ReadNextString(packetData);
ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_registry, registryName)); ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.forge_fml2_registry, registryName));
} }
fmlResponsePacket.AddRange(DataTypes.GetVarInt(99)); fmlResponsePacket.AddRange(DataTypes.GetVarInt(99));
fmlResponseReady = true; fmlResponseReady = true;
break; break;
@ -442,7 +450,8 @@ namespace MinecraftClient.Protocol.Handlers
public static bool ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo? forgeInfo) public static bool ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo? forgeInfo)
{ {
return ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML) // MC 1.12 and lower return ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML) // MC 1.12 and lower
|| ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML2); // MC 1.13 and greater || ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML2) // MC 1.13 and greater
|| ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML3); // MC 1.18 and greater
} }
/// <summary> /// <summary>
@ -464,7 +473,7 @@ namespace MinecraftClient.Protocol.Handlers
{ {
if (ServerMayForceForge(protocolVersion)) if (ServerMayForceForge(protocolVersion))
{ {
return new ForgeInfo(FMLVersion.FML2); return new ForgeInfo(FMLVersion.FML3);
} }
else throw new InvalidOperationException(Translations.error_forgeforce); else throw new InvalidOperationException(Translations.error_forgeforce);
} }
@ -494,6 +503,11 @@ namespace MinecraftClient.Protocol.Handlers
versionField = "fmlNetworkVersion"; versionField = "fmlNetworkVersion";
versionString = "2"; versionString = "2";
break; break;
case FMLVersion.FML3:
forgeDataTag = "forgeData";
versionField = "fmlNetworkVersion";
versionString = "3";
break;
default: default:
throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!"); throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!");
} }
@ -523,6 +537,6 @@ namespace MinecraftClient.Protocol.Handlers
} }
} }
return false; return false;
} }
} }
} }