diff --git a/MinecraftClient/Mapping/Dimension.cs b/MinecraftClient/Mapping/Dimension.cs index 75642d51..72cdf844 100644 --- a/MinecraftClient/Mapping/Dimension.cs +++ b/MinecraftClient/Mapping/Dimension.cs @@ -22,6 +22,13 @@ namespace MinecraftClient.Mapping /// public readonly bool piglinSafe = false; + /// + /// Possibly the light level(s) at which monsters can spawn. + /// + public readonly int monsterSpawnMinLightLevel = 0; + public readonly int monsterSpawnMaxLightLevel = 7; + public readonly int monsterSpawnBlockLightLimit = 0; + /// /// When false, compasses spin randomly. When true, nether portals can spawn zombified piglins. /// @@ -132,6 +139,25 @@ namespace MinecraftClient.Mapping if (nbt.ContainsKey("piglin_safe")) this.piglinSafe = 1 == (byte)nbt["piglin_safe"]; + if (nbt.ContainsKey("monster_spawn_light_level")) + { + try + { + var monsterSpawnLightLevelObj = nbt["monster_spawn_light_level"]; + if (monsterSpawnLightLevelObj.GetType() == typeof(int)) + this.monsterSpawnMinLightLevel = this.monsterSpawnMaxLightLevel = (int)monsterSpawnLightLevelObj; + else + { + var inclusive = (Dictionary)(((Dictionary)monsterSpawnLightLevelObj)["value"]); + this.monsterSpawnMinLightLevel = (int)inclusive["min_inclusive"]; + this.monsterSpawnMaxLightLevel = (int)inclusive["max_inclusive"]; + } + + } + catch (KeyNotFoundException) { } + } + if (nbt.ContainsKey("monster_spawn_block_light_limit")) + this.monsterSpawnBlockLightLimit = (int)nbt["monster_spawn_block_light_limit"]; if (nbt.ContainsKey("natural")) this.natural = 1 == (byte)nbt["natural"]; if (nbt.ContainsKey("ambient_light")) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index aee80a25..4b745644 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -19,7 +19,9 @@ namespace MinecraftClient.Mapping /// /// The dimension info of the world /// - private static Dimension dimension = new Dimension(); + private static Dimension curDimension = new Dimension(); + + private static Dictionary? dimensionList = null; /// /// Lock for thread safety @@ -89,15 +91,35 @@ namespace MinecraftClient.Mapping } } + /// - /// Set dimension type + /// Storage of all dimensional data - 1.19.1 and above + /// + /// Registry Codec nbt data + public static void StoreDimensionList(Dictionary registryCodec) + { + dimensionList = new(); + var dimensionListNbt = (object[])(((Dictionary)registryCodec["minecraft:dimension_type"])["value"]); + foreach (Dictionary dimensionNbt in dimensionListNbt) + { + string dimensionName = (string)dimensionNbt["name"]; + Dictionary element = (Dictionary)dimensionNbt["element"]; + dimensionList.Add(dimensionName, new Dimension(dimensionName, element)); + } + } + + + /// + /// Set current dimension - 1.16 and above /// /// The name of the dimension type /// The dimension type (NBT Tag Compound) - public static void SetDimension(string name, Dictionary nbt) + public static void SetDimension(string name) { - // will change in 1.19 and above - dimension = new Dimension(name, nbt); + if (dimensionList!.TryGetValue(name, out Dimension? dimension)) + curDimension = dimension; + else + Console.WriteLine("Can't find dimension \"" + name + "\""); } /// @@ -106,7 +128,7 @@ namespace MinecraftClient.Mapping /// Current dimension public static Dimension GetDimension() { - return dimension; + return curDimension; } /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 9c8666f1..cfd8568f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -97,7 +97,7 @@ namespace MinecraftClient.Protocol.Handlers this.log = handler.GetLogger(); this.randomGen = RandomNumberGenerator.Create(); - if (handler.GetTerrainEnabled() && this.protocolVersion > MC_1_18_2_Version) + if (handler.GetTerrainEnabled() && this.protocolVersion > MC_1_19_Version) { log.Error(Translations.Get("extra.terrainandmovement_disabled")); handler.SetTerrainEnabled(false); @@ -357,12 +357,10 @@ namespace MinecraftClient.Protocol.Handlers int worldCount = dataTypes.ReadNextVarInt(packetData); // Dimension Count (World Count) - 1.16 and above for (int i = 0; i < worldCount; i++) dataTypes.ReadNextString(packetData); // Dimension Names (World Names) - 1.16 and above - dataTypes.ReadNextNbt(packetData); // Registry Codec (Dimension Codec) - 1.16 and above + var registryCodec = dataTypes.ReadNextNbt(packetData); // Registry Codec (Dimension Codec) - 1.16 and above + World.StoreDimensionList(registryCodec); } - string? currentDimensionName = null; - Dictionary? currentDimensionType = null; - // Current dimension // NBT Tag Compound: 1.16.2 and above // String identifier: 1.16 and 1.16.1 @@ -371,12 +369,9 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_16_Version) { if (protocolVersion >= MC_1_19_Version) - { - dataTypes.ReadNextString(packetData); // Dimension Type: Identifier - currentDimensionType = new Dictionary(); - } + dataTypes.ReadNextString(packetData); // Dimension Type: Identifier else if (protocolVersion >= MC_1_16_2_Version) - currentDimensionType = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound + dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); this.currentDimension = 0; @@ -390,10 +385,10 @@ namespace MinecraftClient.Protocol.Handlers dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below if (protocolVersion >= MC_1_16_Version) - currentDimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - - if (protocolVersion >= MC_1_16_2_Version) - World.SetDimension(currentDimensionName, currentDimensionType); + { + string dimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above + World.SetDimension(dimensionName); + } if (protocolVersion >= MC_1_15_Version) dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above @@ -576,31 +571,26 @@ namespace MinecraftClient.Protocol.Handlers } break; case PacketTypesIn.Respawn: - string? dimensionNameInRespawn = null; - Dictionary dimensionTypeInRespawn = null; if (protocolVersion >= MC_1_16_Version) { if (protocolVersion >= MC_1_19_Version) - { - dataTypes.ReadNextString(packetData); // Dimension Type: Identifier - dimensionTypeInRespawn = new Dictionary(); - } + dataTypes.ReadNextString(packetData); // Dimension Type: Identifier else if (protocolVersion >= MC_1_16_2_Version) - dimensionTypeInRespawn = dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound + dataTypes.ReadNextNbt(packetData); // Dimension Type: NBT Tag Compound else dataTypes.ReadNextString(packetData); this.currentDimension = 0; } - else - { - // 1.15 and below + else + { // 1.15 and below this.currentDimension = dataTypes.ReadNextInt(packetData); } - if (protocolVersion >= MC_1_16_Version) - dimensionNameInRespawn = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above - if (protocolVersion >= MC_1_16_2_Version) - World.SetDimension(dimensionNameInRespawn, dimensionTypeInRespawn); + if (protocolVersion >= MC_1_16_Version) + { + string dimensionName = dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above + World.SetDimension(dimensionName); + } if (protocolVersion < MC_1_14_Version) dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below