From fde50c17288727b5b237f461dd9b471410691536 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Tue, 5 Mar 2024 18:54:29 +0500 Subject: [PATCH 001/484] AntiCheat fix prevent Block Breaking --- MinecraftClient/ChatBots/AutoDig.cs | 6 +++--- MinecraftClient/ChatBots/Farmer.cs | 2 +- MinecraftClient/ChatBots/WebSocketBot.cs | 7 ++++--- MinecraftClient/Commands/Dig.cs | 4 ++-- MinecraftClient/McClient.cs | 5 ++--- MinecraftClient/Scripting/ChatBot.cs | 5 +++-- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index cddb6ffd..17c27895 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -285,7 +285,7 @@ namespace MinecraftClient.ChatBots if (Config.Mode == Configs.ModeType.lookat || (Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc))) { - if (DigBlock(blockLoc, lookAtBlock: false)) + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: false)) { currentDig = blockLoc; if (Config.Log_Block_Dig) @@ -346,7 +346,7 @@ namespace MinecraftClient.ChatBots if (minDistance <= 6.0) { - if (DigBlock(target, lookAtBlock: true)) + if (DigBlock(target, Direction.Down, lookAtBlock: true)) { currentDig = target; if (Config.Log_Block_Dig) @@ -380,7 +380,7 @@ namespace MinecraftClient.ChatBots ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) || (Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))) { - if (DigBlock(blockLoc, lookAtBlock: true)) + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: true)) { currentDig = blockLoc; if (Config.Log_Block_Dig) diff --git a/MinecraftClient/ChatBots/Farmer.cs b/MinecraftClient/ChatBots/Farmer.cs index f072ba2e..7c15791c 100644 --- a/MinecraftClient/ChatBots/Farmer.cs +++ b/MinecraftClient/ChatBots/Farmer.cs @@ -831,7 +831,7 @@ namespace MinecraftClient.ChatBots // Yoinked from Daenges's Sugarcane Farmer private bool WaitForDigBlock(Location block, int digTimeout = 1000) { - if (!DigBlock(block.ToFloor())) return false; + if (!DigBlock(block.ToFloor(), Direction.Down)) return false; short i = 0; // Maximum wait time of 10 sec. while (GetWorld().GetBlock(block).Type != Material.Air && i <= digTimeout) { diff --git a/MinecraftClient/ChatBots/WebSocketBot.cs b/MinecraftClient/ChatBots/WebSocketBot.cs index 1aa6caa9..d4fc6842 100644 --- a/MinecraftClient/ChatBots/WebSocketBot.cs +++ b/MinecraftClient/ChatBots/WebSocketBot.cs @@ -651,9 +651,10 @@ public class WebSocketBot : ChatBot var result = cmd.Parameters.Length switch { - 3 => DigBlock(location), - 4 => DigBlock(location, (bool)cmd.Parameters[3]), - 5 => DigBlock(location, (bool)cmd.Parameters[3], (bool)cmd.Parameters[4]), + // TODO Get Direction from the arguments + 3 => DigBlock(location, Direction.Down), + 4 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3]), + 5 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3], (bool)cmd.Parameters[4]), _ => false }; diff --git a/MinecraftClient/Commands/Dig.cs b/MinecraftClient/Commands/Dig.cs index 3a00c44b..b6ff9420 100644 --- a/MinecraftClient/Commands/Dig.cs +++ b/MinecraftClient/Commands/Dig.cs @@ -58,7 +58,7 @@ namespace MinecraftClient.Commands Block block = handler.GetWorld().GetBlock(blockToBreak); if (block.Type == Material.Air) return r.SetAndReturn(Status.Fail, Translations.cmd_dig_no_block); - else if (handler.DigBlock(blockToBreak, duration: duration)) + else if (handler.DigBlock(blockToBreak, Direction.Down, duration: duration)) { blockToBreak = blockToBreak.ToCenter(); return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_dig_dig, blockToBreak.X, blockToBreak.Y, blockToBreak.Z, block.GetTypeString())); @@ -78,7 +78,7 @@ namespace MinecraftClient.Commands return r.SetAndReturn(Status.Fail, Translations.cmd_dig_too_far); else if (block.Type == Material.Air) return r.SetAndReturn(Status.Fail, Translations.cmd_dig_no_block); - else if (handler.DigBlock(blockLoc, lookAtBlock: false, duration: duration)) + else if (handler.DigBlock(blockLoc, Direction.Down, lookAtBlock: false, duration: duration)) return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_dig_dig, blockLoc.X, blockLoc.Y, blockLoc.Z, block.GetTypeString())); else return r.SetAndReturn(Status.Fail, Translations.cmd_dig_fail); diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index c7296d52..786f35e1 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2266,16 +2266,15 @@ namespace MinecraftClient /// Location of block to dig /// Also perform the "arm swing" animation /// Also look at the block before digging - public bool DigBlock(Location location, bool swingArms = true, bool lookAtBlock = true, double duration = 0) + public bool DigBlock(Location location, Direction blockFace, bool swingArms = true, bool lookAtBlock = true, double duration = 0) { if (!GetTerrainEnabled()) return false; if (InvokeRequired) - return InvokeOnMainThread(() => DigBlock(location, swingArms, lookAtBlock, duration)); + return InvokeOnMainThread(() => DigBlock(location, blockFace, swingArms, lookAtBlock, duration)); // TODO select best face from current player location - Direction blockFace = Direction.Down; lock (DigLock) { diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index 36c365be..ac77d935 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -1072,11 +1072,12 @@ namespace MinecraftClient.Scripting /// Attempt to dig a block at the specified location /// /// Location of block to dig + /// Example: if your player is under a block that is being destroyed, use Down /// Also perform the "arm swing" animation /// Also look at the block before digging - protected bool DigBlock(Location location, bool swingArms = true, bool lookAtBlock = true) + protected bool DigBlock(Location location, Direction direction, bool swingArms = true, bool lookAtBlock = true) { - return Handler.DigBlock(location, swingArms, lookAtBlock); + return Handler.DigBlock(location, direction, swingArms, lookAtBlock); } /// From 91ef890bb615ab140552499891279002fb22af57 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Tue, 5 Mar 2024 20:30:58 +0500 Subject: [PATCH 002/484] Auxiliary class for Direction, preparation for autodetection of the broken side of the block --- MinecraftClient/ChatBots/WebSocketBot.cs | 2 +- MinecraftClient/Commands/Dig.cs | 1 + .../Mapping/DirectionExtensions.cs | 39 +++++++++++++++++++ MinecraftClient/McClient.cs | 4 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 MinecraftClient/Mapping/DirectionExtensions.cs diff --git a/MinecraftClient/ChatBots/WebSocketBot.cs b/MinecraftClient/ChatBots/WebSocketBot.cs index d4fc6842..778ff018 100644 --- a/MinecraftClient/ChatBots/WebSocketBot.cs +++ b/MinecraftClient/ChatBots/WebSocketBot.cs @@ -651,7 +651,7 @@ public class WebSocketBot : ChatBot var result = cmd.Parameters.Length switch { - // TODO Get Direction from the arguments + // TODO Get blockFace direction from arguments 3 => DigBlock(location, Direction.Down), 4 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3]), 5 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3], (bool)cmd.Parameters[4]), diff --git a/MinecraftClient/Commands/Dig.cs b/MinecraftClient/Commands/Dig.cs index b6ff9420..477e2c77 100644 --- a/MinecraftClient/Commands/Dig.cs +++ b/MinecraftClient/Commands/Dig.cs @@ -22,6 +22,7 @@ namespace MinecraftClient.Commands ); dispatcher.Register(l => l.Literal(CmdName) + // TODO Get blockFace direction from arguments .Executes(r => DigLookAt(r.Source)) .Then(l => l.Argument("Duration", Arguments.Double()) .Executes(r => DigLookAt(r.Source, Arguments.GetDouble(r, "Duration")))) diff --git a/MinecraftClient/Mapping/DirectionExtensions.cs b/MinecraftClient/Mapping/DirectionExtensions.cs new file mode 100644 index 00000000..fe47f020 --- /dev/null +++ b/MinecraftClient/Mapping/DirectionExtensions.cs @@ -0,0 +1,39 @@ +namespace MinecraftClient.Mapping +{ + public static class DirectionExtensions + { + public static Direction GetOpposite(this Direction direction) + { + switch (direction) + { + case Direction.SouthEast: + return Direction.NorthEast; + case Direction.SouthWest: + return Direction.NorthWest; + + case Direction.NorthEast: + return Direction.SouthEast; + case Direction.NorthWest: + return Direction.SouthWest; + + case Direction.West: + return Direction.East; + case Direction.East: + return Direction.West; + + case Direction.North: + return Direction.South; + case Direction.South: + return Direction.North; + + case Direction.Down: + return Direction.Up; + case Direction.Up: + return Direction.Down; + default: + return Direction.Up; + + } + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 786f35e1..b58e420e 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2268,14 +2268,14 @@ namespace MinecraftClient /// Also look at the block before digging public bool DigBlock(Location location, Direction blockFace, bool swingArms = true, bool lookAtBlock = true, double duration = 0) { + // TODO select best face from current player location + if (!GetTerrainEnabled()) return false; if (InvokeRequired) return InvokeOnMainThread(() => DigBlock(location, blockFace, swingArms, lookAtBlock, duration)); - // TODO select best face from current player location - lock (DigLock) { if (RemainingDiggingTime > 0 && LastDigPosition != null) From df9443381bc45d19e97d7e6445bb58fec18b43a6 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Tue, 5 Mar 2024 21:49:29 +0500 Subject: [PATCH 003/484] Done auxiliary methods for Direction --- .../Mapping/DirectionExtensions.cs | 26 ++++++++++++++++++- MinecraftClient/McClient.cs | 10 +++++++ MinecraftClient/Scripting/ChatBot.cs | 9 +++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Mapping/DirectionExtensions.cs b/MinecraftClient/Mapping/DirectionExtensions.cs index fe47f020..9a42368c 100644 --- a/MinecraftClient/Mapping/DirectionExtensions.cs +++ b/MinecraftClient/Mapping/DirectionExtensions.cs @@ -1,4 +1,6 @@ -namespace MinecraftClient.Mapping +using System; + +namespace MinecraftClient.Mapping { public static class DirectionExtensions { @@ -35,5 +37,27 @@ } } + + + public static Direction[] HORIZONTAL = + { + Direction.South, + Direction.West, + Direction.North, + Direction.East + }; + + public static Direction FromRotation(double rotation) + { + double floor = Math.Floor((rotation / 90.0) + 0.5); + int value = (int)floor & 3; + + return FromHorizontal(value); + } + + public static Direction FromHorizontal(int value) + { + return HORIZONTAL[Math.Abs(value % HORIZONTAL.Length)]; + } } } diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index b58e420e..4a8b6ab0 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1036,6 +1036,15 @@ namespace MinecraftClient #region Getters: Retrieve data for use in other methods or ChatBots + /// + /// Gets the horizontal direction of the takeoff. + /// + /// Return direction of view + public Direction GetHorizontalFacing() + { + return DirectionExtensions.FromRotation(GetYaw()); + } + /// /// Get max length for chat messages /// @@ -2260,6 +2269,7 @@ namespace MinecraftClient return InvokeOnMainThread(() => handler.SendPlayerBlockPlacement((int)hand, location, blockFace, sequenceId++)); } + /// /// Attempt to dig a block at the specified location /// diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index ac77d935..8e8fc674 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -1631,6 +1631,15 @@ namespace MinecraftClient.Scripting return Handler.GetProtocolVersion(); } + /// + /// Gets the horizontal direction of the takeoff. + /// + /// Return direction of view + protected Direction GetHorizontalFacing() + { + return Handler.GetHorizontalFacing(); + } + /// /// Invoke a task on the main thread, wait for completion and retrieve return value. /// From 08c5c15557495bae780748e69c569cb6d2288ca7 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 16 Jun 2024 01:19:09 +0200 Subject: [PATCH 004/484] 1.20.6 - Not working yet --- .../Inventory/EnchantmentMapping.cs | 88 +++++-- MinecraftClient/Inventory/Enchantments.cs | 75 +++--- .../Mapping/EntityMetadataPalette.cs | 2 +- MinecraftClient/McClient.cs | 5 + MinecraftClient/Program.cs | 2 +- .../Handlers/ConfigurationPacketTypesIn.cs | 13 +- .../Handlers/ConfigurationPacketTypesOut.cs | 2 + .../PacketPalettes/PacketPalette1206.cs | 230 ++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 5 +- .../Protocol/Handlers/PacketTypesIn.cs | 5 + .../Protocol/Handlers/PacketTypesOut.cs | 4 + .../Protocol/Handlers/Protocol16.cs | 10 + .../Protocol/Handlers/Protocol18.cs | 246 +++++++++++++++++- MinecraftClient/Protocol/IMinecraftCom.cs | 13 + .../Protocol/IMinecraftComHandler.cs | 4 +- .../Protocol/Message/ChatParser.cs | 25 +- MinecraftClient/Protocol/ProtocolHandler.cs | 6 +- 17 files changed, 654 insertions(+), 81 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1206.cs diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index badadb99..1768482e 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -10,7 +10,7 @@ namespace MinecraftClient.Inventory { #pragma warning disable format // @formatter:off // 1.14 - 1.15.2 - private static Dictionary enchantmentMappings114 = new Dictionary() + private static Dictionary enchantmentMappings114 = new() { //id type { 0, Enchantment.Protection }, @@ -50,7 +50,7 @@ namespace MinecraftClient.Inventory }; // 1.16 - 1.18 - private static Dictionary enchantmentMappings116 = new Dictionary() + private static Dictionary enchantmentMappings116 = new() { //id type { 0, Enchantment.Protection }, @@ -93,8 +93,8 @@ namespace MinecraftClient.Inventory { 37, Enchantment.VanishingCurse } }; - // 1.19+ - private static Dictionary enchantmentMappings = new Dictionary() + // 1.19 - 1.20.4 + private static Dictionary enchantmentMappings119 = new() { //id type { 0, Enchantment.Protection }, @@ -137,6 +137,54 @@ namespace MinecraftClient.Inventory { 37, Enchantment.Mending }, { 38, Enchantment.VanishingCurse } }; + + // 1.20.6+ + private static Dictionary enchantmentMappings = new() + { + //id type + { 0, Enchantment.Protection }, + { 1, Enchantment.FireProtection }, + { 2, Enchantment.FeatherFalling }, + { 3, Enchantment.BlastProtection }, + { 4, Enchantment.ProjectileProtection }, + { 5, Enchantment.Respiration }, + { 6, Enchantment.AquaAffinity }, + { 7, Enchantment.Thorns }, + { 8, Enchantment.DepthStrieder }, + { 9, Enchantment.FrostWalker }, + { 10, Enchantment.BindingCurse }, + { 11, Enchantment.SoulSpeed }, + { 12, Enchantment.SwiftSneak }, + { 13, Enchantment.Sharpness }, + { 14, Enchantment.Smite }, + { 15, Enchantment.BaneOfArthropods }, + { 16, Enchantment.Knockback }, + { 17, Enchantment.FireAspect }, + { 18, Enchantment.Looting }, + { 19, Enchantment.Sweeping }, + { 20, Enchantment.Efficency }, + { 21, Enchantment.SilkTouch }, + { 22, Enchantment.Unbreaking }, + { 23, Enchantment.Fortune }, + { 24, Enchantment.Power }, + { 25, Enchantment.Punch }, + { 26, Enchantment.Flame }, + { 27, Enchantment.Infinity }, + { 28, Enchantment.LuckOfTheSea }, + { 29, Enchantment.Lure }, + { 30, Enchantment.Loyality }, + { 31, Enchantment.Impaling }, + { 32, Enchantment.Riptide }, + { 33, Enchantment.Channeling }, + { 34, Enchantment.Multishot }, + { 35, Enchantment.QuickCharge }, + { 36, Enchantment.Piercing }, + { 37, Enchantment.Density }, + { 38, Enchantment.Breach }, + { 39, Enchantment.WindBurst }, + { 40, Enchantment.Mending }, + { 41, Enchantment.VanishingCurse } + }; #pragma warning restore format // @formatter:on public static Enchantment GetEnchantmentById(int protocolVersion, short id) @@ -144,34 +192,32 @@ namespace MinecraftClient.Inventory if (protocolVersion < Protocol18Handler.MC_1_14_Version) throw new Exception("Enchantments mappings are not implemented bellow 1.14"); - Dictionary map = enchantmentMappings; + var map = protocolVersion switch + { + >= Protocol18Handler.MC_1_14_Version and < Protocol18Handler.MC_1_16_Version => enchantmentMappings114, + >= Protocol18Handler.MC_1_16_Version and < Protocol18Handler.MC_1_19_Version => enchantmentMappings116, + >= Protocol18Handler.MC_1_19_Version and < Protocol18Handler.MC_1_20_6_Version => enchantmentMappings119, + _ => enchantmentMappings + }; - if (protocolVersion >= Protocol18Handler.MC_1_14_Version && protocolVersion < Protocol18Handler.MC_1_16_Version) - map = enchantmentMappings114; - else if (protocolVersion >= Protocol18Handler.MC_1_16_Version && protocolVersion < Protocol18Handler.MC_1_19_Version) - map = enchantmentMappings116; + if (!map.TryGetValue(id, out var value)) + throw new Exception($"Got an Unknown Enchantment ID {id}, please update the Mappings!"); - if (!map.ContainsKey(id)) - throw new Exception("Got an Unknown Enchantment ID '" + id + "', please update the Mappings!"); - - return map[id]; + return value; } public static string GetEnchantmentName(Enchantment enchantment) { - string? trans = ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase()); - if (string.IsNullOrEmpty(trans)) - return "Unknown Enchantment with ID: " + ((short)enchantment) + " (Probably not named in the code yet)"; - else - return trans; + var translation = ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase()); + return string.IsNullOrEmpty(translation) ? $"Unknown Enchantment with ID: {(short)enchantment} (Probably not named in the code yet)" : translation; } public static string ConvertLevelToRomanNumbers(int num) { - string result = string.Empty; - Dictionary romanNumbers = new Dictionary + var result = string.Empty; + var romanNumbers = new Dictionary { - {"M", 1000 }, + {"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, diff --git a/MinecraftClient/Inventory/Enchantments.cs b/MinecraftClient/Inventory/Enchantments.cs index 34279de0..f1087d51 100644 --- a/MinecraftClient/Inventory/Enchantments.cs +++ b/MinecraftClient/Inventory/Enchantments.cs @@ -3,44 +3,47 @@ // Not implemented for 1.14 public enum Enchantment : short { - Protection = 0, - FireProtection, - FeatherFalling, - BlastProtection, - ProjectileProtection, - Respiration, - AquaAffinity, - Thorns, - DepthStrieder, - FrostWalker, - BindingCurse, - SoulSpeed, - SwiftSneak, - Sharpness, - Smite, + AquaAffinity = 0, BaneOfArthropods, - Knockback, - FireAspect, - Looting, - Sweeping, - Efficency, - SilkTouch, - Unbreaking, - Fortune, - Power, - Punch, - Flame, - Infinity, - LuckOfTheSea, - Lure, - Loyality, - Impaling, - Riptide, + BindingCurse, + BlastProtection, + Breach, Channeling, - Multishot, - QuickCharge, - Piercing, + DepthStrieder, + Density, + Efficency, + FeatherFalling, + FireAspect, + FireProtection, + Flame, + Fortune, + FrostWalker, + Impaling, + Infinity, + Knockback, + Looting, + LuckOfTheSea, + Loyality, + Lure, Mending, - VanishingCurse + Multishot, + Piercing, + Power, + ProjectileProtection, + Protection, + Punch, + QuickCharge, + Respiration, + Riptide, + Sharpness, + SilkTouch, + Smite, + SoulSpeed, + Sweeping, + SwiftSneak, + Thorns, + Unbreaking, + VanishingCurse, + WindBurst } } diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 15963231..5b220474 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_12_2_Version => new EntityMetadataPalette1122(), // 1.9 - 1.12.2 <= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2 <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 - <= Protocol18Handler.MC_1_20_4_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 + + <= Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.6 + _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index f7dd7fcd..8149a06c 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -118,6 +118,9 @@ namespace MinecraftClient // ChatBot OnNetworkPacket event private bool networkPacketCaptureEnabled = false; + + // Cookies + private Dictionary Cookies { get; set; } = new(); public int GetServerPort() { return port; } public string GetServerHost() { return host; } @@ -143,6 +146,8 @@ namespace MinecraftClient public ILogger GetLogger() { return Log; } public int GetPlayerEntityID() { return playerEntityID; } public List GetLoadedChatBots() { return new List(bots); } + public void GetCookie(string key, out byte[]? data) => Cookies.TryGetValue(key, out data); + public void SetCookie(string key, byte[] data) => Cookies[key] = data; readonly TcpClient client; readonly IMinecraftCom handler; diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 80137cff..c70d7c31 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.20.4"; + public const string MCHighestVersion = "1.20.6"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs index c9ca6e59..f6add9cf 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs @@ -2,16 +2,21 @@ namespace MinecraftClient.Protocol.Handlers; public enum ConfigurationPacketTypesIn { - PluginMessage, + CookieRequest, Disconnect, + FeatureFlags, FinishConfiguration, KeepAlive, + KnownDataPacks, Ping, + PluginMessage, RegistryData, - ResourcePack, RemoveResourcePack, - FeatureFlags, + ResetChat, + ResourcePack, + StoreCookie, + Transfer, UpdateTags, Unknown -} \ No newline at end of file +} diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs index f951a38d..32a99ec2 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs @@ -8,6 +8,8 @@ public enum ConfigurationPacketTypesOut KeepAlive, Pong, ResourcePackResponse, + CookieResponse, + KnownDataPacks, Unknown } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1206.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1206.cs new file mode 100644 index 00000000..2a5abce5 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1206.cs @@ -0,0 +1,230 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1206 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Added in 1.19.4 + { 0x01, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity) + { 0x02, PacketTypesIn.SpawnExperienceOrb }, // (Wiki name: Spawn Exeprience Orb) + { 0x03, PacketTypesIn.EntityAnimation }, // (Wiki name: Entity Animation (clientbound)) + { 0x04, PacketTypesIn.Statistics }, // (Wiki name: Award Statistics) + { 0x05, PacketTypesIn.BlockChangedAck }, // Added 1.19 (Wiki name: Acknowledge Block Change) + { 0x06, PacketTypesIn.BlockBreakAnimation }, // (Wiki name: Set Block Destroy Stage) + { 0x07, PacketTypesIn.BlockEntityData }, // + { 0x08, PacketTypesIn.BlockAction }, // + { 0x09, PacketTypesIn.BlockChange }, // (Wiki name: Block Update) + { 0x0A, PacketTypesIn.BossBar }, // + { 0x0B, PacketTypesIn.ServerDifficulty }, // (Wiki name: Change Difficulty) + { 0x0C, PacketTypesIn.ChunkBatchFinished }, // Added in 1.20.2 + { 0x0D, PacketTypesIn.ChunkBatchStarted }, // Added in 1.20.2 + { 0x0E, PacketTypesIn.ChunksBiomes }, // Added in 1.19.4 + { 0x0F, PacketTypesIn.ClearTiles }, // + { 0x10, PacketTypesIn.TabComplete }, // (Wiki name: Command Suggestions Response) + { 0x11, PacketTypesIn.DeclareCommands }, // (Wiki name: Commands) + { 0x12, PacketTypesIn.CloseWindow }, // (Wiki name: Close Container (clientbound)) + { 0x13, PacketTypesIn.WindowItems }, // (Wiki name: Set Container Content) + { 0x14, PacketTypesIn.WindowProperty }, // (Wiki name: Set Container Property) + { 0x15, PacketTypesIn.SetSlot }, // (Wiki name: Set Container Slot) + { 0x16, PacketTypesIn.CookieRequest }, // Added in 1.20.6 + { 0x17, PacketTypesIn.SetCooldown }, // + { 0x18, PacketTypesIn.ChatSuggestions }, // Added in 1.19.1 + { 0x19, PacketTypesIn.PluginMessage }, // (Wiki name: Plugin Message (clientbound)) + { 0x1A, PacketTypesIn.DamageEvent }, // Added in 1.19.4 + { 0x1B, PacketTypesIn.DebugSample }, // Added in 1.20.6 + { 0x1C, PacketTypesIn.HideMessage }, // Added in 1.19.1 + { 0x1D, PacketTypesIn.Disconnect }, // + { 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Added in 1.19.3 (Wiki name: Disguised Chat Message) + { 0x1F, PacketTypesIn.EntityStatus }, // (Wiki name: Entity Event) + { 0x20, PacketTypesIn.Explosion }, // Changed in 1.19 (Location fields are now Double instead of Float) (Wiki name: Explosion) + { 0x21, PacketTypesIn.UnloadChunk }, // (Wiki name: Forget Chunk) + { 0x22, PacketTypesIn.ChangeGameState }, // (Wiki name: Game Event) + { 0x23, PacketTypesIn.OpenHorseWindow }, // (Wiki name: Horse Screen Open) + { 0x24, PacketTypesIn.HurtAnimation }, // Added in 1.19.4 + { 0x25, PacketTypesIn.InitializeWorldBorder }, // + { 0x26, PacketTypesIn.KeepAlive }, // + { 0x27, PacketTypesIn.ChunkData }, // + { 0x28, PacketTypesIn.Effect }, // (Wiki name: World Event) + { 0x29, PacketTypesIn.Particle }, // Changed in 1.19 (Wiki name: Level Particle) (No need to be implemented) + { 0x2A, PacketTypesIn.UpdateLight }, // (Wiki name: Light Update) + { 0x2B, PacketTypesIn.JoinGame }, // Changed in 1.20.2 (Wiki name: Login (play)) + { 0x2C, PacketTypesIn.MapData }, // (Wiki name: Map Item Data) + { 0x2D, PacketTypesIn.TradeList }, // (Wiki name: Merchant Offers) + { 0x2E, PacketTypesIn.EntityPosition }, // (Wiki name: Move Entity Position) + { 0x2F, PacketTypesIn.EntityPositionAndRotation }, // (Wiki name: Move Entity Position and Rotation) + { 0x30, PacketTypesIn.EntityRotation }, // (Wiki name: Move Entity Rotation) + { 0x31, PacketTypesIn.VehicleMove }, // (Wiki name: Move Vehicle) + { 0x32, PacketTypesIn.OpenBook }, // + { 0x33, PacketTypesIn.OpenWindow }, // (Wiki name: Open Screen) + { 0x34, PacketTypesIn.OpenSignEditor }, // + { 0x35, PacketTypesIn.Ping }, // (Wiki name: Ping (play)) + { 0x36, PacketTypesIn.PingResponse }, // Added in 1.20.2 + { 0x37, PacketTypesIn.CraftRecipeResponse }, // (Wiki name: Place Ghost Recipe) + { 0x38, PacketTypesIn.PlayerAbilities }, // + { 0x39, PacketTypesIn.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Player Chat Message) + { 0x3A, PacketTypesIn.EndCombatEvent }, // (Wiki name: End Combat) + { 0x3B, PacketTypesIn.EnterCombatEvent }, // (Wiki name: Enter Combat) + { 0x3C, PacketTypesIn.DeathCombatEvent }, // (Wiki name: Combat Death) + { 0x3D, PacketTypesIn.PlayerRemove }, // Added in 1.19.3 (Not used) + { 0x3E, PacketTypesIn.PlayerInfo }, // Changed in 1.19 (Heavy changes) + { 0x3F, PacketTypesIn.FacePlayer }, // (Wiki name: Player Look At) + { 0x40, PacketTypesIn.PlayerPositionAndLook }, // (Wiki name: Synchronize Player Position) + { 0x41, PacketTypesIn.UnlockRecipes }, // (Wiki name: Update Recipe Book) + { 0x42, PacketTypesIn.DestroyEntities }, // (Wiki name: Remove Entites) + { 0x43, PacketTypesIn.RemoveEntityEffect }, // + { 0x44, PacketTypesIn.ResetScore }, // Added in 1.20.3 + { 0x45, PacketTypesIn.RemoveResourcePack }, // Added in 1.20.3 + { 0x46, PacketTypesIn.ResourcePackSend }, // (Wiki name: Add Resource pack (play)) + { 0x47, PacketTypesIn.Respawn }, // Changed in 1.20.2 + { 0x48, PacketTypesIn.EntityHeadLook }, // (Wiki name: Set Head Rotation) + { 0x49, PacketTypesIn.MultiBlockChange }, // (Wiki name: Update Section Blocks) + { 0x4A, PacketTypesIn.SelectAdvancementTab }, // + { 0x4B, PacketTypesIn.ServerData }, // Added in 1.19 + { 0x4C, PacketTypesIn.ActionBar }, // (Wiki name: Set Action Bar Text) + { 0x4D, PacketTypesIn.WorldBorderCenter }, // (Wiki name: Set Border Center) + { 0x4E, PacketTypesIn.WorldBorderLerpSize }, // + { 0x4F, PacketTypesIn.WorldBorderSize }, // (Wiki name: Set World Border Size) + { 0x50, PacketTypesIn.WorldBorderWarningDelay }, // (Wiki name: Set World Border Warning Delay) + { 0x51, PacketTypesIn.WorldBorderWarningReach }, // (Wiki name: Set Border Warning Distance) + { 0x52, PacketTypesIn.Camera }, // (Wiki name: Set Camera) + { 0x53, PacketTypesIn.HeldItemChange }, // (Wiki name: Set Held Item) + { 0x54, PacketTypesIn.UpdateViewPosition }, // (Wiki name: Set Center Chunk) + { 0x55, PacketTypesIn.UpdateViewDistance }, // (Wiki name: Set Render Distance) + { 0x56, PacketTypesIn.SpawnPosition }, // (Wiki name: Set Default Spawn Position) + { 0x57, PacketTypesIn.DisplayScoreboard }, // (Wiki name: Set Display Objective) + { 0x58, PacketTypesIn.EntityMetadata }, // (Wiki name: Set Entity Metadata) + { 0x59, PacketTypesIn.AttachEntity }, // (Wiki name: Link Entities) + { 0x5A, PacketTypesIn.EntityVelocity }, // (Wiki name: Set Entity Velocity) + { 0x5B, PacketTypesIn.EntityEquipment }, // (Wiki name: Set Equipment) + { 0x5C, PacketTypesIn.SetExperience }, // Changed in 1.20.2 + { 0x5D, PacketTypesIn.UpdateHealth }, // (Wiki name: Set Health) + { 0x5E, PacketTypesIn.ScoreboardObjective }, // (Wiki name: Update Objectives) - Changed in 1.20.3 + { 0x5F, PacketTypesIn.SetPassengers }, // + { 0x60, PacketTypesIn.Teams }, // (Wiki name: Update Teams) + { 0x61, PacketTypesIn.UpdateScore }, // (Wiki name: Update Score) + { 0x62, PacketTypesIn.UpdateSimulationDistance }, // (Wiki name: Set Simulation Distance) + { 0x63, PacketTypesIn.SetTitleSubTitle }, // (Wiki name: Set Subtitle Test) + { 0x64, PacketTypesIn.TimeUpdate }, // (Wiki name: Set Time) + { 0x65, PacketTypesIn.SetTitleText }, // (Wiki name: Set Title) + { 0x66, PacketTypesIn.SetTitleTime }, // (Wiki name: Set Title Animation Times) + { 0x67, PacketTypesIn.EntitySoundEffect }, // (Wiki name: Sound Entity) + { 0x68, PacketTypesIn.SoundEffect }, // Changed in 1.19 (Added "Seed" field) (Wiki name: Sound Effect) (No need to be implemented) + { 0x69, PacketTypesIn.StartConfiguration }, // Added in 1.20.2 + { 0x6A, PacketTypesIn.StopSound }, // + { 0x6B, PacketTypesIn.StoreCookie }, // Added in 1.20.6 + { 0x6C, PacketTypesIn.SystemChat }, // Added in 1.19 (Wiki name: System Chat Message) + { 0x6D, PacketTypesIn.PlayerListHeaderAndFooter }, // (Wiki name: Set Tab List Header And Footer) + { 0x6E, PacketTypesIn.NBTQueryResponse }, // (Wiki name: Tag Query Response) + { 0x6F, PacketTypesIn.CollectItem }, // (Wiki name: Pickup Item) + { 0x70, PacketTypesIn.EntityTeleport }, // (Wiki name: Teleport Entity) + { 0x71, PacketTypesIn.SetTickingState }, // Added in 1.20.3 + { 0x72, PacketTypesIn.StepTick }, // Added in 1.20.3 + { 0x73, PacketTypesIn.Transfer }, // Added in 1.20.6 + { 0x74, PacketTypesIn.Advancements }, // (Wiki name: Update Advancements) (Unused) + { 0x75, PacketTypesIn.EntityProperties }, // (Wiki name: Update Attributes) + { 0x76, PacketTypesIn.EntityEffect }, // Changed in 1.19 (Added "Has Factor Data" and "Factor Codec" fields) (Wiki name: Entity Effect) + { 0x77, PacketTypesIn.DeclareRecipes }, // (Wiki name: Update Recipes) (Unused) + { 0x78, PacketTypesIn.Tags }, // (Wiki name: Update Tags) + { 0x79, PacketTypesIn.ProjectilePower }, // Added in 1.20.6 + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation) + { 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag) + { 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficulty) + { 0x03, PacketTypesOut.MessageAcknowledgment }, // Added in 1.19.1 + { 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19 + { 0x05, PacketTypesOut.SignedChatCommand }, // Added in 1.20.6 + { 0x06, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat) + { 0x07, PacketTypesOut.PlayerSession }, // Added in 1.19.3 + { 0x08, PacketTypesOut.ChunkBatchReceived }, // Added in 1.20.2 + { 0x09, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command) + { 0x0A, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information) + { 0x0B, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request) + { 0x0C, PacketTypesOut.AcknowledgeConfiguration }, // Added in 1.20.2 + { 0x0D, PacketTypesOut.ClickWindowButton }, // (Wiki name: Click Container Button) + { 0x0E, PacketTypesOut.ClickWindow }, // (Wiki name: Click Container) + { 0x0F, PacketTypesOut.CloseWindow }, // (Wiki name: Close Container (serverbound)) + { 0x10, PacketTypesOut.ChangeContainerSlotState }, // Added in 1.20.3 + { 0x11, PacketTypesOut.CookieResponse }, // Added in 1.20.6 + { 0x12, PacketTypesOut.PluginMessage }, // (Wiki name: Serverbound Plugin Message) + { 0x13, PacketTypesOut.DebugSampleSubscription }, // Added in 1.20.6 + { 0x14, PacketTypesOut.EditBook }, // + { 0x15, PacketTypesOut.EntityNBTRequest }, // (Wiki name: Query Entity Tag) + { 0x16, PacketTypesOut.InteractEntity }, // (Wiki name: Interact) + { 0x17, PacketTypesOut.GenerateStructure }, // (Wiki name: Jigsaw Generate) + { 0x18, PacketTypesOut.KeepAlive }, // (Wiki name: Serverbound Keep Alive (play)) + { 0x19, PacketTypesOut.LockDifficulty }, // + { 0x1A, PacketTypesOut.PlayerPosition }, // (Wiki name: Move Player Position) + { 0x1B, PacketTypesOut.PlayerPositionAndRotation }, // (Wiki name: Set Player Position and Rotation) + { 0x1C, PacketTypesOut.PlayerRotation }, // (Wiki name: Set Player Rotation) + { 0x1D, PacketTypesOut.PlayerMovement }, // (Wiki name: Set Player On Ground) + { 0x1E, PacketTypesOut.VehicleMove }, // (Wiki name: Move Vehicle (serverbound)) + { 0x1F, PacketTypesOut.SteerBoat }, // (Wiki name: Paddle Boat) + { 0x20, PacketTypesOut.PickItem }, // + { 0x21, PacketTypesOut.PingRequest }, // Added in 1.20.2 + { 0x22, PacketTypesOut.CraftRecipeRequest }, // (Wiki name: Place recipe) + { 0x23, PacketTypesOut.PlayerAbilities }, // + { 0x24, PacketTypesOut.PlayerDigging }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Player Action) + { 0x25, PacketTypesOut.EntityAction }, // (Wiki name: Player Command) + { 0x26, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input) + { 0x27, PacketTypesOut.Pong }, // (Wiki name: Pong (play)) + { 0x28, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings) + { 0x29, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe) + { 0x2A, PacketTypesOut.NameItem }, // (Wiki name: Rename Item) + { 0x2B, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound)) + { 0x2C, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements) + { 0x2D, PacketTypesOut.SelectTrade }, // + { 0x2E, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (No need to be implemented yet) + { 0x2F, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound)) + { 0x30, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Program Command Block) + { 0x31, PacketTypesOut.UpdateCommandBlockMinecart }, // (Wiki name: Program Command Block Minecart) + { 0x32, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot) + { 0x33, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Program Jigsaw Block) + { 0x34, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Program Structure Block) + { 0x35, PacketTypesOut.UpdateSign }, // (Wiki name: Update Sign) + { 0x36, PacketTypesOut.Animation }, // (Wiki name: Swing Arm) + { 0x37, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity) + { 0x38, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On) + { 0x39, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item) + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks } + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index e012f853..5deac47b 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,7 +48,7 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_20_4_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_20_6_Version => throw new NotImplementedException(Translations .exception_palette_packet), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), <= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(), @@ -67,7 +67,8 @@ namespace MinecraftClient.Protocol.Handlers <= Protocol18Handler.MC_1_19_4_Version => new PacketPalette1194(), <= Protocol18Handler.MC_1_20_Version => new PacketPalette1194(), <= Protocol18Handler.MC_1_20_2_Version => new PacketPalette1202(), - _ => new PacketPalette1204() + <= Protocol18Handler.MC_1_20_4_Version => new PacketPalette1204(), + _ => new PacketPalette1206() }; p.SetForgeEnabled(forgeEnabled); diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index b4b8debc..9eab7b39 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -29,9 +29,11 @@ CloseWindow, // CollectItem, // CombatEvent, // + CookieRequest, // Added in 1.20.6 CraftRecipeResponse, // DamageEvent, // Added in 1.19.4 DeathCombatEvent, // + DebugSample, // Added in 1.20.6 DeclareCommands, // DeclareRecipes, // DestroyEntities, // @@ -83,6 +85,7 @@ PlayerPositionAndLook, // PluginMessage, // ProfilelessChatMessage, // Added in 1.19.3 + ProjectilePower, // Added in 1.20.6 RemoveEntityEffect, // RemoveResourcePack, // Added in 1.20.3 ResetScore, // Added in 1.20.3 @@ -115,6 +118,7 @@ StartConfiguration, // Added in 1.20.2 Statistics, // StopSound, // + StoreCookie, // Added in 1.20.6 SystemChat, // Added in 1.19 TabComplete, // Tags, // @@ -122,6 +126,7 @@ TimeUpdate, // Title, // TradeList, // + Transfer, // Added in 1.20.6 Unknown, // For old version packet that have been removed and not used by mcc UnloadChunk, // UnlockRecipes, // diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index 61221968..1149a71f 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -20,6 +20,8 @@ CloseWindow, // CraftRecipeRequest, // CreativeInventoryAction, // + CookieResponse, // Added in 1.20.6 + DebugSampleSubscription, // Added in 1.20.6 EditBook, // EnchantItem, // For 1.13.2 or below EntityAction, // @@ -28,6 +30,7 @@ HeldItemChange, // InteractEntity, // KeepAlive, // + KnownDataPacks, // Added in 1.20.6 LockDifficulty, // MessageAcknowledgment, // Added in 1.19.1 (1.19.2) NameItem, // @@ -52,6 +55,7 @@ SetDifficulty, // SetDisplayedRecipe, // Added in 1.16.2 SetRecipeBookState, // Added in 1.16.2 + SignedChatCommand, // Added in 1.20.6 Spectate, // SteerBoat, // SteerVehicle, // diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index e4faf0bf..969d5e11 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -236,6 +236,16 @@ namespace MinecraftClient.Protocol.Handlers return netRead != null ? netRead.Item1.ManagedThreadId : -1; } + public bool SendCookieResponse(string name, byte[]? data) + { + throw new NotImplementedException(); + } + + public bool SendKnownDataPacks(List<(string, string, string)> knownDataPacks) + { + throw new NotImplementedException(); + } + public void Dispose() { try diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 43962bb3..43a45030 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -70,6 +70,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_20_Version = 763; internal const int MC_1_20_2_Version = 764; internal const int MC_1_20_4_Version = 765; + internal const int MC_1_20_6_Version = 766; private int compression_treshold = 0; private int autocomplete_transaction_id = 0; @@ -391,8 +392,16 @@ namespace MinecraftClient.Protocol.Handlers List responseData = new(); var understood = pForge.HandleLoginPluginRequest(channel, packetData, ref responseData); SendLoginPluginResponse(messageId, understood, responseData.ToArray()); - return understood; + break; + // Cookie Request + case 0x05: + var cookieName = dataTypes.ReadNextString(packetData); + var cookieData = null as byte[]; + McClient.Instance?.GetCookie(cookieName, out cookieData); + SendCookieResponse(cookieName, cookieData); + break; + // Ignore other packets at this stage default: return true; @@ -404,6 +413,13 @@ namespace MinecraftClient.Protocol.Handlers case CurrentState.Configuration: switch (packetPalette.GetIncomingConfigurationTypeById(packetId)) { + case ConfigurationPacketTypesIn.CookieRequest: + var cookieName = dataTypes.ReadNextString(packetData); + var cookieData = null as byte[]; + McClient.Instance?.GetCookie(cookieName, out cookieData); + SendCookieResponse(cookieName, cookieData); + break; + case ConfigurationPacketTypesIn.Disconnect: handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, dataTypes.ReadNextChat(packetData)); @@ -423,11 +439,48 @@ namespace MinecraftClient.Protocol.Handlers break; case ConfigurationPacketTypesIn.RegistryData: - var registryCodec = dataTypes.ReadNextNbt(packetData); - ChatParser.ReadChatType(registryCodec); + if (protocolVersion < MC_1_20_6_Version) + { + var registryCodec = dataTypes.ReadNextNbt(packetData); + ChatParser.ReadChatType(registryCodec); - if (handler.GetTerrainEnabled()) - World.StoreDimensionList(registryCodec); + if (handler.GetTerrainEnabled()) + World.StoreDimensionList(registryCodec); + } + else + { + var registryId = dataTypes.ReadNextString(packetData); + var entryCount = dataTypes.ReadNextVarInt(packetData); + + // Ignore other registries to save on time, we need only these 2 + if(registryId is not ("minecraft:dimension_type" or "minecraft:chat_type")) + break; + + var avaliableChats = new Dictionary(); + var dimensionType = new Dictionary(); + + for (var i = 0; i < entryCount; i++) + { + var entryId = dataTypes.ReadNextString(packetData); + var hasData = dataTypes.ReadNextBool(packetData); + + if (hasData) + { + dataTypes.ReadNextNbt(packetData); // Never seem to be sent because hasData is always false + } + + if (registryId == "minecraft:chat_type") + avaliableChats.Add(i, entryId); + else dimensionType.Add(i, entryId); + } + + if (registryId == "minecraft:chat_type") + ChatParser.ReadChatType(avaliableChats); + else + { + // TODO: 1.20.6 Somehow store this data from dimensionType in the World class + } + } break; @@ -439,6 +492,35 @@ namespace MinecraftClient.Protocol.Handlers case ConfigurationPacketTypesIn.ResourcePack: HandleResourcePackPacket(packetData); break; + + case ConfigurationPacketTypesIn.StoreCookie: + var name = dataTypes.ReadNextString(packetData); + var data = dataTypes.ReadNextByteArray(packetData); + McClient.Instance?.SetCookie(name, data); + break; + + case ConfigurationPacketTypesIn.Transfer: + var host = dataTypes.ReadNextString(packetData); + var port = dataTypes.ReadNextVarInt(packetData); + + // TODO: 1.20.6 Implement Host Chaging in the McClient class + // McClient.Instance?.Transfer(host, port); + break; + + case ConfigurationPacketTypesIn.KnownDataPacks: + var knownPacksCount = dataTypes.ReadNextVarInt(packetData); + List<(string, string, string)> knownDataPacks = new(); + + for (var i = 0; i < knownPacksCount; i++) + { + var nameSpace = dataTypes.ReadNextString(packetData); + var id = dataTypes.ReadNextString(packetData); + var version = dataTypes.ReadNextString(packetData); + knownDataPacks.Add((nameSpace, id, version)); + } + + SendKnownDataPacks(knownDataPacks); + break; // Ignore other packets at this stage default: @@ -574,7 +656,7 @@ namespace MinecraftClient.Protocol.Handlers { var registryCodec = dataTypes.ReadNextNbt( - packetData); // Registry Codec (Dimension Codec) - 1.16 and above + packetData); // Registry Codec (Dimension Codec) - 1.16 - 1.20.1 if (protocolVersion >= MC_1_19_Version) ChatParser.ReadChatType(registryCodec); if (handler.GetTerrainEnabled()) @@ -591,6 +673,7 @@ namespace MinecraftClient.Protocol.Handlers // varInt: [1.9.1 to 1.15.2] // byte: below 1.9.1 string? dimensionTypeName = null; + int? dimensionTypeInt2 = null; Dictionary? dimensionType = null; switch (protocolVersion) { @@ -598,6 +681,9 @@ namespace MinecraftClient.Protocol.Handlers { switch (protocolVersion) { + case >= MC_1_20_6_Version: + dimensionTypeInt2 = dataTypes.ReadNextVarInt(packetData); + break; case >= MC_1_19_Version: dimensionTypeName = dataTypes.ReadNextString(packetData); // Dimension Type: Identifier @@ -642,9 +728,12 @@ namespace MinecraftClient.Protocol.Handlers World.StoreOneDimension(dimensionName, dimensionType!); World.SetDimension(dimensionName); break; - default: + case < MC_1_20_6_Version: World.SetDimension(dimensionTypeName!); break; + case >= MC_1_20_6_Version: + // TODO: 1.20.6 Set the dimension (use dimensionTypeInt) + break; } } @@ -713,6 +802,9 @@ namespace MinecraftClient.Protocol.Handlers } dataTypes.ReadNextVarInt(packetData); // Portal Cooldown + + if (protocolVersion >= MC_1_20_6_Version) + dataTypes.ReadNextBool(packetData); // Enforoces Secure Chat } break; case PacketTypesIn.SpawnPainting: // Just skip, no need for this @@ -1105,7 +1197,7 @@ namespace MinecraftClient.Protocol.Handlers }; } - // TODO: Write a function to use this data ? But seems not too useful + // Maybe write a function to use this data ? But seems not too useful } break; @@ -1148,10 +1240,15 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.Respawn: string? dimensionTypeNameRespawn = null; Dictionary? dimensionTypeRespawn = null; + int? dimensionTypeInt = null; + if (protocolVersion >= MC_1_16_Version) { switch (protocolVersion) { + case >= MC_1_20_6_Version: + dimensionTypeInt = dataTypes.ReadNextVarInt(packetData); + break; case >= MC_1_19_Version: dimensionTypeNameRespawn = dataTypes.ReadNextString(packetData); // Dimension Type: Identifier @@ -1189,9 +1286,12 @@ namespace MinecraftClient.Protocol.Handlers World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); World.SetDimension(dimensionName); break; - case >= MC_1_19_Version: + case < MC_1_20_6_Version: World.SetDimension(dimensionTypeNameRespawn!); break; + case >= MC_1_20_6_Version: + // TODO: 1.20.6 Set the dimension (use dimensionTypeInt) + break; } } @@ -2262,7 +2362,7 @@ namespace MinecraftClient.Protocol.Handlers var hasFactorData = false; Dictionary? factorCodec = null; - if (protocolVersion >= MC_1_19_Version) + if (protocolVersion >= MC_1_19_Version && protocolVersion < MC_1_20_6_Version) { hasFactorData = dataTypes.ReadNextBool(packetData); if (hasFactorData) @@ -2642,6 +2742,27 @@ namespace MinecraftClient.Protocol.Handlers dataTypes.ReadNextBool(packetData); break; + case PacketTypesIn.CookieRequest: + var cookieName = dataTypes.ReadNextString(packetData); + var cookieData = null as byte[]; + McClient.Instance?.GetCookie(cookieName, out cookieData); + SendCookieResponse(cookieName, cookieData); + break; + + case PacketTypesIn.StoreCookie: + var cookieName2 = dataTypes.ReadNextString(packetData); + var cookieData2 = dataTypes.ReadNextByteArray(packetData); + McClient.Instance?.SetCookie(cookieName2, cookieData2); + break; + + case PacketTypesIn.Transfer: + var host = dataTypes.ReadNextString(packetData); + var port = dataTypes.ReadNextVarInt(packetData); + + // TODO: 1.20.6 Implement Host Chaging in the McClient class + // McClient.Instance?.Transfer(host, port); + break; + default: return false; //Ignored packet } @@ -2845,9 +2966,15 @@ namespace MinecraftClient.Protocol.Handlers var serverId = dataTypes.ReadNextString(packetData); var serverPublicKey = dataTypes.ReadNextByteArray(packetData); var token = dataTypes.ReadNextByteArray(packetData); + + var shouldAuthetnicate = false; + + if (protocolVersion >= MC_1_20_6_Version) + shouldAuthetnicate = dataTypes.ReadNextBool(packetData); + return StartEncryption(handler.GetUserUuidStr(), handler.GetSessionID(), Config.Main.General.AccountType, token, serverId, - serverPublicKey, playerKeyPair, session); + serverPublicKey, playerKeyPair, session, shouldAuthetnicate); } // Login successful @@ -2882,7 +3009,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// True if encryption was successful private bool StartEncryption(string uuid, string sessionID, LoginType type, byte[] token, string serverIDhash, - byte[] serverPublicKey, PlayerKeyPair? playerKeyPair, SessionToken session) + byte[] serverPublicKey, PlayerKeyPair? playerKeyPair, SessionToken session, bool shouldAuthetnicate) { var RSAService = CryptoHandler.DecodeRSAPublicKey(serverPublicKey)!; var secretKey = CryptoHandler.ClientAESPrivateKey ?? CryptoHandler.GenerateAESPrivateKey(); @@ -2902,6 +3029,10 @@ namespace MinecraftClient.Protocol.Handlers if (session.SessionPreCheckTask.Result) // PreCheck Success needCheckSession = false; } + + // 1.20.6++ + if (shouldAuthetnicate) + needCheckSession = true; if (needCheckSession) { @@ -2971,6 +3102,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); return false; + //Login successful case 0x02: { @@ -2993,6 +3125,10 @@ namespace MinecraftClient.Protocol.Handlers } } + // Strict Error Handling (Ignored) + if (protocolVersion >= MC_1_20_6_Version) + dataTypes.ReadNextBool(packetData); + currentState = protocolVersion < MC_1_20_2_Version ? CurrentState.Play : CurrentState.Configuration; @@ -4538,7 +4674,90 @@ namespace MinecraftClient.Protocol.Handlers return false; } } + + public bool SendCookieResponse(string name, byte[]? data) + { + try + { + var packet = new List(); + var hasPayload = data is not null; + packet.AddRange(dataTypes.GetString(name)); // Identifier + packet.AddRange(dataTypes.GetBool(hasPayload)); // Has payload + + if (hasPayload) + packet.AddRange(dataTypes.GetArray(data!)); // Payload Data Array Size + Data Array + switch(currentState) + { + case CurrentState.Login: + SendPacket(0x04, packet); + break; + + case CurrentState.Configuration: + SendPacket(ConfigurationPacketTypesOut.CookieResponse, packet); + break; + + case CurrentState.Play: + SendPacket(PacketTypesOut.CookieResponse, packet); + break; + } + + return true; + } + catch (SocketException) + { + return false; + } + catch (System.IO.IOException) + { + return false; + } + catch (ObjectDisposedException) + { + return false; + } + } + + public bool SendKnownDataPacks(List<(string, string, string)> knownDataPacks) + { + try + { + var packet = new List(); + packet.AddRange(DataTypes.GetVarInt(knownDataPacks.Count)); // Known Packs Count + foreach (var dataPack in knownDataPacks) + { + packet.AddRange(dataTypes.GetString(dataPack.Item1)); + packet.AddRange(dataTypes.GetString(dataPack.Item2)); + packet.AddRange(dataTypes.GetString(dataPack.Item3)); + } + + switch(currentState) + { + case CurrentState.Configuration: + SendPacket(ConfigurationPacketTypesOut.KnownDataPacks, packet); + break; + + case CurrentState.Play: + SendPacket(PacketTypesOut.KnownDataPacks, packet); + break; + } + + return true; + } + catch (SocketException) + { + return false; + } + catch (System.IO.IOException) + { + return false; + } + catch (ObjectDisposedException) + { + return false; + } + } + private byte[] GenerateSalt() { var salt = new byte[8]; @@ -4559,6 +4778,7 @@ namespace MinecraftClient.Protocol.Handlers { Login = 0, Configuration, - Play + Play, + Transfer } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs index eb5d03ed..12cdee09 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -273,5 +273,18 @@ namespace MinecraftClient.Protocol /// /// Net read thread ID int GetNetMainThreadId(); + + /// + /// Send the server a requested cookie + /// + /// The cookie identifier/name + /// The cookie data byte array + bool SendCookieResponse(string name, byte[]? data); + + /// + /// Send the server known data packs + /// + /// The clist of tuples containing info about the kown data packs (namespace, id, version) + bool SendKnownDataPacks(List<(string, string, string)> knownDataPacks); } } diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 138913ec..d6033e9b 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -44,7 +44,9 @@ namespace MinecraftClient.Protocol int GetProtocolVersion(); Container? GetInventory(int inventoryID); ILogger GetLogger(); - + void GetCookie(string key, out byte[]? data); + void SetCookie(string key, byte[] data); + /// /// Invoke a task on the main thread, wait for completion and retrieve return value. /// diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index 5bfd2b66..b540e3b6 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -31,9 +31,32 @@ namespace MinecraftClient.Protocol.Message public static Dictionary? ChatId2Type; + // Used to store Chat Types in 1.20.6+ + public static void ReadChatType(Dictionary data) + { + var chatTypeDictionary = ChatId2Type ?? new Dictionary(); + + foreach (var (chatId, chatName) in data) + { + chatTypeDictionary[chatId] = chatName switch + { + "minecraft:chat" => MessageType.CHAT, + "minecraft:emote_command" => MessageType.EMOTE_COMMAND, + "minecraft:msg_command_incoming" => MessageType.MSG_COMMAND_INCOMING, + "minecraft:msg_command_outgoing" => MessageType.MSG_COMMAND_OUTGOING, + "minecraft:say_command" => MessageType.SAY_COMMAND, + "minecraft:team_msg_command_incoming" => MessageType.TEAM_MSG_COMMAND_INCOMING, + "minecraft:team_msg_command_outgoing" => MessageType.TEAM_MSG_COMMAND_OUTGOING, + _ => MessageType.CHAT, + }; + } + + ChatId2Type = chatTypeDictionary; + } + public static void ReadChatType(Dictionary registryCodec) { - Dictionary chatTypeDictionary = ChatId2Type ?? new(); + var chatTypeDictionary = ChatId2Type ?? new Dictionary(); var chatTypeListNbt = (object[])(((Dictionary)registryCodec["minecraft:chat_type"])["value"]); foreach (var (chatName, chatId) in from Dictionary chatTypeNbt in chatTypeListNbt diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index cbf1b1cd..a2ea85b5 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -153,7 +153,7 @@ namespace MinecraftClient.Protocol int[] suppoertedVersionsProtocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, - 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765 + 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -345,6 +345,9 @@ namespace MinecraftClient.Protocol case "1.20.3": case "1.20.4": return 765; + case "1.20.5": + case "1.20.6": + return 766; default: return 0; } @@ -424,6 +427,7 @@ namespace MinecraftClient.Protocol 763 => "1.20", 764 => "1.20.2", 765 => "1.20.4", + 766 => "1.20.6", _ => "0.0" }; } From 67e36a92d238694c715f5c54f55a308213467eda Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 30 Jun 2024 11:26:41 +0200 Subject: [PATCH 005/484] First working version, not fully tested --- MinecraftClient/Mapping/World.cs | 144 +++++++++++++++++- MinecraftClient/McClient.cs | 78 +++++++++- .../Protocol/Handlers/Protocol18.cs | 141 ++++++++--------- .../Protocol/IMinecraftComHandler.cs | 3 + 4 files changed, 294 insertions(+), 72 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 0b2e02f9..f2f285b4 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -69,6 +69,149 @@ namespace MinecraftClient.Mapping } } + public static void LoadDefaultDimensions1206Plus() + { + // TODO: Move this to a JSON file. + + var defaultRegistryCodec = new Dictionary + { + { "minecraft:dimension_type", new Dictionary + { + { "value", new object[] + { + new Dictionary + { + { "name", "minecraft:overworld" }, + { "id", 0 }, + { "element", new Dictionary + { + { "piglin_safe", (byte)0 }, + { "natural", 1 }, + { "ambient_light", 0.0 }, + { "monster_spawn_block_light_limit", 0 }, + { "infiniburn", "#minecraft:infiniburn_overworld" }, + { "respawn_anchor_works", 0 }, + { "has_skylight", 1 }, + { "bed_works", 1 }, + { "effects", "minecraft:overworld" }, + { "has_raids", 1 }, + { "logical_height", 384 }, + { "coordinate_scale", 1.0 }, + { "monster_spawn_light_level", new Dictionary + { + { "min_inclusive", 0 }, + { "max_inclusive", 7 }, + { "type", "minecraft:uniform" } + } + }, + { "min_y", -64 }, + { "ultrawarm", 0 }, + { "has_ceiling", 0 }, + { "height", 384 } + } + } + }, + new Dictionary + { + { "name", "minecraft:overworld_caves" }, + { "id", 1 }, + { "element", new Dictionary + { + { "piglin_safe", (byte)0 }, + { "natural", 1 }, + { "ambient_light", 0.0 }, + { "monster_spawn_block_light_limit", 0 }, + { "infiniburn", "#minecraft:infiniburn_overworld" }, + { "respawn_anchor_works", 0 }, + { "has_skylight", 1 }, + { "bed_works", 1 }, + { "effects", "minecraft:overworld" }, + { "has_raids", 1 }, + { "logical_height", 384 }, + { "coordinate_scale", 1.0 }, + { "monster_spawn_light_level", new Dictionary + { + { "min_inclusive", 0 }, + { "max_inclusive", 7 }, + { "type", "minecraft:uniform" } + } + }, + { "min_y", -64 }, + { "ultrawarm", 0 }, + { "has_ceiling", 1 }, + { "height", 384 } + } + } + }, + new Dictionary + { + { "name", "minecraft:the_end" }, + { "id", 2 }, + { "element", new Dictionary + { + { "piglin_safe", (byte)0 }, + { "natural", 0 }, + { "ambient_light", 0.0 }, + { "monster_spawn_block_light_limit", 0 }, + { "infiniburn", "#minecraft:infiniburn_end" }, + { "respawn_anchor_works", 0 }, + { "has_skylight", 0 }, + { "bed_works", 0 }, + { "effects", "minecraft:the_end" }, + { "fixed_time", 6000 }, + { "has_raids", 1 }, + { "logical_height", 256 }, + { "coordinate_scale", 1.0 }, + { "monster_spawn_light_level", new Dictionary + { + { "min_inclusive", 0 }, + { "max_inclusive", 7 }, + { "type", "minecraft:uniform" } + } + }, + { "min_y", 0 }, + { "ultrawarm", 0 }, + { "has_ceiling", 0 }, + { "height", 256 } + } + } + }, + new Dictionary + { + { "name", "minecraft:the_nether" }, + { "id", 3 }, + { "element", new Dictionary + { + { "piglin_safe", (byte)1 }, + { "natural", 0 }, + { "ambient_light", 0.1 }, + { "monster_spawn_block_light_limit", 15 }, + { "infiniburn", "#minecraft:infiniburn_nether" }, + { "respawn_anchor_works", 1 }, + { "has_skylight", 0 }, + { "bed_works", 0 }, + { "effects", "minecraft:the_nether" }, + { "fixed_time", 18000 }, + { "has_raids", 0 }, + { "logical_height", 128 }, + { "coordinate_scale", 8.0 }, + { "monster_spawn_light_level", 7 }, + { "min_y", 0 }, + { "ultrawarm", 1 }, + { "has_ceiling", 1 }, + { "height", 256 } + } + } + } + } + } + } + } + }; + + StoreDimensionList(defaultRegistryCodec); + } + /// /// Store one dimension - Directly used in 1.16.2 to 1.18.2 /// @@ -92,7 +235,6 @@ namespace MinecraftClient.Mapping curDimension = dimensionList[name]; // Should not fail } - /// /// Get current dimension /// diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 8149a06c..35cc97e4 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -148,9 +148,11 @@ namespace MinecraftClient public List GetLoadedChatBots() { return new List(bots); } public void GetCookie(string key, out byte[]? data) => Cookies.TryGetValue(key, out data); public void SetCookie(string key, byte[] data) => Cookies[key] = data; + public void DeleteCookie(string key) => Cookies.Remove(key, out var data); - readonly TcpClient client; - readonly IMinecraftCom handler; + TcpClient client; + IMinecraftCom handler; + SessionToken _sessionToken; CancellationTokenSource? cmdprompt = null; Tuple? timeoutdetector = null; @@ -186,6 +188,7 @@ namespace MinecraftClient this.port = port; this.protocolversion = protocolversion; this.playerKeyPair = playerKeyPair; + _sessionToken = session; Log = Settings.Config.Logging.LogToFile ? new FileLogLogger(Config.AppVar.ExpandVars(Settings.Config.Logging.LogFile), Settings.Config.Logging.PrependTimestamp) @@ -294,6 +297,77 @@ namespace MinecraftClient } } } + + public void Transfer(string newHost, int newPort) + { + try + { + Log.Info($"Initiating a transfer to: {host}:{port}"); + + // Unload bots + UnloadAllBots(); + bots.Clear(); + + // Close existing connection + client.Close(); + + // Establish new connection + client = ProxyHandler.NewTcpClient(newHost, newPort); + client.ReceiveBufferSize = 1024 * 1024; + client.ReceiveTimeout = Config.Main.Advanced.TcpTimeout * 1000; + + // Reinitialize the protocol handler + handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, null, this); + Log.Info($"Connected to {host}:{port}"); + + // Retry login process + if (handler.Login(playerKeyPair, _sessionToken)) + { + foreach (var bot in botsOnHold) + BotLoad(bot, false); + botsOnHold.Clear(); + + Log.Info("Successfully transferred connection and logged in."); + cmdprompt = new CancellationTokenSource(); + ConsoleInteractive.ConsoleReader.BeginReadThread(); + ConsoleInteractive.ConsoleReader.MessageReceived += ConsoleReaderOnMessageReceived; + ConsoleInteractive.ConsoleReader.OnInputChange += ConsoleIO.AutocompleteHandler; + } + else + { + Log.Error("Failed to login to the new host."); + throw new Exception("Login failed after transfer."); + } + } + catch (Exception ex) + { + Log.Error($"Transfer to {newHost}:{newPort} failed: {ex.Message}"); + + // Handle reconnection attempts + if (timeoutdetector != null) + { + timeoutdetector.Item2.Cancel(); + timeoutdetector = null; + } + + if (ReconnectionAttemptsLeft > 0) + { + Log.Info($"Reconnecting... Attempts left: {ReconnectionAttemptsLeft}"); + Thread.Sleep(5000); + ReconnectionAttemptsLeft--; + Program.Restart(); + } + else if (InternalConfig.InteractiveMode) + { + ConsoleInteractive.ConsoleReader.StopReadThread(); + ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived; + ConsoleInteractive.ConsoleReader.OnInputChange -= ConsoleIO.AutocompleteHandler; + Program.HandleFailure(); + } + + throw new Exception("Transfer failed and reconnection attempts exhausted."); + } + } /// /// Register bots diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 43a45030..e089e78d 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -449,6 +449,9 @@ namespace MinecraftClient.Protocol.Handlers } else { + // TODO: Implement proper parsing for 1.20.6 when there is a custom data pack on the server + // THis is a temporary workaround to get the client to be useable asap + var registryId = dataTypes.ReadNextString(packetData); var entryCount = dataTypes.ReadNextVarInt(packetData); @@ -466,7 +469,8 @@ namespace MinecraftClient.Protocol.Handlers if (hasData) { - dataTypes.ReadNextNbt(packetData); // Never seem to be sent because hasData is always false + // TODO: Parse in case when the server data packs differ from the client + dataTypes.ReadNextNbt(packetData); } if (registryId == "minecraft:chat_type") @@ -476,9 +480,9 @@ namespace MinecraftClient.Protocol.Handlers if (registryId == "minecraft:chat_type") ChatParser.ReadChatType(avaliableChats); - else + else { - // TODO: 1.20.6 Somehow store this data from dimensionType in the World class + World.LoadDefaultDimensions1206Plus(); } } @@ -502,9 +506,8 @@ namespace MinecraftClient.Protocol.Handlers case ConfigurationPacketTypesIn.Transfer: var host = dataTypes.ReadNextString(packetData); var port = dataTypes.ReadNextVarInt(packetData); - - // TODO: 1.20.6 Implement Host Chaging in the McClient class - // McClient.Instance?.Transfer(host, port); + + McClient.Instance?.Transfer(host, port); break; case ConfigurationPacketTypesIn.KnownDataPacks: @@ -673,7 +676,6 @@ namespace MinecraftClient.Protocol.Handlers // varInt: [1.9.1 to 1.15.2] // byte: below 1.9.1 string? dimensionTypeName = null; - int? dimensionTypeInt2 = null; Dictionary? dimensionType = null; switch (protocolVersion) { @@ -681,9 +683,6 @@ namespace MinecraftClient.Protocol.Handlers { switch (protocolVersion) { - case >= MC_1_20_6_Version: - dimensionTypeInt2 = dataTypes.ReadNextVarInt(packetData); - break; case >= MC_1_19_Version: dimensionTypeName = dataTypes.ReadNextString(packetData); // Dimension Type: Identifier @@ -731,9 +730,6 @@ namespace MinecraftClient.Protocol.Handlers case < MC_1_20_6_Version: World.SetDimension(dimensionTypeName!); break; - case >= MC_1_20_6_Version: - // TODO: 1.20.6 Set the dimension (use dimensionTypeInt) - break; } } @@ -782,8 +778,19 @@ namespace MinecraftClient.Protocol.Handlers else { dataTypes.ReadNextBool(packetData); // Do limited crafting - var dimensionTypeName = - dataTypes.ReadNextString(packetData); // Dimension Type: Identifier + + // Dimension Type (string bellow 1.20.6, VarInt for 1.20.6+) + var dimensionTypeName = protocolVersion < MC_1_20_6_Version + ? dataTypes.ReadNextString(packetData) // < 1.20.6 + : (dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry + { + 0 => "minecraft:overworld", + 1 => "minecraft:overworld_caves", + 2 => "minecraft:the_end", + 3 => "minecraft:the_nether", + _ => null + } ?? "minecraft:overworld"); + dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above if (handler.GetTerrainEnabled()) @@ -1240,14 +1247,20 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.Respawn: string? dimensionTypeNameRespawn = null; Dictionary? dimensionTypeRespawn = null; - int? dimensionTypeInt = null; if (protocolVersion >= MC_1_16_Version) { switch (protocolVersion) { case >= MC_1_20_6_Version: - dimensionTypeInt = dataTypes.ReadNextVarInt(packetData); + dimensionTypeNameRespawn = dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry + { + 0 => "minecraft:overworld", + 1 => "minecraft:overworld_caves", + 2 => "minecraft:the_end", + 3 => "minecraft:the_nether", + _ => null + } ?? "minecraft:overworld"; break; case >= MC_1_19_Version: dimensionTypeNameRespawn = @@ -1286,12 +1299,9 @@ namespace MinecraftClient.Protocol.Handlers World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); World.SetDimension(dimensionName); break; - case < MC_1_20_6_Version: + case <= MC_1_20_6_Version: World.SetDimension(dimensionTypeNameRespawn!); break; - case >= MC_1_20_6_Version: - // TODO: 1.20.6 Set the dimension (use dimensionTypeInt) - break; } } @@ -2759,8 +2769,7 @@ namespace MinecraftClient.Protocol.Handlers var host = dataTypes.ReadNextString(packetData); var port = dataTypes.ReadNextVarInt(packetData); - // TODO: 1.20.6 Implement Host Chaging in the McClient class - // McClient.Instance?.Transfer(host, port); + McClient.Instance?.Transfer(host, port); break; default: @@ -3393,14 +3402,14 @@ namespace MinecraftClient.Protocol.Handlers SendMessageAcknowledgment(ConsumeAcknowledgment()); } } - + /// - /// Send a chat command to the server - 1.19 and above + /// Send a chat command to the server, with or without signing based on the online mode and version. /// /// Command - /// PlayerKeyPair + /// PlayerKeyPair (optional) /// True if properly sent - public bool SendChatCommand(string command, PlayerKeyPair? playerKeyPair) + public bool SendChatCommand(string command, PlayerKeyPair? playerKeyPair = null) { if (string.IsNullOrEmpty(command)) return true; @@ -3410,85 +3419,78 @@ namespace MinecraftClient.Protocol.Handlers log.Debug($"chat command = {command}"); + if (protocolVersion >= MC_1_20_6_Version && !isOnlineMode) + { + List fields = new(); + fields.AddRange(dataTypes.GetString(command)); + SendPacket(PacketTypesOut.ChatCommand, fields); + return true; + } + try { - List>? needSigned = null; // List< Argument Name, Argument Value > - if (playerKeyPair != null && isOnlineMode && protocolVersion >= MC_1_19_Version - && Config.Signature is { LoginWithSecureProfile: true, SignMessageInCommand: true }) + List>? needSigned = null; + + if (protocolVersion >= MC_1_19_Version && Config.Signature is { LoginWithSecureProfile: true, SignMessageInCommand: true }) needSigned = DeclareCommands.CollectSignArguments(command); lock (MessageSigningLock) { - var acknowledgment1192 = - protocolVersion == MC_1_19_2_Version ? ConsumeAcknowledgment() : null; + var acknowledgment1192 = protocolVersion == MC_1_19_2_Version ? ConsumeAcknowledgment() : null; - var (acknowledgment1193, bitset1193, messageCount1193) = - protocolVersion >= MC_1_19_3_Version - ? lastSeenMessagesCollector.Collect_1_19_3() - : new(Array.Empty(), Array.Empty(), 0); + var (acknowledgment1193, bitset1193, messageCount1193) = protocolVersion >= MC_1_19_3_Version + ? lastSeenMessagesCollector.Collect_1_19_3() + : new(Array.Empty(), Array.Empty(), 0); List fields = new(); - - // Command: String fields.AddRange(dataTypes.GetString(command)); - - // Timestamp: Instant(Long) var timeNow = DateTimeOffset.UtcNow; fields.AddRange(DataTypes.GetLong(timeNow.ToUnixTimeMilliseconds())); - if (needSigned == null || needSigned!.Count == 0) + if (needSigned == null || needSigned.Count == 0) { - fields.AddRange(DataTypes.GetLong(0)); // Salt: Long - fields.AddRange(DataTypes.GetVarInt(0)); // Signature Length: VarInt + fields.AddRange(DataTypes.GetLong(0)); + fields.AddRange(DataTypes.GetVarInt(0)); } else { var uuid = handler.GetUserUuid(); var salt = GenerateSalt(); - fields.AddRange(salt); // Salt: Long - fields.AddRange(DataTypes.GetVarInt(needSigned.Count)); // Signature Length: VarInt + fields.AddRange(salt); + fields.AddRange(DataTypes.GetVarInt(needSigned.Count)); foreach (var (argName, message) in needSigned) { - fields.AddRange(dataTypes.GetString(argName)); // Argument name: String - + fields.AddRange(dataTypes.GetString(argName)); var sign = protocolVersion switch { - MC_1_19_Version => playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, - ref salt), - MC_1_19_2_Version => playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, - ref salt, acknowledgment1192!.lastSeen), - _ => playerKeyPair!.PrivateKey.SignMessage(message, uuid, chatUuid, messageIndex++, - timeNow, ref salt, acknowledgment1193) + MC_1_19_Version => playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt), + MC_1_19_2_Version => playerKeyPair!.PrivateKey.SignMessage(message, uuid, timeNow, ref salt, acknowledgment1192!.lastSeen), + _ => playerKeyPair!.PrivateKey.SignMessage(message, uuid, chatUuid, messageIndex++, timeNow, ref salt, acknowledgment1193) }; if (protocolVersion <= MC_1_19_2_Version) - fields.AddRange(DataTypes.GetVarInt(sign.Length)); // Signature length: VarInt + fields.AddRange(DataTypes.GetVarInt(sign.Length)); - fields.AddRange(sign); // Signature: Byte Array + fields.AddRange(sign); } } if (protocolVersion <= MC_1_19_2_Version) - fields.AddRange(dataTypes.GetBool(false)); // Signed Preview: Boolean + fields.AddRange(dataTypes.GetBool(false)); switch (protocolVersion) { case MC_1_19_2_Version: - // Message Acknowledgment (1.19.2) - fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment1192!, - isOnlineMode && Config.Signature.LoginWithSecureProfile)); + fields.AddRange(dataTypes.GetAcknowledgment(acknowledgment1192!, isOnlineMode && Config.Signature.LoginWithSecureProfile)); break; case >= MC_1_19_3_Version: - // message count fields.AddRange(DataTypes.GetVarInt(messageCount1193)); - - // Acknowledged: BitSet fields.AddRange(bitset1193); break; } - SendPacket(PacketTypesOut.ChatCommand, fields); + SendPacket(protocolVersion < MC_1_20_6_Version ? PacketTypesOut.ChatCommand : PacketTypesOut.SignedChatCommand, fields); } return true; @@ -3506,7 +3508,7 @@ namespace MinecraftClient.Protocol.Handlers return false; } } - + /// /// Send a chat message to the server /// @@ -4687,21 +4689,22 @@ namespace MinecraftClient.Protocol.Handlers if (hasPayload) packet.AddRange(dataTypes.GetArray(data!)); // Payload Data Array Size + Data Array - switch(currentState) + switch (currentState) { - case CurrentState.Login: + case CurrentState.Login: SendPacket(0x04, packet); break; - - case CurrentState.Configuration: + + case CurrentState.Configuration: SendPacket(ConfigurationPacketTypesOut.CookieResponse, packet); break; - + case CurrentState.Play: SendPacket(PacketTypesOut.CookieResponse, packet); break; } + McClient.Instance?.DeleteCookie(name); return true; } catch (SocketException) diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index d6033e9b..a64021b5 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -46,6 +46,9 @@ namespace MinecraftClient.Protocol ILogger GetLogger(); void GetCookie(string key, out byte[]? data); void SetCookie(string key, byte[] data); + void DeleteCookie(string key); + + void Transfer(string newHost, int newPort); /// /// Invoke a task on the main thread, wait for completion and retrieve return value. From 5a6fd577e52dd4b1fa4c0123defacd435d5195b7 Mon Sep 17 00:00:00 2001 From: Anon Date: Tue, 2 Jul 2024 11:08:46 +0200 Subject: [PATCH 006/484] Inventory, Terrain and Entity handling --- .../Inventory/ItemPalettes/ItemPalette110.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette111.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette112.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette115.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette1161.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette1162.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette117.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette118.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette119.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette1193.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette1194.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette120.cs | 4 +- .../Inventory/ItemPalettes/ItemPalette1204.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette1206.cs | 1348 +++++++++++++ .../Inventory/ItemPalettes/ItemPalette18.cs | 2 +- .../Inventory/ItemPalettes/ItemPalette19.cs | 2 +- MinecraftClient/Inventory/ItemType.cs | 21 +- .../Mapping/BlockPalettes/BlockPalette120.cs | 2 +- .../Mapping/BlockPalettes/Palette112.cs | 2 +- .../Mapping/BlockPalettes/Palette113.cs | 2 +- .../Mapping/BlockPalettes/Palette114.cs | 2 +- .../Mapping/BlockPalettes/Palette115.cs | 2 +- .../Mapping/BlockPalettes/Palette116.cs | 2 +- .../Mapping/BlockPalettes/Palette117.cs | 2 +- .../Mapping/BlockPalettes/Palette119.cs | 2 +- .../Mapping/BlockPalettes/Palette1193.cs | 2 +- .../Mapping/BlockPalettes/Palette1194.cs | 2 +- .../Mapping/BlockPalettes/Palette1206.cs | 1766 +++++++++++++++++ .../EntityPalettes/EntityPalette1206.cs | 148 ++ MinecraftClient/Mapping/EntityType.cs | 4 + MinecraftClient/Mapping/Material.cs | 3 +- MinecraftClient/Mapping/Material2Tool.cs | 3 +- .../Protocol/Handlers/DataTypes.cs | 94 +- .../Handlers/Packet/s2c/DeclareCommands.cs | 21 +- .../Protocol/Handlers/Protocol18.cs | 46 +- 35 files changed, 3456 insertions(+), 66 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1206.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1206.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1206.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs index f284d949..7a6a6d79 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs @@ -71,7 +71,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[1835008] = ItemType.DetectorRail; mappings[1900544] = ItemType.StickyPiston; mappings[1966080] = ItemType.Cobweb; - mappings[2031617] = ItemType.Grass; + mappings[2031617] = ItemType.ShortGrass; mappings[2031618] = ItemType.Fern; mappings[2097152] = ItemType.DeadBush; mappings[2162688] = ItemType.Piston; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs index 9d9f20bb..02f26948 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs @@ -71,7 +71,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[1835008] = ItemType.DetectorRail; mappings[1900544] = ItemType.StickyPiston; mappings[1966080] = ItemType.Cobweb; - mappings[2031617] = ItemType.Grass; + mappings[2031617] = ItemType.ShortGrass; mappings[2031618] = ItemType.Fern; mappings[2097152] = ItemType.DeadBush; mappings[2162688] = ItemType.Piston; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs index 2826641d..b6758b62 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs @@ -62,7 +62,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[1769472] = ItemType.PoweredRail; mappings[1835008] = ItemType.DetectorRail; mappings[1900544] = ItemType.StickyPiston; - mappings[2031617] = ItemType.Grass; + mappings[2031617] = ItemType.ShortGrass; mappings[2031618] = ItemType.Fern; mappings[2097152] = ItemType.DeadBush; mappings[2162688] = ItemType.Piston; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs index 8c67fff8..35593662 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs @@ -88,7 +88,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[73] = ItemType.DetectorRail; mappings[74] = ItemType.StickyPiston; mappings[75] = ItemType.Cobweb; - mappings[76] = ItemType.Grass; + mappings[76] = ItemType.ShortGrass; mappings[77] = ItemType.Fern; mappings[78] = ItemType.DeadBush; mappings[79] = ItemType.Seagrass; @@ -531,7 +531,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[516] = ItemType.Jigsaw; mappings[517] = ItemType.Composter; mappings[518] = ItemType.TurtleHelmet; - mappings[519] = ItemType.Scute; + mappings[519] = ItemType.TurtleScute; mappings[520] = ItemType.IronShovel; mappings[521] = ItemType.IronPickaxe; mappings[522] = ItemType.IronAxe; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs index 20dae2ad..4bdb9006 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs @@ -101,7 +101,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[86] = ItemType.DetectorRail; mappings[87] = ItemType.StickyPiston; mappings[88] = ItemType.Cobweb; - mappings[89] = ItemType.Grass; + mappings[89] = ItemType.ShortGrass; mappings[90] = ItemType.Fern; mappings[91] = ItemType.DeadBush; mappings[92] = ItemType.Seagrass; @@ -583,7 +583,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[568] = ItemType.StructureBlock; mappings[569] = ItemType.Jigsaw; mappings[570] = ItemType.TurtleHelmet; - mappings[571] = ItemType.Scute; + mappings[571] = ItemType.TurtleScute; mappings[572] = ItemType.IronShovel; mappings[573] = ItemType.IronPickaxe; mappings[574] = ItemType.IronAxe; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs index bdacf33a..5a82eef4 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs @@ -101,7 +101,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[86] = ItemType.DetectorRail; mappings[87] = ItemType.StickyPiston; mappings[88] = ItemType.Cobweb; - mappings[89] = ItemType.Grass; + mappings[89] = ItemType.ShortGrass; mappings[90] = ItemType.Fern; mappings[91] = ItemType.DeadBush; mappings[92] = ItemType.Seagrass; @@ -583,7 +583,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[568] = ItemType.StructureBlock; mappings[569] = ItemType.Jigsaw; mappings[570] = ItemType.TurtleHelmet; - mappings[571] = ItemType.Scute; + mappings[571] = ItemType.TurtleScute; mappings[572] = ItemType.FlintAndSteel; mappings[573] = ItemType.Apple; mappings[574] = ItemType.Bow; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs index f21c9465..be1bd517 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs @@ -158,7 +158,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[147] = ItemType.ChiseledSandstone; mappings[148] = ItemType.CutSandstone; mappings[149] = ItemType.Cobweb; - mappings[150] = ItemType.Grass; + mappings[150] = ItemType.ShortGrass; mappings[151] = ItemType.Fern; mappings[152] = ItemType.Azalea; mappings[153] = ItemType.FloweringAzalea; @@ -687,7 +687,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[676] = ItemType.StructureBlock; mappings[677] = ItemType.Jigsaw; mappings[678] = ItemType.TurtleHelmet; - mappings[679] = ItemType.Scute; + mappings[679] = ItemType.TurtleScute; mappings[680] = ItemType.FlintAndSteel; mappings[681] = ItemType.Apple; mappings[682] = ItemType.Bow; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs index 8db51826..bc3f25ad 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs @@ -158,7 +158,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[147] = ItemType.ChiseledSandstone; mappings[148] = ItemType.CutSandstone; mappings[149] = ItemType.Cobweb; - mappings[150] = ItemType.Grass; + mappings[150] = ItemType.ShortGrass; mappings[151] = ItemType.Fern; mappings[152] = ItemType.Azalea; mappings[153] = ItemType.FloweringAzalea; @@ -687,7 +687,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[676] = ItemType.StructureBlock; mappings[677] = ItemType.Jigsaw; mappings[678] = ItemType.TurtleHelmet; - mappings[679] = ItemType.Scute; + mappings[679] = ItemType.TurtleScute; mappings[680] = ItemType.FlintAndSteel; mappings[681] = ItemType.Apple; mappings[682] = ItemType.Bow; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs index a47104e7..a1ab48d3 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs @@ -449,7 +449,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[598] = ItemType.GraniteSlab; mappings[581] = ItemType.GraniteStairs; mappings[355] = ItemType.GraniteWall; - mappings[160] = ItemType.Grass; + mappings[160] = ItemType.ShortGrass; mappings[14] = ItemType.GrassBlock; mappings[42] = ItemType.Gravel; mappings[1032] = ItemType.GrayBanner; @@ -927,7 +927,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[626] = ItemType.SculkSensor; mappings[329] = ItemType.SculkShrieker; mappings[327] = ItemType.SculkVein; - mappings[715] = ItemType.Scute; + mappings[715] = ItemType.TurtleScute; mappings[461] = ItemType.SeaLantern; mappings[166] = ItemType.SeaPickle; mappings[165] = ItemType.Seagrass; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs index 563b16a5..6677721e 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs @@ -473,7 +473,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[608] = ItemType.GraniteSlab; mappings[591] = ItemType.GraniteStairs; mappings[365] = ItemType.GraniteWall; - mappings[164] = ItemType.Grass; + mappings[164] = ItemType.ShortGrass; mappings[14] = ItemType.GrassBlock; mappings[44] = ItemType.Gravel; mappings[1066] = ItemType.GrayBanner; @@ -956,7 +956,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[636] = ItemType.SculkSensor; mappings[337] = ItemType.SculkShrieker; mappings[335] = ItemType.SculkVein; - mappings[732] = ItemType.Scute; + mappings[732] = ItemType.TurtleScute; mappings[471] = ItemType.SeaLantern; mappings[170] = ItemType.SeaPickle; mappings[169] = ItemType.Seagrass; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs index 5306eac3..ef04e7dc 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs @@ -495,7 +495,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[622] = ItemType.GraniteSlab; mappings[605] = ItemType.GraniteStairs; mappings[379] = ItemType.GraniteWall; - mappings[172] = ItemType.Grass; + mappings[172] = ItemType.ShortGrass; mappings[14] = ItemType.GrassBlock; mappings[47] = ItemType.Gravel; mappings[1090] = ItemType.GrayBanner; @@ -985,7 +985,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[650] = ItemType.SculkSensor; mappings[350] = ItemType.SculkShrieker; mappings[348] = ItemType.SculkVein; - mappings[753] = ItemType.Scute; + mappings[753] = ItemType.TurtleScute; mappings[485] = ItemType.SeaLantern; mappings[178] = ItemType.SeaPickle; mappings[177] = ItemType.Seagrass; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs index fdce6150..2ca03bed 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs @@ -505,7 +505,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[625] = ItemType.GraniteSlab; mappings[608] = ItemType.GraniteStairs; mappings[381] = ItemType.GraniteWall; - mappings[173] = ItemType.Grass; + mappings[173] = ItemType.ShortGrass; mappings[14] = ItemType.GrassBlock; mappings[48] = ItemType.Gravel; mappings[1094] = ItemType.GrayBanner; @@ -1003,7 +1003,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[653] = ItemType.SculkSensor; mappings[352] = ItemType.SculkShrieker; mappings[350] = ItemType.SculkVein; - mappings[757] = ItemType.Scute; + mappings[757] = ItemType.TurtleScute; mappings[487] = ItemType.SeaLantern; mappings[179] = ItemType.SeaPickle; mappings[178] = ItemType.Seagrass; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs index 13f7676e..3796e4cb 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs @@ -1025,7 +1025,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[674] = ItemType.SculkSensor; mappings[373] = ItemType.SculkShrieker; mappings[371] = ItemType.SculkVein; - mappings[794] = ItemType.Scute; + mappings[794] = ItemType.TurtleScute; mappings[508] = ItemType.SeaLantern; mappings[200] = ItemType.SeaPickle; mappings[199] = ItemType.Seagrass; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1206.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1206.cs new file mode 100644 index 00000000..d0dceeeb --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1206.cs @@ -0,0 +1,1348 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1206 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1206() + { + mappings[782] = ItemType.AcaciaBoat; + mappings[688] = ItemType.AcaciaButton; + mappings[783] = ItemType.AcaciaChestBoat; + mappings[715] = ItemType.AcaciaDoor; + mappings[315] = ItemType.AcaciaFence; + mappings[754] = ItemType.AcaciaFenceGate; + mappings[901] = ItemType.AcaciaHangingSign; + mappings[180] = ItemType.AcaciaLeaves; + mappings[136] = ItemType.AcaciaLog; + mappings[40] = ItemType.AcaciaPlanks; + mappings[703] = ItemType.AcaciaPressurePlate; + mappings[52] = ItemType.AcaciaSapling; + mappings[890] = ItemType.AcaciaSign; + mappings[256] = ItemType.AcaciaSlab; + mappings[387] = ItemType.AcaciaStairs; + mappings[735] = ItemType.AcaciaTrapdoor; + mappings[170] = ItemType.AcaciaWood; + mappings[764] = ItemType.ActivatorRail; + mappings[0] = ItemType.Air; + mappings[1009] = ItemType.AllaySpawnEgg; + mappings[221] = ItemType.Allium; + mappings[86] = ItemType.AmethystBlock; + mappings[1258] = ItemType.AmethystCluster; + mappings[808] = ItemType.AmethystShard; + mappings[80] = ItemType.AncientDebris; + mappings[6] = ItemType.Andesite; + mappings[648] = ItemType.AndesiteSlab; + mappings[631] = ItemType.AndesiteStairs; + mappings[407] = ItemType.AndesiteWall; + mappings[1285] = ItemType.AnglerPotterySherd; + mappings[419] = ItemType.Anvil; + mappings[799] = ItemType.Apple; + mappings[1286] = ItemType.ArcherPotterySherd; + mappings[796] = ItemType.ArmadilloScute; + mappings[1008] = ItemType.ArmadilloSpawnEgg; + mappings[1123] = ItemType.ArmorStand; + mappings[1287] = ItemType.ArmsUpPotterySherd; + mappings[801] = ItemType.Arrow; + mappings[919] = ItemType.AxolotlBucket; + mappings[1010] = ItemType.AxolotlSpawnEgg; + mappings[197] = ItemType.Azalea; + mappings[184] = ItemType.AzaleaLeaves; + mappings[222] = ItemType.AzureBluet; + mappings[1099] = ItemType.BakedPotato; + mappings[251] = ItemType.Bamboo; + mappings[144] = ItemType.BambooBlock; + mappings[692] = ItemType.BambooButton; + mappings[791] = ItemType.BambooChestRaft; + mappings[719] = ItemType.BambooDoor; + mappings[319] = ItemType.BambooFence; + mappings[758] = ItemType.BambooFenceGate; + mappings[905] = ItemType.BambooHangingSign; + mappings[47] = ItemType.BambooMosaic; + mappings[261] = ItemType.BambooMosaicSlab; + mappings[392] = ItemType.BambooMosaicStairs; + mappings[44] = ItemType.BambooPlanks; + mappings[707] = ItemType.BambooPressurePlate; + mappings[790] = ItemType.BambooRaft; + mappings[894] = ItemType.BambooSign; + mappings[260] = ItemType.BambooSlab; + mappings[391] = ItemType.BambooStairs; + mappings[739] = ItemType.BambooTrapdoor; + mappings[1202] = ItemType.Barrel; + mappings[443] = ItemType.Barrier; + mappings[328] = ItemType.Basalt; + mappings[1011] = ItemType.BatSpawnEgg; + mappings[396] = ItemType.Beacon; + mappings[56] = ItemType.Bedrock; + mappings[1219] = ItemType.BeeNest; + mappings[1012] = ItemType.BeeSpawnEgg; + mappings[988] = ItemType.Beef; + mappings[1220] = ItemType.Beehive; + mappings[1154] = ItemType.Beetroot; + mappings[1155] = ItemType.BeetrootSeeds; + mappings[1156] = ItemType.BeetrootSoup; + mappings[1210] = ItemType.Bell; + mappings[249] = ItemType.BigDripleaf; + mappings[778] = ItemType.BirchBoat; + mappings[686] = ItemType.BirchButton; + mappings[779] = ItemType.BirchChestBoat; + mappings[713] = ItemType.BirchDoor; + mappings[313] = ItemType.BirchFence; + mappings[752] = ItemType.BirchFenceGate; + mappings[899] = ItemType.BirchHangingSign; + mappings[178] = ItemType.BirchLeaves; + mappings[134] = ItemType.BirchLog; + mappings[38] = ItemType.BirchPlanks; + mappings[701] = ItemType.BirchPressurePlate; + mappings[50] = ItemType.BirchSapling; + mappings[888] = ItemType.BirchSign; + mappings[254] = ItemType.BirchSlab; + mappings[385] = ItemType.BirchStairs; + mappings[733] = ItemType.BirchTrapdoor; + mappings[168] = ItemType.BirchWood; + mappings[1148] = ItemType.BlackBanner; + mappings[979] = ItemType.BlackBed; + mappings[1254] = ItemType.BlackCandle; + mappings[461] = ItemType.BlackCarpet; + mappings[570] = ItemType.BlackConcrete; + mappings[586] = ItemType.BlackConcretePowder; + mappings[959] = ItemType.BlackDye; + mappings[554] = ItemType.BlackGlazedTerracotta; + mappings[538] = ItemType.BlackShulkerBox; + mappings[486] = ItemType.BlackStainedGlass; + mappings[502] = ItemType.BlackStainedGlassPane; + mappings[442] = ItemType.BlackTerracotta; + mappings[217] = ItemType.BlackWool; + mappings[1225] = ItemType.Blackstone; + mappings[1226] = ItemType.BlackstoneSlab; + mappings[1227] = ItemType.BlackstoneStairs; + mappings[412] = ItemType.BlackstoneWall; + mappings[1288] = ItemType.BladePotterySherd; + mappings[1204] = ItemType.BlastFurnace; + mappings[1002] = ItemType.BlazePowder; + mappings[994] = ItemType.BlazeRod; + mappings[1013] = ItemType.BlazeSpawnEgg; + mappings[1144] = ItemType.BlueBanner; + mappings[975] = ItemType.BlueBed; + mappings[1250] = ItemType.BlueCandle; + mappings[457] = ItemType.BlueCarpet; + mappings[566] = ItemType.BlueConcrete; + mappings[582] = ItemType.BlueConcretePowder; + mappings[955] = ItemType.BlueDye; + mappings[550] = ItemType.BlueGlazedTerracotta; + mappings[619] = ItemType.BlueIce; + mappings[220] = ItemType.BlueOrchid; + mappings[534] = ItemType.BlueShulkerBox; + mappings[482] = ItemType.BlueStainedGlass; + mappings[498] = ItemType.BlueStainedGlassPane; + mappings[438] = ItemType.BlueTerracotta; + mappings[213] = ItemType.BlueWool; + mappings[1014] = ItemType.BoggedSpawnEgg; + mappings[1284] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[961] = ItemType.Bone; + mappings[520] = ItemType.BoneBlock; + mappings[960] = ItemType.BoneMeal; + mappings[925] = ItemType.Book; + mappings[286] = ItemType.Bookshelf; + mappings[800] = ItemType.Bow; + mappings[848] = ItemType.Bowl; + mappings[600] = ItemType.BrainCoral; + mappings[595] = ItemType.BrainCoralBlock; + mappings[610] = ItemType.BrainCoralFan; + mappings[855] = ItemType.Bread; + mappings[1329] = ItemType.BreezeRod; + mappings[1015] = ItemType.BreezeSpawnEgg; + mappings[1289] = ItemType.BrewerPotterySherd; + mappings[1004] = ItemType.BrewingStand; + mappings[921] = ItemType.Brick; + mappings[270] = ItemType.BrickSlab; + mappings[361] = ItemType.BrickStairs; + mappings[399] = ItemType.BrickWall; + mappings[285] = ItemType.Bricks; + mappings[1145] = ItemType.BrownBanner; + mappings[976] = ItemType.BrownBed; + mappings[1251] = ItemType.BrownCandle; + mappings[458] = ItemType.BrownCarpet; + mappings[567] = ItemType.BrownConcrete; + mappings[583] = ItemType.BrownConcretePowder; + mappings[956] = ItemType.BrownDye; + mappings[551] = ItemType.BrownGlazedTerracotta; + mappings[234] = ItemType.BrownMushroom; + mappings[352] = ItemType.BrownMushroomBlock; + mappings[535] = ItemType.BrownShulkerBox; + mappings[483] = ItemType.BrownStainedGlass; + mappings[499] = ItemType.BrownStainedGlassPane; + mappings[439] = ItemType.BrownTerracotta; + mappings[214] = ItemType.BrownWool; + mappings[1265] = ItemType.Brush; + mappings[601] = ItemType.BubbleCoral; + mappings[596] = ItemType.BubbleCoralBlock; + mappings[611] = ItemType.BubbleCoralFan; + mappings[908] = ItemType.Bucket; + mappings[87] = ItemType.BuddingAmethyst; + mappings[930] = ItemType.Bundle; + mappings[1290] = ItemType.BurnPotterySherd; + mappings[308] = ItemType.Cactus; + mappings[963] = ItemType.Cake; + mappings[11] = ItemType.Calcite; + mappings[676] = ItemType.CalibratedSculkSensor; + mappings[1017] = ItemType.CamelSpawnEgg; + mappings[1215] = ItemType.Campfire; + mappings[1238] = ItemType.Candle; + mappings[1097] = ItemType.Carrot; + mappings[771] = ItemType.CarrotOnAStick; + mappings[1205] = ItemType.CartographyTable; + mappings[323] = ItemType.CarvedPumpkin; + mappings[1016] = ItemType.CatSpawnEgg; + mappings[1005] = ItemType.Cauldron; + mappings[1018] = ItemType.CaveSpiderSpawnEgg; + mappings[356] = ItemType.Chain; + mappings[515] = ItemType.ChainCommandBlock; + mappings[863] = ItemType.ChainmailBoots; + mappings[861] = ItemType.ChainmailChestplate; + mappings[860] = ItemType.ChainmailHelmet; + mappings[862] = ItemType.ChainmailLeggings; + mappings[803] = ItemType.Charcoal; + mappings[784] = ItemType.CherryBoat; + mappings[689] = ItemType.CherryButton; + mappings[785] = ItemType.CherryChestBoat; + mappings[716] = ItemType.CherryDoor; + mappings[316] = ItemType.CherryFence; + mappings[755] = ItemType.CherryFenceGate; + mappings[902] = ItemType.CherryHangingSign; + mappings[181] = ItemType.CherryLeaves; + mappings[137] = ItemType.CherryLog; + mappings[41] = ItemType.CherryPlanks; + mappings[704] = ItemType.CherryPressurePlate; + mappings[53] = ItemType.CherrySapling; + mappings[891] = ItemType.CherrySign; + mappings[257] = ItemType.CherrySlab; + mappings[388] = ItemType.CherryStairs; + mappings[736] = ItemType.CherryTrapdoor; + mappings[171] = ItemType.CherryWood; + mappings[299] = ItemType.Chest; + mappings[767] = ItemType.ChestMinecart; + mappings[990] = ItemType.Chicken; + mappings[1019] = ItemType.ChickenSpawnEgg; + mappings[420] = ItemType.ChippedAnvil; + mappings[287] = ItemType.ChiseledBookshelf; + mappings[96] = ItemType.ChiseledCopper; + mappings[350] = ItemType.ChiseledDeepslate; + mappings[368] = ItemType.ChiseledNetherBricks; + mappings[1232] = ItemType.ChiseledPolishedBlackstone; + mappings[422] = ItemType.ChiseledQuartzBlock; + mappings[511] = ItemType.ChiseledRedSandstone; + mappings[192] = ItemType.ChiseledSandstone; + mappings[343] = ItemType.ChiseledStoneBricks; + mappings[16] = ItemType.ChiseledTuff; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[294] = ItemType.ChorusFlower; + mappings[1150] = ItemType.ChorusFruit; + mappings[293] = ItemType.ChorusPlant; + mappings[309] = ItemType.Clay; + mappings[922] = ItemType.ClayBall; + mappings[932] = ItemType.Clock; + mappings[802] = ItemType.Coal; + mappings[81] = ItemType.CoalBlock; + mappings[62] = ItemType.CoalOre; + mappings[29] = ItemType.CoarseDirt; + mappings[1269] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[652] = ItemType.CobbledDeepslateSlab; + mappings[635] = ItemType.CobbledDeepslateStairs; + mappings[415] = ItemType.CobbledDeepslateWall; + mappings[35] = ItemType.Cobblestone; + mappings[269] = ItemType.CobblestoneSlab; + mappings[304] = ItemType.CobblestoneStairs; + mappings[397] = ItemType.CobblestoneWall; + mappings[194] = ItemType.Cobweb; + mappings[943] = ItemType.CocoaBeans; + mappings[935] = ItemType.Cod; + mappings[917] = ItemType.CodBucket; + mappings[1020] = ItemType.CodSpawnEgg; + mappings[395] = ItemType.CommandBlock; + mappings[1130] = ItemType.CommandBlockMinecart; + mappings[661] = ItemType.Comparator; + mappings[928] = ItemType.Compass; + mappings[1201] = ItemType.Composter; + mappings[620] = ItemType.Conduit; + mappings[989] = ItemType.CookedBeef; + mappings[991] = ItemType.CookedChicken; + mappings[939] = ItemType.CookedCod; + mappings[1132] = ItemType.CookedMutton; + mappings[882] = ItemType.CookedPorkchop; + mappings[1119] = ItemType.CookedRabbit; + mappings[940] = ItemType.CookedSalmon; + mappings[980] = ItemType.Cookie; + mappings[89] = ItemType.CopperBlock; + mappings[1316] = ItemType.CopperBulb; + mappings[722] = ItemType.CopperDoor; + mappings[1308] = ItemType.CopperGrate; + mappings[812] = ItemType.CopperIngot; + mappings[66] = ItemType.CopperOre; + mappings[742] = ItemType.CopperTrapdoor; + mappings[228] = ItemType.Cornflower; + mappings[1021] = ItemType.CowSpawnEgg; + mappings[347] = ItemType.CrackedDeepslateBricks; + mappings[349] = ItemType.CrackedDeepslateTiles; + mappings[367] = ItemType.CrackedNetherBricks; + mappings[1236] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[342] = ItemType.CrackedStoneBricks; + mappings[981] = ItemType.Crafter; + mappings[300] = ItemType.CraftingTable; + mappings[1193] = ItemType.CreeperBannerPattern; + mappings[1107] = ItemType.CreeperHead; + mappings[1022] = ItemType.CreeperSpawnEgg; + mappings[693] = ItemType.CrimsonButton; + mappings[720] = ItemType.CrimsonDoor; + mappings[320] = ItemType.CrimsonFence; + mappings[759] = ItemType.CrimsonFenceGate; + mappings[236] = ItemType.CrimsonFungus; + mappings[906] = ItemType.CrimsonHangingSign; + mappings[174] = ItemType.CrimsonHyphae; + mappings[33] = ItemType.CrimsonNylium; + mappings[45] = ItemType.CrimsonPlanks; + mappings[708] = ItemType.CrimsonPressurePlate; + mappings[238] = ItemType.CrimsonRoots; + mappings[895] = ItemType.CrimsonSign; + mappings[262] = ItemType.CrimsonSlab; + mappings[393] = ItemType.CrimsonStairs; + mappings[142] = ItemType.CrimsonStem; + mappings[740] = ItemType.CrimsonTrapdoor; + mappings[1189] = ItemType.Crossbow; + mappings[1224] = ItemType.CryingObsidian; + mappings[100] = ItemType.CutCopper; + mappings[108] = ItemType.CutCopperSlab; + mappings[104] = ItemType.CutCopperStairs; + mappings[512] = ItemType.CutRedSandstone; + mappings[276] = ItemType.CutRedSandstoneSlab; + mappings[193] = ItemType.CutSandstone; + mappings[267] = ItemType.CutSandstoneSlab; + mappings[1142] = ItemType.CyanBanner; + mappings[973] = ItemType.CyanBed; + mappings[1248] = ItemType.CyanCandle; + mappings[455] = ItemType.CyanCarpet; + mappings[564] = ItemType.CyanConcrete; + mappings[580] = ItemType.CyanConcretePowder; + mappings[953] = ItemType.CyanDye; + mappings[548] = ItemType.CyanGlazedTerracotta; + mappings[532] = ItemType.CyanShulkerBox; + mappings[480] = ItemType.CyanStainedGlass; + mappings[496] = ItemType.CyanStainedGlassPane; + mappings[436] = ItemType.CyanTerracotta; + mappings[211] = ItemType.CyanWool; + mappings[421] = ItemType.DamagedAnvil; + mappings[218] = ItemType.Dandelion; + mappings[1291] = ItemType.DangerPotterySherd; + mappings[786] = ItemType.DarkOakBoat; + mappings[690] = ItemType.DarkOakButton; + mappings[787] = ItemType.DarkOakChestBoat; + mappings[717] = ItemType.DarkOakDoor; + mappings[317] = ItemType.DarkOakFence; + mappings[756] = ItemType.DarkOakFenceGate; + mappings[903] = ItemType.DarkOakHangingSign; + mappings[182] = ItemType.DarkOakLeaves; + mappings[138] = ItemType.DarkOakLog; + mappings[42] = ItemType.DarkOakPlanks; + mappings[705] = ItemType.DarkOakPressurePlate; + mappings[54] = ItemType.DarkOakSapling; + mappings[892] = ItemType.DarkOakSign; + mappings[258] = ItemType.DarkOakSlab; + mappings[389] = ItemType.DarkOakStairs; + mappings[737] = ItemType.DarkOakTrapdoor; + mappings[172] = ItemType.DarkOakWood; + mappings[505] = ItemType.DarkPrismarine; + mappings[280] = ItemType.DarkPrismarineSlab; + mappings[508] = ItemType.DarkPrismarineStairs; + mappings[674] = ItemType.DaylightDetector; + mappings[604] = ItemType.DeadBrainCoral; + mappings[590] = ItemType.DeadBrainCoralBlock; + mappings[615] = ItemType.DeadBrainCoralFan; + mappings[605] = ItemType.DeadBubbleCoral; + mappings[591] = ItemType.DeadBubbleCoralBlock; + mappings[616] = ItemType.DeadBubbleCoralFan; + mappings[199] = ItemType.DeadBush; + mappings[606] = ItemType.DeadFireCoral; + mappings[592] = ItemType.DeadFireCoralBlock; + mappings[617] = ItemType.DeadFireCoralFan; + mappings[607] = ItemType.DeadHornCoral; + mappings[593] = ItemType.DeadHornCoralBlock; + mappings[618] = ItemType.DeadHornCoralFan; + mappings[608] = ItemType.DeadTubeCoral; + mappings[589] = ItemType.DeadTubeCoralBlock; + mappings[614] = ItemType.DeadTubeCoralFan; + mappings[1167] = ItemType.DebugStick; + mappings[288] = ItemType.DecoratedPot; + mappings[8] = ItemType.Deepslate; + mappings[654] = ItemType.DeepslateBrickSlab; + mappings[637] = ItemType.DeepslateBrickStairs; + mappings[417] = ItemType.DeepslateBrickWall; + mappings[346] = ItemType.DeepslateBricks; + mappings[63] = ItemType.DeepslateCoalOre; + mappings[67] = ItemType.DeepslateCopperOre; + mappings[77] = ItemType.DeepslateDiamondOre; + mappings[73] = ItemType.DeepslateEmeraldOre; + mappings[69] = ItemType.DeepslateGoldOre; + mappings[65] = ItemType.DeepslateIronOre; + mappings[75] = ItemType.DeepslateLapisOre; + mappings[71] = ItemType.DeepslateRedstoneOre; + mappings[655] = ItemType.DeepslateTileSlab; + mappings[638] = ItemType.DeepslateTileStairs; + mappings[418] = ItemType.DeepslateTileWall; + mappings[348] = ItemType.DeepslateTiles; + mappings[762] = ItemType.DetectorRail; + mappings[804] = ItemType.Diamond; + mappings[840] = ItemType.DiamondAxe; + mappings[91] = ItemType.DiamondBlock; + mappings[871] = ItemType.DiamondBoots; + mappings[869] = ItemType.DiamondChestplate; + mappings[868] = ItemType.DiamondHelmet; + mappings[841] = ItemType.DiamondHoe; + mappings[1126] = ItemType.DiamondHorseArmor; + mappings[870] = ItemType.DiamondLeggings; + mappings[76] = ItemType.DiamondOre; + mappings[839] = ItemType.DiamondPickaxe; + mappings[838] = ItemType.DiamondShovel; + mappings[837] = ItemType.DiamondSword; + mappings[4] = ItemType.Diorite; + mappings[651] = ItemType.DioriteSlab; + mappings[634] = ItemType.DioriteStairs; + mappings[411] = ItemType.DioriteWall; + mappings[28] = ItemType.Dirt; + mappings[464] = ItemType.DirtPath; + mappings[1184] = ItemType.DiscFragment5; + mappings[668] = ItemType.Dispenser; + mappings[1023] = ItemType.DolphinSpawnEgg; + mappings[1024] = ItemType.DonkeySpawnEgg; + mappings[1157] = ItemType.DragonBreath; + mappings[379] = ItemType.DragonEgg; + mappings[1108] = ItemType.DragonHead; + mappings[985] = ItemType.DriedKelp; + mappings[923] = ItemType.DriedKelpBlock; + mappings[26] = ItemType.DripstoneBlock; + mappings[669] = ItemType.Dropper; + mappings[1025] = ItemType.DrownedSpawnEgg; + mappings[1268] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1264] = ItemType.EchoShard; + mappings[927] = ItemType.Egg; + mappings[1026] = ItemType.ElderGuardianSpawnEgg; + mappings[773] = ItemType.Elytra; + mappings[805] = ItemType.Emerald; + mappings[382] = ItemType.EmeraldBlock; + mappings[72] = ItemType.EmeraldOre; + mappings[1114] = ItemType.EnchantedBook; + mappings[885] = ItemType.EnchantedGoldenApple; + mappings[375] = ItemType.EnchantingTable; + mappings[1149] = ItemType.EndCrystal; + mappings[376] = ItemType.EndPortalFrame; + mappings[292] = ItemType.EndRod; + mappings[377] = ItemType.EndStone; + mappings[644] = ItemType.EndStoneBrickSlab; + mappings[626] = ItemType.EndStoneBrickStairs; + mappings[410] = ItemType.EndStoneBrickWall; + mappings[378] = ItemType.EndStoneBricks; + mappings[381] = ItemType.EnderChest; + mappings[1027] = ItemType.EnderDragonSpawnEgg; + mappings[1006] = ItemType.EnderEye; + mappings[993] = ItemType.EnderPearl; + mappings[1028] = ItemType.EndermanSpawnEgg; + mappings[1029] = ItemType.EndermiteSpawnEgg; + mappings[1030] = ItemType.EvokerSpawnEgg; + mappings[1088] = ItemType.ExperienceBottle; + mappings[1292] = ItemType.ExplorerPotterySherd; + mappings[97] = ItemType.ExposedChiseledCopper; + mappings[93] = ItemType.ExposedCopper; + mappings[1317] = ItemType.ExposedCopperBulb; + mappings[723] = ItemType.ExposedCopperDoor; + mappings[1309] = ItemType.ExposedCopperGrate; + mappings[743] = ItemType.ExposedCopperTrapdoor; + mappings[101] = ItemType.ExposedCutCopper; + mappings[109] = ItemType.ExposedCutCopperSlab; + mappings[105] = ItemType.ExposedCutCopperStairs; + mappings[1272] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[301] = ItemType.Farmland; + mappings[851] = ItemType.Feather; + mappings[1001] = ItemType.FermentedSpiderEye; + mappings[196] = ItemType.Fern; + mappings[982] = ItemType.FilledMap; + mappings[1089] = ItemType.FireCharge; + mappings[602] = ItemType.FireCoral; + mappings[597] = ItemType.FireCoralBlock; + mappings[612] = ItemType.FireCoralFan; + mappings[1112] = ItemType.FireworkRocket; + mappings[1113] = ItemType.FireworkStar; + mappings[931] = ItemType.FishingRod; + mappings[1206] = ItemType.FletchingTable; + mappings[880] = ItemType.Flint; + mappings[798] = ItemType.FlintAndSteel; + mappings[1283] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1198] = ItemType.FlowBannerPattern; + mappings[1293] = ItemType.FlowPotterySherd; + mappings[1192] = ItemType.FlowerBannerPattern; + mappings[1096] = ItemType.FlowerPot; + mappings[198] = ItemType.FloweringAzalea; + mappings[185] = ItemType.FloweringAzaleaLeaves; + mappings[1031] = ItemType.FoxSpawnEgg; + mappings[1294] = ItemType.FriendPotterySherd; + mappings[1032] = ItemType.FrogSpawnEgg; + mappings[1263] = ItemType.Frogspawn; + mappings[302] = ItemType.Furnace; + mappings[768] = ItemType.FurnaceMinecart; + mappings[1033] = ItemType.GhastSpawnEgg; + mappings[995] = ItemType.GhastTear; + mappings[1228] = ItemType.GildedBlackstone; + mappings[188] = ItemType.Glass; + mappings[999] = ItemType.GlassBottle; + mappings[357] = ItemType.GlassPane; + mappings[1007] = ItemType.GlisteringMelonSlice; + mappings[1196] = ItemType.GlobeBannerPattern; + mappings[1214] = ItemType.GlowBerries; + mappings[942] = ItemType.GlowInkSac; + mappings[1095] = ItemType.GlowItemFrame; + mappings[360] = ItemType.GlowLichen; + mappings[1034] = ItemType.GlowSquidSpawnEgg; + mappings[332] = ItemType.Glowstone; + mappings[934] = ItemType.GlowstoneDust; + mappings[1200] = ItemType.GoatHorn; + mappings[1035] = ItemType.GoatSpawnEgg; + mappings[90] = ItemType.GoldBlock; + mappings[814] = ItemType.GoldIngot; + mappings[996] = ItemType.GoldNugget; + mappings[68] = ItemType.GoldOre; + mappings[884] = ItemType.GoldenApple; + mappings[830] = ItemType.GoldenAxe; + mappings[875] = ItemType.GoldenBoots; + mappings[1102] = ItemType.GoldenCarrot; + mappings[873] = ItemType.GoldenChestplate; + mappings[872] = ItemType.GoldenHelmet; + mappings[831] = ItemType.GoldenHoe; + mappings[1125] = ItemType.GoldenHorseArmor; + mappings[874] = ItemType.GoldenLeggings; + mappings[829] = ItemType.GoldenPickaxe; + mappings[828] = ItemType.GoldenShovel; + mappings[827] = ItemType.GoldenSword; + mappings[2] = ItemType.Granite; + mappings[647] = ItemType.GraniteSlab; + mappings[630] = ItemType.GraniteStairs; + mappings[403] = ItemType.GraniteWall; + mappings[27] = ItemType.GrassBlock; + mappings[61] = ItemType.Gravel; + mappings[1140] = ItemType.GrayBanner; + mappings[971] = ItemType.GrayBed; + mappings[1246] = ItemType.GrayCandle; + mappings[453] = ItemType.GrayCarpet; + mappings[562] = ItemType.GrayConcrete; + mappings[578] = ItemType.GrayConcretePowder; + mappings[951] = ItemType.GrayDye; + mappings[546] = ItemType.GrayGlazedTerracotta; + mappings[530] = ItemType.GrayShulkerBox; + mappings[478] = ItemType.GrayStainedGlass; + mappings[494] = ItemType.GrayStainedGlassPane; + mappings[434] = ItemType.GrayTerracotta; + mappings[209] = ItemType.GrayWool; + mappings[1146] = ItemType.GreenBanner; + mappings[977] = ItemType.GreenBed; + mappings[1252] = ItemType.GreenCandle; + mappings[459] = ItemType.GreenCarpet; + mappings[568] = ItemType.GreenConcrete; + mappings[584] = ItemType.GreenConcretePowder; + mappings[957] = ItemType.GreenDye; + mappings[552] = ItemType.GreenGlazedTerracotta; + mappings[536] = ItemType.GreenShulkerBox; + mappings[484] = ItemType.GreenStainedGlass; + mappings[500] = ItemType.GreenStainedGlassPane; + mappings[440] = ItemType.GreenTerracotta; + mappings[215] = ItemType.GreenWool; + mappings[1207] = ItemType.Grindstone; + mappings[1036] = ItemType.GuardianSpawnEgg; + mappings[852] = ItemType.Gunpowder; + mappings[1199] = ItemType.GusterBannerPattern; + mappings[1295] = ItemType.GusterPotterySherd; + mappings[248] = ItemType.HangingRoots; + mappings[445] = ItemType.HayBlock; + mappings[1188] = ItemType.HeartOfTheSea; + mappings[1296] = ItemType.HeartPotterySherd; + mappings[1297] = ItemType.HeartbreakPotterySherd; + mappings[85] = ItemType.HeavyCore; + mappings[698] = ItemType.HeavyWeightedPressurePlate; + mappings[1037] = ItemType.HoglinSpawnEgg; + mappings[665] = ItemType.HoneyBlock; + mappings[1221] = ItemType.HoneyBottle; + mappings[1218] = ItemType.Honeycomb; + mappings[1222] = ItemType.HoneycombBlock; + mappings[667] = ItemType.Hopper; + mappings[770] = ItemType.HopperMinecart; + mappings[603] = ItemType.HornCoral; + mappings[598] = ItemType.HornCoralBlock; + mappings[613] = ItemType.HornCoralFan; + mappings[1038] = ItemType.HorseSpawnEgg; + mappings[1282] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1298] = ItemType.HowlPotterySherd; + mappings[1039] = ItemType.HuskSpawnEgg; + mappings[306] = ItemType.Ice; + mappings[338] = ItemType.InfestedChiseledStoneBricks; + mappings[334] = ItemType.InfestedCobblestone; + mappings[337] = ItemType.InfestedCrackedStoneBricks; + mappings[339] = ItemType.InfestedDeepslate; + mappings[336] = ItemType.InfestedMossyStoneBricks; + mappings[333] = ItemType.InfestedStone; + mappings[335] = ItemType.InfestedStoneBricks; + mappings[941] = ItemType.InkSac; + mappings[835] = ItemType.IronAxe; + mappings[355] = ItemType.IronBars; + mappings[88] = ItemType.IronBlock; + mappings[867] = ItemType.IronBoots; + mappings[865] = ItemType.IronChestplate; + mappings[710] = ItemType.IronDoor; + mappings[1040] = ItemType.IronGolemSpawnEgg; + mappings[864] = ItemType.IronHelmet; + mappings[836] = ItemType.IronHoe; + mappings[1124] = ItemType.IronHorseArmor; + mappings[810] = ItemType.IronIngot; + mappings[866] = ItemType.IronLeggings; + mappings[1165] = ItemType.IronNugget; + mappings[64] = ItemType.IronOre; + mappings[834] = ItemType.IronPickaxe; + mappings[833] = ItemType.IronShovel; + mappings[832] = ItemType.IronSword; + mappings[730] = ItemType.IronTrapdoor; + mappings[1094] = ItemType.ItemFrame; + mappings[324] = ItemType.JackOLantern; + mappings[793] = ItemType.Jigsaw; + mappings[310] = ItemType.Jukebox; + mappings[780] = ItemType.JungleBoat; + mappings[687] = ItemType.JungleButton; + mappings[781] = ItemType.JungleChestBoat; + mappings[714] = ItemType.JungleDoor; + mappings[314] = ItemType.JungleFence; + mappings[753] = ItemType.JungleFenceGate; + mappings[900] = ItemType.JungleHangingSign; + mappings[179] = ItemType.JungleLeaves; + mappings[135] = ItemType.JungleLog; + mappings[39] = ItemType.JunglePlanks; + mappings[702] = ItemType.JunglePressurePlate; + mappings[51] = ItemType.JungleSapling; + mappings[889] = ItemType.JungleSign; + mappings[255] = ItemType.JungleSlab; + mappings[386] = ItemType.JungleStairs; + mappings[734] = ItemType.JungleTrapdoor; + mappings[169] = ItemType.JungleWood; + mappings[244] = ItemType.Kelp; + mappings[1166] = ItemType.KnowledgeBook; + mappings[303] = ItemType.Ladder; + mappings[1211] = ItemType.Lantern; + mappings[190] = ItemType.LapisBlock; + mappings[806] = ItemType.LapisLazuli; + mappings[74] = ItemType.LapisOre; + mappings[1257] = ItemType.LargeAmethystBud; + mappings[470] = ItemType.LargeFern; + mappings[910] = ItemType.LavaBucket; + mappings[1128] = ItemType.Lead; + mappings[913] = ItemType.Leather; + mappings[859] = ItemType.LeatherBoots; + mappings[857] = ItemType.LeatherChestplate; + mappings[856] = ItemType.LeatherHelmet; + mappings[1127] = ItemType.LeatherHorseArmor; + mappings[858] = ItemType.LeatherLeggings; + mappings[670] = ItemType.Lectern; + mappings[672] = ItemType.Lever; + mappings[444] = ItemType.Light; + mappings[1136] = ItemType.LightBlueBanner; + mappings[967] = ItemType.LightBlueBed; + mappings[1242] = ItemType.LightBlueCandle; + mappings[449] = ItemType.LightBlueCarpet; + mappings[558] = ItemType.LightBlueConcrete; + mappings[574] = ItemType.LightBlueConcretePowder; + mappings[947] = ItemType.LightBlueDye; + mappings[542] = ItemType.LightBlueGlazedTerracotta; + mappings[526] = ItemType.LightBlueShulkerBox; + mappings[474] = ItemType.LightBlueStainedGlass; + mappings[490] = ItemType.LightBlueStainedGlassPane; + mappings[430] = ItemType.LightBlueTerracotta; + mappings[205] = ItemType.LightBlueWool; + mappings[1141] = ItemType.LightGrayBanner; + mappings[972] = ItemType.LightGrayBed; + mappings[1247] = ItemType.LightGrayCandle; + mappings[454] = ItemType.LightGrayCarpet; + mappings[563] = ItemType.LightGrayConcrete; + mappings[579] = ItemType.LightGrayConcretePowder; + mappings[952] = ItemType.LightGrayDye; + mappings[547] = ItemType.LightGrayGlazedTerracotta; + mappings[531] = ItemType.LightGrayShulkerBox; + mappings[479] = ItemType.LightGrayStainedGlass; + mappings[495] = ItemType.LightGrayStainedGlassPane; + mappings[435] = ItemType.LightGrayTerracotta; + mappings[210] = ItemType.LightGrayWool; + mappings[697] = ItemType.LightWeightedPressurePlate; + mappings[673] = ItemType.LightningRod; + mappings[466] = ItemType.Lilac; + mappings[229] = ItemType.LilyOfTheValley; + mappings[365] = ItemType.LilyPad; + mappings[1138] = ItemType.LimeBanner; + mappings[969] = ItemType.LimeBed; + mappings[1244] = ItemType.LimeCandle; + mappings[451] = ItemType.LimeCarpet; + mappings[560] = ItemType.LimeConcrete; + mappings[576] = ItemType.LimeConcretePowder; + mappings[949] = ItemType.LimeDye; + mappings[544] = ItemType.LimeGlazedTerracotta; + mappings[528] = ItemType.LimeShulkerBox; + mappings[476] = ItemType.LimeStainedGlass; + mappings[492] = ItemType.LimeStainedGlassPane; + mappings[432] = ItemType.LimeTerracotta; + mappings[207] = ItemType.LimeWool; + mappings[1161] = ItemType.LingeringPotion; + mappings[1041] = ItemType.LlamaSpawnEgg; + mappings[1223] = ItemType.Lodestone; + mappings[1191] = ItemType.Loom; + mappings[1093] = ItemType.Mace; + mappings[1135] = ItemType.MagentaBanner; + mappings[966] = ItemType.MagentaBed; + mappings[1241] = ItemType.MagentaCandle; + mappings[448] = ItemType.MagentaCarpet; + mappings[557] = ItemType.MagentaConcrete; + mappings[573] = ItemType.MagentaConcretePowder; + mappings[946] = ItemType.MagentaDye; + mappings[541] = ItemType.MagentaGlazedTerracotta; + mappings[525] = ItemType.MagentaShulkerBox; + mappings[473] = ItemType.MagentaStainedGlass; + mappings[489] = ItemType.MagentaStainedGlassPane; + mappings[429] = ItemType.MagentaTerracotta; + mappings[204] = ItemType.MagentaWool; + mappings[516] = ItemType.MagmaBlock; + mappings[1003] = ItemType.MagmaCream; + mappings[1042] = ItemType.MagmaCubeSpawnEgg; + mappings[788] = ItemType.MangroveBoat; + mappings[691] = ItemType.MangroveButton; + mappings[789] = ItemType.MangroveChestBoat; + mappings[718] = ItemType.MangroveDoor; + mappings[318] = ItemType.MangroveFence; + mappings[757] = ItemType.MangroveFenceGate; + mappings[904] = ItemType.MangroveHangingSign; + mappings[183] = ItemType.MangroveLeaves; + mappings[139] = ItemType.MangroveLog; + mappings[43] = ItemType.MangrovePlanks; + mappings[706] = ItemType.MangrovePressurePlate; + mappings[55] = ItemType.MangrovePropagule; + mappings[140] = ItemType.MangroveRoots; + mappings[893] = ItemType.MangroveSign; + mappings[259] = ItemType.MangroveSlab; + mappings[390] = ItemType.MangroveStairs; + mappings[738] = ItemType.MangroveTrapdoor; + mappings[173] = ItemType.MangroveWood; + mappings[1101] = ItemType.Map; + mappings[1256] = ItemType.MediumAmethystBud; + mappings[358] = ItemType.Melon; + mappings[987] = ItemType.MelonSeeds; + mappings[984] = ItemType.MelonSlice; + mappings[914] = ItemType.MilkBucket; + mappings[766] = ItemType.Minecart; + mappings[1299] = ItemType.MinerPotterySherd; + mappings[1195] = ItemType.MojangBannerPattern; + mappings[1043] = ItemType.MooshroomSpawnEgg; + mappings[247] = ItemType.MossBlock; + mappings[245] = ItemType.MossCarpet; + mappings[289] = ItemType.MossyCobblestone; + mappings[643] = ItemType.MossyCobblestoneSlab; + mappings[625] = ItemType.MossyCobblestoneStairs; + mappings[398] = ItemType.MossyCobblestoneWall; + mappings[641] = ItemType.MossyStoneBrickSlab; + mappings[623] = ItemType.MossyStoneBrickStairs; + mappings[402] = ItemType.MossyStoneBrickWall; + mappings[341] = ItemType.MossyStoneBricks; + mappings[1300] = ItemType.MournerPotterySherd; + mappings[32] = ItemType.Mud; + mappings[272] = ItemType.MudBrickSlab; + mappings[363] = ItemType.MudBrickStairs; + mappings[405] = ItemType.MudBrickWall; + mappings[345] = ItemType.MudBricks; + mappings[141] = ItemType.MuddyMangroveRoots; + mappings[1044] = ItemType.MuleSpawnEgg; + mappings[354] = ItemType.MushroomStem; + mappings[849] = ItemType.MushroomStew; + mappings[1178] = ItemType.MusicDisc11; + mappings[1168] = ItemType.MusicDisc13; + mappings[1182] = ItemType.MusicDisc5; + mappings[1170] = ItemType.MusicDiscBlocks; + mappings[1169] = ItemType.MusicDiscCat; + mappings[1171] = ItemType.MusicDiscChirp; + mappings[1172] = ItemType.MusicDiscFar; + mappings[1173] = ItemType.MusicDiscMall; + mappings[1174] = ItemType.MusicDiscMellohi; + mappings[1180] = ItemType.MusicDiscOtherside; + mappings[1183] = ItemType.MusicDiscPigstep; + mappings[1181] = ItemType.MusicDiscRelic; + mappings[1175] = ItemType.MusicDiscStal; + mappings[1176] = ItemType.MusicDiscStrad; + mappings[1179] = ItemType.MusicDiscWait; + mappings[1177] = ItemType.MusicDiscWard; + mappings[1131] = ItemType.Mutton; + mappings[364] = ItemType.Mycelium; + mappings[1129] = ItemType.NameTag; + mappings[1187] = ItemType.NautilusShell; + mappings[1115] = ItemType.NetherBrick; + mappings[369] = ItemType.NetherBrickFence; + mappings[273] = ItemType.NetherBrickSlab; + mappings[370] = ItemType.NetherBrickStairs; + mappings[406] = ItemType.NetherBrickWall; + mappings[366] = ItemType.NetherBricks; + mappings[78] = ItemType.NetherGoldOre; + mappings[79] = ItemType.NetherQuartzOre; + mappings[240] = ItemType.NetherSprouts; + mappings[1110] = ItemType.NetherStar; + mappings[997] = ItemType.NetherWart; + mappings[517] = ItemType.NetherWartBlock; + mappings[845] = ItemType.NetheriteAxe; + mappings[92] = ItemType.NetheriteBlock; + mappings[879] = ItemType.NetheriteBoots; + mappings[877] = ItemType.NetheriteChestplate; + mappings[876] = ItemType.NetheriteHelmet; + mappings[846] = ItemType.NetheriteHoe; + mappings[815] = ItemType.NetheriteIngot; + mappings[878] = ItemType.NetheriteLeggings; + mappings[844] = ItemType.NetheritePickaxe; + mappings[816] = ItemType.NetheriteScrap; + mappings[843] = ItemType.NetheriteShovel; + mappings[842] = ItemType.NetheriteSword; + mappings[1266] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[325] = ItemType.Netherrack; + mappings[681] = ItemType.NoteBlock; + mappings[774] = ItemType.OakBoat; + mappings[684] = ItemType.OakButton; + mappings[775] = ItemType.OakChestBoat; + mappings[711] = ItemType.OakDoor; + mappings[311] = ItemType.OakFence; + mappings[750] = ItemType.OakFenceGate; + mappings[897] = ItemType.OakHangingSign; + mappings[176] = ItemType.OakLeaves; + mappings[132] = ItemType.OakLog; + mappings[36] = ItemType.OakPlanks; + mappings[699] = ItemType.OakPressurePlate; + mappings[48] = ItemType.OakSapling; + mappings[886] = ItemType.OakSign; + mappings[252] = ItemType.OakSlab; + mappings[383] = ItemType.OakStairs; + mappings[731] = ItemType.OakTrapdoor; + mappings[166] = ItemType.OakWood; + mappings[666] = ItemType.Observer; + mappings[290] = ItemType.Obsidian; + mappings[1045] = ItemType.OcelotSpawnEgg; + mappings[1260] = ItemType.OchreFroglight; + mappings[1328] = ItemType.OminousBottle; + mappings[1326] = ItemType.OminousTrialKey; + mappings[1134] = ItemType.OrangeBanner; + mappings[965] = ItemType.OrangeBed; + mappings[1240] = ItemType.OrangeCandle; + mappings[447] = ItemType.OrangeCarpet; + mappings[556] = ItemType.OrangeConcrete; + mappings[572] = ItemType.OrangeConcretePowder; + mappings[945] = ItemType.OrangeDye; + mappings[540] = ItemType.OrangeGlazedTerracotta; + mappings[524] = ItemType.OrangeShulkerBox; + mappings[472] = ItemType.OrangeStainedGlass; + mappings[488] = ItemType.OrangeStainedGlassPane; + mappings[428] = ItemType.OrangeTerracotta; + mappings[224] = ItemType.OrangeTulip; + mappings[203] = ItemType.OrangeWool; + mappings[227] = ItemType.OxeyeDaisy; + mappings[99] = ItemType.OxidizedChiseledCopper; + mappings[95] = ItemType.OxidizedCopper; + mappings[1319] = ItemType.OxidizedCopperBulb; + mappings[725] = ItemType.OxidizedCopperDoor; + mappings[1311] = ItemType.OxidizedCopperGrate; + mappings[745] = ItemType.OxidizedCopperTrapdoor; + mappings[103] = ItemType.OxidizedCutCopper; + mappings[111] = ItemType.OxidizedCutCopperSlab; + mappings[107] = ItemType.OxidizedCutCopperStairs; + mappings[463] = ItemType.PackedIce; + mappings[344] = ItemType.PackedMud; + mappings[883] = ItemType.Painting; + mappings[1046] = ItemType.PandaSpawnEgg; + mappings[924] = ItemType.Paper; + mappings[1047] = ItemType.ParrotSpawnEgg; + mappings[1262] = ItemType.PearlescentFroglight; + mappings[468] = ItemType.Peony; + mappings[268] = ItemType.PetrifiedOakSlab; + mappings[1186] = ItemType.PhantomMembrane; + mappings[1048] = ItemType.PhantomSpawnEgg; + mappings[1049] = ItemType.PigSpawnEgg; + mappings[1197] = ItemType.PiglinBannerPattern; + mappings[1051] = ItemType.PiglinBruteSpawnEgg; + mappings[1109] = ItemType.PiglinHead; + mappings[1050] = ItemType.PiglinSpawnEgg; + mappings[1052] = ItemType.PillagerSpawnEgg; + mappings[1139] = ItemType.PinkBanner; + mappings[970] = ItemType.PinkBed; + mappings[1245] = ItemType.PinkCandle; + mappings[452] = ItemType.PinkCarpet; + mappings[561] = ItemType.PinkConcrete; + mappings[577] = ItemType.PinkConcretePowder; + mappings[950] = ItemType.PinkDye; + mappings[545] = ItemType.PinkGlazedTerracotta; + mappings[246] = ItemType.PinkPetals; + mappings[529] = ItemType.PinkShulkerBox; + mappings[477] = ItemType.PinkStainedGlass; + mappings[493] = ItemType.PinkStainedGlassPane; + mappings[433] = ItemType.PinkTerracotta; + mappings[226] = ItemType.PinkTulip; + mappings[208] = ItemType.PinkWool; + mappings[662] = ItemType.Piston; + mappings[232] = ItemType.PitcherPlant; + mappings[1153] = ItemType.PitcherPod; + mappings[1105] = ItemType.PlayerHead; + mappings[1301] = ItemType.PlentyPotterySherd; + mappings[30] = ItemType.Podzol; + mappings[1259] = ItemType.PointedDripstone; + mappings[1100] = ItemType.PoisonousPotato; + mappings[1053] = ItemType.PolarBearSpawnEgg; + mappings[7] = ItemType.PolishedAndesite; + mappings[650] = ItemType.PolishedAndesiteSlab; + mappings[633] = ItemType.PolishedAndesiteStairs; + mappings[329] = ItemType.PolishedBasalt; + mappings[1229] = ItemType.PolishedBlackstone; + mappings[1234] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1235] = ItemType.PolishedBlackstoneBrickStairs; + mappings[414] = ItemType.PolishedBlackstoneBrickWall; + mappings[1233] = ItemType.PolishedBlackstoneBricks; + mappings[683] = ItemType.PolishedBlackstoneButton; + mappings[696] = ItemType.PolishedBlackstonePressurePlate; + mappings[1230] = ItemType.PolishedBlackstoneSlab; + mappings[1231] = ItemType.PolishedBlackstoneStairs; + mappings[413] = ItemType.PolishedBlackstoneWall; + mappings[10] = ItemType.PolishedDeepslate; + mappings[653] = ItemType.PolishedDeepslateSlab; + mappings[636] = ItemType.PolishedDeepslateStairs; + mappings[416] = ItemType.PolishedDeepslateWall; + mappings[5] = ItemType.PolishedDiorite; + mappings[642] = ItemType.PolishedDioriteSlab; + mappings[624] = ItemType.PolishedDioriteStairs; + mappings[3] = ItemType.PolishedGranite; + mappings[639] = ItemType.PolishedGraniteSlab; + mappings[621] = ItemType.PolishedGraniteStairs; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[1151] = ItemType.PoppedChorusFruit; + mappings[219] = ItemType.Poppy; + mappings[881] = ItemType.Porkchop; + mappings[1098] = ItemType.Potato; + mappings[998] = ItemType.Potion; + mappings[911] = ItemType.PowderSnowBucket; + mappings[761] = ItemType.PoweredRail; + mappings[503] = ItemType.Prismarine; + mappings[279] = ItemType.PrismarineBrickSlab; + mappings[507] = ItemType.PrismarineBrickStairs; + mappings[504] = ItemType.PrismarineBricks; + mappings[1117] = ItemType.PrismarineCrystals; + mappings[1116] = ItemType.PrismarineShard; + mappings[278] = ItemType.PrismarineSlab; + mappings[506] = ItemType.PrismarineStairs; + mappings[400] = ItemType.PrismarineWall; + mappings[1302] = ItemType.PrizePotterySherd; + mappings[938] = ItemType.Pufferfish; + mappings[915] = ItemType.PufferfishBucket; + mappings[1054] = ItemType.PufferfishSpawnEgg; + mappings[322] = ItemType.Pumpkin; + mappings[1111] = ItemType.PumpkinPie; + mappings[986] = ItemType.PumpkinSeeds; + mappings[1143] = ItemType.PurpleBanner; + mappings[974] = ItemType.PurpleBed; + mappings[1249] = ItemType.PurpleCandle; + mappings[456] = ItemType.PurpleCarpet; + mappings[565] = ItemType.PurpleConcrete; + mappings[581] = ItemType.PurpleConcretePowder; + mappings[954] = ItemType.PurpleDye; + mappings[549] = ItemType.PurpleGlazedTerracotta; + mappings[533] = ItemType.PurpleShulkerBox; + mappings[481] = ItemType.PurpleStainedGlass; + mappings[497] = ItemType.PurpleStainedGlassPane; + mappings[437] = ItemType.PurpleTerracotta; + mappings[212] = ItemType.PurpleWool; + mappings[295] = ItemType.PurpurBlock; + mappings[296] = ItemType.PurpurPillar; + mappings[277] = ItemType.PurpurSlab; + mappings[297] = ItemType.PurpurStairs; + mappings[807] = ItemType.Quartz; + mappings[423] = ItemType.QuartzBlock; + mappings[424] = ItemType.QuartzBricks; + mappings[425] = ItemType.QuartzPillar; + mappings[274] = ItemType.QuartzSlab; + mappings[426] = ItemType.QuartzStairs; + mappings[1118] = ItemType.Rabbit; + mappings[1121] = ItemType.RabbitFoot; + mappings[1122] = ItemType.RabbitHide; + mappings[1055] = ItemType.RabbitSpawnEgg; + mappings[1120] = ItemType.RabbitStew; + mappings[763] = ItemType.Rail; + mappings[1281] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1056] = ItemType.RavagerSpawnEgg; + mappings[811] = ItemType.RawCopper; + mappings[83] = ItemType.RawCopperBlock; + mappings[813] = ItemType.RawGold; + mappings[84] = ItemType.RawGoldBlock; + mappings[809] = ItemType.RawIron; + mappings[82] = ItemType.RawIronBlock; + mappings[929] = ItemType.RecoveryCompass; + mappings[1147] = ItemType.RedBanner; + mappings[978] = ItemType.RedBed; + mappings[1253] = ItemType.RedCandle; + mappings[460] = ItemType.RedCarpet; + mappings[569] = ItemType.RedConcrete; + mappings[585] = ItemType.RedConcretePowder; + mappings[958] = ItemType.RedDye; + mappings[553] = ItemType.RedGlazedTerracotta; + mappings[235] = ItemType.RedMushroom; + mappings[353] = ItemType.RedMushroomBlock; + mappings[649] = ItemType.RedNetherBrickSlab; + mappings[632] = ItemType.RedNetherBrickStairs; + mappings[408] = ItemType.RedNetherBrickWall; + mappings[519] = ItemType.RedNetherBricks; + mappings[60] = ItemType.RedSand; + mappings[510] = ItemType.RedSandstone; + mappings[275] = ItemType.RedSandstoneSlab; + mappings[513] = ItemType.RedSandstoneStairs; + mappings[401] = ItemType.RedSandstoneWall; + mappings[537] = ItemType.RedShulkerBox; + mappings[485] = ItemType.RedStainedGlass; + mappings[501] = ItemType.RedStainedGlassPane; + mappings[441] = ItemType.RedTerracotta; + mappings[223] = ItemType.RedTulip; + mappings[216] = ItemType.RedWool; + mappings[657] = ItemType.Redstone; + mappings[659] = ItemType.RedstoneBlock; + mappings[680] = ItemType.RedstoneLamp; + mappings[70] = ItemType.RedstoneOre; + mappings[658] = ItemType.RedstoneTorch; + mappings[351] = ItemType.ReinforcedDeepslate; + mappings[660] = ItemType.Repeater; + mappings[514] = ItemType.RepeatingCommandBlock; + mappings[1237] = ItemType.RespawnAnchor; + mappings[1276] = ItemType.RibArmorTrimSmithingTemplate; + mappings[31] = ItemType.RootedDirt; + mappings[467] = ItemType.RoseBush; + mappings[992] = ItemType.RottenFlesh; + mappings[765] = ItemType.Saddle; + mappings[936] = ItemType.Salmon; + mappings[916] = ItemType.SalmonBucket; + mappings[1057] = ItemType.SalmonSpawnEgg; + mappings[57] = ItemType.Sand; + mappings[191] = ItemType.Sandstone; + mappings[266] = ItemType.SandstoneSlab; + mappings[380] = ItemType.SandstoneStairs; + mappings[409] = ItemType.SandstoneWall; + mappings[656] = ItemType.Scaffolding; + mappings[1303] = ItemType.ScrapePotterySherd; + mappings[371] = ItemType.Sculk; + mappings[373] = ItemType.SculkCatalyst; + mappings[675] = ItemType.SculkSensor; + mappings[374] = ItemType.SculkShrieker; + mappings[372] = ItemType.SculkVein; + mappings[509] = ItemType.SeaLantern; + mappings[201] = ItemType.SeaPickle; + mappings[200] = ItemType.Seagrass; + mappings[1267] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1279] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1304] = ItemType.SheafPotterySherd; + mappings[983] = ItemType.Shears; + mappings[1058] = ItemType.SheepSpawnEgg; + mappings[1305] = ItemType.ShelterPotterySherd; + mappings[1162] = ItemType.Shield; + mappings[195] = ItemType.ShortGrass; + mappings[1217] = ItemType.Shroomlight; + mappings[522] = ItemType.ShulkerBox; + mappings[1164] = ItemType.ShulkerShell; + mappings[1059] = ItemType.ShulkerSpawnEgg; + mappings[1280] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1060] = ItemType.SilverfishSpawnEgg; + mappings[1062] = ItemType.SkeletonHorseSpawnEgg; + mappings[1103] = ItemType.SkeletonSkull; + mappings[1061] = ItemType.SkeletonSpawnEgg; + mappings[1194] = ItemType.SkullBannerPattern; + mappings[1306] = ItemType.SkullPotterySherd; + mappings[926] = ItemType.SlimeBall; + mappings[664] = ItemType.SlimeBlock; + mappings[1063] = ItemType.SlimeSpawnEgg; + mappings[1255] = ItemType.SmallAmethystBud; + mappings[250] = ItemType.SmallDripleaf; + mappings[1208] = ItemType.SmithingTable; + mappings[1203] = ItemType.Smoker; + mappings[330] = ItemType.SmoothBasalt; + mappings[281] = ItemType.SmoothQuartz; + mappings[646] = ItemType.SmoothQuartzSlab; + mappings[629] = ItemType.SmoothQuartzStairs; + mappings[282] = ItemType.SmoothRedSandstone; + mappings[640] = ItemType.SmoothRedSandstoneSlab; + mappings[622] = ItemType.SmoothRedSandstoneStairs; + mappings[283] = ItemType.SmoothSandstone; + mappings[645] = ItemType.SmoothSandstoneSlab; + mappings[628] = ItemType.SmoothSandstoneStairs; + mappings[284] = ItemType.SmoothStone; + mappings[265] = ItemType.SmoothStoneSlab; + mappings[588] = ItemType.SnifferEgg; + mappings[1064] = ItemType.SnifferSpawnEgg; + mappings[1307] = ItemType.SnortPotterySherd; + mappings[1275] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[305] = ItemType.Snow; + mappings[307] = ItemType.SnowBlock; + mappings[1065] = ItemType.SnowGolemSpawnEgg; + mappings[912] = ItemType.Snowball; + mappings[1216] = ItemType.SoulCampfire; + mappings[1212] = ItemType.SoulLantern; + mappings[326] = ItemType.SoulSand; + mappings[327] = ItemType.SoulSoil; + mappings[331] = ItemType.SoulTorch; + mappings[298] = ItemType.Spawner; + mappings[1159] = ItemType.SpectralArrow; + mappings[1000] = ItemType.SpiderEye; + mappings[1066] = ItemType.SpiderSpawnEgg; + mappings[1277] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1158] = ItemType.SplashPotion; + mappings[186] = ItemType.Sponge; + mappings[233] = ItemType.SporeBlossom; + mappings[776] = ItemType.SpruceBoat; + mappings[685] = ItemType.SpruceButton; + mappings[777] = ItemType.SpruceChestBoat; + mappings[712] = ItemType.SpruceDoor; + mappings[312] = ItemType.SpruceFence; + mappings[751] = ItemType.SpruceFenceGate; + mappings[898] = ItemType.SpruceHangingSign; + mappings[177] = ItemType.SpruceLeaves; + mappings[133] = ItemType.SpruceLog; + mappings[37] = ItemType.SprucePlanks; + mappings[700] = ItemType.SprucePressurePlate; + mappings[49] = ItemType.SpruceSapling; + mappings[887] = ItemType.SpruceSign; + mappings[253] = ItemType.SpruceSlab; + mappings[384] = ItemType.SpruceStairs; + mappings[732] = ItemType.SpruceTrapdoor; + mappings[167] = ItemType.SpruceWood; + mappings[933] = ItemType.Spyglass; + mappings[1067] = ItemType.SquidSpawnEgg; + mappings[847] = ItemType.Stick; + mappings[663] = ItemType.StickyPiston; + mappings[1] = ItemType.Stone; + mappings[825] = ItemType.StoneAxe; + mappings[271] = ItemType.StoneBrickSlab; + mappings[362] = ItemType.StoneBrickStairs; + mappings[404] = ItemType.StoneBrickWall; + mappings[340] = ItemType.StoneBricks; + mappings[682] = ItemType.StoneButton; + mappings[826] = ItemType.StoneHoe; + mappings[824] = ItemType.StonePickaxe; + mappings[695] = ItemType.StonePressurePlate; + mappings[823] = ItemType.StoneShovel; + mappings[264] = ItemType.StoneSlab; + mappings[627] = ItemType.StoneStairs; + mappings[822] = ItemType.StoneSword; + mappings[1209] = ItemType.Stonecutter; + mappings[1068] = ItemType.StraySpawnEgg; + mappings[1069] = ItemType.StriderSpawnEgg; + mappings[850] = ItemType.String; + mappings[149] = ItemType.StrippedAcaciaLog; + mappings[159] = ItemType.StrippedAcaciaWood; + mappings[165] = ItemType.StrippedBambooBlock; + mappings[147] = ItemType.StrippedBirchLog; + mappings[157] = ItemType.StrippedBirchWood; + mappings[150] = ItemType.StrippedCherryLog; + mappings[160] = ItemType.StrippedCherryWood; + mappings[163] = ItemType.StrippedCrimsonHyphae; + mappings[153] = ItemType.StrippedCrimsonStem; + mappings[151] = ItemType.StrippedDarkOakLog; + mappings[161] = ItemType.StrippedDarkOakWood; + mappings[148] = ItemType.StrippedJungleLog; + mappings[158] = ItemType.StrippedJungleWood; + mappings[152] = ItemType.StrippedMangroveLog; + mappings[162] = ItemType.StrippedMangroveWood; + mappings[145] = ItemType.StrippedOakLog; + mappings[155] = ItemType.StrippedOakWood; + mappings[146] = ItemType.StrippedSpruceLog; + mappings[156] = ItemType.StrippedSpruceWood; + mappings[164] = ItemType.StrippedWarpedHyphae; + mappings[154] = ItemType.StrippedWarpedStem; + mappings[792] = ItemType.StructureBlock; + mappings[521] = ItemType.StructureVoid; + mappings[962] = ItemType.Sugar; + mappings[243] = ItemType.SugarCane; + mappings[465] = ItemType.Sunflower; + mappings[59] = ItemType.SuspiciousGravel; + mappings[58] = ItemType.SuspiciousSand; + mappings[1190] = ItemType.SuspiciousStew; + mappings[1213] = ItemType.SweetBerries; + mappings[920] = ItemType.TadpoleBucket; + mappings[1070] = ItemType.TadpoleSpawnEgg; + mappings[469] = ItemType.TallGrass; + mappings[671] = ItemType.Target; + mappings[462] = ItemType.Terracotta; + mappings[1274] = ItemType.TideArmorTrimSmithingTemplate; + mappings[189] = ItemType.TintedGlass; + mappings[1160] = ItemType.TippedArrow; + mappings[679] = ItemType.Tnt; + mappings[769] = ItemType.TntMinecart; + mappings[291] = ItemType.Torch; + mappings[231] = ItemType.Torchflower; + mappings[1152] = ItemType.TorchflowerSeeds; + mappings[1163] = ItemType.TotemOfUndying; + mappings[1071] = ItemType.TraderLlamaSpawnEgg; + mappings[678] = ItemType.TrappedChest; + mappings[1325] = ItemType.TrialKey; + mappings[1324] = ItemType.TrialSpawner; + mappings[1185] = ItemType.Trident; + mappings[677] = ItemType.TripwireHook; + mappings[937] = ItemType.TropicalFish; + mappings[918] = ItemType.TropicalFishBucket; + mappings[1072] = ItemType.TropicalFishSpawnEgg; + mappings[599] = ItemType.TubeCoral; + mappings[594] = ItemType.TubeCoralBlock; + mappings[609] = ItemType.TubeCoralFan; + mappings[12] = ItemType.Tuff; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[21] = ItemType.TuffBricks; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[587] = ItemType.TurtleEgg; + mappings[794] = ItemType.TurtleHelmet; + mappings[795] = ItemType.TurtleScute; + mappings[1073] = ItemType.TurtleSpawnEgg; + mappings[242] = ItemType.TwistingVines; + mappings[1327] = ItemType.Vault; + mappings[1261] = ItemType.VerdantFroglight; + mappings[1273] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1074] = ItemType.VexSpawnEgg; + mappings[1075] = ItemType.VillagerSpawnEgg; + mappings[1076] = ItemType.VindicatorSpawnEgg; + mappings[359] = ItemType.Vine; + mappings[1077] = ItemType.WanderingTraderSpawnEgg; + mappings[1271] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1078] = ItemType.WardenSpawnEgg; + mappings[694] = ItemType.WarpedButton; + mappings[721] = ItemType.WarpedDoor; + mappings[321] = ItemType.WarpedFence; + mappings[760] = ItemType.WarpedFenceGate; + mappings[237] = ItemType.WarpedFungus; + mappings[772] = ItemType.WarpedFungusOnAStick; + mappings[907] = ItemType.WarpedHangingSign; + mappings[175] = ItemType.WarpedHyphae; + mappings[34] = ItemType.WarpedNylium; + mappings[46] = ItemType.WarpedPlanks; + mappings[709] = ItemType.WarpedPressurePlate; + mappings[239] = ItemType.WarpedRoots; + mappings[896] = ItemType.WarpedSign; + mappings[263] = ItemType.WarpedSlab; + mappings[394] = ItemType.WarpedStairs; + mappings[143] = ItemType.WarpedStem; + mappings[741] = ItemType.WarpedTrapdoor; + mappings[518] = ItemType.WarpedWartBlock; + mappings[909] = ItemType.WaterBucket; + mappings[116] = ItemType.WaxedChiseledCopper; + mappings[112] = ItemType.WaxedCopperBlock; + mappings[1320] = ItemType.WaxedCopperBulb; + mappings[726] = ItemType.WaxedCopperDoor; + mappings[1312] = ItemType.WaxedCopperGrate; + mappings[746] = ItemType.WaxedCopperTrapdoor; + mappings[120] = ItemType.WaxedCutCopper; + mappings[128] = ItemType.WaxedCutCopperSlab; + mappings[124] = ItemType.WaxedCutCopperStairs; + mappings[117] = ItemType.WaxedExposedChiseledCopper; + mappings[113] = ItemType.WaxedExposedCopper; + mappings[1321] = ItemType.WaxedExposedCopperBulb; + mappings[727] = ItemType.WaxedExposedCopperDoor; + mappings[1313] = ItemType.WaxedExposedCopperGrate; + mappings[747] = ItemType.WaxedExposedCopperTrapdoor; + mappings[121] = ItemType.WaxedExposedCutCopper; + mappings[129] = ItemType.WaxedExposedCutCopperSlab; + mappings[125] = ItemType.WaxedExposedCutCopperStairs; + mappings[119] = ItemType.WaxedOxidizedChiseledCopper; + mappings[115] = ItemType.WaxedOxidizedCopper; + mappings[1323] = ItemType.WaxedOxidizedCopperBulb; + mappings[729] = ItemType.WaxedOxidizedCopperDoor; + mappings[1315] = ItemType.WaxedOxidizedCopperGrate; + mappings[749] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[123] = ItemType.WaxedOxidizedCutCopper; + mappings[131] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[127] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[118] = ItemType.WaxedWeatheredChiseledCopper; + mappings[114] = ItemType.WaxedWeatheredCopper; + mappings[1322] = ItemType.WaxedWeatheredCopperBulb; + mappings[728] = ItemType.WaxedWeatheredCopperDoor; + mappings[1314] = ItemType.WaxedWeatheredCopperGrate; + mappings[748] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[122] = ItemType.WaxedWeatheredCutCopper; + mappings[130] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[126] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[1278] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[98] = ItemType.WeatheredChiseledCopper; + mappings[94] = ItemType.WeatheredCopper; + mappings[1318] = ItemType.WeatheredCopperBulb; + mappings[724] = ItemType.WeatheredCopperDoor; + mappings[1310] = ItemType.WeatheredCopperGrate; + mappings[744] = ItemType.WeatheredCopperTrapdoor; + mappings[102] = ItemType.WeatheredCutCopper; + mappings[110] = ItemType.WeatheredCutCopperSlab; + mappings[106] = ItemType.WeatheredCutCopperStairs; + mappings[241] = ItemType.WeepingVines; + mappings[187] = ItemType.WetSponge; + mappings[854] = ItemType.Wheat; + mappings[853] = ItemType.WheatSeeds; + mappings[1133] = ItemType.WhiteBanner; + mappings[964] = ItemType.WhiteBed; + mappings[1239] = ItemType.WhiteCandle; + mappings[446] = ItemType.WhiteCarpet; + mappings[555] = ItemType.WhiteConcrete; + mappings[571] = ItemType.WhiteConcretePowder; + mappings[944] = ItemType.WhiteDye; + mappings[539] = ItemType.WhiteGlazedTerracotta; + mappings[523] = ItemType.WhiteShulkerBox; + mappings[471] = ItemType.WhiteStainedGlass; + mappings[487] = ItemType.WhiteStainedGlassPane; + mappings[427] = ItemType.WhiteTerracotta; + mappings[225] = ItemType.WhiteTulip; + mappings[202] = ItemType.WhiteWool; + mappings[1270] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1090] = ItemType.WindCharge; + mappings[1079] = ItemType.WitchSpawnEgg; + mappings[230] = ItemType.WitherRose; + mappings[1104] = ItemType.WitherSkeletonSkull; + mappings[1081] = ItemType.WitherSkeletonSpawnEgg; + mappings[1080] = ItemType.WitherSpawnEgg; + mappings[797] = ItemType.WolfArmor; + mappings[1082] = ItemType.WolfSpawnEgg; + mappings[820] = ItemType.WoodenAxe; + mappings[821] = ItemType.WoodenHoe; + mappings[819] = ItemType.WoodenPickaxe; + mappings[818] = ItemType.WoodenShovel; + mappings[817] = ItemType.WoodenSword; + mappings[1091] = ItemType.WritableBook; + mappings[1092] = ItemType.WrittenBook; + mappings[1137] = ItemType.YellowBanner; + mappings[968] = ItemType.YellowBed; + mappings[1243] = ItemType.YellowCandle; + mappings[450] = ItemType.YellowCarpet; + mappings[559] = ItemType.YellowConcrete; + mappings[575] = ItemType.YellowConcretePowder; + mappings[948] = ItemType.YellowDye; + mappings[543] = ItemType.YellowGlazedTerracotta; + mappings[527] = ItemType.YellowShulkerBox; + mappings[475] = ItemType.YellowStainedGlass; + mappings[491] = ItemType.YellowStainedGlassPane; + mappings[431] = ItemType.YellowTerracotta; + mappings[206] = ItemType.YellowWool; + mappings[1083] = ItemType.ZoglinSpawnEgg; + mappings[1106] = ItemType.ZombieHead; + mappings[1085] = ItemType.ZombieHorseSpawnEgg; + mappings[1084] = ItemType.ZombieSpawnEgg; + mappings[1086] = ItemType.ZombieVillagerSpawnEgg; + mappings[1087] = ItemType.ZombifiedPiglinSpawnEgg; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs index 0d8cc231..57f942d9 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs @@ -70,7 +70,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[1769472] = ItemType.PoweredRail; mappings[1835008] = ItemType.DetectorRail; mappings[1900544] = ItemType.StickyPiston; - mappings[2031617] = ItemType.Grass; + mappings[2031617] = ItemType.ShortGrass; mappings[2031618] = ItemType.Fern; mappings[2097152] = ItemType.DeadBush; mappings[2162688] = ItemType.Piston; diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs index 332ff5b7..c4251f62 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs @@ -66,7 +66,7 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[1769472] = ItemType.PoweredRail; mappings[1835008] = ItemType.DetectorRail; mappings[1900544] = ItemType.StickyPiston; - mappings[2031617] = ItemType.Grass; + mappings[2031617] = ItemType.ShortGrass; mappings[2031618] = ItemType.Fern; mappings[2097152] = ItemType.DeadBush; mappings[2293760] = ItemType.WhiteWool; diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 175ebcef..bfe150d1 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -47,6 +47,8 @@ Anvil, Apple, ArcherPotterySherd, + ArmadilloScute, + ArmadilloSpawnEgg, ArmorStand, ArmsUpPotterySherd, Arrow, @@ -143,6 +145,8 @@ BlueStainedGlassPane, BlueTerracotta, BlueWool, + BoggedSpawnEgg, + BoltArmorTrimSmithingTemplate, Bone, BoneBlock, BoneMeal, @@ -154,6 +158,7 @@ BrainCoralBlock, BrainCoralFan, Bread, + BreezeRod, BreezeSpawnEgg, BrewerPotterySherd, BrewingStand, @@ -478,6 +483,9 @@ FletchingTable, Flint, FlintAndSteel, + FlowArmorTrimSmithingTemplate, + FlowBannerPattern, + FlowPotterySherd, FlowerBannerPattern, FlowerPot, FloweringAzalea, @@ -525,7 +533,6 @@ GraniteSlab, GraniteStairs, GraniteWall, - Grass, // 1.20.3+ renamed to ShortGrass GrassBlock, Gravel, GrayBanner, @@ -557,11 +564,14 @@ Grindstone, GuardianSpawnEgg, Gunpowder, + GusterBannerPattern, + GusterPotterySherd, HangingRoots, HayBlock, HeartOfTheSea, HeartPotterySherd, HeartbreakPotterySherd, + HeavyCore, HeavyWeightedPressurePlate, HoglinSpawnEgg, HoneyBlock, @@ -693,6 +703,7 @@ LlamaSpawnEgg, Lodestone, Loom, + Mace, MagentaBanner, MagentaBed, MagentaCandle, @@ -825,6 +836,8 @@ Obsidian, OcelotSpawnEgg, OchreFroglight, + OminousBottle, + OminousTrialKey, OrangeBanner, OrangeBed, OrangeCandle, @@ -1027,12 +1040,12 @@ SandstoneStairs, SandstoneWall, Scaffolding, + ScrapePotterySherd, Sculk, SculkCatalyst, SculkSensor, SculkShrieker, SculkVein, - Scute, SeaLantern, SeaPickle, Seagrass, @@ -1200,8 +1213,10 @@ TuffWall, TurtleEgg, TurtleHelmet, + TurtleScute, TurtleSpawnEgg, TwistingVines, + Vault, VerdantFroglight, VexArmorTrimSmithingTemplate, VexSpawnEgg, @@ -1295,11 +1310,13 @@ WhiteTulip, WhiteWool, WildArmorTrimSmithingTemplate, + WindCharge, WitchSpawnEgg, WitherRose, WitherSkeletonSkull, WitherSkeletonSpawnEgg, WitherSpawnEgg, + WolfArmor, WolfSpawnEgg, WoodenAxe, WoodenHoe, diff --git a/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs b/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs index 18691621..f6a36358 100644 --- a/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs +++ b/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs @@ -641,7 +641,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[i] = Material.GraniteStairs; for (int i = 15315; i <= 15638; i++) materials[i] = Material.GraniteWall; - materials[2005] = Material.Grass; + materials[2005] = Material.ShortGrass; for (int i = 8; i <= 9; i++) materials[i] = Material.GrassBlock; materials[118] = Material.Gravel; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette112.cs b/MinecraftClient/Mapping/BlockPalettes/Palette112.cs index 023d1c05..cdfd4a53 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette112.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette112.cs @@ -43,7 +43,7 @@ namespace MinecraftClient.Mapping.BlockPalettes { 28, Material.DetectorRail }, { 29, Material.StickyPiston }, // PistonStickyBase { 30, Material.Cobweb }, // Web - { 31, Material.Grass }, // LongGrass + { 31, Material.TallGrass }, // LongGrass { 32, Material.DeadBush }, { 33, Material.Piston }, // PistonBase { 34, Material.PistonHead }, // PistonExtension diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs index 847728bd..239df049 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs @@ -167,7 +167,7 @@ namespace MinecraftClient.Mapping.BlockPalettes for (int i = 1028; i <= 1039; i++) materials[i] = Material.StickyPiston; materials[1040] = Material.Cobweb; - materials[1041] = Material.Grass; + materials[1041] = Material.ShortGrass; materials[1042] = Material.Fern; materials[1043] = Material.DeadBush; materials[1044] = Material.Seagrass; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs index 97c12231..4e51ffea 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs @@ -167,7 +167,7 @@ namespace MinecraftClient.Mapping.BlockPalettes for (int i = 1328; i <= 1339; i++) materials[i] = Material.StickyPiston; materials[1340] = Material.Cobweb; - materials[1341] = Material.Grass; + materials[1341] = Material.ShortGrass; materials[1342] = Material.Fern; materials[1343] = Material.DeadBush; materials[1344] = Material.Seagrass; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs index aabe901b..449b95be 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs @@ -167,7 +167,7 @@ namespace MinecraftClient.Mapping.BlockPalettes for (int i = 1328; i <= 1339; i++) materials[i] = Material.StickyPiston; materials[1340] = Material.Cobweb; - materials[1341] = Material.Grass; + materials[1341] = Material.ShortGrass; materials[1342] = Material.Fern; materials[1343] = Material.DeadBush; materials[1344] = Material.Seagrass; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs index abc31d57..8927218f 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs @@ -164,7 +164,7 @@ namespace MinecraftClient.Mapping.BlockPalettes for (int i = 1329; i <= 1340; i++) materials[i] = Material.StickyPiston; materials[1341] = Material.Cobweb; - materials[1342] = Material.Grass; + materials[1342] = Material.ShortGrass; materials[1343] = Material.Fern; materials[1344] = Material.DeadBush; materials[1345] = Material.Seagrass; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs index 34cccd75..154c62cc 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs @@ -172,7 +172,7 @@ namespace MinecraftClient.Mapping.BlockPalettes for (int i = 1385; i <= 1396; i++) materials[i] = Material.StickyPiston; materials[1397] = Material.Cobweb; - materials[1398] = Material.Grass; + materials[1398] = Material.ShortGrass; materials[1399] = Material.Fern; materials[1400] = Material.DeadBush; materials[1401] = Material.Seagrass; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs index d8e9d760..548df06f 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs @@ -554,7 +554,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[i] = Material.GraniteStairs; for (int i = 13044; i <= 13367; i++) materials[i] = Material.GraniteWall; - materials[1596] = Material.Grass; + materials[1596] = Material.ShortGrass; for (int i = 8; i <= 9; i++) materials[i] = Material.GrassBlock; materials[109] = Material.Gravel; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs index eb1e61fb..cb15a64f 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs @@ -604,7 +604,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[i] = Material.GraniteStairs; for (int i = 14828; i <= 15151; i++) materials[i] = Material.GraniteWall; - materials[1954] = Material.Grass; + materials[1954] = Material.ShortGrass; for (int i = 8; i <= 9; i++) materials[i] = Material.GrassBlock; materials[111] = Material.Gravel; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs index 83c7ff29..c5a45ef4 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs @@ -639,7 +639,7 @@ namespace MinecraftClient.Mapping.BlockPalettes materials[i] = Material.GraniteStairs; for (int i = 15297; i <= 15620; i++) materials[i] = Material.GraniteWall; - materials[2001] = Material.Grass; + materials[2001] = Material.ShortGrass; for (int i = 8; i <= 9; i++) materials[i] = Material.GrassBlock; materials[118] = Material.Gravel; diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1206.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1206.cs new file mode 100644 index 00000000..070d6dbb --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1206.cs @@ -0,0 +1,1766 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1206 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1206() + { + for (int i = 8707; i <= 8730; i++) + materials[i] = Material.AcaciaButton; + for (int i = 12014; i <= 12077; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 11662; i <= 11693; i++) + materials[i] = Material.AcaciaFence; + for (int i = 11406; i <= 11437; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5026; i <= 5089; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 349; i <= 376; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 5724; i <= 5725; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 4398; i <= 4429; i++) + materials[i] = Material.AcaciaSign; + for (int i = 11186; i <= 11191; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 9884; i <= 9963; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 6217; i <= 6280; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 5562; i <= 5569; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 4786; i <= 4793; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.AcaciaWood; + for (int i = 9320; i <= 9343; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2079] = Material.Allium; + materials[21031] = Material.AmethystBlock; + for (int i = 21033; i <= 21044; i++) + materials[i] = Material.AmethystCluster; + materials[19448] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 14136; i <= 14141; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 13762; i <= 13841; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 16752; i <= 17075; i++) + materials[i] = Material.AndesiteWall; + for (int i = 9107; i <= 9110; i++) + materials[i] = Material.Anvil; + for (int i = 6817; i <= 6820; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 6813; i <= 6816; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[24824] = Material.Azalea; + for (int i = 461; i <= 488; i++) + materials[i] = Material.AzaleaLeaves; + materials[2080] = Material.AzureBluet; + for (int i = 12945; i <= 12956; i++) + materials[i] = Material.Bamboo; + for (int i = 159; i <= 161; i++) + materials[i] = Material.BambooBlock; + for (int i = 8803; i <= 8826; i++) + materials[i] = Material.BambooButton; + for (int i = 12270; i <= 12333; i++) + materials[i] = Material.BambooDoor; + for (int i = 11790; i <= 11821; i++) + materials[i] = Material.BambooFence; + for (int i = 11534; i <= 11565; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 5474; i <= 5537; i++) + materials[i] = Material.BambooHangingSign; + materials[24] = Material.BambooMosaic; + for (int i = 11216; i <= 11221; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 10284; i <= 10363; i++) + materials[i] = Material.BambooMosaicStairs; + materials[23] = Material.BambooPlanks; + for (int i = 5732; i <= 5733; i++) + materials[i] = Material.BambooPressurePlate; + materials[12944] = Material.BambooSapling; + for (int i = 4558; i <= 4589; i++) + materials[i] = Material.BambooSign; + for (int i = 11210; i <= 11215; i++) + materials[i] = Material.BambooSlab; + for (int i = 10204; i <= 10283; i++) + materials[i] = Material.BambooStairs; + for (int i = 6473; i <= 6536; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 5618; i <= 5625; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 4826; i <= 4833; i++) + materials[i] = Material.BambooWallSign; + for (int i = 18408; i <= 18419; i++) + materials[i] = Material.Barrel; + for (int i = 10365; i <= 10366; i++) + materials[i] = Material.Barrier; + for (int i = 5852; i <= 5854; i++) + materials[i] = Material.Basalt; + materials[7918] = Material.Beacon; + materials[79] = Material.Bedrock; + for (int i = 19397; i <= 19420; i++) + materials[i] = Material.BeeNest; + for (int i = 19421; i <= 19444; i++) + materials[i] = Material.Beehive; + for (int i = 12509; i <= 12512; i++) + materials[i] = Material.Beetroots; + for (int i = 18471; i <= 18502; i++) + materials[i] = Material.Bell; + for (int i = 24844; i <= 24875; i++) + materials[i] = Material.BigDripleaf; + for (int i = 24876; i <= 24883; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 8659; i <= 8682; i++) + materials[i] = Material.BirchButton; + for (int i = 11886; i <= 11949; i++) + materials[i] = Material.BirchDoor; + for (int i = 11598; i <= 11629; i++) + materials[i] = Material.BirchFence; + for (int i = 11342; i <= 11373; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 4962; i <= 5025; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 293; i <= 320; i++) + materials[i] = Material.BirchLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 5720; i <= 5721; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.BirchSapling; + for (int i = 4366; i <= 4397; i++) + materials[i] = Material.BirchSign; + for (int i = 11174; i <= 11179; i++) + materials[i] = Material.BirchSlab; + for (int i = 7746; i <= 7825; i++) + materials[i] = Material.BirchStairs; + for (int i = 6089; i <= 6152; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 5554; i <= 5561; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 4778; i <= 4785; i++) + materials[i] = Material.BirchWallSign; + for (int i = 195; i <= 197; i++) + materials[i] = Material.BirchWood; + for (int i = 10999; i <= 11014; i++) + materials[i] = Material.BlackBanner; + for (int i = 1928; i <= 1943; i++) + materials[i] = Material.BlackBed; + for (int i = 20981; i <= 20996; i++) + materials[i] = Material.BlackCandle; + for (int i = 21029; i <= 21030; i++) + materials[i] = Material.BlackCandleCake; + materials[10743] = Material.BlackCarpet; + materials[12743] = Material.BlackConcrete; + materials[12759] = Material.BlackConcretePowder; + for (int i = 12724; i <= 12727; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 12658; i <= 12663; i++) + materials[i] = Material.BlackShulkerBox; + materials[5960] = Material.BlackStainedGlass; + for (int i = 9852; i <= 9883; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[9371] = Material.BlackTerracotta; + for (int i = 11075; i <= 11078; i++) + materials[i] = Material.BlackWallBanner; + materials[2062] = Material.BlackWool; + materials[19460] = Material.Blackstone; + for (int i = 19865; i <= 19870; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 19461; i <= 19540; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 19541; i <= 19864; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 18428; i <= 18435; i++) + materials[i] = Material.BlastFurnace; + for (int i = 10935; i <= 10950; i++) + materials[i] = Material.BlueBanner; + for (int i = 1864; i <= 1879; i++) + materials[i] = Material.BlueBed; + for (int i = 20917; i <= 20932; i++) + materials[i] = Material.BlueCandle; + for (int i = 21021; i <= 21022; i++) + materials[i] = Material.BlueCandleCake; + materials[10739] = Material.BlueCarpet; + materials[12739] = Material.BlueConcrete; + materials[12755] = Material.BlueConcretePowder; + for (int i = 12708; i <= 12711; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[12941] = Material.BlueIce; + materials[2078] = Material.BlueOrchid; + for (int i = 12634; i <= 12639; i++) + materials[i] = Material.BlueShulkerBox; + materials[5956] = Material.BlueStainedGlass; + for (int i = 9724; i <= 9755; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[9367] = Material.BlueTerracotta; + for (int i = 11059; i <= 11062; i++) + materials[i] = Material.BlueWallBanner; + materials[2058] = Material.BlueWool; + for (int i = 12546; i <= 12548; i++) + materials[i] = Material.BoneBlock; + materials[2096] = Material.Bookshelf; + for (int i = 12825; i <= 12826; i++) + materials[i] = Material.BrainCoral; + materials[12809] = Material.BrainCoralBlock; + for (int i = 12845; i <= 12846; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 12901; i <= 12908; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 7390; i <= 7397; i++) + materials[i] = Material.BrewingStand; + for (int i = 11258; i <= 11263; i++) + materials[i] = Material.BrickSlab; + for (int i = 7029; i <= 7108; i++) + materials[i] = Material.BrickStairs; + for (int i = 14160; i <= 14483; i++) + materials[i] = Material.BrickWall; + materials[2093] = Material.Bricks; + for (int i = 10951; i <= 10966; i++) + materials[i] = Material.BrownBanner; + for (int i = 1880; i <= 1895; i++) + materials[i] = Material.BrownBed; + for (int i = 20933; i <= 20948; i++) + materials[i] = Material.BrownCandle; + for (int i = 21023; i <= 21024; i++) + materials[i] = Material.BrownCandleCake; + materials[10740] = Material.BrownCarpet; + materials[12740] = Material.BrownConcrete; + materials[12756] = Material.BrownConcretePowder; + for (int i = 12712; i <= 12715; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2089] = Material.BrownMushroom; + for (int i = 6549; i <= 6612; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 12640; i <= 12645; i++) + materials[i] = Material.BrownShulkerBox; + materials[5957] = Material.BrownStainedGlass; + for (int i = 9756; i <= 9787; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[9368] = Material.BrownTerracotta; + for (int i = 11063; i <= 11066; i++) + materials[i] = Material.BrownWallBanner; + materials[2059] = Material.BrownWool; + for (int i = 12960; i <= 12961; i++) + materials[i] = Material.BubbleColumn; + for (int i = 12827; i <= 12828; i++) + materials[i] = Material.BubbleCoral; + materials[12810] = Material.BubbleCoralBlock; + for (int i = 12847; i <= 12848; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 12909; i <= 12916; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[21032] = Material.BuddingAmethyst; + for (int i = 5782; i <= 5797; i++) + materials[i] = Material.Cactus; + for (int i = 5874; i <= 5880; i++) + materials[i] = Material.Cake; + materials[22316] = Material.Calcite; + for (int i = 22415; i <= 22798; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 18511; i <= 18542; i++) + materials[i] = Material.Campfire; + for (int i = 20725; i <= 20740; i++) + materials[i] = Material.Candle; + for (int i = 20997; i <= 20998; i++) + materials[i] = Material.CandleCake; + for (int i = 8595; i <= 8602; i++) + materials[i] = Material.Carrots; + materials[18436] = Material.CartographyTable; + for (int i = 5866; i <= 5869; i++) + materials[i] = Material.CarvedPumpkin; + materials[7398] = Material.Cauldron; + materials[12959] = Material.CaveAir; + for (int i = 24769; i <= 24820; i++) + materials[i] = Material.CaveVines; + for (int i = 24821; i <= 24822; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 6773; i <= 6778; i++) + materials[i] = Material.Chain; + for (int i = 12527; i <= 12538; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 8731; i <= 8754; i++) + materials[i] = Material.CherryButton; + for (int i = 12078; i <= 12141; i++) + materials[i] = Material.CherryDoor; + for (int i = 11694; i <= 11725; i++) + materials[i] = Material.CherryFence; + for (int i = 11438; i <= 11469; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5090; i <= 5153; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 377; i <= 404; i++) + materials[i] = Material.CherryLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 5726; i <= 5727; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.CherrySapling; + for (int i = 4430; i <= 4461; i++) + materials[i] = Material.CherrySign; + for (int i = 11192; i <= 11197; i++) + materials[i] = Material.CherrySlab; + for (int i = 9964; i <= 10043; i++) + materials[i] = Material.CherryStairs; + for (int i = 6281; i <= 6344; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 5570; i <= 5577; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 4794; i <= 4801; i++) + materials[i] = Material.CherryWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.CherryWood; + for (int i = 2954; i <= 2977; i++) + materials[i] = Material.Chest; + for (int i = 9111; i <= 9114; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2097; i <= 2352; i++) + materials[i] = Material.ChiseledBookshelf; + materials[22951] = Material.ChiseledCopper; + materials[26551] = Material.ChiseledDeepslate; + materials[20722] = Material.ChiseledNetherBricks; + materials[19874] = Material.ChiseledPolishedBlackstone; + materials[9236] = Material.ChiseledQuartzBlock; + materials[11080] = Material.ChiseledRedSandstone; + materials[536] = Material.ChiseledSandstone; + materials[6540] = Material.ChiseledStoneBricks; + materials[21903] = Material.ChiseledTuff; + materials[22315] = Material.ChiseledTuffBricks; + for (int i = 12404; i <= 12409; i++) + materials[i] = Material.ChorusFlower; + for (int i = 12340; i <= 12403; i++) + materials[i] = Material.ChorusPlant; + materials[5798] = Material.Clay; + materials[10745] = Material.CoalBlock; + materials[127] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[24907] = Material.CobbledDeepslate; + for (int i = 24988; i <= 24993; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 24908; i <= 24987; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 24994; i <= 25317; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 11252; i <= 11257; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 4682; i <= 4761; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 7919; i <= 8242; i++) + materials[i] = Material.CobblestoneWall; + materials[2004] = Material.Cobweb; + for (int i = 7419; i <= 7430; i++) + materials[i] = Material.Cocoa; + for (int i = 7906; i <= 7917; i++) + materials[i] = Material.CommandBlock; + for (int i = 9175; i <= 9190; i++) + materials[i] = Material.Comparator; + for (int i = 19372; i <= 19380; i++) + materials[i] = Material.Composter; + for (int i = 12942; i <= 12943; i++) + materials[i] = Material.Conduit; + materials[22938] = Material.CopperBlock; + for (int i = 24692; i <= 24695; i++) + materials[i] = Material.CopperBulb; + for (int i = 23652; i <= 23715; i++) + materials[i] = Material.CopperDoor; + for (int i = 24676; i <= 24677; i++) + materials[i] = Material.CopperGrate; + materials[22942] = Material.CopperOre; + for (int i = 24164; i <= 24227; i++) + materials[i] = Material.CopperTrapdoor; + materials[2086] = Material.Cornflower; + materials[26552] = Material.CrackedDeepslateBricks; + materials[26553] = Material.CrackedDeepslateTiles; + materials[20723] = Material.CrackedNetherBricks; + materials[19873] = Material.CrackedPolishedBlackstoneBricks; + materials[6539] = Material.CrackedStoneBricks; + for (int i = 26590; i <= 26637; i++) + materials[i] = Material.Crafter; + materials[4277] = Material.CraftingTable; + for (int i = 8987; i <= 9018; i++) + materials[i] = Material.CreeperHead; + for (int i = 9019; i <= 9026; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 19100; i <= 19123; i++) + materials[i] = Material.CrimsonButton; + for (int i = 19148; i <= 19211; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 18684; i <= 18715; i++) + materials[i] = Material.CrimsonFence; + for (int i = 18876; i <= 18907; i++) + materials[i] = Material.CrimsonFenceGate; + materials[18609] = Material.CrimsonFungus; + for (int i = 5282; i <= 5345; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 18602; i <= 18604; i++) + materials[i] = Material.CrimsonHyphae; + materials[18608] = Material.CrimsonNylium; + materials[18666] = Material.CrimsonPlanks; + for (int i = 18680; i <= 18681; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[18665] = Material.CrimsonRoots; + for (int i = 19276; i <= 19307; i++) + materials[i] = Material.CrimsonSign; + for (int i = 18668; i <= 18673; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 18940; i <= 19019; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 18596; i <= 18598; i++) + materials[i] = Material.CrimsonStem; + for (int i = 18748; i <= 18811; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 5602; i <= 5609; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 19340; i <= 19347; i++) + materials[i] = Material.CrimsonWallSign; + materials[19449] = Material.CryingObsidian; + materials[22947] = Material.CutCopper; + for (int i = 23294; i <= 23299; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 23196; i <= 23275; i++) + materials[i] = Material.CutCopperStairs; + materials[11081] = Material.CutRedSandstone; + for (int i = 11294; i <= 11299; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[537] = Material.CutSandstone; + for (int i = 11240; i <= 11245; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 10903; i <= 10918; i++) + materials[i] = Material.CyanBanner; + for (int i = 1832; i <= 1847; i++) + materials[i] = Material.CyanBed; + for (int i = 20885; i <= 20900; i++) + materials[i] = Material.CyanCandle; + for (int i = 21017; i <= 21018; i++) + materials[i] = Material.CyanCandleCake; + materials[10737] = Material.CyanCarpet; + materials[12737] = Material.CyanConcrete; + materials[12753] = Material.CyanConcretePowder; + for (int i = 12700; i <= 12703; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 12622; i <= 12627; i++) + materials[i] = Material.CyanShulkerBox; + materials[5954] = Material.CyanStainedGlass; + for (int i = 9660; i <= 9691; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[9365] = Material.CyanTerracotta; + for (int i = 11051; i <= 11054; i++) + materials[i] = Material.CyanWallBanner; + materials[2056] = Material.CyanWool; + for (int i = 9115; i <= 9118; i++) + materials[i] = Material.DamagedAnvil; + materials[2075] = Material.Dandelion; + for (int i = 8755; i <= 8778; i++) + materials[i] = Material.DarkOakButton; + for (int i = 12142; i <= 12205; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 11726; i <= 11757; i++) + materials[i] = Material.DarkOakFence; + for (int i = 11470; i <= 11501; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 5218; i <= 5281; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 405; i <= 432; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 5728; i <= 5729; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 4494; i <= 4525; i++) + materials[i] = Material.DarkOakSign; + for (int i = 11198; i <= 11203; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 10044; i <= 10123; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 6345; i <= 6408; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 5586; i <= 5593; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 4810; i <= 4817; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.DarkOakWood; + materials[10465] = Material.DarkPrismarine; + for (int i = 10718; i <= 10723; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 10626; i <= 10705; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 9191; i <= 9222; i++) + materials[i] = Material.DaylightDetector; + for (int i = 12815; i <= 12816; i++) + materials[i] = Material.DeadBrainCoral; + materials[12804] = Material.DeadBrainCoralBlock; + for (int i = 12835; i <= 12836; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 12861; i <= 12868; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 12817; i <= 12818; i++) + materials[i] = Material.DeadBubbleCoral; + materials[12805] = Material.DeadBubbleCoralBlock; + for (int i = 12837; i <= 12838; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 12869; i <= 12876; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2007] = Material.DeadBush; + for (int i = 12819; i <= 12820; i++) + materials[i] = Material.DeadFireCoral; + materials[12806] = Material.DeadFireCoralBlock; + for (int i = 12839; i <= 12840; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 12877; i <= 12884; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 12821; i <= 12822; i++) + materials[i] = Material.DeadHornCoral; + materials[12807] = Material.DeadHornCoralBlock; + for (int i = 12841; i <= 12842; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 12885; i <= 12892; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 12813; i <= 12814; i++) + materials[i] = Material.DeadTubeCoral; + materials[12803] = Material.DeadTubeCoralBlock; + for (int i = 12833; i <= 12834; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 12853; i <= 12860; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 26574; i <= 26589; i++) + materials[i] = Material.DecoratedPot; + for (int i = 24904; i <= 24906; i++) + materials[i] = Material.Deepslate; + for (int i = 26221; i <= 26226; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 26141; i <= 26220; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 26227; i <= 26550; i++) + materials[i] = Material.DeepslateBrickWall; + materials[26140] = Material.DeepslateBricks; + materials[128] = Material.DeepslateCoalOre; + materials[22943] = Material.DeepslateCopperOre; + materials[4275] = Material.DeepslateDiamondOre; + materials[7512] = Material.DeepslateEmeraldOre; + materials[124] = Material.DeepslateGoldOre; + materials[126] = Material.DeepslateIronOre; + materials[521] = Material.DeepslateLapisOre; + for (int i = 5736; i <= 5737; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 25810; i <= 25815; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 25730; i <= 25809; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 25816; i <= 26139; i++) + materials[i] = Material.DeepslateTileWall; + materials[25729] = Material.DeepslateTiles; + for (int i = 1968; i <= 1991; i++) + materials[i] = Material.DetectorRail; + materials[4276] = Material.DiamondBlock; + materials[4274] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 14154; i <= 14159; i++) + materials[i] = Material.DioriteSlab; + for (int i = 14002; i <= 14081; i++) + materials[i] = Material.DioriteStairs; + for (int i = 18048; i <= 18371; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[12513] = Material.DirtPath; + for (int i = 523; i <= 534; i++) + materials[i] = Material.Dispenser; + materials[7416] = Material.DragonEgg; + for (int i = 9027; i <= 9058; i++) + materials[i] = Material.DragonHead; + for (int i = 9059; i <= 9066; i++) + materials[i] = Material.DragonWallHead; + materials[12787] = Material.DriedKelpBlock; + materials[24768] = Material.DripstoneBlock; + for (int i = 9344; i <= 9355; i++) + materials[i] = Material.Dropper; + materials[7665] = Material.EmeraldBlock; + materials[7511] = Material.EmeraldOre; + materials[7389] = Material.EnchantingTable; + materials[12514] = Material.EndGateway; + materials[7406] = Material.EndPortal; + for (int i = 7407; i <= 7414; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 12334; i <= 12339; i++) + materials[i] = Material.EndRod; + materials[7415] = Material.EndStone; + for (int i = 14112; i <= 14117; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 13362; i <= 13441; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 17724; i <= 18047; i++) + materials[i] = Material.EndStoneBrickWall; + materials[12494] = Material.EndStoneBricks; + for (int i = 7513; i <= 7520; i++) + materials[i] = Material.EnderChest; + materials[22950] = Material.ExposedChiseledCopper; + materials[22939] = Material.ExposedCopper; + for (int i = 24696; i <= 24699; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 23716; i <= 23779; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 24678; i <= 24679; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 24228; i <= 24291; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[22946] = Material.ExposedCutCopper; + for (int i = 23288; i <= 23293; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 23116; i <= 23195; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 4286; i <= 4293; i++) + materials[i] = Material.Farmland; + materials[2006] = Material.Fern; + for (int i = 2360; i <= 2871; i++) + materials[i] = Material.Fire; + for (int i = 12829; i <= 12830; i++) + materials[i] = Material.FireCoral; + materials[12811] = Material.FireCoralBlock; + for (int i = 12849; i <= 12850; i++) + materials[i] = Material.FireCoralFan; + for (int i = 12917; i <= 12924; i++) + materials[i] = Material.FireCoralWallFan; + materials[18437] = Material.FletchingTable; + materials[8567] = Material.FlowerPot; + materials[24825] = Material.FloweringAzalea; + for (int i = 489; i <= 516; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[26572] = Material.Frogspawn; + for (int i = 12539; i <= 12542; i++) + materials[i] = Material.FrostedIce; + for (int i = 4294; i <= 4301; i++) + materials[i] = Material.Furnace; + materials[20285] = Material.GildedBlackstone; + materials[519] = Material.Glass; + for (int i = 6779; i <= 6810; i++) + materials[i] = Material.GlassPane; + for (int i = 6869; i <= 6996; i++) + materials[i] = Material.GlowLichen; + materials[5863] = Material.Glowstone; + materials[2091] = Material.GoldBlock; + materials[123] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 14130; i <= 14135; i++) + materials[i] = Material.GraniteSlab; + for (int i = 13682; i <= 13761; i++) + materials[i] = Material.GraniteStairs; + for (int i = 15456; i <= 15779; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[118] = Material.Gravel; + for (int i = 10871; i <= 10886; i++) + materials[i] = Material.GrayBanner; + for (int i = 1800; i <= 1815; i++) + materials[i] = Material.GrayBed; + for (int i = 20853; i <= 20868; i++) + materials[i] = Material.GrayCandle; + for (int i = 21013; i <= 21014; i++) + materials[i] = Material.GrayCandleCake; + materials[10735] = Material.GrayCarpet; + materials[12735] = Material.GrayConcrete; + materials[12751] = Material.GrayConcretePowder; + for (int i = 12692; i <= 12695; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 12610; i <= 12615; i++) + materials[i] = Material.GrayShulkerBox; + materials[5952] = Material.GrayStainedGlass; + for (int i = 9596; i <= 9627; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[9363] = Material.GrayTerracotta; + for (int i = 11043; i <= 11046; i++) + materials[i] = Material.GrayWallBanner; + materials[2054] = Material.GrayWool; + for (int i = 10967; i <= 10982; i++) + materials[i] = Material.GreenBanner; + for (int i = 1896; i <= 1911; i++) + materials[i] = Material.GreenBed; + for (int i = 20949; i <= 20964; i++) + materials[i] = Material.GreenCandle; + for (int i = 21025; i <= 21026; i++) + materials[i] = Material.GreenCandleCake; + materials[10741] = Material.GreenCarpet; + materials[12741] = Material.GreenConcrete; + materials[12757] = Material.GreenConcretePowder; + for (int i = 12716; i <= 12719; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 12646; i <= 12651; i++) + materials[i] = Material.GreenShulkerBox; + materials[5958] = Material.GreenStainedGlass; + for (int i = 9788; i <= 9819; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[9369] = Material.GreenTerracotta; + for (int i = 11067; i <= 11070; i++) + materials[i] = Material.GreenWallBanner; + materials[2060] = Material.GreenWool; + for (int i = 18438; i <= 18449; i++) + materials[i] = Material.Grindstone; + for (int i = 24900; i <= 24901; i++) + materials[i] = Material.HangingRoots; + for (int i = 10725; i <= 10727; i++) + materials[i] = Material.HayBlock; + for (int i = 26682; i <= 26683; i++) + materials[i] = Material.HeavyCore; + for (int i = 9159; i <= 9174; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[19445] = Material.HoneyBlock; + materials[19446] = Material.HoneycombBlock; + for (int i = 9225; i <= 9234; i++) + materials[i] = Material.Hopper; + for (int i = 12831; i <= 12832; i++) + materials[i] = Material.HornCoral; + materials[12812] = Material.HornCoralBlock; + for (int i = 12851; i <= 12852; i++) + materials[i] = Material.HornCoralFan; + for (int i = 12925; i <= 12932; i++) + materials[i] = Material.HornCoralWallFan; + materials[5780] = Material.Ice; + materials[6548] = Material.InfestedChiseledStoneBricks; + materials[6544] = Material.InfestedCobblestone; + materials[6547] = Material.InfestedCrackedStoneBricks; + for (int i = 26554; i <= 26556; i++) + materials[i] = Material.InfestedDeepslate; + materials[6546] = Material.InfestedMossyStoneBricks; + materials[6543] = Material.InfestedStone; + materials[6545] = Material.InfestedStoneBricks; + for (int i = 6741; i <= 6772; i++) + materials[i] = Material.IronBars; + materials[2092] = Material.IronBlock; + for (int i = 5652; i <= 5715; i++) + materials[i] = Material.IronDoor; + materials[125] = Material.IronOre; + for (int i = 10399; i <= 10462; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 5870; i <= 5873; i++) + materials[i] = Material.JackOLantern; + for (int i = 19360; i <= 19371; i++) + materials[i] = Material.Jigsaw; + for (int i = 5815; i <= 5816; i++) + materials[i] = Material.Jukebox; + for (int i = 8683; i <= 8706; i++) + materials[i] = Material.JungleButton; + for (int i = 11950; i <= 12013; i++) + materials[i] = Material.JungleDoor; + for (int i = 11630; i <= 11661; i++) + materials[i] = Material.JungleFence; + for (int i = 11374; i <= 11405; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 5154; i <= 5217; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 321; i <= 348; i++) + materials[i] = Material.JungleLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 5722; i <= 5723; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.JungleSapling; + for (int i = 4462; i <= 4493; i++) + materials[i] = Material.JungleSign; + for (int i = 11180; i <= 11185; i++) + materials[i] = Material.JungleSlab; + for (int i = 7826; i <= 7905; i++) + materials[i] = Material.JungleStairs; + for (int i = 6153; i <= 6216; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 5578; i <= 5585; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 4802; i <= 4809; i++) + materials[i] = Material.JungleWallSign; + for (int i = 198; i <= 200; i++) + materials[i] = Material.JungleWood; + for (int i = 12760; i <= 12785; i++) + materials[i] = Material.Kelp; + materials[12786] = Material.KelpPlant; + for (int i = 4654; i <= 4661; i++) + materials[i] = Material.Ladder; + for (int i = 18503; i <= 18506; i++) + materials[i] = Material.Lantern; + materials[522] = Material.LapisBlock; + materials[520] = Material.LapisOre; + for (int i = 21045; i <= 21056; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 10757; i <= 10758; i++) + materials[i] = Material.LargeFern; + for (int i = 96; i <= 111; i++) + materials[i] = Material.Lava; + materials[7402] = Material.LavaCauldron; + for (int i = 18450; i <= 18465; i++) + materials[i] = Material.Lectern; + for (int i = 5626; i <= 5649; i++) + materials[i] = Material.Lever; + for (int i = 10367; i <= 10398; i++) + materials[i] = Material.Light; + for (int i = 10807; i <= 10822; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1736; i <= 1751; i++) + materials[i] = Material.LightBlueBed; + for (int i = 20789; i <= 20804; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 21005; i <= 21006; i++) + materials[i] = Material.LightBlueCandleCake; + materials[10731] = Material.LightBlueCarpet; + materials[12731] = Material.LightBlueConcrete; + materials[12747] = Material.LightBlueConcretePowder; + for (int i = 12676; i <= 12679; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 12586; i <= 12591; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[5948] = Material.LightBlueStainedGlass; + for (int i = 9468; i <= 9499; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[9359] = Material.LightBlueTerracotta; + for (int i = 11027; i <= 11030; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2050] = Material.LightBlueWool; + for (int i = 10887; i <= 10902; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1816; i <= 1831; i++) + materials[i] = Material.LightGrayBed; + for (int i = 20869; i <= 20884; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 21015; i <= 21016; i++) + materials[i] = Material.LightGrayCandleCake; + materials[10736] = Material.LightGrayCarpet; + materials[12736] = Material.LightGrayConcrete; + materials[12752] = Material.LightGrayConcretePowder; + for (int i = 12696; i <= 12699; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 12616; i <= 12621; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[5953] = Material.LightGrayStainedGlass; + for (int i = 9628; i <= 9659; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[9364] = Material.LightGrayTerracotta; + for (int i = 11047; i <= 11050; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2055] = Material.LightGrayWool; + for (int i = 9143; i <= 9158; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 24724; i <= 24747; i++) + materials[i] = Material.LightningRod; + for (int i = 10749; i <= 10750; i++) + materials[i] = Material.Lilac; + materials[2088] = Material.LilyOfTheValley; + materials[7271] = Material.LilyPad; + for (int i = 10839; i <= 10854; i++) + materials[i] = Material.LimeBanner; + for (int i = 1768; i <= 1783; i++) + materials[i] = Material.LimeBed; + for (int i = 20821; i <= 20836; i++) + materials[i] = Material.LimeCandle; + for (int i = 21009; i <= 21010; i++) + materials[i] = Material.LimeCandleCake; + materials[10733] = Material.LimeCarpet; + materials[12733] = Material.LimeConcrete; + materials[12749] = Material.LimeConcretePowder; + for (int i = 12684; i <= 12687; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 12598; i <= 12603; i++) + materials[i] = Material.LimeShulkerBox; + materials[5950] = Material.LimeStainedGlass; + for (int i = 9532; i <= 9563; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[9361] = Material.LimeTerracotta; + for (int i = 11035; i <= 11038; i++) + materials[i] = Material.LimeWallBanner; + materials[2052] = Material.LimeWool; + materials[19459] = Material.Lodestone; + for (int i = 18404; i <= 18407; i++) + materials[i] = Material.Loom; + for (int i = 10791; i <= 10806; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1720; i <= 1735; i++) + materials[i] = Material.MagentaBed; + for (int i = 20773; i <= 20788; i++) + materials[i] = Material.MagentaCandle; + for (int i = 21003; i <= 21004; i++) + materials[i] = Material.MagentaCandleCake; + materials[10730] = Material.MagentaCarpet; + materials[12730] = Material.MagentaConcrete; + materials[12746] = Material.MagentaConcretePowder; + for (int i = 12672; i <= 12675; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 12580; i <= 12585; i++) + materials[i] = Material.MagentaShulkerBox; + materials[5947] = Material.MagentaStainedGlass; + for (int i = 9436; i <= 9467; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[9358] = Material.MagentaTerracotta; + for (int i = 11023; i <= 11026; i++) + materials[i] = Material.MagentaWallBanner; + materials[2049] = Material.MagentaWool; + materials[12543] = Material.MagmaBlock; + for (int i = 8779; i <= 8802; i++) + materials[i] = Material.MangroveButton; + for (int i = 12206; i <= 12269; i++) + materials[i] = Material.MangroveDoor; + for (int i = 11758; i <= 11789; i++) + materials[i] = Material.MangroveFence; + for (int i = 11502; i <= 11533; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 5410; i <= 5473; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 433; i <= 460; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.MangroveLog; + materials[22] = Material.MangrovePlanks; + for (int i = 5730; i <= 5731; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 39; i <= 78; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 154; i <= 155; i++) + materials[i] = Material.MangroveRoots; + for (int i = 4526; i <= 4557; i++) + materials[i] = Material.MangroveSign; + for (int i = 11204; i <= 11209; i++) + materials[i] = Material.MangroveSlab; + for (int i = 10124; i <= 10203; i++) + materials[i] = Material.MangroveStairs; + for (int i = 6409; i <= 6472; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 5594; i <= 5601; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 4818; i <= 4825; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.MangroveWood; + for (int i = 21057; i <= 21068; i++) + materials[i] = Material.MediumAmethystBud; + materials[6812] = Material.Melon; + for (int i = 6829; i <= 6836; i++) + materials[i] = Material.MelonStem; + materials[24843] = Material.MossBlock; + materials[24826] = Material.MossCarpet; + materials[2353] = Material.MossyCobblestone; + for (int i = 14106; i <= 14111; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 13282; i <= 13361; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 8243; i <= 8566; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 14094; i <= 14099; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 13122; i <= 13201; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 15132; i <= 15455; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[6538] = Material.MossyStoneBricks; + for (int i = 2063; i <= 2074; i++) + materials[i] = Material.MovingPiston; + materials[24903] = Material.Mud; + for (int i = 11270; i <= 11275; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 7189; i <= 7268; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 16104; i <= 16427; i++) + materials[i] = Material.MudBrickWall; + materials[6542] = Material.MudBricks; + for (int i = 156; i <= 158; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 6677; i <= 6740; i++) + materials[i] = Material.MushroomStem; + for (int i = 7269; i <= 7270; i++) + materials[i] = Material.Mycelium; + for (int i = 7273; i <= 7304; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 11276; i <= 11281; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 7305; i <= 7384; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 16428; i <= 16751; i++) + materials[i] = Material.NetherBrickWall; + materials[7272] = Material.NetherBricks; + materials[129] = Material.NetherGoldOre; + for (int i = 5864; i <= 5865; i++) + materials[i] = Material.NetherPortal; + materials[9224] = Material.NetherQuartzOre; + materials[18595] = Material.NetherSprouts; + for (int i = 7385; i <= 7388; i++) + materials[i] = Material.NetherWart; + materials[12544] = Material.NetherWartBlock; + materials[19447] = Material.NetheriteBlock; + materials[5849] = Material.Netherrack; + for (int i = 538; i <= 1687; i++) + materials[i] = Material.NoteBlock; + for (int i = 8611; i <= 8634; i++) + materials[i] = Material.OakButton; + for (int i = 4590; i <= 4653; i++) + materials[i] = Material.OakDoor; + for (int i = 5817; i <= 5848; i++) + materials[i] = Material.OakFence; + for (int i = 6997; i <= 7028; i++) + materials[i] = Material.OakFenceGate; + for (int i = 4834; i <= 4897; i++) + materials[i] = Material.OakHangingSign; + for (int i = 237; i <= 264; i++) + materials[i] = Material.OakLeaves; + for (int i = 130; i <= 132; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 5716; i <= 5717; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 25; i <= 26; i++) + materials[i] = Material.OakSapling; + for (int i = 4302; i <= 4333; i++) + materials[i] = Material.OakSign; + for (int i = 11162; i <= 11167; i++) + materials[i] = Material.OakSlab; + for (int i = 2874; i <= 2953; i++) + materials[i] = Material.OakStairs; + for (int i = 5961; i <= 6024; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 5538; i <= 5545; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 4762; i <= 4769; i++) + materials[i] = Material.OakWallSign; + for (int i = 189; i <= 191; i++) + materials[i] = Material.OakWood; + for (int i = 12550; i <= 12561; i++) + materials[i] = Material.Observer; + materials[2354] = Material.Obsidian; + for (int i = 26563; i <= 26565; i++) + materials[i] = Material.OchreFroglight; + for (int i = 10775; i <= 10790; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1704; i <= 1719; i++) + materials[i] = Material.OrangeBed; + for (int i = 20757; i <= 20772; i++) + materials[i] = Material.OrangeCandle; + for (int i = 21001; i <= 21002; i++) + materials[i] = Material.OrangeCandleCake; + materials[10729] = Material.OrangeCarpet; + materials[12729] = Material.OrangeConcrete; + materials[12745] = Material.OrangeConcretePowder; + for (int i = 12668; i <= 12671; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 12574; i <= 12579; i++) + materials[i] = Material.OrangeShulkerBox; + materials[5946] = Material.OrangeStainedGlass; + for (int i = 9404; i <= 9435; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[9357] = Material.OrangeTerracotta; + materials[2082] = Material.OrangeTulip; + for (int i = 11019; i <= 11022; i++) + materials[i] = Material.OrangeWallBanner; + materials[2048] = Material.OrangeWool; + materials[2085] = Material.OxeyeDaisy; + materials[22948] = Material.OxidizedChiseledCopper; + materials[22941] = Material.OxidizedCopper; + for (int i = 24704; i <= 24707; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 23780; i <= 23843; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 24682; i <= 24683; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 24292; i <= 24355; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[22944] = Material.OxidizedCutCopper; + for (int i = 23276; i <= 23281; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 22956; i <= 23035; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[10746] = Material.PackedIce; + materials[6541] = Material.PackedMud; + for (int i = 26569; i <= 26571; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 10753; i <= 10754; i++) + materials[i] = Material.Peony; + for (int i = 11246; i <= 11251; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 9067; i <= 9098; i++) + materials[i] = Material.PiglinHead; + for (int i = 9099; i <= 9106; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 10855; i <= 10870; i++) + materials[i] = Material.PinkBanner; + for (int i = 1784; i <= 1799; i++) + materials[i] = Material.PinkBed; + for (int i = 20837; i <= 20852; i++) + materials[i] = Material.PinkCandle; + for (int i = 21011; i <= 21012; i++) + materials[i] = Material.PinkCandleCake; + materials[10734] = Material.PinkCarpet; + materials[12734] = Material.PinkConcrete; + materials[12750] = Material.PinkConcretePowder; + for (int i = 12688; i <= 12691; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 24827; i <= 24842; i++) + materials[i] = Material.PinkPetals; + for (int i = 12604; i <= 12609; i++) + materials[i] = Material.PinkShulkerBox; + materials[5951] = Material.PinkStainedGlass; + for (int i = 9564; i <= 9595; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[9362] = Material.PinkTerracotta; + materials[2084] = Material.PinkTulip; + for (int i = 11039; i <= 11042; i++) + materials[i] = Material.PinkWallBanner; + materials[2053] = Material.PinkWool; + for (int i = 2011; i <= 2022; i++) + materials[i] = Material.Piston; + for (int i = 2023; i <= 2046; i++) + materials[i] = Material.PistonHead; + for (int i = 12497; i <= 12506; i++) + materials[i] = Material.PitcherCrop; + for (int i = 12507; i <= 12508; i++) + materials[i] = Material.PitcherPlant; + for (int i = 8947; i <= 8978; i++) + materials[i] = Material.PlayerHead; + for (int i = 8979; i <= 8986; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 24748; i <= 24767; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 14148; i <= 14153; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 13922; i <= 14001; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 5855; i <= 5857; i++) + materials[i] = Material.PolishedBasalt; + materials[19871] = Material.PolishedBlackstone; + for (int i = 19875; i <= 19880; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 19881; i <= 19960; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 19961; i <= 20284; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[19872] = Material.PolishedBlackstoneBricks; + for (int i = 20374; i <= 20397; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 20372; i <= 20373; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 20366; i <= 20371; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 20286; i <= 20365; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 20398; i <= 20721; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[25318] = Material.PolishedDeepslate; + for (int i = 25399; i <= 25404; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 25319; i <= 25398; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 25405; i <= 25728; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 14100; i <= 14105; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 13202; i <= 13281; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 14082; i <= 14087; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 12962; i <= 13041; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[21492] = Material.PolishedTuff; + for (int i = 21493; i <= 21498; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 21499; i <= 21578; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 21579; i <= 21902; i++) + materials[i] = Material.PolishedTuffWall; + materials[2077] = Material.Poppy; + for (int i = 8603; i <= 8610; i++) + materials[i] = Material.Potatoes; + materials[8573] = Material.PottedAcaciaSapling; + materials[8581] = Material.PottedAllium; + materials[26561] = Material.PottedAzaleaBush; + materials[8582] = Material.PottedAzureBluet; + materials[12957] = Material.PottedBamboo; + materials[8571] = Material.PottedBirchSapling; + materials[8580] = Material.PottedBlueOrchid; + materials[8592] = Material.PottedBrownMushroom; + materials[8594] = Material.PottedCactus; + materials[8574] = Material.PottedCherrySapling; + materials[8588] = Material.PottedCornflower; + materials[19455] = Material.PottedCrimsonFungus; + materials[19457] = Material.PottedCrimsonRoots; + materials[8578] = Material.PottedDandelion; + materials[8575] = Material.PottedDarkOakSapling; + materials[8593] = Material.PottedDeadBush; + materials[8577] = Material.PottedFern; + materials[26562] = Material.PottedFloweringAzaleaBush; + materials[8572] = Material.PottedJungleSapling; + materials[8589] = Material.PottedLilyOfTheValley; + materials[8576] = Material.PottedMangrovePropagule; + materials[8569] = Material.PottedOakSapling; + materials[8584] = Material.PottedOrangeTulip; + materials[8587] = Material.PottedOxeyeDaisy; + materials[8586] = Material.PottedPinkTulip; + materials[8579] = Material.PottedPoppy; + materials[8591] = Material.PottedRedMushroom; + materials[8583] = Material.PottedRedTulip; + materials[8570] = Material.PottedSpruceSapling; + materials[8568] = Material.PottedTorchflower; + materials[19456] = Material.PottedWarpedFungus; + materials[19458] = Material.PottedWarpedRoots; + materials[8585] = Material.PottedWhiteTulip; + materials[8590] = Material.PottedWitherRose; + materials[22318] = Material.PowderSnow; + for (int i = 7403; i <= 7405; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1944; i <= 1967; i++) + materials[i] = Material.PoweredRail; + materials[10463] = Material.Prismarine; + for (int i = 10712; i <= 10717; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 10546; i <= 10625; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[10464] = Material.PrismarineBricks; + for (int i = 10706; i <= 10711; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 10466; i <= 10545; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 14484; i <= 14807; i++) + materials[i] = Material.PrismarineWall; + materials[6811] = Material.Pumpkin; + for (int i = 6821; i <= 6828; i++) + materials[i] = Material.PumpkinStem; + for (int i = 10919; i <= 10934; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1848; i <= 1863; i++) + materials[i] = Material.PurpleBed; + for (int i = 20901; i <= 20916; i++) + materials[i] = Material.PurpleCandle; + for (int i = 21019; i <= 21020; i++) + materials[i] = Material.PurpleCandleCake; + materials[10738] = Material.PurpleCarpet; + materials[12738] = Material.PurpleConcrete; + materials[12754] = Material.PurpleConcretePowder; + for (int i = 12704; i <= 12707; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 12628; i <= 12633; i++) + materials[i] = Material.PurpleShulkerBox; + materials[5955] = Material.PurpleStainedGlass; + for (int i = 9692; i <= 9723; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[9366] = Material.PurpleTerracotta; + for (int i = 11055; i <= 11058; i++) + materials[i] = Material.PurpleWallBanner; + materials[2057] = Material.PurpleWool; + materials[12410] = Material.PurpurBlock; + for (int i = 12411; i <= 12413; i++) + materials[i] = Material.PurpurPillar; + for (int i = 11300; i <= 11305; i++) + materials[i] = Material.PurpurSlab; + for (int i = 12414; i <= 12493; i++) + materials[i] = Material.PurpurStairs; + materials[9235] = Material.QuartzBlock; + materials[20724] = Material.QuartzBricks; + for (int i = 9237; i <= 9239; i++) + materials[i] = Material.QuartzPillar; + for (int i = 11282; i <= 11287; i++) + materials[i] = Material.QuartzSlab; + for (int i = 9240; i <= 9319; i++) + materials[i] = Material.QuartzStairs; + for (int i = 4662; i <= 4681; i++) + materials[i] = Material.Rail; + materials[26559] = Material.RawCopperBlock; + materials[26560] = Material.RawGoldBlock; + materials[26558] = Material.RawIronBlock; + for (int i = 10983; i <= 10998; i++) + materials[i] = Material.RedBanner; + for (int i = 1912; i <= 1927; i++) + materials[i] = Material.RedBed; + for (int i = 20965; i <= 20980; i++) + materials[i] = Material.RedCandle; + for (int i = 21027; i <= 21028; i++) + materials[i] = Material.RedCandleCake; + materials[10742] = Material.RedCarpet; + materials[12742] = Material.RedConcrete; + materials[12758] = Material.RedConcretePowder; + for (int i = 12720; i <= 12723; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2090] = Material.RedMushroom; + for (int i = 6613; i <= 6676; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 14142; i <= 14147; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 13842; i <= 13921; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 17076; i <= 17399; i++) + materials[i] = Material.RedNetherBrickWall; + materials[12545] = Material.RedNetherBricks; + materials[117] = Material.RedSand; + materials[11079] = Material.RedSandstone; + for (int i = 11288; i <= 11293; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 11082; i <= 11161; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 14808; i <= 15131; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 12652; i <= 12657; i++) + materials[i] = Material.RedShulkerBox; + materials[5959] = Material.RedStainedGlass; + for (int i = 9820; i <= 9851; i++) + materials[i] = Material.RedStainedGlassPane; + materials[9370] = Material.RedTerracotta; + materials[2081] = Material.RedTulip; + for (int i = 11071; i <= 11074; i++) + materials[i] = Material.RedWallBanner; + materials[2061] = Material.RedWool; + materials[9223] = Material.RedstoneBlock; + for (int i = 7417; i <= 7418; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 5734; i <= 5735; i++) + materials[i] = Material.RedstoneOre; + for (int i = 5738; i <= 5739; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 5740; i <= 5747; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 2978; i <= 4273; i++) + materials[i] = Material.RedstoneWire; + materials[26573] = Material.ReinforcedDeepslate; + for (int i = 5881; i <= 5944; i++) + materials[i] = Material.Repeater; + for (int i = 12515; i <= 12526; i++) + materials[i] = Material.RepeatingCommandBlock; + for (int i = 19450; i <= 19454; i++) + materials[i] = Material.RespawnAnchor; + materials[24902] = Material.RootedDirt; + for (int i = 10751; i <= 10752; i++) + materials[i] = Material.RoseBush; + materials[112] = Material.Sand; + materials[535] = Material.Sandstone; + for (int i = 11234; i <= 11239; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 7431; i <= 7510; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 17400; i <= 17723; i++) + materials[i] = Material.SandstoneWall; + for (int i = 18372; i <= 18403; i++) + materials[i] = Material.Scaffolding; + materials[22799] = Material.Sculk; + for (int i = 22928; i <= 22929; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 22319; i <= 22414; i++) + materials[i] = Material.SculkSensor; + for (int i = 22930; i <= 22937; i++) + materials[i] = Material.SculkShrieker; + for (int i = 22800; i <= 22927; i++) + materials[i] = Material.SculkVein; + materials[10724] = Material.SeaLantern; + for (int i = 12933; i <= 12940; i++) + materials[i] = Material.SeaPickle; + materials[2008] = Material.Seagrass; + materials[2005] = Material.ShortGrass; + materials[18610] = Material.Shroomlight; + for (int i = 12562; i <= 12567; i++) + materials[i] = Material.ShulkerBox; + for (int i = 8827; i <= 8858; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 8859; i <= 8866; i++) + materials[i] = Material.SkeletonWallSkull; + materials[10364] = Material.SlimeBlock; + for (int i = 21069; i <= 21080; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 24884; i <= 24899; i++) + materials[i] = Material.SmallDripleaf; + materials[18466] = Material.SmithingTable; + for (int i = 18420; i <= 18427; i++) + materials[i] = Material.Smoker; + materials[26557] = Material.SmoothBasalt; + materials[11308] = Material.SmoothQuartz; + for (int i = 14124; i <= 14129; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 13602; i <= 13681; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[11309] = Material.SmoothRedSandstone; + for (int i = 14088; i <= 14093; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 13042; i <= 13121; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[11307] = Material.SmoothSandstone; + for (int i = 14118; i <= 14123; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 13522; i <= 13601; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[11306] = Material.SmoothStone; + for (int i = 11228; i <= 11233; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 12800; i <= 12802; i++) + materials[i] = Material.SnifferEgg; + for (int i = 5772; i <= 5779; i++) + materials[i] = Material.Snow; + materials[5781] = Material.SnowBlock; + for (int i = 18543; i <= 18574; i++) + materials[i] = Material.SoulCampfire; + materials[2872] = Material.SoulFire; + for (int i = 18507; i <= 18510; i++) + materials[i] = Material.SoulLantern; + materials[5850] = Material.SoulSand; + materials[5851] = Material.SoulSoil; + materials[5858] = Material.SoulTorch; + for (int i = 5859; i <= 5862; i++) + materials[i] = Material.SoulWallTorch; + materials[2873] = Material.Spawner; + materials[517] = Material.Sponge; + materials[24823] = Material.SporeBlossom; + for (int i = 8635; i <= 8658; i++) + materials[i] = Material.SpruceButton; + for (int i = 11822; i <= 11885; i++) + materials[i] = Material.SpruceDoor; + for (int i = 11566; i <= 11597; i++) + materials[i] = Material.SpruceFence; + for (int i = 11310; i <= 11341; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 4898; i <= 4961; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 265; i <= 292; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 133; i <= 135; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 5718; i <= 5719; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 27; i <= 28; i++) + materials[i] = Material.SpruceSapling; + for (int i = 4334; i <= 4365; i++) + materials[i] = Material.SpruceSign; + for (int i = 11168; i <= 11173; i++) + materials[i] = Material.SpruceSlab; + for (int i = 7666; i <= 7745; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6025; i <= 6088; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 5546; i <= 5553; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 4770; i <= 4777; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 192; i <= 194; i++) + materials[i] = Material.SpruceWood; + for (int i = 1992; i <= 2003; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 11264; i <= 11269; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 7109; i <= 7188; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 15780; i <= 16103; i++) + materials[i] = Material.StoneBrickWall; + materials[6537] = Material.StoneBricks; + for (int i = 5748; i <= 5771; i++) + materials[i] = Material.StoneButton; + for (int i = 5650; i <= 5651; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 11222; i <= 11227; i++) + materials[i] = Material.StoneSlab; + for (int i = 13442; i <= 13521; i++) + materials[i] = Material.StoneStairs; + for (int i = 18467; i <= 18470; i++) + materials[i] = Material.Stonecutter; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 165; i <= 167; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 219; i <= 221; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 18605; i <= 18607; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 18599; i <= 18601; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 168; i <= 170; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 222; i <= 224; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 213; i <= 215; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 162; i <= 164; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 216; i <= 218; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 18588; i <= 18590; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 18582; i <= 18584; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 19356; i <= 19359; i++) + materials[i] = Material.StructureBlock; + materials[12549] = Material.StructureVoid; + for (int i = 5799; i <= 5814; i++) + materials[i] = Material.SugarCane; + for (int i = 10747; i <= 10748; i++) + materials[i] = Material.Sunflower; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 113; i <= 116; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 18575; i <= 18578; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 10755; i <= 10756; i++) + materials[i] = Material.TallGrass; + for (int i = 2009; i <= 2010; i++) + materials[i] = Material.TallSeagrass; + for (int i = 19381; i <= 19396; i++) + materials[i] = Material.Target; + materials[10744] = Material.Terracotta; + materials[22317] = Material.TintedGlass; + for (int i = 2094; i <= 2095; i++) + materials[i] = Material.Tnt; + materials[2355] = Material.Torch; + materials[2076] = Material.Torchflower; + for (int i = 12495; i <= 12496; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 9119; i <= 9142; i++) + materials[i] = Material.TrappedChest; + for (int i = 26638; i <= 26649; i++) + materials[i] = Material.TrialSpawner; + for (int i = 7537; i <= 7664; i++) + materials[i] = Material.Tripwire; + for (int i = 7521; i <= 7536; i++) + materials[i] = Material.TripwireHook; + for (int i = 12823; i <= 12824; i++) + materials[i] = Material.TubeCoral; + materials[12808] = Material.TubeCoralBlock; + for (int i = 12843; i <= 12844; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 12893; i <= 12900; i++) + materials[i] = Material.TubeCoralWallFan; + materials[21081] = Material.Tuff; + for (int i = 21905; i <= 21910; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 21911; i <= 21990; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 21991; i <= 22314; i++) + materials[i] = Material.TuffBrickWall; + materials[21904] = Material.TuffBricks; + for (int i = 21082; i <= 21087; i++) + materials[i] = Material.TuffSlab; + for (int i = 21088; i <= 21167; i++) + materials[i] = Material.TuffStairs; + for (int i = 21168; i <= 21491; i++) + materials[i] = Material.TuffWall; + for (int i = 12788; i <= 12799; i++) + materials[i] = Material.TurtleEgg; + for (int i = 18638; i <= 18663; i++) + materials[i] = Material.TwistingVines; + materials[18664] = Material.TwistingVinesPlant; + for (int i = 26650; i <= 26681; i++) + materials[i] = Material.Vault; + for (int i = 26566; i <= 26568; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 6837; i <= 6868; i++) + materials[i] = Material.Vine; + materials[12958] = Material.VoidAir; + for (int i = 2356; i <= 2359; i++) + materials[i] = Material.WallTorch; + for (int i = 19124; i <= 19147; i++) + materials[i] = Material.WarpedButton; + for (int i = 19212; i <= 19275; i++) + materials[i] = Material.WarpedDoor; + for (int i = 18716; i <= 18747; i++) + materials[i] = Material.WarpedFence; + for (int i = 18908; i <= 18939; i++) + materials[i] = Material.WarpedFenceGate; + materials[18592] = Material.WarpedFungus; + for (int i = 5346; i <= 5409; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 18585; i <= 18587; i++) + materials[i] = Material.WarpedHyphae; + materials[18591] = Material.WarpedNylium; + materials[18667] = Material.WarpedPlanks; + for (int i = 18682; i <= 18683; i++) + materials[i] = Material.WarpedPressurePlate; + materials[18594] = Material.WarpedRoots; + for (int i = 19308; i <= 19339; i++) + materials[i] = Material.WarpedSign; + for (int i = 18674; i <= 18679; i++) + materials[i] = Material.WarpedSlab; + for (int i = 19020; i <= 19099; i++) + materials[i] = Material.WarpedStairs; + for (int i = 18579; i <= 18581; i++) + materials[i] = Material.WarpedStem; + for (int i = 18812; i <= 18875; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 5610; i <= 5617; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 19348; i <= 19355; i++) + materials[i] = Material.WarpedWallSign; + materials[18593] = Material.WarpedWartBlock; + for (int i = 80; i <= 95; i++) + materials[i] = Material.Water; + for (int i = 7399; i <= 7401; i++) + materials[i] = Material.WaterCauldron; + materials[22955] = Material.WaxedChiseledCopper; + materials[23300] = Material.WaxedCopperBlock; + for (int i = 24708; i <= 24711; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 23908; i <= 23971; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 24684; i <= 24685; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 24420; i <= 24483; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[23307] = Material.WaxedCutCopper; + for (int i = 23646; i <= 23651; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 23548; i <= 23627; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[22954] = Material.WaxedExposedChiseledCopper; + materials[23302] = Material.WaxedExposedCopper; + for (int i = 24712; i <= 24715; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 23972; i <= 24035; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 24686; i <= 24687; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 24484; i <= 24547; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[23306] = Material.WaxedExposedCutCopper; + for (int i = 23640; i <= 23645; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 23468; i <= 23547; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[22952] = Material.WaxedOxidizedChiseledCopper; + materials[23303] = Material.WaxedOxidizedCopper; + for (int i = 24720; i <= 24723; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 24036; i <= 24099; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 24690; i <= 24691; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 24548; i <= 24611; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[23304] = Material.WaxedOxidizedCutCopper; + for (int i = 23628; i <= 23633; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 23308; i <= 23387; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[22953] = Material.WaxedWeatheredChiseledCopper; + materials[23301] = Material.WaxedWeatheredCopper; + for (int i = 24716; i <= 24719; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 24100; i <= 24163; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 24688; i <= 24689; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 24612; i <= 24675; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[23305] = Material.WaxedWeatheredCutCopper; + for (int i = 23634; i <= 23639; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 23388; i <= 23467; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[22949] = Material.WeatheredChiseledCopper; + materials[22940] = Material.WeatheredCopper; + for (int i = 24700; i <= 24703; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 23844; i <= 23907; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 24680; i <= 24681; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 24356; i <= 24419; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[22945] = Material.WeatheredCutCopper; + for (int i = 23282; i <= 23287; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 23036; i <= 23115; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 18611; i <= 18636; i++) + materials[i] = Material.WeepingVines; + materials[18637] = Material.WeepingVinesPlant; + materials[518] = Material.WetSponge; + for (int i = 4278; i <= 4285; i++) + materials[i] = Material.Wheat; + for (int i = 10759; i <= 10774; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1688; i <= 1703; i++) + materials[i] = Material.WhiteBed; + for (int i = 20741; i <= 20756; i++) + materials[i] = Material.WhiteCandle; + for (int i = 20999; i <= 21000; i++) + materials[i] = Material.WhiteCandleCake; + materials[10728] = Material.WhiteCarpet; + materials[12728] = Material.WhiteConcrete; + materials[12744] = Material.WhiteConcretePowder; + for (int i = 12664; i <= 12667; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 12568; i <= 12573; i++) + materials[i] = Material.WhiteShulkerBox; + materials[5945] = Material.WhiteStainedGlass; + for (int i = 9372; i <= 9403; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[9356] = Material.WhiteTerracotta; + materials[2083] = Material.WhiteTulip; + for (int i = 11015; i <= 11018; i++) + materials[i] = Material.WhiteWallBanner; + materials[2047] = Material.WhiteWool; + materials[2087] = Material.WitherRose; + for (int i = 8867; i <= 8898; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 8899; i <= 8906; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 10823; i <= 10838; i++) + materials[i] = Material.YellowBanner; + for (int i = 1752; i <= 1767; i++) + materials[i] = Material.YellowBed; + for (int i = 20805; i <= 20820; i++) + materials[i] = Material.YellowCandle; + for (int i = 21007; i <= 21008; i++) + materials[i] = Material.YellowCandleCake; + materials[10732] = Material.YellowCarpet; + materials[12732] = Material.YellowConcrete; + materials[12748] = Material.YellowConcretePowder; + for (int i = 12680; i <= 12683; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 12592; i <= 12597; i++) + materials[i] = Material.YellowShulkerBox; + materials[5949] = Material.YellowStainedGlass; + for (int i = 9500; i <= 9531; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[9360] = Material.YellowTerracotta; + for (int i = 11031; i <= 11034; i++) + materials[i] = Material.YellowWallBanner; + materials[2051] = Material.YellowWool; + for (int i = 8907; i <= 8938; i++) + materials[i] = Material.ZombieHead; + for (int i = 8939; i <= 8946; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1206.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1206.cs new file mode 100644 index 00000000..734a431d --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1206.cs @@ -0,0 +1,148 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1206 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1206() + { + mappings[0] = EntityType.Allay; + mappings[1] = EntityType.AreaEffectCloud; + mappings[2] = EntityType.Armadillo; + mappings[3] = EntityType.ArmorStand; + mappings[4] = EntityType.Arrow; + mappings[5] = EntityType.Axolotl; + mappings[6] = EntityType.Bat; + mappings[7] = EntityType.Bee; + mappings[8] = EntityType.Blaze; + mappings[9] = EntityType.BlockDisplay; + mappings[10] = EntityType.Boat; + mappings[11] = EntityType.Bogged; + mappings[12] = EntityType.Breeze; + mappings[13] = EntityType.BreezeWindCharge; + mappings[14] = EntityType.Camel; + mappings[15] = EntityType.Cat; + mappings[16] = EntityType.CaveSpider; + mappings[17] = EntityType.ChestBoat; + mappings[18] = EntityType.ChestMinecart; + mappings[19] = EntityType.Chicken; + mappings[20] = EntityType.Cod; + mappings[21] = EntityType.CommandBlockMinecart; + mappings[22] = EntityType.Cow; + mappings[23] = EntityType.Creeper; + mappings[24] = EntityType.Dolphin; + mappings[25] = EntityType.Donkey; + mappings[26] = EntityType.DragonFireball; + mappings[27] = EntityType.Drowned; + mappings[28] = EntityType.Egg; + mappings[29] = EntityType.ElderGuardian; + mappings[30] = EntityType.EndCrystal; + mappings[31] = EntityType.EnderDragon; + mappings[32] = EntityType.EnderPearl; + mappings[33] = EntityType.Enderman; + mappings[34] = EntityType.Endermite; + mappings[35] = EntityType.Evoker; + mappings[36] = EntityType.EvokerFangs; + mappings[37] = EntityType.ExperienceBottle; + mappings[38] = EntityType.ExperienceOrb; + mappings[39] = EntityType.EyeOfEnder; + mappings[40] = EntityType.FallingBlock; + mappings[62] = EntityType.Fireball; + mappings[41] = EntityType.FireworkRocket; + mappings[129] = EntityType.FishingBobber; + mappings[42] = EntityType.Fox; + mappings[43] = EntityType.Frog; + mappings[44] = EntityType.FurnaceMinecart; + mappings[45] = EntityType.Ghast; + mappings[46] = EntityType.Giant; + mappings[47] = EntityType.GlowItemFrame; + mappings[48] = EntityType.GlowSquid; + mappings[49] = EntityType.Goat; + mappings[50] = EntityType.Guardian; + mappings[51] = EntityType.Hoglin; + mappings[52] = EntityType.HopperMinecart; + mappings[53] = EntityType.Horse; + mappings[54] = EntityType.Husk; + mappings[55] = EntityType.Illusioner; + mappings[56] = EntityType.Interaction; + mappings[57] = EntityType.IronGolem; + mappings[58] = EntityType.Item; + mappings[59] = EntityType.ItemDisplay; + mappings[60] = EntityType.ItemFrame; + mappings[63] = EntityType.LeashKnot; + mappings[64] = EntityType.LightningBolt; + mappings[65] = EntityType.Llama; + mappings[66] = EntityType.LlamaSpit; + mappings[67] = EntityType.MagmaCube; + mappings[68] = EntityType.Marker; + mappings[69] = EntityType.Minecart; + mappings[70] = EntityType.Mooshroom; + mappings[71] = EntityType.Mule; + mappings[72] = EntityType.Ocelot; + mappings[61] = EntityType.OminousItemSpawner; + mappings[73] = EntityType.Painting; + mappings[74] = EntityType.Panda; + mappings[75] = EntityType.Parrot; + mappings[76] = EntityType.Phantom; + mappings[77] = EntityType.Pig; + mappings[78] = EntityType.Piglin; + mappings[79] = EntityType.PiglinBrute; + mappings[80] = EntityType.Pillager; + mappings[128] = EntityType.Player; + mappings[81] = EntityType.PolarBear; + mappings[82] = EntityType.Potion; + mappings[83] = EntityType.Pufferfish; + mappings[84] = EntityType.Rabbit; + mappings[85] = EntityType.Ravager; + mappings[86] = EntityType.Salmon; + mappings[87] = EntityType.Sheep; + mappings[88] = EntityType.Shulker; + mappings[89] = EntityType.ShulkerBullet; + mappings[90] = EntityType.Silverfish; + mappings[91] = EntityType.Skeleton; + mappings[92] = EntityType.SkeletonHorse; + mappings[93] = EntityType.Slime; + mappings[94] = EntityType.SmallFireball; + mappings[95] = EntityType.Sniffer; + mappings[96] = EntityType.SnowGolem; + mappings[97] = EntityType.Snowball; + mappings[98] = EntityType.SpawnerMinecart; + mappings[99] = EntityType.SpectralArrow; + mappings[100] = EntityType.Spider; + mappings[101] = EntityType.Squid; + mappings[102] = EntityType.Stray; + mappings[103] = EntityType.Strider; + mappings[104] = EntityType.Tadpole; + mappings[105] = EntityType.TextDisplay; + mappings[106] = EntityType.Tnt; + mappings[107] = EntityType.TntMinecart; + mappings[108] = EntityType.TraderLlama; + mappings[109] = EntityType.Trident; + mappings[110] = EntityType.TropicalFish; + mappings[111] = EntityType.Turtle; + mappings[112] = EntityType.Vex; + mappings[113] = EntityType.Villager; + mappings[114] = EntityType.Vindicator; + mappings[115] = EntityType.WanderingTrader; + mappings[116] = EntityType.Warden; + mappings[117] = EntityType.WindCharge; + mappings[118] = EntityType.Witch; + mappings[119] = EntityType.Wither; + mappings[120] = EntityType.WitherSkeleton; + mappings[121] = EntityType.WitherSkull; + mappings[122] = EntityType.Wolf; + mappings[123] = EntityType.Zoglin; + mappings[124] = EntityType.Zombie; + mappings[125] = EntityType.ZombieHorse; + mappings[126] = EntityType.ZombieVillager; + mappings[127] = EntityType.ZombifiedPiglin; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 9a036bac..1b628729 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -16,6 +16,7 @@ { Allay, AreaEffectCloud, + Armadillo, ArmorStand, Arrow, Axolotl, @@ -24,7 +25,9 @@ Blaze, BlockDisplay, Boat, + Bogged, Breeze, + BreezeWindCharge, Camel, Cat, CaveSpider, @@ -84,6 +87,7 @@ Mooshroom, Mule, Ocelot, + OminousItemSpawner, Painting, Panda, Parrot, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index f5cbc9aa..68300610 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -409,7 +409,6 @@ GraniteSlab, GraniteStairs, GraniteWall, - Grass, // 1.20.3+ renamed to ShortGrass GrassBlock, Gravel, GrayBanner, @@ -443,6 +442,7 @@ Grindstone, HangingRoots, HayBlock, + HeavyCore, HeavyWeightedPressurePlate, HoneyBlock, HoneycombBlock, @@ -965,6 +965,7 @@ TurtleEgg, TwistingVines, TwistingVinesPlant, + Vault, VerdantFroglight, Vine, VoidAir, diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs index 34c09c6c..65992480 100644 --- a/MinecraftClient/Mapping/Material2Tool.cs +++ b/MinecraftClient/Mapping/Material2Tool.cs @@ -365,7 +365,7 @@ namespace MinecraftClient.Mapping Material.CyanConcretePowder, Material.Dirt, Material.Farmland, - Material.Grass, + Material.ShortGrass, Material.GrassBlock, Material.DirtPath, Material.Gravel, @@ -374,6 +374,7 @@ namespace MinecraftClient.Mapping Material.LightBlueConcretePowder, Material.LightGrayConcretePowder, Material.LimeConcretePowder, + Material.TallGrass, Material.MagentaConcretePowder, Material.Mycelium, Material.OrangeConcretePowder, diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index dd109709..d3b77945 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -797,10 +797,12 @@ namespace MinecraftClient.Protocol.Handlers }; break; case EntityMetaDataType.OptionalVarInt: // Optional VarInt - if (ReadNextBool(cache)) + + if (protocolversion < Protocol18Handler.MC_1_20_6_Version) { - value = ReadNextVarInt(cache); - } + if (ReadNextBool(cache)) + value = ReadNextVarInt(cache); + } else value = ReadNextVarInt(cache); break; case EntityMetaDataType.Pose: // Pose @@ -879,15 +881,21 @@ namespace MinecraftClient.Protocol.Handlers switch (particleId) { + case 1: // 1.20.6+ + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) + ReadNextVarInt(cache); // BlockState (minecraft:block) + break; + case 2: - // 1.18 + + // 1.18 if (protocolversion > Protocol18Handler.MC_1_17_1_Version) - ReadNextVarInt(cache); // Block state (minecraft:block) + ReadNextVarInt(cache); // Block state (minecraft:block before 1.20.6, minecraft:block_marker in 1.20.6+) break; case 3: - if (protocolversion is < Protocol18Handler.MC_1_17_Version or > Protocol18Handler.MC_1_17_1_Version) + if (protocolversion is (< Protocol18Handler.MC_1_17_Version or > Protocol18Handler.MC_1_17_1_Version) + and < Protocol18Handler.MC_1_20_6_Version) ReadNextVarInt( - cache); // Block State (minecraft:block before 1.18, minecraft:block_marker after 1.18) + cache); // Block State (minecraft:block before 1.18, minecraft:block_marker after 1.18 up to 1.20.6) break; case 4: if (protocolversion is Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version) @@ -898,11 +906,24 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion < Protocol18Handler.MC_1_15_Version) ReadDustParticle(cache); break; + case 13: + // 1.20,6+ - minecraft:dust + ReadDustParticle(cache); + break; case 14: - // 1.15 - 1.16.5 and 1.18 - 1.19.4 - if (protocolversion is >= Protocol18Handler.MC_1_15_Version and < Protocol18Handler.MC_1_17_Version - or > Protocol18Handler.MC_1_17_1_Version) - ReadDustParticle(cache); + switch (protocolversion) + { + // 1.15 - 1.16.5 and 1.18 - 1.20.4 + case >= Protocol18Handler.MC_1_15_Version and < Protocol18Handler.MC_1_17_Version + or > Protocol18Handler.MC_1_17_1_Version and < Protocol18Handler.MC_1_20_6_Version: + ReadDustParticle(cache); + break; + // 1.20.6+ + case >= Protocol18Handler.MC_1_20_6_Version: + ReadDustParticleColorTransition(cache); + break; + } + break; case 15: switch (protocolversion) @@ -910,7 +931,8 @@ namespace MinecraftClient.Protocol.Handlers case Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version: ReadDustParticle(cache); break; - case > Protocol18Handler.MC_1_17_1_Version: + // 1.18 - 1.20.4 + case > Protocol18Handler.MC_1_17_1_Version and < Protocol18Handler.MC_1_20_6_Version: ReadDustParticleColorTransition(cache); break; } @@ -920,21 +942,26 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion is Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version) ReadDustParticleColorTransition(cache); break; + case 20: + // 1.20.6+ + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) + ReadNextInt(cache); // minecraft:entity_effect + break; case 23: // 1.15 - 1.16.5 if (protocolversion is >= Protocol18Handler.MC_1_15_Version and < Protocol18Handler.MC_1_17_Version) ReadNextVarInt(cache); // Block State (minecraft:falling_dust) break; case 24: - // 1.18 - 1.19.2 onwards + // 1.18 - 1.19.3 if (protocolversion is > Protocol18Handler.MC_1_17_1_Version and < Protocol18Handler.MC_1_19_3_Version) ReadNextVarInt(cache); // Block State (minecraft:falling_dust) break; case 25: - // 1.17 - 1.17.1 and 1.19.3 onwards + // 1.17 - 1.17.1 and 1.19.3 - 1.20.4 if (protocolversion is Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version - or >= Protocol18Handler.MC_1_19_3_Version) + or (>= Protocol18Handler.MC_1_19_3_Version and < Protocol18Handler.MC_1_20_6_Version)) ReadNextVarInt(cache); // Block State (minecraft:falling_dust) break; case 27: @@ -942,8 +969,14 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion < Protocol18Handler.MC_1_15_Version) ReadNextItemSlot(cache, itemPalette); // Item (minecraft:item) break; + case 28: + // 1.20.6+ + if (protocolversion > Protocol18Handler.MC_1_20_6_Version) + ReadNextVarInt(cache); // minecraft:falling_dust (BlockState) + break; case 30: - if (protocolversion >= Protocol18Handler.MC_1_19_3_Version) + // 1.19.3 - 1.20.4 + if (protocolversion is >= Protocol18Handler.MC_1_19_3_Version and < Protocol18Handler.MC_1_20_6_Version) ReadNextFloat(cache); // Roll (minecraft:sculk_charge) break; case 32: @@ -951,6 +984,11 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion is >= Protocol18Handler.MC_1_15_Version and < Protocol18Handler.MC_1_17_Version) ReadNextItemSlot(cache, itemPalette); // Item (minecraft:item) break; + case 35: + // 1.20.6+ + if (protocolversion > Protocol18Handler.MC_1_20_6_Version) + ReadNextFloat(cache); // minecraft:sculk_charge (Roll) + break; case 36: switch (protocolversion) { @@ -958,6 +996,7 @@ namespace MinecraftClient.Protocol.Handlers case Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version: ReadNextItemSlot(cache, itemPalette); // Item (minecraft:item) break; + // 1.18 - 1.19.2 case > Protocol18Handler.MC_1_17_1_Version and < Protocol18Handler.MC_1_19_3_Version: // minecraft:vibration ReadNextLocation(cache); // Origin (Starting Position) @@ -968,7 +1007,7 @@ namespace MinecraftClient.Protocol.Handlers break; case 37: - // minecraft:vibration + // minecraft:vibration - 1.17 - 1.17.1 if (protocolversion is Protocol18Handler.MC_1_17_Version or Protocol18Handler.MC_1_17_1_Version) { ReadNextDouble(cache); // Origin X @@ -982,11 +1021,13 @@ namespace MinecraftClient.Protocol.Handlers break; case 39: - if (protocolversion >= Protocol18Handler.MC_1_19_3_Version) + // 1.19.3 - 1.20.4 + if (protocolversion is >= Protocol18Handler.MC_1_19_3_Version and < Protocol18Handler.MC_1_20_6_Version) ReadNextItemSlot(cache, itemPalette); // Item (minecraft:item) break; case 40: - if (protocolversion >= Protocol18Handler.MC_1_19_3_Version) + // 1.19.3 - 1.20.4 + if (protocolversion is >= Protocol18Handler.MC_1_19_3_Version and < Protocol18Handler.MC_1_20_6_Version) { var positionSourceType = ReadNextString(cache); switch (positionSourceType) @@ -1004,6 +1045,21 @@ namespace MinecraftClient.Protocol.Handlers } break; + case 44: + // 1.20.6+ + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) + ReadNextItemSlot(cache, itemPalette); // minecraft:item (Item) + break; + case 99: + // 1.20.6+ + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) + ReadNextVarInt(cache); // minecraft:shriek (Delay) + break; + case 105: + // 1.20.6+ + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) + ReadNextVarInt(cache); // minecraft:dust_pillar (BlockState) + break; } } diff --git a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs index 07d37c72..6e4575ab 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -103,7 +103,8 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c new ParserEmpty(dataTypes, packetData), _ => new ParserEmpty(dataTypes, packetData), }; - else // 1.20.3+ + else if (protocolVersion is > Protocol18Handler.MC_1_20_2_Version and < Protocol18Handler.MC_1_20_6_Version) + // 1.20.3 - 1.20.4 parser = parserId switch { 1 => new ParserFloat(dataTypes, packetData), @@ -127,6 +128,24 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c 52 => new ParserForgeEnum(dataTypes, packetData), _ => new ParserEmpty(dataTypes, packetData), }; + else // 1.20.6+ + parser = parserId switch + { + 1 => new ParserFloat(dataTypes, packetData), + 2 => new ParserDouble(dataTypes, packetData), + 3 => new ParserInteger(dataTypes, packetData), + 4 => new ParserLong(dataTypes, packetData), + 5 => new ParserString(dataTypes, packetData), + 6 => new ParserEntity(dataTypes, packetData), + 30 => new ParserScoreHolder(dataTypes, packetData), + 41 => new ParserTime(dataTypes, packetData), + 42 => new ParserResourceOrTag(dataTypes, packetData), + 43 => new ParserResourceOrTag(dataTypes, packetData), + 44 => new ParserResource(dataTypes, packetData), + 45 => new ParserResource(dataTypes, packetData), + 52 => new ParserForgeEnum(dataTypes, packetData), + _ => new ParserEmpty(dataTypes, packetData), + }; } string? suggestionsType = ((flags & 0x10) == 0x10) ? dataTypes.ReadNextString(packetData) : null; diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 5a67294a..b682551f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -123,21 +123,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_20_4_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_20_6_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_20_4_Version) + protocolVersion is < MC_1_8_Version or > MC_1_20_6_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_20_4_Version) + protocolVersion is < MC_1_8_Version or > MC_1_20_6_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -146,8 +146,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_20_4_Version when handler.GetTerrainEnabled() => + > MC_1_20_6_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + MC_1_20_6_Version => new Palette1206(), >= MC_1_20_4_Version => new Palette1204(), >= MC_1_20_Version => new Palette120(), MC_1_19_4_Version => new Palette1194(), @@ -164,8 +165,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_20_4_Version when handler.GetEntityHandlingEnabled() => + > MC_1_20_6_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + MC_1_20_6_Version => new EntityPalette1206(), >= MC_1_20_4_Version => new EntityPalette1204(), >= MC_1_20_Version => new EntityPalette120(), MC_1_19_4_Version => new EntityPalette1194(), @@ -186,8 +188,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_20_4_Version when handler.GetInventoryEnabled() => + > MC_1_20_6_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + MC_1_20_6_Version => new ItemPalette1206(), >= MC_1_20_4_Version => new ItemPalette1204(), >= MC_1_20_Version => new ItemPalette120(), MC_1_19_4_Version => new ItemPalette1194(), @@ -2499,11 +2502,38 @@ namespace MinecraftClient.Protocol.Handlers var numberOfProperties = protocolVersion >= MC_1_17_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); + + var attributeDictionary = new Dictionary + { + { 0, "generic.armor" }, + { 1, "generic.armor_toughness" }, + { 2, "generic.attack_damage" }, + { 3, "generic.attack_knockback" }, + { 4, "generic.attack_speed" }, + { 5, "generic.block_break_speed" }, + { 6, "generic.block_interaction_range" }, + { 7, "generic.entity_interaction_range" }, + { 8, "generic.fall_damage_multiplier" }, + { 9, "generic.flying_speed" }, + { 10, "generic.follow_range" }, + { 11, "generic.gravity" }, + { 12, "generic.jump_strength" }, + { 13, "generic.knockback_resistance" }, + { 14, "generic.luck" }, + { 15, "generic.max_absorption" }, + { 16, "generic.max_health" }, + { 17, "generic.movement_speed" }, + { 18, "generic.safe_fall_distance" }, + { 19, "generic.scale" }, + { 20, "zombie.spawn_reinforcements" }, + { 21, "generic.step_height" } + }; Dictionary keys = new(); for (var i = 0; i < numberOfProperties; i++) { - var propertyKey = dataTypes.ReadNextString(packetData); + var propertyKey = protocolVersion < MC_1_20_6_Version ? dataTypes.ReadNextString(packetData) + : attributeDictionary[dataTypes.ReadNextVarInt(packetData)]; var propertyValue2 = dataTypes.ReadNextDouble(packetData); List op0 = new(); @@ -2549,7 +2579,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_20_4_Version => throw new NotImplementedException(Translations + > MC_1_20_6_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, From efe23eb1f95a94ea87aa857688c14bc24b0cbdec Mon Sep 17 00:00:00 2001 From: a08381 <632785425@163.com> Date: Sun, 11 Aug 2024 01:43:46 +0800 Subject: [PATCH 007/484] add Yggdrasil authlib multi-user selection. --- MinecraftClient/Protocol/ProtocolHandler.cs | 19 +++++++++++++++++-- .../ConfigComments/ConfigComments.Designer.cs | 9 +++++++++ .../ConfigComments/ConfigComments.resx | 3 +++ MinecraftClient/Settings.cs | 3 +++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index cbf1b1cd..dab73249 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -637,9 +637,24 @@ namespace MinecraftClient.Protocol ConsoleIO.WriteLine(Translations.mcc_avaliable_profiles + availableProfiles); - ConsoleIO.WriteLine(Translations.mcc_select_profile); - string selectedProfileName = ConsoleIO.ReadLine(); + string selectedProfileName; + + if (Config.Main.General.AuthUser == "") + { + ConsoleIO.WriteLine(Translations.mcc_select_profile); + selectedProfileName = ConsoleIO.ReadLine(); + } + else + { + selectedProfileName = Config.Main.General.AuthUser; + + } + ConsoleIO.WriteLine(Translations.mcc_selected_profile + " " + selectedProfileName); + + // ConsoleIO.WriteLine(Translations.mcc_select_profile); + // string selectedProfileName = ConsoleIO.ReadLine(); + // ConsoleIO.WriteLine(Translations.mcc_selected_profile + " " + selectedProfileName); Json.JSONData? selectedProfile = null; foreach (Json.JSONData profile in loginResponse.Properties["availableProfiles"] .DataArray) diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs b/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs index 65bb9a0b..4dcf11cd 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs @@ -1748,6 +1748,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Yggdrasil authlib multi-user selection.. + /// + internal static string Main_General_AuthlibUser { + get { + return ResourceManager.GetString("Main.General.AuthlibUser", resourceCulture); + } + } + /// /// Looks up a localized string similar to The address of the game server, "Host" can be filled in with domain name or IP address. (The "Port" field can be deleted, it will be resolved automatically). /// diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index ca440314..5908d88c 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -855,4 +855,7 @@ If the connection to the Minecraft game server is blocked by the firewall, set E Set to false to opt-out of Sentry error logging. + + Yggdrasil authlib multi-user selection. + \ No newline at end of file diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index d8d564c9..1461413a 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -496,6 +496,9 @@ namespace MinecraftClient public LoginMethod Method = LoginMethod.mcc; [TomlInlineComment("$Main.General.AuthlibServer$")] public AuthlibServer AuthServer = new(string.Empty); + + [TomlInlineComment("$Main.General.AuthlibUser$")] + public string AuthUser = ""; public enum LoginType { mojang, microsoft,yggdrasil }; From f54c5aab44b6e0fe40f5cf2a562abd846675a954 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:54:58 +0000 Subject: [PATCH 008/484] Bump webpack from 5.76.1 to 5.94.0 in /docs Bumps [webpack](https://github.com/webpack/webpack) from 5.76.1 to 5.94.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.76.1...v5.94.0) --- updated-dependencies: - dependency-name: webpack dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 421 ++++++++++++++++++++++++++++++------------------- 1 file changed, 259 insertions(+), 162 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 7c3cb3be..c532b447 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -52,16 +52,35 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/source-map@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" @@ -70,12 +89,33 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== @@ -217,31 +257,10 @@ dependencies: "@types/ms" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.4.9" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.9.tgz#f7371980148697f4b582b086630319b55324b5aa" - integrity sha512-jFCSo4wJzlHQLCpceUhUnXdrPuCNOjGFMQ8Eg6JXxlz3QaCKOb7eGi2cephQdM4XTYsNej69P9JDJ1zqNIbncQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.31" @@ -286,7 +305,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -796,125 +815,125 @@ dependencies: vue-demi "*" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -935,16 +954,21 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn@^8.5.0, acorn@^8.7.1: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.8.2: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -1209,7 +1233,17 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.21.4: +browserslist@^4.21.10: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== + dependencies: + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +browserslist@^4.21.4: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -1288,6 +1322,11 @@ caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz#70cdae959096756a85713b36dd9cb82e62325639" integrity sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg== +caniuse-lite@^1.0.30001646: + version "1.0.30001655" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz#0ce881f5a19a2dcfda2ecd927df4d5c1684b982f" + integrity sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg== + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2285,6 +2324,11 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== +electron-to-chromium@^1.5.4: + version "1.5.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" + integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -2295,10 +2339,10 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -2325,10 +2369,10 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== esbuild-android-64@0.15.12: version "0.15.12" @@ -2475,6 +2519,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2849,11 +2898,16 @@ globby@^13.1.1, globby@^13.1.2: merge2 "^1.4.1" slash "^4.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.2.11: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + graphlib@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" @@ -3735,6 +3789,11 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -3954,6 +4013,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -4287,7 +4351,7 @@ sass@^1.55.0: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -4296,6 +4360,15 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + schema-utils@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" @@ -4359,6 +4432,13 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -4674,18 +4754,18 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" -terser@^5.10.0, terser@^5.14.1: +terser@^5.10.0: version "5.15.1" resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.1.tgz#8561af6e0fd6d839669c73b92bdd5777d870ed6c" integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw== @@ -4695,6 +4775,16 @@ terser@^5.10.0, terser@^5.14.1: commander "^2.20.0" source-map-support "~0.5.20" +terser@^5.26.0: + version "5.31.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" @@ -4801,6 +4891,14 @@ update-browserslist-db@^1.0.9: escalade "^3.1.1" picocolors "^1.0.0" +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -4949,10 +5047,10 @@ vuepress@^2.0.0-beta.53: dependencies: vuepress-vite "2.0.0-beta.53" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -5047,33 +5145,32 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.74.0: - version "5.76.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.1.tgz#7773de017e988bccb0f13c7d75ec245f377d295c" - integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.1" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: From 63b027d84aefec55528b02a2fe247ea3a8ac414d Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 1 Sep 2024 20:42:39 +0200 Subject: [PATCH 009/484] First Version of Structured Components --- .../Protocol/Handlers/DataTypes.cs | 107 ++++++++++++++---- .../Protocol/Handlers/SocketWrapper.cs | 2 +- .../Subcomponents/TestSubComonent.cs | 19 ++++ .../Components/TestComponent.cs | 29 +++++ .../Core/StructuredComponent.cs | 12 ++ .../Core/StructuredComponentRegistry.cs | 63 +++++++++++ .../StructuredComponents/Core/SubComponent.cs | 11 ++ .../Core/SubComponentRegistry.cs | 29 +++++ .../StructuredComponentsRegistry1206.cs | 13 +++ .../Subcomponents/TestSubComponentRegistry.cs | 12 ++ .../StructuredComponentsHandler.cs | 43 +++++++ 11 files changed, 314 insertions(+), 26 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index d3b77945..b62d511c 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -6,6 +6,8 @@ using MinecraftClient.Inventory; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Mapping; using MinecraftClient.Mapping.EntityPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers @@ -13,7 +15,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Handle data types encoding / decoding /// - class DataTypes + public class DataTypes { /// /// Protocol version for adjusting data types @@ -419,37 +421,92 @@ namespace MinecraftClient.Protocol.Handlers /// The item that was read or NULL for an empty slot public Item? ReadNextItemSlot(Queue cache, ItemPalette itemPalette) { - // MC 1.13.2 and greater - if (protocolversion >= Protocol18Handler.MC_1_13_Version) + var itemId = -1; + var itemCount = 0; + var nbt = null as Dictionary; + var item = null as Item; + var strcturedComponentsToAdd = new List(); + + switch (protocolversion) { - var itemPresent = ReadNextBool(cache); + // MC 1.13.2 and greater + case >= Protocol18Handler.MC_1_20_6_Version: + itemCount = ReadNextVarInt(cache); - if (!itemPresent) - return null; + if (itemCount <= 0) return null; + + itemId = ReadNextVarInt(cache); + item = new Item(itemPalette.FromId(itemId), itemCount, null); + + var numberOfComponentsToAdd = ReadNextVarInt(cache); + var numberofComponentsToRemove = ReadNextVarInt(cache); - var itemId = ReadNextVarInt(cache); + for (var i = 0; i < numberOfComponentsToAdd; i++) + { + var componentTypeId = ReadNextVarInt(cache); - if (itemId == -1) - return null; + var strcuturedComponentHandler = new StructuredComponentsHandler(protocolversion, this); + strcturedComponentsToAdd.Add(strcuturedComponentHandler.Parse(componentTypeId, cache)); + } - var type = itemPalette.FromId(itemId); - var itemCount = ReadNextByte(cache); - var nbt = ReadNextNbt(cache); - return new Item(type, itemCount, nbt); + for (var i = 0; i < numberofComponentsToRemove; i++) + { + // TODO + } + + // TODO: Wire up the strctured components in the Item class (extract info, update fields, etc..) + // Look at: https://wiki.vg/index.php?title=Slot_Data&oldid=19350#Structured_components + + return item; + case >= Protocol18Handler.MC_1_13_Version: + { + var itemPresent = ReadNextBool(cache); + + if (!itemPresent) + return null; + + itemId = ReadNextVarInt(cache); + + if (itemId == -1) + return null; + + var type = itemPalette.FromId(itemId); + itemCount = ReadNextByte(cache); + nbt = ReadNextNbt(cache); + return new Item(type, itemCount, nbt); + } + default: + { + itemId = ReadNextShort(cache); + + if (itemId == -1) + return null; + + itemCount = ReadNextByte(cache); + var data = ReadNextShort(cache); + nbt = ReadNextNbt(cache); + + // For 1.8 - 1.12.2 we combine Item Id and Item Data/Damage to a single value using: (id << 16) | data + return new Item(itemPalette.FromId((itemId << 16) | (ushort)data), itemCount, data, nbt); + } } - else + } + + private void ReadNextDetail(Queue cache) + { + var potionEffectId = ReadNextVarInt(cache); + + // Details + var potionEffectAmplifier = ReadNextVarInt(cache); + var duration = ReadNextVarInt(cache); // -1 for infinite + var ambient = ReadNextBool(cache); + var showParticles = ReadNextBool(cache); + var showIcon = ReadNextBool(cache); + var hasHiddenEffect = ReadNextBool(cache); + + if (hasHiddenEffect) { - var itemId = ReadNextShort(cache); - - if (itemId == -1) - return null; - - var itemCount = ReadNextByte(cache); - var data = ReadNextShort(cache); - var nbt = ReadNextNbt(cache); - - // For 1.8 - 1.12.2 we combine Item Id and Item Data/Damage to a single value using: (id << 16) | data - return new Item(itemPalette.FromId((itemId << 16) | (ushort)data), itemCount, data, nbt); + ReadNextDetail(cache); } } diff --git a/MinecraftClient/Protocol/Handlers/SocketWrapper.cs b/MinecraftClient/Protocol/Handlers/SocketWrapper.cs index d9793024..e74fc84a 100644 --- a/MinecraftClient/Protocol/Handlers/SocketWrapper.cs +++ b/MinecraftClient/Protocol/Handlers/SocketWrapper.cs @@ -7,7 +7,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Wrapper for handling unencrypted & encrypted socket /// - class SocketWrapper + public class SocketWrapper { readonly TcpClient c; AesCfb8Stream? s; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs new file mode 100644 index 00000000..fbed4b70 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; + +public class TestSubComonent(DataTypes dataTypes) : SubComponent(dataTypes) +{ + public int Test { get; set; } + + public override void Parse(Queue data) + { + Test = DataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + throw new System.NotImplementedException(); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs new file mode 100644 index 00000000..befa1217 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components; + +public class TestComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int TestInt { get; set; } + public string TestString { get; set; } = null!; + + public TestSubComonent TestSubComonent { get; set; } = null!; + + public override void Parse(Queue data) + { + TestInt = dataTypes.ReadNextVarInt(data); + TestString = dataTypes.ReadNextString(data); + TestSubComonent = (SubComponentRegistry.ParseSubComponent("TestSubComponent", data) as TestSubComonent)!; + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(TestInt)); + data.AddRange(DataTypes.GetString(TestString)); + data.AddRange(TestSubComonent.Serialize()); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs new file mode 100644 index 00000000..01995dc2 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class StructuredComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) +{ + protected DataTypes DataTypes { get; private set; } = dataTypes; + protected SubComponentRegistry SubComponentRegistry { get; private set; } = subComponentRegistry; + + public abstract void Parse(Queue data); + public abstract Queue Serialize(); +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs new file mode 100644 index 00000000..4dffe457 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class StructuredComponentRegistry(SubComponentRegistry subComponentRegistry, DataTypes dataTypes) +{ + private Dictionary ComponentParsers { get; } = new(); + private Dictionary IdToComponent { get; } = new(); + private Dictionary ComponentToId { get; } = new(); + + protected void RegisterComponent(int id, string name) where T : StructuredComponent + { + if (string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name)) + throw new ArgumentNullException(nameof(name)); + + name = name.ToLower(); + + if (ComponentParsers.ContainsKey(name) || IdToComponent.ContainsValue(name) + || ComponentToId.ContainsKey(name) || IdToComponent.ContainsKey(id)) + throw new InvalidOperationException($"A component with name '{name}' or id '{id}' is already registered."); + + ComponentParsers[name] = typeof(T); + IdToComponent[id] = name; + ComponentToId[name] = id; + } + + public StructuredComponent ParseComponent(int id, Queue data) + { + if (IdToComponent.TryGetValue(id, out var name)) + { + if (ComponentParsers.TryGetValue(name, out var type)) + { + var component = + Activator.CreateInstance(type, dataTypes, subComponentRegistry) as StructuredComponent + ?? throw new InvalidOperationException($"Could not instantiate a parser for a structured component type {name}"); + + component.Parse(data); + return component; + } + } + + throw new Exception($"No parser found for component with ID {id}"); + } + + public string GetComponentNameById(int id) + { + if (IdToComponent.TryGetValue(id, out var value)) + return value; + + throw new Exception($"No component found for ID {id}"); + } + + public int GetComponentIdByName(string name) + { + name = name.ToLower(); + + if (ComponentToId.TryGetValue(name, out var value)) + return value; + + throw new Exception($"No ID found for component {name}"); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs new file mode 100644 index 00000000..af63dce8 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class SubComponent(DataTypes dataTypes) +{ + protected DataTypes DataTypes { get; private set; } = dataTypes; + + public abstract void Parse(Queue data); + public abstract Queue Serialize(); +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs new file mode 100644 index 00000000..844107c1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class SubComponentRegistry(DataTypes dataTypes) +{ + private readonly Dictionary _subComponentParsers = new(); + + protected void RegisterSubComponent(string name) where T : SubComponent + { + if(_subComponentParsers.TryGetValue(name, out _)) + throw new Exception($"Sub component {name} already registered!"); + + _subComponentParsers.Add(name, typeof(T)); + } + + public SubComponent ParseSubComponent(string name, Queue data) + { + if(!_subComponentParsers.TryGetValue(name, out var subComponentParserType)) + throw new Exception($"Sub component {name} not registered!"); + + var instance= Activator.CreateInstance(subComponentParserType, dataTypes) as SubComponent ?? + throw new InvalidOperationException($"Could not create instance of a sub component parser type: {subComponentParserType.Name}"); + + instance.Parse(data); + return instance; + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs new file mode 100644 index 00000000..d69507ab --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -0,0 +1,13 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry1206 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry1206(SubComponentRegistry subComponentRegistry, DataTypes dataTypes) : base( + subComponentRegistry, dataTypes) + { + RegisterComponent(0, "minecraft:test"); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs new file mode 100644 index 00000000..c10bbc49 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs @@ -0,0 +1,12 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; + +public class TestSubComponentRegistry : SubComponentRegistry +{ + public TestSubComponentRegistry(DataTypes dataTypes) : base(dataTypes) + { + RegisterSubComponent("TestSubcomponent"); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs new file mode 100644 index 00000000..6a03e040 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents; + +public class StructuredComponentsHandler +{ + private StructuredComponentRegistry ComponentRegistry { get; } + + public StructuredComponentsHandler( + int protocolVersion, + DataTypes dataTypes) + { + // Get the appropriate subcomponent registry type based on the protocol version and then instantiate it + var subcomponentRegistryType = protocolVersion switch + { + Protocol18Handler.MC_1_20_6_Version => typeof(TestSubComponentRegistry), + _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") + }; + + var subcomponentRegistry = Activator.CreateInstance(subcomponentRegistryType, dataTypes) as SubComponentRegistry + ?? throw new InvalidOperationException($"Failed to instantiate a component registry for type {nameof(subcomponentRegistryType)}"); + + // Get the appropriate component registry type based on the protocol version and then instantiate it + var registryType = protocolVersion switch + { + Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), + _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") + }; + + ComponentRegistry = Activator.CreateInstance(registryType, subcomponentRegistry, dataTypes) as StructuredComponentRegistry + ?? throw new InvalidOperationException($"Failed to instantiate a component registry for type {nameof(registryType)}"); + } + + public StructuredComponent Parse(int componentId, Queue data) + { + return ComponentRegistry.ParseComponent(componentId, data); + } +} \ No newline at end of file From 27e66433cdd1997a7ff69e0dfb7ca6d79646e30d Mon Sep 17 00:00:00 2001 From: breadbyte <14045257+breadbyte@users.noreply.github.com> Date: Sat, 7 Sep 2024 03:45:45 +0800 Subject: [PATCH 010/484] Hotfix for 'minecraft:chat_type' not present in the dictionary (#2794) --- .../Protocol/Message/ChatParser.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index 5bfd2b66..c4ef9837 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -34,8 +34,25 @@ namespace MinecraftClient.Protocol.Message public static void ReadChatType(Dictionary registryCodec) { Dictionary chatTypeDictionary = ChatId2Type ?? new(); - var chatTypeListNbt = - (object[])(((Dictionary)registryCodec["minecraft:chat_type"])["value"]); + + // Check if the chat type registry is in the correct format + if (!registryCodec.ContainsKey("minecraft:chat_type")) { + + // If not, then we force the registry to be in the correct format + if (registryCodec.ContainsKey("chat_type")) { + + foreach (var key in registryCodec.Keys.ToArray()) { + // Skip entries with a namespace already + if (key.Contains(':', StringComparison.OrdinalIgnoreCase)) continue; + + // Assume all other entries are in the minecraft namespace + registryCodec["minecraft:" + key] = registryCodec[key]; + registryCodec.Remove(key); + } + } + } + + var chatTypeListNbt = (object[])(((Dictionary)registryCodec["minecraft:chat_type"])["value"]); foreach (var (chatName, chatId) in from Dictionary chatTypeNbt in chatTypeListNbt let chatName = (string)chatTypeNbt["name"] let chatId = (int)chatTypeNbt["id"] From 76e873ed54c15cb3c97b0cac003b8b935de84f1e Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 11 Sep 2024 19:12:31 +0200 Subject: [PATCH 011/484] WIP: Added some strctured components --- MinecraftClient/Inventory/Enchantment.cs | 3 + MinecraftClient/Inventory/EnchantmentData.cs | 6 +- .../Inventory/EnchantmentMapping.cs | 320 +++++++++--------- MinecraftClient/Inventory/Enchantments.cs | 2 +- MinecraftClient/Inventory/ItemRarity.cs | 9 + MinecraftClient/McClient.cs | 20 +- .../1_20_6/AttributeModifiersComponent1206.cs | 39 +++ .../1_20_6/CanBreakComponent1206.cs | 39 +++ .../1_20_6/CanPlaceOnComponent1206.cs | 39 +++ .../1_20_6/CustomDataComponent1206.cs | 21 ++ .../1_20_6/CustomModelDataComponent1206.cs | 21 ++ .../1_20_6/CustomNameComponent1206.cs | 22 ++ .../Components/1_20_6/DamageComponent1206.cs | 21 ++ .../1_20_6/EnchantmentsComponent1206.cs | 35 ++ .../HideAdditionalTooltipComponent1206.cs | 5 + .../1_20_6/HideTooltipComponent1206.cs | 5 + .../1_20_6/ItemNameComponent1206.cs | 22 ++ .../Components/1_20_6/LoreComponent1206.cs | 34 ++ .../1_20_6/MaxDamageComponent1206.cs | 21 ++ .../1_20_6/MaxStackSizeComponent1206.cs | 21 ++ .../Components/1_20_6/RarityComponent1206.cs | 22 ++ .../1_20_6/UnbreakableComponent1206.cs | 21 ++ .../TestSubComonent.cs => EmptyComponent.cs} | 9 +- .../1_20_6/AttributeSubComponent1206.cs | 41 +++ .../1_20_6/BlockPredicateSubcomponent1206.cs | 75 ++++ .../1_20_6/BlockSetSubcomponent1206.cs | 50 +++ .../1_20_6/PropertySubComponent1206.cs | 57 ++++ .../Components/Subcomponents/SubComponents.cs | 9 + .../Components/TestComponent.cs | 29 -- .../StructuredComponents/Core/SubComponent.cs | 5 +- .../Core/SubComponentRegistry.cs | 10 +- .../StructuredComponentsRegistry1206.cs | 19 +- .../Subcomponents/SubComponentRegistry1206.cs | 16 + .../Subcomponents/TestSubComponentRegistry.cs | 12 - .../StructuredComponentsHandler.cs | 2 +- MinecraftClient/Scripting/ChatBot.cs | 6 +- 36 files changed, 857 insertions(+), 231 deletions(-) create mode 100644 MinecraftClient/Inventory/Enchantment.cs create mode 100644 MinecraftClient/Inventory/ItemRarity.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/{Subcomponents/TestSubComonent.cs => EmptyComponent.cs} (54%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs delete mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs delete mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs diff --git a/MinecraftClient/Inventory/Enchantment.cs b/MinecraftClient/Inventory/Enchantment.cs new file mode 100644 index 00000000..09b513f9 --- /dev/null +++ b/MinecraftClient/Inventory/Enchantment.cs @@ -0,0 +1,3 @@ +namespace MinecraftClient.Inventory; + +public record Enchantment(Enchantments Type, int Level); \ No newline at end of file diff --git a/MinecraftClient/Inventory/EnchantmentData.cs b/MinecraftClient/Inventory/EnchantmentData.cs index c42dd920..427fe012 100644 --- a/MinecraftClient/Inventory/EnchantmentData.cs +++ b/MinecraftClient/Inventory/EnchantmentData.cs @@ -2,9 +2,9 @@ { public class EnchantmentData { - public Enchantment TopEnchantment { get; set; } - public Enchantment MiddleEnchantment { get; set; } - public Enchantment BottomEnchantment { get; set; } + public Enchantments TopEnchantment { get; set; } + public Enchantments MiddleEnchantment { get; set; } + public Enchantments BottomEnchantment { get; set; } // Seed for rendering Standard Galactic Language (symbols in the enchanting table) (Useful for poeple who use MCC for the protocol) public short Seed { get; set; } diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index 1768482e..4f6fca47 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -10,184 +10,184 @@ namespace MinecraftClient.Inventory { #pragma warning disable format // @formatter:off // 1.14 - 1.15.2 - private static Dictionary enchantmentMappings114 = new() + private static Dictionary enchantmentMappings114 = new() { //id type - { 0, Enchantment.Protection }, - { 1, Enchantment.FireProtection }, - { 2, Enchantment.FeatherFalling }, - { 3, Enchantment.BlastProtection }, - { 4, Enchantment.ProjectileProtection }, - { 5, Enchantment.Respiration }, - { 6, Enchantment.AquaAffinity }, - { 7, Enchantment.Thorns }, - { 8, Enchantment.DepthStrieder }, - { 9, Enchantment.FrostWalker }, - { 10, Enchantment.BindingCurse }, - { 11, Enchantment.Sharpness }, - { 12, Enchantment.Smite }, - { 13, Enchantment.BaneOfArthropods }, - { 14, Enchantment.Knockback }, - { 15, Enchantment.FireAspect }, - { 16, Enchantment.Looting }, - { 17, Enchantment.Sweeping }, - { 18, Enchantment.Efficency }, - { 19, Enchantment.SilkTouch }, - { 20, Enchantment.Unbreaking }, - { 21, Enchantment.Fortune }, - { 22, Enchantment.Power }, - { 23, Enchantment.Punch }, - { 24, Enchantment.Flame }, - { 25, Enchantment.Infinity }, - { 26, Enchantment.LuckOfTheSea }, - { 27, Enchantment.Lure }, - { 28, Enchantment.Loyality }, - { 29, Enchantment.Impaling }, - { 30, Enchantment.Riptide }, - { 31, Enchantment.Channeling }, - { 32, Enchantment.Mending }, - { 33, Enchantment.VanishingCurse } + { 0, Enchantments.Protection }, + { 1, Enchantments.FireProtection }, + { 2, Enchantments.FeatherFalling }, + { 3, Enchantments.BlastProtection }, + { 4, Enchantments.ProjectileProtection }, + { 5, Enchantments.Respiration }, + { 6, Enchantments.AquaAffinity }, + { 7, Enchantments.Thorns }, + { 8, Enchantments.DepthStrieder }, + { 9, Enchantments.FrostWalker }, + { 10, Enchantments.BindingCurse }, + { 11, Enchantments.Sharpness }, + { 12, Enchantments.Smite }, + { 13, Enchantments.BaneOfArthropods }, + { 14, Enchantments.Knockback }, + { 15, Enchantments.FireAspect }, + { 16, Enchantments.Looting }, + { 17, Enchantments.Sweeping }, + { 18, Enchantments.Efficency }, + { 19, Enchantments.SilkTouch }, + { 20, Enchantments.Unbreaking }, + { 21, Enchantments.Fortune }, + { 22, Enchantments.Power }, + { 23, Enchantments.Punch }, + { 24, Enchantments.Flame }, + { 25, Enchantments.Infinity }, + { 26, Enchantments.LuckOfTheSea }, + { 27, Enchantments.Lure }, + { 28, Enchantments.Loyality }, + { 29, Enchantments.Impaling }, + { 30, Enchantments.Riptide }, + { 31, Enchantments.Channeling }, + { 32, Enchantments.Mending }, + { 33, Enchantments.VanishingCurse } }; // 1.16 - 1.18 - private static Dictionary enchantmentMappings116 = new() + private static Dictionary enchantmentMappings116 = new() { //id type - { 0, Enchantment.Protection }, - { 1, Enchantment.FireProtection }, - { 2, Enchantment.FeatherFalling }, - { 3, Enchantment.BlastProtection }, - { 4, Enchantment.ProjectileProtection }, - { 5, Enchantment.Respiration }, - { 6, Enchantment.AquaAffinity }, - { 7, Enchantment.Thorns }, - { 8, Enchantment.DepthStrieder }, - { 9, Enchantment.FrostWalker }, - { 10, Enchantment.BindingCurse }, - { 11, Enchantment.SoulSpeed }, - { 12, Enchantment.Sharpness }, - { 13, Enchantment.Smite }, - { 14, Enchantment.BaneOfArthropods }, - { 15, Enchantment.Knockback }, - { 16, Enchantment.FireAspect }, - { 17, Enchantment.Looting }, - { 18, Enchantment.Sweeping }, - { 19, Enchantment.Efficency }, - { 20, Enchantment.SilkTouch }, - { 21, Enchantment.Unbreaking }, - { 22, Enchantment.Fortune }, - { 23, Enchantment.Power }, - { 24, Enchantment.Punch }, - { 25, Enchantment.Flame }, - { 26, Enchantment.Infinity }, - { 27, Enchantment.LuckOfTheSea }, - { 28, Enchantment.Lure }, - { 29, Enchantment.Loyality }, - { 30, Enchantment.Impaling }, - { 31, Enchantment.Riptide }, - { 32, Enchantment.Channeling }, - { 33, Enchantment.Multishot }, - { 34, Enchantment.QuickCharge }, - { 35, Enchantment.Piercing }, - { 36, Enchantment.Mending }, - { 37, Enchantment.VanishingCurse } + { 0, Enchantments.Protection }, + { 1, Enchantments.FireProtection }, + { 2, Enchantments.FeatherFalling }, + { 3, Enchantments.BlastProtection }, + { 4, Enchantments.ProjectileProtection }, + { 5, Enchantments.Respiration }, + { 6, Enchantments.AquaAffinity }, + { 7, Enchantments.Thorns }, + { 8, Enchantments.DepthStrieder }, + { 9, Enchantments.FrostWalker }, + { 10, Enchantments.BindingCurse }, + { 11, Enchantments.SoulSpeed }, + { 12, Enchantments.Sharpness }, + { 13, Enchantments.Smite }, + { 14, Enchantments.BaneOfArthropods }, + { 15, Enchantments.Knockback }, + { 16, Enchantments.FireAspect }, + { 17, Enchantments.Looting }, + { 18, Enchantments.Sweeping }, + { 19, Enchantments.Efficency }, + { 20, Enchantments.SilkTouch }, + { 21, Enchantments.Unbreaking }, + { 22, Enchantments.Fortune }, + { 23, Enchantments.Power }, + { 24, Enchantments.Punch }, + { 25, Enchantments.Flame }, + { 26, Enchantments.Infinity }, + { 27, Enchantments.LuckOfTheSea }, + { 28, Enchantments.Lure }, + { 29, Enchantments.Loyality }, + { 30, Enchantments.Impaling }, + { 31, Enchantments.Riptide }, + { 32, Enchantments.Channeling }, + { 33, Enchantments.Multishot }, + { 34, Enchantments.QuickCharge }, + { 35, Enchantments.Piercing }, + { 36, Enchantments.Mending }, + { 37, Enchantments.VanishingCurse } }; // 1.19 - 1.20.4 - private static Dictionary enchantmentMappings119 = new() + private static Dictionary enchantmentMappings119 = new() { //id type - { 0, Enchantment.Protection }, - { 1, Enchantment.FireProtection }, - { 2, Enchantment.FeatherFalling }, - { 3, Enchantment.BlastProtection }, - { 4, Enchantment.ProjectileProtection }, - { 5, Enchantment.Respiration }, - { 6, Enchantment.AquaAffinity }, - { 7, Enchantment.Thorns }, - { 8, Enchantment.DepthStrieder }, - { 9, Enchantment.FrostWalker }, - { 10, Enchantment.BindingCurse }, - { 11, Enchantment.SoulSpeed }, - { 12, Enchantment.SwiftSneak }, - { 13, Enchantment.Sharpness }, - { 14, Enchantment.Smite }, - { 15, Enchantment.BaneOfArthropods }, - { 16, Enchantment.Knockback }, - { 17, Enchantment.FireAspect }, - { 18, Enchantment.Looting }, - { 19, Enchantment.Sweeping }, - { 20, Enchantment.Efficency }, - { 21, Enchantment.SilkTouch }, - { 22, Enchantment.Unbreaking }, - { 23, Enchantment.Fortune }, - { 24, Enchantment.Power }, - { 25, Enchantment.Punch }, - { 26, Enchantment.Flame }, - { 27, Enchantment.Infinity }, - { 28, Enchantment.LuckOfTheSea }, - { 29, Enchantment.Lure }, - { 30, Enchantment.Loyality }, - { 31, Enchantment.Impaling }, - { 32, Enchantment.Riptide }, - { 33, Enchantment.Channeling }, - { 34, Enchantment.Multishot }, - { 35, Enchantment.QuickCharge }, - { 36, Enchantment.Piercing }, - { 37, Enchantment.Mending }, - { 38, Enchantment.VanishingCurse } + { 0, Enchantments.Protection }, + { 1, Enchantments.FireProtection }, + { 2, Enchantments.FeatherFalling }, + { 3, Enchantments.BlastProtection }, + { 4, Enchantments.ProjectileProtection }, + { 5, Enchantments.Respiration }, + { 6, Enchantments.AquaAffinity }, + { 7, Enchantments.Thorns }, + { 8, Enchantments.DepthStrieder }, + { 9, Enchantments.FrostWalker }, + { 10, Enchantments.BindingCurse }, + { 11, Enchantments.SoulSpeed }, + { 12, Enchantments.SwiftSneak }, + { 13, Enchantments.Sharpness }, + { 14, Enchantments.Smite }, + { 15, Enchantments.BaneOfArthropods }, + { 16, Enchantments.Knockback }, + { 17, Enchantments.FireAspect }, + { 18, Enchantments.Looting }, + { 19, Enchantments.Sweeping }, + { 20, Enchantments.Efficency }, + { 21, Enchantments.SilkTouch }, + { 22, Enchantments.Unbreaking }, + { 23, Enchantments.Fortune }, + { 24, Enchantments.Power }, + { 25, Enchantments.Punch }, + { 26, Enchantments.Flame }, + { 27, Enchantments.Infinity }, + { 28, Enchantments.LuckOfTheSea }, + { 29, Enchantments.Lure }, + { 30, Enchantments.Loyality }, + { 31, Enchantments.Impaling }, + { 32, Enchantments.Riptide }, + { 33, Enchantments.Channeling }, + { 34, Enchantments.Multishot }, + { 35, Enchantments.QuickCharge }, + { 36, Enchantments.Piercing }, + { 37, Enchantments.Mending }, + { 38, Enchantments.VanishingCurse } }; // 1.20.6+ - private static Dictionary enchantmentMappings = new() + private static Dictionary enchantmentMappings = new() { //id type - { 0, Enchantment.Protection }, - { 1, Enchantment.FireProtection }, - { 2, Enchantment.FeatherFalling }, - { 3, Enchantment.BlastProtection }, - { 4, Enchantment.ProjectileProtection }, - { 5, Enchantment.Respiration }, - { 6, Enchantment.AquaAffinity }, - { 7, Enchantment.Thorns }, - { 8, Enchantment.DepthStrieder }, - { 9, Enchantment.FrostWalker }, - { 10, Enchantment.BindingCurse }, - { 11, Enchantment.SoulSpeed }, - { 12, Enchantment.SwiftSneak }, - { 13, Enchantment.Sharpness }, - { 14, Enchantment.Smite }, - { 15, Enchantment.BaneOfArthropods }, - { 16, Enchantment.Knockback }, - { 17, Enchantment.FireAspect }, - { 18, Enchantment.Looting }, - { 19, Enchantment.Sweeping }, - { 20, Enchantment.Efficency }, - { 21, Enchantment.SilkTouch }, - { 22, Enchantment.Unbreaking }, - { 23, Enchantment.Fortune }, - { 24, Enchantment.Power }, - { 25, Enchantment.Punch }, - { 26, Enchantment.Flame }, - { 27, Enchantment.Infinity }, - { 28, Enchantment.LuckOfTheSea }, - { 29, Enchantment.Lure }, - { 30, Enchantment.Loyality }, - { 31, Enchantment.Impaling }, - { 32, Enchantment.Riptide }, - { 33, Enchantment.Channeling }, - { 34, Enchantment.Multishot }, - { 35, Enchantment.QuickCharge }, - { 36, Enchantment.Piercing }, - { 37, Enchantment.Density }, - { 38, Enchantment.Breach }, - { 39, Enchantment.WindBurst }, - { 40, Enchantment.Mending }, - { 41, Enchantment.VanishingCurse } + { 0, Enchantments.Protection }, + { 1, Enchantments.FireProtection }, + { 2, Enchantments.FeatherFalling }, + { 3, Enchantments.BlastProtection }, + { 4, Enchantments.ProjectileProtection }, + { 5, Enchantments.Respiration }, + { 6, Enchantments.AquaAffinity }, + { 7, Enchantments.Thorns }, + { 8, Enchantments.DepthStrieder }, + { 9, Enchantments.FrostWalker }, + { 10, Enchantments.BindingCurse }, + { 11, Enchantments.SoulSpeed }, + { 12, Enchantments.SwiftSneak }, + { 13, Enchantments.Sharpness }, + { 14, Enchantments.Smite }, + { 15, Enchantments.BaneOfArthropods }, + { 16, Enchantments.Knockback }, + { 17, Enchantments.FireAspect }, + { 18, Enchantments.Looting }, + { 19, Enchantments.Sweeping }, + { 20, Enchantments.Efficency }, + { 21, Enchantments.SilkTouch }, + { 22, Enchantments.Unbreaking }, + { 23, Enchantments.Fortune }, + { 24, Enchantments.Power }, + { 25, Enchantments.Punch }, + { 26, Enchantments.Flame }, + { 27, Enchantments.Infinity }, + { 28, Enchantments.LuckOfTheSea }, + { 29, Enchantments.Lure }, + { 30, Enchantments.Loyality }, + { 31, Enchantments.Impaling }, + { 32, Enchantments.Riptide }, + { 33, Enchantments.Channeling }, + { 34, Enchantments.Multishot }, + { 35, Enchantments.QuickCharge }, + { 36, Enchantments.Piercing }, + { 37, Enchantments.Density }, + { 38, Enchantments.Breach }, + { 39, Enchantments.WindBurst }, + { 40, Enchantments.Mending }, + { 41, Enchantments.VanishingCurse } }; #pragma warning restore format // @formatter:on - public static Enchantment GetEnchantmentById(int protocolVersion, short id) + public static Enchantments GetEnchantmentById(int protocolVersion, short id) { if (protocolVersion < Protocol18Handler.MC_1_14_Version) throw new Exception("Enchantments mappings are not implemented bellow 1.14"); @@ -206,9 +206,9 @@ namespace MinecraftClient.Inventory return value; } - public static string GetEnchantmentName(Enchantment enchantment) + public static string GetEnchantmentName(Enchantments enchantment) { - var translation = ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase()); + var translation = ChatParser.TranslateString("Enchantments.minecraft." + enchantment.ToString().ToUnderscoreCase()); return string.IsNullOrEmpty(translation) ? $"Unknown Enchantment with ID: {(short)enchantment} (Probably not named in the code yet)" : translation; } diff --git a/MinecraftClient/Inventory/Enchantments.cs b/MinecraftClient/Inventory/Enchantments.cs index f1087d51..13fdd595 100644 --- a/MinecraftClient/Inventory/Enchantments.cs +++ b/MinecraftClient/Inventory/Enchantments.cs @@ -1,7 +1,7 @@ namespace MinecraftClient.Inventory { // Not implemented for 1.14 - public enum Enchantment : short + public enum Enchantments : short { AquaAffinity = 0, BaneOfArthropods, diff --git a/MinecraftClient/Inventory/ItemRarity.cs b/MinecraftClient/Inventory/ItemRarity.cs new file mode 100644 index 00000000..a6cc0330 --- /dev/null +++ b/MinecraftClient/Inventory/ItemRarity.cs @@ -0,0 +1,9 @@ +namespace MinecraftClient.Inventory; + +public enum ItemRarity : int +{ + Common = 0, + Uncommon, + Rare, + Epic +} \ No newline at end of file diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index f7775564..50761914 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2948,27 +2948,27 @@ namespace MinecraftClient // We got the last property for enchantment if (propertyId == 9 && propertyValue != -1) { - short topEnchantmentLevelRequirement = inventory.Properties[0]; - short middleEnchantmentLevelRequirement = inventory.Properties[1]; - short bottomEnchantmentLevelRequirement = inventory.Properties[2]; + var topEnchantmentLevelRequirement = inventory.Properties[0]; + var middleEnchantmentLevelRequirement = inventory.Properties[1]; + var bottomEnchantmentLevelRequirement = inventory.Properties[2]; - Enchantment topEnchantment = EnchantmentMapping.GetEnchantmentById( + var topEnchantment = EnchantmentMapping.GetEnchantmentById( GetProtocolVersion(), inventory.Properties[4]); - Enchantment middleEnchantment = EnchantmentMapping.GetEnchantmentById( + var middleEnchantment = EnchantmentMapping.GetEnchantmentById( GetProtocolVersion(), inventory.Properties[5]); - Enchantment bottomEnchantment = EnchantmentMapping.GetEnchantmentById( + var bottomEnchantment = EnchantmentMapping.GetEnchantmentById( GetProtocolVersion(), inventory.Properties[6]); - short topEnchantmentLevel = inventory.Properties[7]; - short middleEnchantmentLevel = inventory.Properties[8]; - short bottomEnchantmentLevel = inventory.Properties[9]; + var topEnchantmentLevel = inventory.Properties[7]; + var middleEnchantmentLevel = inventory.Properties[8]; + var bottomEnchantmentLevel = inventory.Properties[9]; - StringBuilder sb = new(); + var sb = new StringBuilder(); sb.AppendLine(Translations.Enchantment_enchantments_available + ":"); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs new file mode 100644 index 00000000..c2eaa2da --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class AttributeModifiersComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int NumberOfAttributes { get; set; } + public List Attributes { get; set; } = new(); + public bool ShowInTooltip { get; set; } + + public override void Parse(Queue data) + { + NumberOfAttributes = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfAttributes; i++) + Attributes.Add((AttributeSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); + + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfAttributes)); + + if(NumberOfAttributes > 0 && Attributes.Count == 0) + throw new ArgumentNullException($"Can not serialize a AttributeModifiersComponent when the Attributes is empty but NumberOfAttributes is > 0!"); + + foreach (var attribute in Attributes) + data.AddRange(attribute.Serialize()); + + data.AddRange(DataTypes.GetBool(ShowInTooltip)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs new file mode 100644 index 00000000..24d50cf5 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CanBreakComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int NumberOfPredicates { get; set; } + public List BlockPredicates { get; set; } = new(); + public bool ShowInTooltip { get; set; } + + public override void Parse(Queue data) + { + NumberOfPredicates = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfPredicates; i++) + BlockPredicates.Add((BlockPredicateSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); + + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfPredicates)); + + if(NumberOfPredicates > 0 && BlockPredicates.Count == 0) + throw new ArgumentNullException($"Can not serialize a CanBreakComponent when the BlockPredicates is empty but NumberOfPredicates is > 0!"); + + foreach (var blockPredicate in BlockPredicates) + data.AddRange(blockPredicate.Serialize()); + + data.AddRange(DataTypes.GetBool(ShowInTooltip)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs new file mode 100644 index 00000000..f19211b6 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CanPlaceOnComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int NumberOfPredicates { get; set; } + public List BlockPredicates { get; set; } = new(); + public bool ShowInTooltip { get; set; } + + public override void Parse(Queue data) + { + NumberOfPredicates = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfPredicates; i++) + BlockPredicates.Add((BlockPredicateSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); + + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfPredicates)); + + if(NumberOfPredicates > 0 && BlockPredicates.Count == 0) + throw new ArgumentNullException($"Can not serialize a CanPlaceOnComponent when the BlockPredicates is empty but NumberOfPredicates is > 0!"); + + foreach (var blockPredicate in BlockPredicates) + data.AddRange(blockPredicate.Serialize()); + + data.AddRange(DataTypes.GetBool(ShowInTooltip)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs new file mode 100644 index 00000000..58732f0a --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CustomDataComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } = new(); + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs new file mode 100644 index 00000000..965c4040 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CustomModelDataComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int Value { get; set; } + + public override void Parse(Queue data) + { + Value = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Value)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs new file mode 100644 index 00000000..71d95001 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CustomNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public string CustomName { get; set; } = string.Empty; + + public override void Parse(Queue data) + { + CustomName = ChatParser.ParseText(dataTypes.ReadNextString(data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(CustomName)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs new file mode 100644 index 00000000..2e6bbadd --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class DamageComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int Damage { get; set; } + + public override void Parse(Queue data) + { + Damage = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Damage)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs new file mode 100644 index 00000000..be5b6e81 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class EnchantmentsComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int NumberOfEnchantments { get; set; } + public List Enchantments { get; set; } = new(); + public bool ShowTooltip { get; set; } + + public override void Parse(Queue data) + { + NumberOfEnchantments = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfEnchantments; i++) + Enchantments.Add(new Enchantment((Enchantments)dataTypes.ReadNextVarInt(data), dataTypes.ReadNextVarInt(data))); + + ShowTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Enchantments.Count)); + foreach (var enchantment in Enchantments) + { + data.AddRange(DataTypes.GetVarInt((int)enchantment.Type)); + data.AddRange(DataTypes.GetVarInt(enchantment.Level)); + } + data.AddRange(DataTypes.GetBool(ShowTooltip)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs new file mode 100644 index 00000000..1c3d5f84 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs @@ -0,0 +1,5 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class HideAdditionalTooltipComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs new file mode 100644 index 00000000..c93fa8f9 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs @@ -0,0 +1,5 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class HideTooltipComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs new file mode 100644 index 00000000..16107244 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ItemNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public string ItemName { get; set; } = string.Empty; + + public override void Parse(Queue data) + { + ItemName = ChatParser.ParseText(dataTypes.ReadNextString(data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(ItemName)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs new file mode 100644 index 00000000..5a88e04b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class LoreNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int NumberOfLines { get; set; } + public List Lines { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfLines = dataTypes.ReadNextVarInt(data); + + if (NumberOfLines <= 0) return; + + for (var i = 0; i < NumberOfLines; i++) + Lines.Add(ChatParser.ParseText(dataTypes.ReadNextString(data))); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Lines.Count)); + + if (Lines.Count <= 0) return new Queue(data); + + foreach (var line in Lines) + data.AddRange(DataTypes.GetString(line)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs new file mode 100644 index 00000000..c3890dfb --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MaxDamageComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int MaxDamage { get; set; } + + public override void Parse(Queue data) + { + MaxDamage = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(MaxDamage)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs new file mode 100644 index 00000000..de210a2b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MaxStackSizeComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public int MaxStackSize { get; set; } + + public override void Parse(Queue data) + { + MaxStackSize = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(MaxStackSize)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs new file mode 100644 index 00000000..f14b6d4d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class RarityComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public ItemRarity Rarity { get; set; } + + public override void Parse(Queue data) + { + Rarity = (ItemRarity)dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt((int)Rarity)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs new file mode 100644 index 00000000..a3dfd786 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class UnbrekableComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +{ + public bool Unbrekable { get; set; } + + public override void Parse(Queue data) + { + Unbrekable = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetBool(Unbrekable)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs similarity index 54% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs index fbed4b70..0cc40762 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/TestSubComonent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs @@ -1,19 +1,16 @@ using System.Collections.Generic; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; -namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components; -public class TestSubComonent(DataTypes dataTypes) : SubComponent(dataTypes) +public class EmptyComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) { - public int Test { get; set; } - public override void Parse(Queue data) { - Test = DataTypes.ReadNextVarInt(data); } public override Queue Serialize() { - throw new System.NotImplementedException(); + return new Queue(); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs new file mode 100644 index 00000000..c7d63dd3 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class AttributeSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int TypeId { get; set; } + public Guid Uuid { get; set; } + public string? Name { get; set; } + public double Value { get; set; } + public int Operation { get; set; } + public int Slot { get; set; } + + protected override void Parse(Queue data) + { + TypeId = dataTypes.ReadNextVarInt(data); + Uuid = dataTypes.ReadNextUUID(data); + Name = dataTypes.ReadNextString(data); + Value = dataTypes.ReadNextDouble(data); + Operation = dataTypes.ReadNextVarInt(data); + Slot = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(TypeId)); + data.AddRange(DataTypes.GetUUID(Uuid)); + + if (string.IsNullOrEmpty(Name?.Trim())) + throw new ArgumentNullException($"Can not serialize AttributeSubComponent due to Name being null or empty!"); + + data.AddRange(DataTypes.GetString(Name)); + data.AddRange(DataTypes.GetDouble(Value)); + data.AddRange(DataTypes.GetVarInt(Operation)); + data.AddRange(DataTypes.GetVarInt(Slot)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs new file mode 100644 index 00000000..fae29a94 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class BlockPredicateSubcomponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public bool HasBlocks { get; set; } + public BlockSetSubcomponent1206? BlockSet { get; set; } + public bool HasProperities { get; set; } + public List? Properties { get; set; } + public bool HasNbt { get; set; } + public Dictionary? Nbt { get; set; } + + protected override void Parse(Queue data) + { + HasBlocks = dataTypes.ReadNextBool(data); + + if (HasBlocks) + BlockSet = (BlockSetSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); + + HasProperities = dataTypes.ReadNextBool(data); + + if (HasProperities) + { + Properties = new(); + var numberOfProperties = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < numberOfProperties; i++) + Properties.Add((PropertySubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Property, data)); + } + + HasNbt = dataTypes.ReadNextBool(data); + + if (HasNbt) + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + + // Block Sets + data.AddRange(DataTypes.GetBool(HasBlocks)); + if (HasBlocks) + { + if(BlockSet == null) + throw new ArgumentNullException($"Can not serialize a BlockPredicate when the BlockSet is empty but HasBlocks is true!"); + + data.AddRange(BlockSet.Serialize()); + } + + // Properites + data.AddRange(DataTypes.GetBool(HasProperities)); + if (HasProperities) + { + if(Properties == null || Properties.Count == 0) + throw new ArgumentNullException($"Can not serialize a BlockPredicate when the Properties is empty but HasProperties is true!"); + + foreach (var property in Properties) + data.AddRange(property.Serialize()); + } + + // NBT + if (HasNbt) + { + if(Nbt == null) + throw new ArgumentNullException($"Can not serialize a BlockPredicate when the Nbt is empty but HasNbt is true!"); + + data.AddRange(DataTypes.GetNbt(Nbt)); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs new file mode 100644 index 00000000..a35eeec1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class BlockSetSubcomponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int Type { get; set; } + public string? TagName { get; set; } + public List? BlockIds { get; set; } + + protected override void Parse(Queue data) + { + Type = DataTypes.ReadNextVarInt(data); + + if (Type == 0) + TagName = dataTypes.ReadNextString(data); + + if (Type == 0) return; + + BlockIds = []; + + for (var i = 0; i < Type - 1; i++) + BlockIds.Add(dataTypes.ReadNextVarInt(data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Type)); + if (Type == 0) + { + if (string.IsNullOrEmpty(TagName?.Trim())) + throw new ArgumentNullException($"Can not serialize an empty tag name when the Block Set type is 0!"); + + data.AddRange(DataTypes.GetString(TagName)); + } + + if (Type == 0) return new Queue(data); + + if(BlockIds == null || BlockIds.Count == 0) + throw new ArgumentNullException($"Can not serialize an empty list of Block IDs in a Block Set when the type is not 0!"); + + for(var i = 0; i < Type - 1; i++) + data.AddRange(DataTypes.GetVarInt(BlockIds[i])); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs new file mode 100644 index 00000000..64742c5f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class PropertySubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public string? Name { get; set; } + public bool IsExactMatch { get; set; } + public string? ExactValue { get; set; } + public string? MinValue { get; set; } + public string? MaxValue { get; set; } + + protected override void Parse(Queue data) + { + Name = dataTypes.ReadNextString(data); + IsExactMatch = dataTypes.ReadNextBool(data); + + if (IsExactMatch) + ExactValue = dataTypes.ReadNextString(data); + else // Ranged Match + { + MinValue = dataTypes.ReadNextString(data); + MaxValue = dataTypes.ReadNextString(data); + } + } + + public override Queue Serialize() + { + var data = new List(); + + if (string.IsNullOrEmpty(Name?.Trim())) + throw new ArgumentNullException($"Can not serialize a Property sub-component if the Name is null or empty!"); + + data.AddRange(DataTypes.GetString(Name)); + data.AddRange(DataTypes.GetBool(IsExactMatch)); + + if (IsExactMatch) + { + if (string.IsNullOrEmpty(ExactValue?.Trim())) + throw new ArgumentNullException($"Can not serialize a Property sub-component if the ExactValue is null or empty when the type is Exact Match!"); + + data.AddRange(DataTypes.GetString(ExactValue)); + } + else + { + if (string.IsNullOrEmpty(MinValue?.Trim()) || string.IsNullOrEmpty(MaxValue?.Trim())) + throw new ArgumentNullException($"Can not serialize a Property sub-component if the MinValue or MaxValue is null or empty when the type is not Exact Match!"); + + data.AddRange(DataTypes.GetString(MinValue)); + data.AddRange(DataTypes.GetString(MaxValue)); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs new file mode 100644 index 00000000..9de0e9ad --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs @@ -0,0 +1,9 @@ +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; + +public class SubComponents +{ + public const string BlockPredicate = "BlockPredicate"; + public const string BlockSet = "BlockSet"; + public const string Property = "Property"; + public const string Attribute = "Attribute"; +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs deleted file mode 100644 index befa1217..00000000 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/TestComponent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; -using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; - -namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components; - -public class TestComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) -{ - public int TestInt { get; set; } - public string TestString { get; set; } = null!; - - public TestSubComonent TestSubComonent { get; set; } = null!; - - public override void Parse(Queue data) - { - TestInt = dataTypes.ReadNextVarInt(data); - TestString = dataTypes.ReadNextString(data); - TestSubComonent = (SubComponentRegistry.ParseSubComponent("TestSubComponent", data) as TestSubComonent)!; - } - - public override Queue Serialize() - { - var data = new List(); - data.AddRange(DataTypes.GetVarInt(TestInt)); - data.AddRange(DataTypes.GetString(TestString)); - data.AddRange(TestSubComonent.Serialize()); - return new Queue(data); - } -} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs index af63dce8..be235a91 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; -public abstract class SubComponent(DataTypes dataTypes) +public abstract class SubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) { protected DataTypes DataTypes { get; private set; } = dataTypes; + protected SubComponentRegistry SubComponentRegistry { get; private set; } = subComponentRegistry; - public abstract void Parse(Queue data); + protected abstract void Parse(Queue data); public abstract Queue Serialize(); } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs index 844107c1..90123fe6 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Reflection; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -20,10 +21,15 @@ public abstract class SubComponentRegistry(DataTypes dataTypes) if(!_subComponentParsers.TryGetValue(name, out var subComponentParserType)) throw new Exception($"Sub component {name} not registered!"); - var instance= Activator.CreateInstance(subComponentParserType, dataTypes) as SubComponent ?? + var instance= Activator.CreateInstance(subComponentParserType, dataTypes, this) as SubComponent ?? throw new InvalidOperationException($"Could not create instance of a sub component parser type: {subComponentParserType.Name}"); - instance.Parse(data); + var parseMethod = instance.GetType().GetMethod("Parse", BindingFlags.Instance | BindingFlags.NonPublic); + + if (parseMethod == null) + throw new InvalidOperationException($"Sub component parser type {subComponentParserType.Name} does not have a Parse method."); + + parseMethod.Invoke(instance, new object[] { data }); return instance; } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs index d69507ab..da70c454 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -1,4 +1,4 @@ -using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; @@ -8,6 +8,21 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry public StructuredComponentsRegistry1206(SubComponentRegistry subComponentRegistry, DataTypes dataTypes) : base( subComponentRegistry, dataTypes) { - RegisterComponent(0, "minecraft:test"); + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); + RegisterComponent(5, "minecraft:custom_name"); + RegisterComponent(6, "minecraft:item_name"); + RegisterComponent(7, "minecraft:lore"); + RegisterComponent(8, "minecraft:rarity"); + RegisterComponent(9, "minecraft:enchantments"); + RegisterComponent(10, "minecraft:can_place_on"); + RegisterComponent(11, "minecraft:can_break"); + RegisterComponent(12, "minecraft:attribute_modifiers"); + RegisterComponent(13, "minecraft:custom_model_data"); + RegisterComponent(14, "minecraft:hide_additional_tooltip"); + RegisterComponent(15, "minecraft:hide_tooltip"); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs new file mode 100644 index 00000000..b2428185 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs @@ -0,0 +1,16 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; + +public class SubComponentRegistry1206 : SubComponentRegistry +{ + public SubComponentRegistry1206(DataTypes dataTypes) : base(dataTypes) + { + RegisterSubComponent(SubComponents.BlockPredicate); + RegisterSubComponent(SubComponents.BlockSet); + RegisterSubComponent(SubComponents.Property); + RegisterSubComponent(SubComponents.Attribute); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs deleted file mode 100644 index c10bbc49..00000000 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/TestSubComponentRegistry.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; -using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; - -namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; - -public class TestSubComponentRegistry : SubComponentRegistry -{ - public TestSubComponentRegistry(DataTypes dataTypes) : base(dataTypes) - { - RegisterSubComponent("TestSubcomponent"); - } -} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index 6a03e040..f22405b1 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -18,7 +18,7 @@ public class StructuredComponentsHandler // Get the appropriate subcomponent registry type based on the protocol version and then instantiate it var subcomponentRegistryType = protocolVersion switch { - Protocol18Handler.MC_1_20_6_Version => typeof(TestSubComponentRegistry), + Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") }; diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index 14ac29d1..eff94a09 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -400,9 +400,9 @@ namespace MinecraftClient.Scripting /// Levels required by player for the enchantment in the middle slot /// Levels required by player for the enchantment in the bottom slot public virtual void OnEnchantments( - Enchantment topEnchantment, - Enchantment middleEnchantment, - Enchantment bottomEnchantment, + Enchantments topEnchantment, + Enchantments middleEnchantment, + Enchantments bottomEnchantment, short topEnchantmentLevel, short middleEnchantmentLevel, short bottomEnchantmentLevel, From 49319fe781a5f2fe7c6f639d6ec713538bd3bc44 Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 11 Sep 2024 20:35:23 +0200 Subject: [PATCH 012/484] Added more components + added item palette reference --- .../Protocol/Handlers/DataTypes.cs | 10 ++-- .../1_20_6/AttributeModifiersComponent1206.cs | 8 +-- .../1_20_6/BundleContentsComponent1206.cs | 37 +++++++++++++ .../1_20_6/CanBreakComponent1206.cs | 4 +- .../1_20_6/CanPlaceOnComponent1206.cs | 4 +- .../1_20_6/ChargedProjectilesComponent1206.cs | 37 +++++++++++++ .../1_20_6/CreativeSlotLockComponent1206.cs | 8 +++ .../1_20_6/CustomDataComponent1206.cs | 4 +- .../1_20_6/CustomModelDataComponent1206.cs | 3 +- .../1_20_6/CustomNameComponent1206.cs | 4 +- .../Components/1_20_6/DamageComponent1206.cs | 4 +- .../1_20_6/DyeColorComponent1206.cs | 26 ++++++++++ .../EnchantmentGlintOverrideComponent1206.cs | 23 ++++++++ .../1_20_6/EnchantmentsComponent1206.cs | 4 +- .../1_20_6/FireResistantComponent1206.cs | 7 +++ .../1_20_6/FoodComponentComponent1206.cs | 52 +++++++++++++++++++ .../HideAdditionalTooltipComponent1206.cs | 4 +- .../1_20_6/HideTooltipComponent1206.cs | 4 +- .../IntangibleProjectileComponent1206.cs | 23 ++++++++ .../1_20_6/ItemNameComponent1206.cs | 4 +- .../Components/1_20_6/LoreComponent1206.cs | 4 +- .../1_20_6/MapColorComponent1206.cs | 23 ++++++++ .../1_20_6/MapDecorationsComponent1206.cs | 23 ++++++++ .../Components/1_20_6/MapIdComponent1206.cs | 23 ++++++++ .../1_20_6/MapPostProcessingComponent1206.cs | 23 ++++++++ .../1_20_6/MaxDamageComponent1206.cs | 4 +- .../1_20_6/MaxStackSizeComponent1206.cs | 4 +- .../PotionContentsComponentComponent1206.cs | 48 +++++++++++++++++ .../Components/1_20_6/RarityComponent1206.cs | 4 +- .../1_20_6/RepairCostComponent1206.cs | 23 ++++++++ .../1_20_6/StoredEnchantmentsComponent1206.cs | 9 ++++ .../Components/1_20_6/ToolComponent1206.cs | 44 ++++++++++++++++ .../1_20_6/UnbreakableComponent1206.cs | 4 +- .../Components/EmptyComponent.cs | 3 +- .../1_20_6/DetailsSubComponent1206.cs | 50 ++++++++++++++++++ .../1_20_6/EffectSubComponent1206.cs | 25 +++++++++ .../1_20_6/PotionEffectSubComponent1206.cs | 25 +++++++++ .../1_20_6/RuleSubComponent1206.cs | 43 +++++++++++++++ .../Components/Subcomponents/SubComponents.cs | 4 ++ .../Core/StructuredComponent.cs | 4 +- .../Core/StructuredComponentRegistry.cs | 5 +- .../StructuredComponentsRegistry1206.cs | 22 +++++++- .../Subcomponents/SubComponentRegistry1206.cs | 4 ++ .../StructuredComponentsHandler.cs | 5 +- 44 files changed, 667 insertions(+), 29 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index b62d511c..45b74645 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -445,18 +445,20 @@ namespace MinecraftClient.Protocol.Handlers { var componentTypeId = ReadNextVarInt(cache); - var strcuturedComponentHandler = new StructuredComponentsHandler(protocolversion, this); + var strcuturedComponentHandler = new StructuredComponentsHandler(protocolversion, this, itemPalette); strcturedComponentsToAdd.Add(strcuturedComponentHandler.Parse(componentTypeId, cache)); } for (var i = 0; i < numberofComponentsToRemove; i++) { - // TODO + // TODO: Check what this does exactly + ReadNextVarInt(cache); // The type of component to remove } // TODO: Wire up the strctured components in the Item class (extract info, update fields, etc..) + // Use strcturedComponentsToAdd // Look at: https://wiki.vg/index.php?title=Slot_Data&oldid=19350#Structured_components - + return item; case >= Protocol18Handler.MC_1_13_Version: { @@ -1537,6 +1539,8 @@ namespace MinecraftClient.Protocol.Handlers /// Item slot representation public byte[] GetItemSlot(Item? item, ItemPalette itemPalette) { + // TODO: Wire up Structured components for 1.20.6 + List slotData = new(); if (protocolversion > Protocol18Handler.MC_1_13_Version) { diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs index c2eaa2da..08e0e5f2 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class AttributeModifiersComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class AttributeModifiersComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfAttributes { get; set; } public List Attributes { get; set; } = new(); @@ -27,8 +29,8 @@ public class AttributeModifiersComponent1206(DataTypes dataTypes, SubComponentRe var data = new List(); data.AddRange(DataTypes.GetVarInt(NumberOfAttributes)); - if(NumberOfAttributes > 0 && Attributes.Count == 0) - throw new ArgumentNullException($"Can not serialize a AttributeModifiersComponent when the Attributes is empty but NumberOfAttributes is > 0!"); + if(Attributes.Count != NumberOfAttributes) + throw new ArgumentNullException($"Can not serialize a AttributeModifiersComponent when the Attributes count != NumberOfAttributes!"); foreach (var attribute in Attributes) data.AddRange(attribute.Serialize()); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs new file mode 100644 index 00000000..075c7a7b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class BundleContentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfItems { get; set; } + public List Items { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfItems = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfItems; i++) + Items.Add(dataTypes.ReadNextItemSlot(data, itemPalette)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + + if (NumberOfItems != Items.Count) + throw new ArgumentNullException($"Cannot serialize BundleContentsComponent1206 because NumberOfItems != Items.Count!"); + + foreach (var item in Items.OfType()) + data.AddRange(DataTypes.GetItemSlot(item, itemPalette)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs index 24d50cf5..cf0433d8 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CanBreakComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class CanBreakComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfPredicates { get; set; } public List BlockPredicates { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs index f19211b6..ef2057c9 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CanPlaceOnComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class CanPlaceOnComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfPredicates { get; set; } public List BlockPredicates { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs new file mode 100644 index 00000000..842af032 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ChargedProjectilesComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfItems { get; set; } + public List Items { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfItems = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfItems; i++) + Items.Add(dataTypes.ReadNextItemSlot(data, itemPalette)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + + if (NumberOfItems != Items.Count) + throw new ArgumentNullException($"Cannot serialize ChargedProjectilesComponent1206 because NumberOfItems != Items.Count!"); + + foreach (var item in Items.OfType()) + data.AddRange(DataTypes.GetItemSlot(item, itemPalette)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs new file mode 100644 index 00000000..5d78ac1f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class CreativeSlotLockComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs index 58732f0a..a359522b 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomDataComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class CustomDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public Dictionary? Nbt { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs index 965c4040..a734faac 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomModelDataComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class CustomModelDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Value { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs index 71d95001..59483d4a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class CustomNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string CustomName { get; set; } = string.Empty; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs index 2e6bbadd..6d135ec1 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class DamageComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class DamageComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Damage { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs new file mode 100644 index 00000000..3667cdc5 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class DyeColorComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Color { get; set; } + public bool ShowInTooltip { get; set; } + + public override void Parse(Queue data) + { + Color = dataTypes.ReadNextInt(data); + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetInt(Color)); + data.AddRange(DataTypes.GetBool(ShowInTooltip)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs new file mode 100644 index 00000000..a5ac05e1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class EnchantmentGlintOverrideComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int HasGlint { get; set; } + + public override void Parse(Queue data) + { + HasGlint = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(HasGlint)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs index be5b6e81..3e849220 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class EnchantmentsComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class EnchantmentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfEnchantments { get; set; } public List Enchantments { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs new file mode 100644 index 00000000..89d4a6af --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs @@ -0,0 +1,7 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class FireResistantComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs new file mode 100644 index 00000000..ad9b6fd9 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class FoodComponentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Nutrition { get; set; } + public bool Saturation { get; set; } + public bool CanAlwaysEat { get; set; } + public float SecondsToEat { get; set; } + public int NumberOfEffects { get; set; } + public List Effects { get; set; } = new(); + + public override void Parse(Queue data) + { + Nutrition = dataTypes.ReadNextVarInt(data); + Saturation = dataTypes.ReadNextBool(data); + CanAlwaysEat = dataTypes.ReadNextBool(data); + SecondsToEat = dataTypes.ReadNextFloat(data); + NumberOfEffects = dataTypes.ReadNextVarInt(data); + + for(var i = 0; i < NumberOfEffects; i++) + Effects.Add((EffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Effect, data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Nutrition)); + data.AddRange(DataTypes.GetBool(Saturation)); + data.AddRange(DataTypes.GetBool(CanAlwaysEat)); + data.AddRange(DataTypes.GetFloat(SecondsToEat)); + data.AddRange(DataTypes.GetFloat(NumberOfEffects)); + + if (NumberOfEffects > 0) + { + if(Effects.Count != NumberOfEffects) + throw new ArgumentNullException($"Can not serialize FoodComponent1206 due to NumberOfEffcets being different from the count of elements in the Effects list!"); + + foreach(var effect in Effects) + data.AddRange(effect.Serialize()); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs index 1c3d5f84..d3b9df83 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs @@ -1,5 +1,7 @@ +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class HideAdditionalTooltipComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, subComponentRegistry); \ No newline at end of file +public class HideAdditionalTooltipComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs index c93fa8f9..a7b23fb8 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs @@ -1,5 +1,7 @@ +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class HideTooltipComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, subComponentRegistry); \ No newline at end of file +public class HideTooltipComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs new file mode 100644 index 00000000..e9f94396 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class IntangibleProjectileComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } = new(); + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs index 16107244..3cb8af44 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class ItemNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class ItemNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string ItemName { get; set; } = string.Empty; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs index 5a88e04b..8aa711ef 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class LoreNameComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class LoreNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfLines { get; set; } public List Lines { get; set; } = []; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs new file mode 100644 index 00000000..17f84f6b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MapColorComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Id { get; set; } + + public override void Parse(Queue data) + { + Id = dataTypes.ReadNextInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetInt(Id)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs new file mode 100644 index 00000000..9111f5b6 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MapDecorationsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } = new(); + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs new file mode 100644 index 00000000..283cf024 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MapIdComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Id { get; set; } + + public override void Parse(Queue data) + { + Id = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Id)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs new file mode 100644 index 00000000..c9abbca1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class MapPostProcessingComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Type { get; set; } + + public override void Parse(Queue data) + { + Type = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Type)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs index c3890dfb..abdd483f 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MaxDamageComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class MaxDamageComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int MaxDamage { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs index de210a2b..ec598351 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MaxStackSizeComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class MaxStackSizeComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int MaxStackSize { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs new file mode 100644 index 00000000..e8a28d65 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class PotionContentsComponentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int PotiononId { get; set; } + public bool HasCustomColor { get; set; } + public int CustomColor { get; set; } + public int NumberOfCustomEffects { get; set; } + public List Effects { get; set; } = new(); + + public override void Parse(Queue data) + { + PotiononId = dataTypes.ReadNextVarInt(data); + HasCustomColor = dataTypes.ReadNextBool(data); + CustomColor = dataTypes.ReadNextInt(data); + NumberOfCustomEffects = dataTypes.ReadNextVarInt(data); + + for(var i = 0; i < NumberOfCustomEffects; i++) + Effects.Add((PotionEffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(PotiononId)); + data.AddRange(DataTypes.GetBool(HasCustomColor)); + data.AddRange(DataTypes.GetInt(CustomColor)); + + if (NumberOfCustomEffects > 0) + { + if(Effects.Count != NumberOfCustomEffects) + throw new ArgumentNullException($"Can not serialize PotionContentsComponentComponent1206 due to NumberOfCustomEffects being different from the count of elements in the Effects list!"); + + foreach(var effect in Effects) + data.AddRange(effect.Serialize()); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs index f14b6d4d..100072c9 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class RarityComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class RarityComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public ItemRarity Rarity { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs new file mode 100644 index 00000000..e4153617 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class RepairCostComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Cost { get; set; } + + public override void Parse(Queue data) + { + Cost = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Cost)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs new file mode 100644 index 00000000..05f5e2d8 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class StoredEnchantmentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EnchantmentsComponent1206(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs new file mode 100644 index 00000000..6a04585b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ToolComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfRules { get; set; } + public List Rules { get; set; } = new(); + public float DefaultMiningSpeed { get; set; } + public int DamagePerBlock { get; set; } + + public override void Parse(Queue data) + { + NumberOfRules = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfRules; i++) + Rules.Add((RuleSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Rule, data)); + + DefaultMiningSpeed = dataTypes.ReadNextFloat(data); + DamagePerBlock = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfRules)); + + if(Rules.Count != NumberOfRules) + throw new ArgumentNullException($"Can not serialize a ToolComponent1206 when the Rules count != NumberOfRules!"); + + foreach (var rule in Rules) + data.AddRange(rule.Serialize()); + + data.AddRange(DataTypes.GetFloat(DefaultMiningSpeed)); + data.AddRange(DataTypes.GetVarInt(DamagePerBlock)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs index a3dfd786..39c19014 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class UnbrekableComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class UnbrekableComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public bool Unbrekable { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs index 0cc40762..8b49c908 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components; -public class EmptyComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, subComponentRegistry) +public class EmptyComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public override void Parse(Queue data) { diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs new file mode 100644 index 00000000..289d432c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class DetailsSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int Amplifier { get; set; } + public int Duration { get; set; } + public bool Ambient { get; set; } + public bool ShowParticles { get; set; } + public bool ShowIcon { get; set; } + public bool HasHiddenEffects { get; set; } + public DetailsSubComponent1206? Detail { get; set; } + + protected override void Parse(Queue data) + { + Amplifier = dataTypes.ReadNextVarInt(data); + Duration = dataTypes.ReadNextVarInt(data); + Ambient = dataTypes.ReadNextBool(data); + ShowParticles = dataTypes.ReadNextBool(data); + ShowIcon = dataTypes.ReadNextBool(data); + HasHiddenEffects = dataTypes.ReadNextBool(data); + + if(HasHiddenEffects) + Detail = (DetailsSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Amplifier)); + data.AddRange(DataTypes.GetVarInt(Duration)); + data.AddRange(DataTypes.GetBool(Ambient)); + data.AddRange(DataTypes.GetBool(ShowParticles)); + data.AddRange(DataTypes.GetBool(ShowIcon)); + data.AddRange(DataTypes.GetBool(HasHiddenEffects)); + + if (HasHiddenEffects) + { + if(Detail is null) + throw new ArgumentNullException($"Can not serialize a DetailSubComponent1206 when the Detail is empty but HasHiddenEffects is true!"); + + data.AddRange(Detail.Serialize()); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs new file mode 100644 index 00000000..b7cd1117 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class EffectSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public PotionEffectSubComponent1206 TypeId { get; set; } + public float Probability { get; set; } + + protected override void Parse(Queue data) + { + TypeId = (PotionEffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data); + Probability = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(TypeId.Serialize()); + data.AddRange(DataTypes.GetFloat(Probability)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs new file mode 100644 index 00000000..c325e313 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class PotionEffectSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int TypeId { get; set; } + public DetailsSubComponent1206 Details { get; set; } + + protected override void Parse(Queue data) + { + TypeId = dataTypes.ReadNextVarInt(data); + Details = (DetailsSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(TypeId)); + data.AddRange(Details.Serialize()); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs new file mode 100644 index 00000000..e5830f4d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class RuleSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public BlockSetSubcomponent1206 Blocks { get; set; } + public bool HasSpeed { get; set; } + public float Speed { get; set; } + public bool HasCorrectDropForBlocks { get; set; } + public bool CorrectDropForBlocks { get; set; } + + protected override void Parse(Queue data) + { + Blocks = (BlockSetSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); + HasSpeed = dataTypes.ReadNextBool(data); + + if(HasSpeed) + Speed = dataTypes.ReadNextFloat(data); + + HasCorrectDropForBlocks = dataTypes.ReadNextBool(data); + + if(HasCorrectDropForBlocks) + CorrectDropForBlocks = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(Blocks.Serialize()); + data.AddRange(DataTypes.GetBool(HasSpeed)); + if(HasSpeed) + data.AddRange(DataTypes.GetFloat(Speed)); + + data.AddRange(DataTypes.GetBool(HasCorrectDropForBlocks)); + if(HasCorrectDropForBlocks) + data.AddRange(DataTypes.GetBool(CorrectDropForBlocks)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs index 9de0e9ad..1c4e8d8d 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs @@ -6,4 +6,8 @@ public class SubComponents public const string BlockSet = "BlockSet"; public const string Property = "Property"; public const string Attribute = "Attribute"; + public const string Effect = "Effect"; + public const string PotionEffect = "PotionEffect"; + public const string Details = "Details"; + public const string Rule = "Rule"; } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs index 01995dc2..7465740b 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; -public abstract class StructuredComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) +public abstract class StructuredComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) { protected DataTypes DataTypes { get; private set; } = dataTypes; protected SubComponentRegistry SubComponentRegistry { get; private set; } = subComponentRegistry; + protected ItemPalette ItemPalette { get; private set; } = itemPalette; public abstract void Parse(Queue data); public abstract Queue Serialize(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs index 4dffe457..11c48e1f 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; -public abstract class StructuredComponentRegistry(SubComponentRegistry subComponentRegistry, DataTypes dataTypes) +public abstract class StructuredComponentRegistry(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) { private Dictionary ComponentParsers { get; } = new(); private Dictionary IdToComponent { get; } = new(); @@ -32,7 +33,7 @@ public abstract class StructuredComponentRegistry(SubComponentRegistry subCompon if (ComponentParsers.TryGetValue(name, out var type)) { var component = - Activator.CreateInstance(type, dataTypes, subComponentRegistry) as StructuredComponent + Activator.CreateInstance(type, dataTypes, itemPalette, subComponentRegistry) as StructuredComponent ?? throw new InvalidOperationException($"Could not instantiate a parser for a structured component type {name}"); component.Parse(data); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs index da70c454..586f8870 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -1,3 +1,4 @@ +using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -5,8 +6,8 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; public class StructuredComponentsRegistry1206 : StructuredComponentRegistry { - public StructuredComponentsRegistry1206(SubComponentRegistry subComponentRegistry, DataTypes dataTypes) : base( - subComponentRegistry, dataTypes) + public StructuredComponentsRegistry1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) { RegisterComponent(0, "minecraft:custom_data"); RegisterComponent(1, "minecraft:max_stack_size"); @@ -24,5 +25,22 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry RegisterComponent(13, "minecraft:custom_model_data"); RegisterComponent(14, "minecraft:hide_additional_tooltip"); RegisterComponent(15, "minecraft:hide_tooltip"); + RegisterComponent(16, "minecraft:repair_cost"); + RegisterComponent(17, "minecraft:creative_slot_lock"); + RegisterComponent(18, "minecraft:enchantment_glint_override"); + RegisterComponent(19, "minecraft:intangible_projectile"); + RegisterComponent(20, "minecraft:food"); + RegisterComponent(21, "minecraft:fire_resistant"); + RegisterComponent(22, "minecraft:tool"); + RegisterComponent(23, "minecraft:stored_enchantments"); + RegisterComponent(24, "minecraft:dyed_color"); + RegisterComponent(25, "minecraft:map_color"); + RegisterComponent(26, "minecraft:map_id"); + RegisterComponent(27, "minecraft:map_decorations"); + RegisterComponent(28, "minecraft:map_post_processing"); + RegisterComponent(29, "minecraft:charged_projectiles"); + RegisterComponent(30, "minecraft:bundle_contents"); + RegisterComponent(31, "minecraft:potion_contents"); + } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs index b2428185..91fa60ea 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs @@ -12,5 +12,9 @@ public class SubComponentRegistry1206 : SubComponentRegistry RegisterSubComponent(SubComponents.BlockSet); RegisterSubComponent(SubComponents.Property); RegisterSubComponent(SubComponents.Attribute); + RegisterSubComponent(SubComponents.Effect); + RegisterSubComponent(SubComponents.PotionEffect); + RegisterSubComponent(SubComponents.Details); + RegisterSubComponent(SubComponents.Rule); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index f22405b1..95502463 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -13,7 +13,8 @@ public class StructuredComponentsHandler public StructuredComponentsHandler( int protocolVersion, - DataTypes dataTypes) + DataTypes dataTypes, + ItemPalette itemPalette) { // Get the appropriate subcomponent registry type based on the protocol version and then instantiate it var subcomponentRegistryType = protocolVersion switch @@ -32,7 +33,7 @@ public class StructuredComponentsHandler _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") }; - ComponentRegistry = Activator.CreateInstance(registryType, subcomponentRegistry, dataTypes) as StructuredComponentRegistry + ComponentRegistry = Activator.CreateInstance(registryType, dataTypes, itemPalette, subcomponentRegistry) as StructuredComponentRegistry ?? throw new InvalidOperationException($"Failed to instantiate a component registry for type {nameof(registryType)}"); } From 4dea688ca291351daa249121a8065b8aba3895bf Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 11 Sep 2024 20:58:24 +0200 Subject: [PATCH 013/484] Added more structured components --- MinecraftClient/Inventory/BookPage.cs | 3 + .../Inventory/SuspiciousStewEffect.cs | 3 + ...1206.cs => PotionContentsComponent1206.cs} | 2 +- .../SuspiciousStewEffectsComponent1206.cs | 39 +++++++++ .../WritableBlookContentComponent1206.cs | 56 ++++++++++++ .../WrittenBlookContentComponent1206.cs | 86 +++++++++++++++++++ .../StructuredComponentsRegistry1206.cs | 6 +- 7 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 MinecraftClient/Inventory/BookPage.cs create mode 100644 MinecraftClient/Inventory/SuspiciousStewEffect.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{PotionContentsComponentComponent1206.cs => PotionContentsComponent1206.cs} (93%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs diff --git a/MinecraftClient/Inventory/BookPage.cs b/MinecraftClient/Inventory/BookPage.cs new file mode 100644 index 00000000..c7ec7e44 --- /dev/null +++ b/MinecraftClient/Inventory/BookPage.cs @@ -0,0 +1,3 @@ +namespace MinecraftClient.Inventory; + +public record BookPage(string RawContent, bool HasFilteredContent, string? FilteredContent); \ No newline at end of file diff --git a/MinecraftClient/Inventory/SuspiciousStewEffect.cs b/MinecraftClient/Inventory/SuspiciousStewEffect.cs new file mode 100644 index 00000000..7b1b5553 --- /dev/null +++ b/MinecraftClient/Inventory/SuspiciousStewEffect.cs @@ -0,0 +1,3 @@ +namespace MinecraftClient.Inventory; + +public record SuspiciousStewEffect(int TypeId, int Duration); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs similarity index 93% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs index e8a28d65..cf86da9b 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponentComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class PotionContentsComponentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class PotionContentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int PotiononId { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs new file mode 100644 index 00000000..00e74b80 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class SuspiciousStewEffectsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfEffects { get; set; } + public List Effects { get; set; } = new(); + + public override void Parse(Queue data) + { + NumberOfEffects = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfEffects; i++) + Effects.Add(new SuspiciousStewEffect(dataTypes.ReadNextVarInt(data), dataTypes.ReadNextVarInt(data))); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfEffects)); + + if (NumberOfEffects != Effects.Count) + throw new InvalidOperationException("Can not serialize SuspiciousStewEffectsComponent1206 because umberOfEffects != Effects.Count!"); + + foreach (var effect in Effects) + { + data.AddRange(DataTypes.GetVarInt(effect.TypeId)); + data.AddRange(DataTypes.GetVarInt(effect.Duration)); + } + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs new file mode 100644 index 00000000..4e32ef37 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class WritableBlookContentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfPages { get; set; } + public List Pages { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfPages = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfPages; i++) + { + var rawContent = dataTypes.ReadNextString(data); + var hasFilteredContent = dataTypes.ReadNextBool(data); + var filteredContent = null as string; + + if(hasFilteredContent) + filteredContent = dataTypes.ReadNextString(data); + + Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent)); + } + } + + public override Queue Serialize() + { + var data = new List(); + + data.AddRange(DataTypes.GetVarInt(NumberOfPages)); + + if (NumberOfPages != Pages.Count) + throw new InvalidOperationException("Can not setialize WritableBlookContentComponent1206 because NumberOfPages != Pages.Count!"); + + foreach (var page in Pages) + { + data.AddRange(DataTypes.GetString(page.RawContent)); + data.AddRange(DataTypes.GetBool(page.HasFilteredContent)); + + if (page.HasFilteredContent) + { + if(page.FilteredContent is null) + throw new InvalidOperationException("Can not setialize WritableBlookContentComponent1206 because page.HasFilteredContent = true, but FilteredContent is null!"); + + data.AddRange(DataTypes.GetString(page.FilteredContent)); + } + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs new file mode 100644 index 00000000..8bc2f060 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class WrittenBlookContentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string RawTitle { get; set; } = null!; + public bool HasFilteredTitle { get; set; } + public string? FilteredTitle { get; set; } + public string Author { get; set; } = null!; + public int Generation { get; set; } + public int NumberOfPages { get; set; } + public List Pages { get; set; } = []; + public bool Resolved { get; set; } + + public override void Parse(Queue data) + { + RawTitle = ChatParser.ParseText(dataTypes.ReadNextString(data)); + HasFilteredTitle = dataTypes.ReadNextBool(data); + + if (HasFilteredTitle) + FilteredTitle = dataTypes.ReadNextString(data); + + Author = dataTypes.ReadNextString(data); + Generation = dataTypes.ReadNextVarInt(data); + NumberOfPages = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfPages; i++) + { + var rawContent = ChatParser.ParseText(dataTypes.ReadNextString(data)); + var hasFilteredContent = dataTypes.ReadNextBool(data); + var filteredContent = null as string; + + if(hasFilteredContent) + filteredContent = dataTypes.ReadNextString(data); + + Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent)); + } + + Resolved = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + + data.AddRange(DataTypes.GetString(RawTitle)); + data.AddRange(DataTypes.GetBool(HasFilteredTitle)); + + if (HasFilteredTitle) + { + if(FilteredTitle is null) + throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because HasFilteredTitle is true but FilteredTitle is null!"); + + data.AddRange(DataTypes.GetString(FilteredTitle)); + } + + data.AddRange(DataTypes.GetString(Author)); + data.AddRange(DataTypes.GetVarInt(Generation)); + data.AddRange(DataTypes.GetVarInt(NumberOfPages)); + + if (NumberOfPages != Pages.Count) + throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because NumberOfPages != Pages.Count!"); + + foreach (var page in Pages) + { + data.AddRange(DataTypes.GetString(page.RawContent)); + data.AddRange(DataTypes.GetBool(page.HasFilteredContent)); + + if (page.HasFilteredContent) + { + if(page.FilteredContent is null) + throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because page.HasFilteredContent = true, but FilteredContent is null!"); + + data.AddRange(DataTypes.GetString(page.FilteredContent)); + } + } + data.AddRange(DataTypes.GetBool(Resolved)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs index 586f8870..12c61695 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -40,7 +40,9 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry RegisterComponent(28, "minecraft:map_post_processing"); RegisterComponent(29, "minecraft:charged_projectiles"); RegisterComponent(30, "minecraft:bundle_contents"); - RegisterComponent(31, "minecraft:potion_contents"); - + RegisterComponent(31, "minecraft:potion_contents"); + RegisterComponent(32, "minecraft:suspicious_stew_effects"); + RegisterComponent(33, "minecraft:writable_book_content"); + RegisterComponent(34, "minecraft:written_book_content"); } } \ No newline at end of file From 0da4a718cb03fa40aeb0e61026c012b3d6a1137c Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 5 Oct 2024 13:37:52 +0200 Subject: [PATCH 014/484] Implemented all structured components, renamed them all to a better format --- .../Inventory/TrimAssetOverride.cs | 3 + ...1206.cs => AttributeModifiersComponent.cs} | 6 +- .../1_20_6/BannerPatternsComponent.cs | 68 +++++++++++ .../Components/1_20_6/BaseColorComponent.cs | 23 ++++ .../Components/1_20_6/BeesComponent.cs | 46 ++++++++ .../Components/1_20_6/BlockStateComponent.cs | 32 ++++++ ...nent1206.cs => BundleContentsComponent.cs} | 2 +- ...kComponent1206.cs => CanBreakComponent.cs} | 6 +- ...omponent1206.cs => CanPlaceOnComponent.cs} | 6 +- ...1206.cs => ChargedProjectilesComponent.cs} | 2 +- .../Components/1_20_6/ContainerComponent.cs | 37 ++++++ .../1_20_6/ContainerLootComponent.cs | 23 ++++ ...nt1206.cs => CreativeSlotLockComponent.cs} | 2 +- ...omponent1206.cs => CustomDataComponent.cs} | 2 +- ...ent1206.cs => CustomModelDataComponent.cs} | 2 +- ...omponent1206.cs => CustomNameComponent.cs} | 2 +- ...ageComponent1206.cs => DamageComponent.cs} | 2 +- .../1_20_6/DebugStickStateComponent.cs | 23 ++++ ...rComponent1206.cs => DyeColorComponent.cs} | 2 +- ...s => EnchantmentGlintOverrideComponent.cs} | 2 +- ...ponent1206.cs => EnchantmentsComponent.cs} | 2 +- .../Components/1_20_6/EntityDataComponent.cs | 29 +++++ ...onent1206.cs => FireResistantComponent.cs} | 2 +- .../1_20_6/FireworkExplosionComponent.cs | 25 ++++ .../Components/1_20_6/FireworksComponent.cs | 49 ++++++++ ...onent1206.cs => FoodComponentComponent.cs} | 6 +- ...6.cs => HideAdditionalTooltipComponent.cs} | 2 +- ...mponent1206.cs => HideTooltipComponent.cs} | 2 +- .../Components/1_20_6/InstrumentComponent.cs | 67 +++++++++++ ...06.cs => IntangibleProjectileComponent.cs} | 2 +- ...eComponent1206.cs => ItemNameComponent.cs} | 2 +- .../Components/1_20_6/LockComponent.cs | 23 ++++ .../1_20_6/LodestoneTrackerComponent.cs | 43 +++++++ ...{LoreComponent1206.cs => LoreComponent.cs} | 0 ...rComponent1206.cs => MapColorComponent.cs} | 2 +- ...nent1206.cs => MapDecorationsComponent.cs} | 2 +- ...apIdComponent1206.cs => MapIdComponent.cs} | 2 +- ...t1206.cs => MapPostProcessingComponent.cs} | 2 +- ...Component1206.cs => MaxDamageComponent.cs} | 2 +- ...ponent1206.cs => MaxStackSizeComponent.cs} | 2 +- .../1_20_6/NoteBlockSoundComponent.cs | 23 ++++ .../1_20_6/OmniousBottleAmplifierComponent.cs | 23 ++++ .../1_20_6/PotDecorationsComponent.cs | 28 +++++ ...nent1206.cs => PotionContentsComponent.cs} | 6 +- .../Components/1_20_6/ProfileComponent.cs | 81 +++++++++++++ ...ityComponent1206.cs => RarityComponent.cs} | 2 +- .../Components/1_20_6/RecipesComponent.cs | 23 ++++ ...omponent1206.cs => RepairCostComponent.cs} | 2 +- ...1206.cs => StoredEnchantmentsComponent.cs} | 4 +- ...6.cs => SuspiciousStewEffectsComponent.cs} | 2 +- ...{ToolComponent1206.cs => ToolComponent.cs} | 6 +- .../Components/1_20_6/TrimComponent.cs | 107 ++++++++++++++++++ ...mponent1206.cs => UnbreakableComponent.cs} | 0 ...06.cs => WritableBlookContentComponent.cs} | 2 +- ...206.cs => WrittenBlookContentComponent.cs} | 2 +- ...ponent1206.cs => AttributeSubComponent.cs} | 2 +- ...t1206.cs => BlockPredicateSubcomponent.cs} | 10 +- ...mponent1206.cs => BlockSetSubcomponent.cs} | 2 +- ...omponent1206.cs => DetailsSubComponent.cs} | 6 +- ...Component1206.cs => EffectSubComponent.cs} | 6 +- .../1_20_6/FireworkExplosionSubComponent.cs | 63 +++++++++++ ...ent1206.cs => PotionEffectSubComponent.cs} | 6 +- ...mponent1206.cs => PropertySubComponent.cs} | 2 +- ...ubComponent1206.cs => RuleSubComponent.cs} | 6 +- .../Components/Subcomponents/SubComponents.cs | 3 +- .../StructuredComponentsRegistry1206.cs | 87 ++++++++------ .../Subcomponents/SubComponentRegistry1206.cs | 18 +-- 67 files changed, 971 insertions(+), 108 deletions(-) create mode 100644 MinecraftClient/Inventory/TrimAssetOverride.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{AttributeModifiersComponent1206.cs => AttributeModifiersComponent.cs} (80%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BannerPatternsComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BaseColorComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BeesComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{BundleContentsComponent1206.cs => BundleContentsComponent.cs} (90%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CanBreakComponent1206.cs => CanBreakComponent.cs} (80%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CanPlaceOnComponent1206.cs => CanPlaceOnComponent.cs} (80%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{ChargedProjectilesComponent1206.cs => ChargedProjectilesComponent.cs} (89%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerLootComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CreativeSlotLockComponent1206.cs => CreativeSlotLockComponent.cs} (69%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MapDecorationsComponent1206.cs => CustomDataComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CustomModelDataComponent1206.cs => CustomModelDataComponent.cs} (74%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CustomNameComponent1206.cs => CustomNameComponent.cs} (85%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{DamageComponent1206.cs => DamageComponent.cs} (83%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DebugStickStateComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{DyeColorComponent1206.cs => DyeColorComponent.cs} (86%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{EnchantmentGlintOverrideComponent1206.cs => EnchantmentGlintOverrideComponent.cs} (82%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{EnchantmentsComponent1206.cs => EnchantmentsComponent.cs} (91%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EntityDataComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{HideTooltipComponent1206.cs => FireResistantComponent.cs} (67%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworkExplosionComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworksComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{FoodComponentComponent1206.cs => FoodComponentComponent.cs} (85%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{HideAdditionalTooltipComponent1206.cs => HideAdditionalTooltipComponent.cs} (65%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{FireResistantComponent1206.cs => HideTooltipComponent.cs} (67%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{IntangibleProjectileComponent1206.cs => IntangibleProjectileComponent.cs} (82%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{ItemNameComponent1206.cs => ItemNameComponent.cs} (85%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LockComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LodestoneTrackerComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{LoreComponent1206.cs => LoreComponent.cs} (100%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MapColorComponent1206.cs => MapColorComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{CustomDataComponent1206.cs => MapDecorationsComponent.cs} (91%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MapIdComponent1206.cs => MapIdComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MapPostProcessingComponent1206.cs => MapPostProcessingComponent.cs} (82%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MaxDamageComponent1206.cs => MaxDamageComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{MaxStackSizeComponent1206.cs => MaxStackSizeComponent.cs} (83%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/NoteBlockSoundComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/OmniousBottleAmplifierComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{PotionContentsComponent1206.cs => PotionContentsComponent.cs} (83%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{RarityComponent1206.cs => RarityComponent.cs} (85%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RecipesComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{RepairCostComponent1206.cs => RepairCostComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{StoredEnchantmentsComponent1206.cs => StoredEnchantmentsComponent.cs} (55%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{SuspiciousStewEffectsComponent1206.cs => SuspiciousStewEffectsComponent.cs} (90%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{ToolComponent1206.cs => ToolComponent.cs} (83%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{UnbreakableComponent1206.cs => UnbreakableComponent.cs} (100%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{WritableBlookContentComponent1206.cs => WritableBlookContentComponent.cs} (90%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/{WrittenBlookContentComponent1206.cs => WrittenBlookContentComponent.cs} (94%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{AttributeSubComponent1206.cs => AttributeSubComponent.cs} (90%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{BlockPredicateSubcomponent1206.cs => BlockPredicateSubcomponent.cs} (80%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{BlockSetSubcomponent1206.cs => BlockSetSubcomponent.cs} (91%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{DetailsSubComponent1206.cs => DetailsSubComponent.cs} (83%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{EffectSubComponent1206.cs => EffectSubComponent.cs} (65%) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/FireworkExplosionSubComponent.cs rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{PotionEffectSubComponent1206.cs => PotionEffectSubComponent.cs} (65%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{PropertySubComponent1206.cs => PropertySubComponent.cs} (93%) rename MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/{RuleSubComponent1206.cs => RuleSubComponent.cs} (80%) diff --git a/MinecraftClient/Inventory/TrimAssetOverride.cs b/MinecraftClient/Inventory/TrimAssetOverride.cs new file mode 100644 index 00000000..7047bde2 --- /dev/null +++ b/MinecraftClient/Inventory/TrimAssetOverride.cs @@ -0,0 +1,3 @@ +namespace MinecraftClient.Inventory; + +public record TrimAssetOverride(int ArmorMaterialType, string AssetName); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs similarity index 80% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs index 08e0e5f2..d969d1b4 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs @@ -7,11 +7,11 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class AttributeModifiersComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class AttributeModifiersComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfAttributes { get; set; } - public List Attributes { get; set; } = new(); + public List Attributes { get; set; } = new(); public bool ShowInTooltip { get; set; } public override void Parse(Queue data) @@ -19,7 +19,7 @@ public class AttributeModifiersComponent1206(DataTypes dataTypes, ItemPalette it NumberOfAttributes = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfAttributes; i++) - Attributes.Add((AttributeSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); + Attributes.Add((AttributeSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); ShowInTooltip = dataTypes.ReadNextBool(data); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BannerPatternsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BannerPatternsComponent.cs new file mode 100644 index 00000000..82df01c9 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BannerPatternsComponent.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class BannerPatternsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfLayers { get; set; } + public List Layers { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfLayers = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfLayers; i++) + { + var patternType = dataTypes.ReadNextVarInt(data); + Layers.Add(new BannerLayer + { + PatternType = patternType, + AssetId = patternType == 0 ? dataTypes.ReadNextString(data) : null, + TranslationKey = patternType == 0 ? dataTypes.ReadNextString(data) : null, + DyeColor = dataTypes.ReadNextVarInt(data) + }); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfLayers)); + + if (NumberOfLayers > 0) + { + if (NumberOfLayers != Layers.Count) + throw new Exception("Can't serialize BannerPatternsComponent because NumberOfLayers and Layers.Count differ!"); + + foreach (var bannerLayer in Layers) + { + data.AddRange(DataTypes.GetVarInt(bannerLayer.PatternType)); + + if (bannerLayer.PatternType == 0) + { + if(string.IsNullOrEmpty(bannerLayer.AssetId) || string.IsNullOrEmpty(bannerLayer.TranslationKey)) + throw new Exception("Can't serialize BannerPatternsComponent because AssetId or TranslationKey is null/empty!"); + + data.AddRange(DataTypes.GetString(bannerLayer.AssetId)); + data.AddRange(DataTypes.GetString(bannerLayer.TranslationKey)); + } + + data.AddRange(DataTypes.GetVarInt(bannerLayer.DyeColor)); + } + } + + return new Queue(data); + } +} + +public class BannerLayer +{ + public int PatternType { get; set; } + public string? AssetId { get; set; } = null!; + public string? TranslationKey { get; set; } = null!; + public int DyeColor { get; set; } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BaseColorComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BaseColorComponent.cs new file mode 100644 index 00000000..0f2d9620 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BaseColorComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class BaseColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int DyeColor { get; set; } + + public override void Parse(Queue data) + { + DyeColor = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(DyeColor)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BeesComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BeesComponent.cs new file mode 100644 index 00000000..f0630fe1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BeesComponent.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class BeesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfBees { get; set; } + public List Bees { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfBees = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < NumberOfBees; i++) + { + Bees.Add(new Bee(dataTypes.ReadNextNbt(data), dataTypes.ReadNextVarInt(data), dataTypes.ReadNextVarInt(data))); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfBees)); + + if (NumberOfBees > 0) + { + if (NumberOfBees != Bees.Count) + throw new Exception("Can't serialize the BeeComponent because NumberOfBees and Bees.Count differ!"); + + foreach (var bee in Bees) + { + data.AddRange(DataTypes.GetNbt(bee.EntityDataNbt)); + data.AddRange(DataTypes.GetVarInt(bee.TicksInHive)); + data.AddRange(DataTypes.GetVarInt(bee.MinTicksInHive)); + } + } + + return new Queue(data); + } +} + +public record Bee(Dictionary? EntityDataNbt, int TicksInHive, int MinTicksInHive); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs new file mode 100644 index 00000000..be3950fe --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class BlockStateComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfProperties { get; set; } + public List<(string, string)> Properties { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfProperties = dataTypes.ReadNextVarInt(data); + for(var i = 0; i < NumberOfProperties; i++) + Properties.Add((dataTypes.ReadNextString(data), dataTypes.ReadNextString(data))); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfProperties)); + for (var i = 0; i < NumberOfProperties; i++) + { + data.AddRange(DataTypes.GetString(Properties[i].Item1)); + data.AddRange(DataTypes.GetString(Properties[i].Item2)); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs similarity index 90% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs index 075c7a7b..063d1d20 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class BundleContentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class BundleContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfItems { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent.cs similarity index 80% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent.cs index cf0433d8..06ca3a7b 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent.cs @@ -7,11 +7,11 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CanBreakComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class CanBreakComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfPredicates { get; set; } - public List BlockPredicates { get; set; } = new(); + public List BlockPredicates { get; set; } = new(); public bool ShowInTooltip { get; set; } public override void Parse(Queue data) @@ -19,7 +19,7 @@ public class CanBreakComponent1206(DataTypes dataTypes, ItemPalette itemPalette, NumberOfPredicates = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfPredicates; i++) - BlockPredicates.Add((BlockPredicateSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); + BlockPredicates.Add((BlockPredicateSubcomponent)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); ShowInTooltip = dataTypes.ReadNextBool(data); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent.cs similarity index 80% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent.cs index ef2057c9..581c089f 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent.cs @@ -7,11 +7,11 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CanPlaceOnComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class CanPlaceOnComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfPredicates { get; set; } - public List BlockPredicates { get; set; } = new(); + public List BlockPredicates { get; set; } = new(); public bool ShowInTooltip { get; set; } public override void Parse(Queue data) @@ -19,7 +19,7 @@ public class CanPlaceOnComponent1206(DataTypes dataTypes, ItemPalette itemPalett NumberOfPredicates = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfPredicates; i++) - BlockPredicates.Add((BlockPredicateSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); + BlockPredicates.Add((BlockPredicateSubcomponent)subComponentRegistry.ParseSubComponent(SubComponents.BlockPredicate, data)); ShowInTooltip = dataTypes.ReadNextBool(data); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs similarity index 89% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs index 842af032..ef0875ef 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class ChargedProjectilesComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class ChargedProjectilesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfItems { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs new file mode 100644 index 00000000..2b050aff --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ContainerComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfItems { get; set; } + public List Items { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfItems = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < NumberOfItems; i++) + { + var item = dataTypes.ReadNextItemSlot(data, ItemPalette); + + if (item is null) + continue; + + Items.Add(item); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + for (var i = 0; i < NumberOfItems; i++) + data.AddRange(DataTypes.GetItemSlot(Items[i], itemPalette)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerLootComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerLootComponent.cs new file mode 100644 index 00000000..d0f951ae --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerLootComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ContainerLootComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent.cs similarity index 69% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent.cs index 5d78ac1f..06989ec9 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent.cs @@ -4,5 +4,5 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CreativeSlotLockComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class CreativeSlotLockComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent.cs index 9111f5b6..22b22b70 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MapDecorationsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class CustomDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public Dictionary? Nbt { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent.cs similarity index 74% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent.cs index a734faac..e8c05528 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomModelDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +public class CustomModelDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Value { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs similarity index 85% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs index 59483d4a..024b7a43 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs @@ -5,7 +5,7 @@ using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class CustomNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string CustomName { get; set; } = string.Empty; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent.cs index 6d135ec1..9ac84800 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class DamageComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class DamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Damage { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DebugStickStateComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DebugStickStateComponent.cs new file mode 100644 index 00000000..7cfc68e4 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DebugStickStateComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class DebugStickStateComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent.cs similarity index 86% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent.cs index 3667cdc5..fc6de3d0 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class DyeColorComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class DyeColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Color { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs similarity index 82% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs index a5ac05e1..bdeb1d24 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class EnchantmentGlintOverrideComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class EnchantmentGlintOverrideComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int HasGlint { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs similarity index 91% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs index 3e849220..e38b41fd 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs @@ -5,7 +5,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class EnchantmentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class EnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfEnchantments { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EntityDataComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EntityDataComponent.cs new file mode 100644 index 00000000..a4e6ef98 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EntityDataComponent.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class EntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} + +public class BucketEntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EntityDataComponent(dataTypes, itemPalette, subComponentRegistry) {} + +public class BlockEntityDataComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EntityDataComponent(dataTypes, itemPalette, subComponentRegistry) {} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent.cs similarity index 67% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent.cs index a7b23fb8..e0eed96c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent.cs @@ -3,5 +3,5 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class HideTooltipComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class FireResistantComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworkExplosionComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworkExplosionComponent.cs new file mode 100644 index 00000000..eeb4e876 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworkExplosionComponent.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class FireworkExplosionComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public FireworkExplosionSubComponent? FireworkExplosionSubComponent { get; set; } + + public override void Parse(Queue data) + { + FireworkExplosionSubComponent = (FireworkExplosionSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.FireworkExplosion, data); + } + + public override Queue Serialize() + { + return FireworkExplosionSubComponent!.Serialize(); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworksComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworksComponent.cs new file mode 100644 index 00000000..c670e95d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireworksComponent.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class FireworksComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int FlightDuration { get; set; } + public int NumberOfExplosions { get; set; } + + public List Explosions { get; set; } = []; + + public override void Parse(Queue data) + { + FlightDuration = dataTypes.ReadNextVarInt(data); + NumberOfExplosions = dataTypes.ReadNextVarInt(data); + + if (NumberOfExplosions > 0) + { + for(var i = 0; i < NumberOfExplosions; i++) + Explosions.Add( + (FireworkExplosionSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.FireworkExplosion, + data)); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(FlightDuration)); + data.AddRange(DataTypes.GetVarInt(NumberOfExplosions)); + if (NumberOfExplosions > 0) + { + if (NumberOfExplosions != Explosions.Count) + throw new Exception("Can't serialize FireworksComponent because NumberOfExplosions and the lenght of Explosions differ!"); + + foreach(var explosion in Explosions) + data.AddRange(explosion.Serialize().ToList()); + } + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs similarity index 85% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs index ad9b6fd9..f848750d 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class FoodComponentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class FoodComponentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Nutrition { get; set; } @@ -15,7 +15,7 @@ public class FoodComponentComponent1206(DataTypes dataTypes, ItemPalette itemPal public bool CanAlwaysEat { get; set; } public float SecondsToEat { get; set; } public int NumberOfEffects { get; set; } - public List Effects { get; set; } = new(); + public List Effects { get; set; } = new(); public override void Parse(Queue data) { @@ -26,7 +26,7 @@ public class FoodComponentComponent1206(DataTypes dataTypes, ItemPalette itemPal NumberOfEffects = dataTypes.ReadNextVarInt(data); for(var i = 0; i < NumberOfEffects; i++) - Effects.Add((EffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Effect, data)); + Effects.Add((EffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Effect, data)); } public override Queue Serialize() diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent.cs similarity index 65% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent.cs index d3b9df83..13a7197a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent.cs @@ -3,5 +3,5 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class HideAdditionalTooltipComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class HideAdditionalTooltipComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent.cs similarity index 67% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent.cs index 89d4a6af..b1d0783e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent.cs @@ -3,5 +3,5 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class FireResistantComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class HideTooltipComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs new file mode 100644 index 00000000..87bb17be --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class InstrumentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int InstrumentType { get; set; } + public int SoundEventType { get; set; } + public string? SoundName { get; set; } = null!; + public bool HasFixedRange { get; set; } + public float FixedRange { get; set; } + public float UseDuration { get; set; } + public float Range { get; set; } + + public override void Parse(Queue data) + { + InstrumentType = dataTypes.ReadNextVarInt(data); + + if (InstrumentType == 0) + { + SoundEventType = dataTypes.ReadNextVarInt(data); + SoundName = dataTypes.ReadNextString(data); + + if (SoundEventType == 0) + { + HasFixedRange = dataTypes.ReadNextBool(data); + FixedRange = dataTypes.ReadNextFloat(data); + } + + UseDuration = dataTypes.ReadNextFloat(data); + Range = dataTypes.ReadNextFloat(data); + } + + // TODO: Check, if we need to load in defaults from a registry + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(InstrumentType)); + + if (InstrumentType == 0) + { + data.AddRange(DataTypes.GetVarInt(SoundEventType)); + + if (string.IsNullOrEmpty(SoundName)) + throw new NullReferenceException("Can't serialize InstrumentComponent because SoundName is empty!"); + + data.AddRange(DataTypes.GetString(SoundName)); + if (SoundEventType == 0) + { + data.AddRange(DataTypes.GetBool(HasFixedRange)); + data.AddRange(DataTypes.GetFloat(FixedRange)); + } + + data.AddRange(DataTypes.GetFloat(UseDuration)); + data.AddRange(DataTypes.GetFloat(Range)); + } + + // TODO: Check, if we need to load in defaults from a registry if InstrumentType != 0 and send them + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent.cs similarity index 82% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent.cs index e9f94396..cba25e6e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class IntangibleProjectileComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class IntangibleProjectileComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public Dictionary? Nbt { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs similarity index 85% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs index 3cb8af44..a7c8bda3 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs @@ -5,7 +5,7 @@ using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class ItemNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class ItemNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string ItemName { get; set; } = string.Empty; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LockComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LockComponent.cs new file mode 100644 index 00000000..c9ebe0b0 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LockComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class LockComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LodestoneTrackerComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LodestoneTrackerComponent.cs new file mode 100644 index 00000000..702b8763 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LodestoneTrackerComponent.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class LodestoneTrackerComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool HasGlobalPosition { get; set; } + public string Dimension { get; set; } = null!; + public Location Position { get; set; } + public bool Tracked { get; set; } + + public override void Parse(Queue data) + { + HasGlobalPosition = dataTypes.ReadNextBool(data); + + if (HasGlobalPosition) + { + Dimension = dataTypes.ReadNextString(data); + Position = dataTypes.ReadNextLocation(data); + } + + Tracked = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetBool(HasGlobalPosition)); + + if (HasGlobalPosition) + { + data.AddRange(DataTypes.GetString(Dimension)); + data.AddRange(DataTypes.GetLocation(Position)); + } + + data.AddRange(DataTypes.GetBool(Tracked)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs similarity index 100% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent.cs index 17f84f6b..7c7e9186 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MapColorComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MapColorComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Id { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent.cs similarity index 91% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent.cs index a359522b..c6f8f343 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class CustomDataComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MapDecorationsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public Dictionary? Nbt { get; set; } = new(); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent.cs index 283cf024..2df65305 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MapIdComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MapIdComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Id { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent.cs similarity index 82% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent.cs index c9abbca1..3d02a8bf 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MapPostProcessingComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MapPostProcessingComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Type { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent.cs index abdd483f..8edbd0c2 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MaxDamageComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MaxDamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int MaxDamage { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent.cs index ec598351..11855c6a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class MaxStackSizeComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class MaxStackSizeComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int MaxStackSize { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/NoteBlockSoundComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/NoteBlockSoundComponent.cs new file mode 100644 index 00000000..d4c0a157 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/NoteBlockSoundComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class NoteBlockSoundComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string Identifier { get; set; } = null!; + + public override void Parse(Queue data) + { + Identifier = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(Identifier)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/OmniousBottleAmplifierComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/OmniousBottleAmplifierComponent.cs new file mode 100644 index 00000000..f92a23e7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/OmniousBottleAmplifierComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class OmniousBottleAmplifierComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Amplifier { get; set; } + + public override void Parse(Queue data) + { + Amplifier = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Amplifier)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs new file mode 100644 index 00000000..74607228 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class PotDecorationsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int NumberOfItems { get; set; } + public List Items { get; set; } = []; + + public override void Parse(Queue data) + { + NumberOfItems = dataTypes.ReadNextVarInt(data); + for(var i = 0; i < NumberOfItems; i++) + Items.Add(dataTypes.ReadNextVarInt(data)); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + for(var i = 0; i < NumberOfItems; i++) + data.AddRange(DataTypes.GetVarInt(Items[i])); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs index cf86da9b..be00c31f 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs @@ -7,14 +7,14 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class PotionContentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int PotiononId { get; set; } public bool HasCustomColor { get; set; } public int CustomColor { get; set; } public int NumberOfCustomEffects { get; set; } - public List Effects { get; set; } = new(); + public List Effects { get; set; } = new(); public override void Parse(Queue data) { @@ -24,7 +24,7 @@ public class PotionContentsComponent1206(DataTypes dataTypes, ItemPalette itemPa NumberOfCustomEffects = dataTypes.ReadNextVarInt(data); for(var i = 0; i < NumberOfCustomEffects; i++) - Effects.Add((PotionEffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data)); + Effects.Add((PotionEffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data)); } public override Queue Serialize() diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs new file mode 100644 index 00000000..fc8dc441 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class ProfileComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool HasName { get; set; } + public string? Name { get; set; } = null!; + public bool HasUniqueId { get; set; } + public Guid Uuid { get; set; } + public int NumberOfProperties { get; set; } + public List ProfileProperties { get; set; } = []; + + public override void Parse(Queue data) + { + HasName = dataTypes.ReadNextBool(data); + + if(HasName) + Name = dataTypes.ReadNextString(data); + + HasUniqueId = dataTypes.ReadNextBool(data); + + if (HasUniqueId) + Uuid = dataTypes.ReadNextUUID(data); + + NumberOfProperties = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < NumberOfProperties; i++) + { + var propertyName = dataTypes.ReadNextString(data); + var propertyValue = dataTypes.ReadNextString(data); + var hasSignature = dataTypes.ReadNextBool(data); + var signature = hasSignature ? dataTypes.ReadNextString(data) : null; + + ProfileProperties.Add(new ProfileProperty(propertyName, propertyValue, hasSignature, signature)); + } + } + + public override Queue Serialize() + { + var data = new List(); + + data.AddRange(DataTypes.GetBool(HasName)); + if (HasName) + { + if (string.IsNullOrEmpty(Name)) + throw new NullReferenceException("Can't serialize the ProfileComponent because the Name is null/empty!"); + + data.AddRange(DataTypes.GetString(Name)); + } + + if (HasUniqueId) + data.AddRange(DataTypes.GetUUID(Uuid)); + + if (NumberOfProperties > 0) + { + if(NumberOfProperties != ProfileProperties.Count) + throw new Exception("Can't serialize the ProfileComponent because the NumberOfProperties and ProfileProperties.Count differ!"); + + foreach (var profileProperty in ProfileProperties) + { + data.AddRange(DataTypes.GetString(profileProperty.Name)); + data.AddRange(DataTypes.GetString(profileProperty.Value)); + data.AddRange(DataTypes.GetBool(profileProperty.HasSignature)); + if (profileProperty.HasSignature) + { + if(string.IsNullOrEmpty(profileProperty.Signature)) + throw new NullReferenceException("Can't serialize the ProfileComponent because HasSignature is true, but the Signature is null/empty!"); + + data.AddRange(DataTypes.GetString(profileProperty.Signature)); + } + } + } + + return new Queue(data); + } +} + +public record ProfileProperty(string Name, string Value, bool HasSignature, string? Signature); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent.cs similarity index 85% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent.cs index 100072c9..4da4cb00 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent.cs @@ -5,7 +5,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class RarityComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class RarityComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public ItemRarity Rarity { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RecipesComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RecipesComponent.cs new file mode 100644 index 00000000..a1101eca --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RecipesComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class RecipesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Dictionary? Nbt { get; set; } + + public override void Parse(Queue data) + { + Nbt = dataTypes.ReadNextNbt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetNbt(Nbt)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent.cs index e4153617..ccd1e2b5 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class RepairCostComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class RepairCostComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Cost { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent.cs similarity index 55% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent.cs index 05f5e2d8..0ddbc431 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent.cs @@ -5,5 +5,5 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class StoredEnchantmentsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) - : EnchantmentsComponent1206(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file +public class StoredEnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EnchantmentsComponent(dataTypes, itemPalette, subComponentRegistry); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent.cs similarity index 90% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent.cs index 00e74b80..a6d81d9a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class SuspiciousStewEffectsComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class SuspiciousStewEffectsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfEffects { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent.cs index 6a04585b..3c09e43e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent.cs @@ -7,11 +7,11 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class ToolComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +public class ToolComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfRules { get; set; } - public List Rules { get; set; } = new(); + public List Rules { get; set; } = new(); public float DefaultMiningSpeed { get; set; } public int DamagePerBlock { get; set; } @@ -20,7 +20,7 @@ public class ToolComponent1206(DataTypes dataTypes, ItemPalette itemPalette, Sub NumberOfRules = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfRules; i++) - Rules.Add((RuleSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Rule, data)); + Rules.Add((RuleSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Rule, data)); DefaultMiningSpeed = dataTypes.ReadNextFloat(data); DamagePerBlock = dataTypes.ReadNextVarInt(data); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs new file mode 100644 index 00000000..25d30c4a --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int TrimMaterialType { get; set; } + public string AssetName { get; set; } = null!; + public int Ingredient { get; set; } + public float ItemModelIndex { get; set; } + public int NumberOfOverrides { get; set; } + public List? Overrides { get; set; } + public string Description { get; set; } = null!; + public int TrimPatternType { get; set; } + public string TrimPatternTypeAssetName { get; set; } = null!; + public int TemplateItem { get; set; } + public string TrimPatternTypeDescription { get; set; } = null!; + public bool Decal { get; set; } + public bool ShowInTooltip { get; set; } + + public override void Parse(Queue data) + { + TrimMaterialType = dataTypes.ReadNextVarInt(data); + + if (TrimMaterialType == 0) + { + AssetName = dataTypes.ReadNextString(data); + Ingredient = dataTypes.ReadNextVarInt(data); + ItemModelIndex = dataTypes.ReadNextFloat(data); + NumberOfOverrides = dataTypes.ReadNextVarInt(data); + + if (NumberOfOverrides > 0) + { + Overrides = []; + + for (var i = 0; i < NumberOfOverrides; i++) + Overrides.Add(new TrimAssetOverride(dataTypes.ReadNextVarInt(data), + dataTypes.ReadNextString(data))); + } + + Description = ChatParser.ParseText(dataTypes.ReadNextString(data)); + } + + TrimPatternType = dataTypes.ReadNextVarInt(data); + + if (TrimPatternType == 0) + { + TrimPatternTypeAssetName = dataTypes.ReadNextString(data); + TemplateItem = dataTypes.ReadNextVarInt(data); + TrimPatternTypeDescription = dataTypes.ReadNextString(data); + Decal = dataTypes.ReadNextBool(data); + } + + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + + data.AddRange(DataTypes.GetVarInt(TrimMaterialType)); + + if (TrimMaterialType == 0) + { + if (string.IsNullOrEmpty(AssetName) || string.IsNullOrEmpty(Description)) + throw new NullReferenceException("Can't serialize the TrimComponent because the Asset Name or Description are null!"); + + data.AddRange(DataTypes.GetString(AssetName)); + data.AddRange(DataTypes.GetVarInt(Ingredient)); + data.AddRange(DataTypes.GetFloat(ItemModelIndex)); + data.AddRange(DataTypes.GetVarInt(NumberOfOverrides)); + if (NumberOfOverrides > 0) + { + if(NumberOfOverrides != Overrides?.Count) + throw new NullReferenceException("Can't serialize the TrimComponent because value of NumberOfOverrides and the size of Overrides don't match!"); + + foreach (var (armorMaterialType, assetName) in Overrides) + { + data.AddRange(DataTypes.GetVarInt(armorMaterialType)); + data.AddRange(DataTypes.GetString(assetName)); + } + } + data.AddRange(DataTypes.GetString(Description)); + + data.AddRange(DataTypes.GetVarInt(TrimPatternType)); + if (TrimPatternType == 0) + { + if (string.IsNullOrEmpty(TrimPatternTypeAssetName) || string.IsNullOrEmpty(TrimPatternTypeDescription)) + throw new NullReferenceException("Can't serialize the TrimComponent because the TrimPatternTypeAssetName or TrimPatternTypeDescription are null!"); + + data.AddRange(DataTypes.GetString(TrimPatternTypeAssetName)); + data.AddRange(DataTypes.GetVarInt(TemplateItem)); + data.AddRange(DataTypes.GetString(TrimPatternTypeDescription)); + data.AddRange(DataTypes.GetBool(Decal)); + } + + data.AddRange(DataTypes.GetBool(ShowInTooltip)); + } + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent.cs similarity index 100% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent.cs diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs similarity index 90% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs index 4e32ef37..9c782d55 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs @@ -6,7 +6,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class WritableBlookContentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +public class WritableBlookContentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfPages { get; set; } public List Pages { get; set; } = []; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs similarity index 94% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs index 8bc2f060..bf315b3d 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs @@ -7,7 +7,7 @@ using MinecraftClient.Protocol.Message; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; -public class WrittenBlookContentComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +public class WrittenBlookContentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string RawTitle { get; set; } = null!; public bool HasFilteredTitle { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.cs similarity index 90% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.cs index c7d63dd3..a29374e1 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class AttributeSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class AttributeSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public int TypeId { get; set; } public Guid Uuid { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs similarity index 80% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs index fae29a94..9a562840 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs @@ -4,12 +4,12 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class BlockPredicateSubcomponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class BlockPredicateSubcomponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public bool HasBlocks { get; set; } - public BlockSetSubcomponent1206? BlockSet { get; set; } + public BlockSetSubcomponent? BlockSet { get; set; } public bool HasProperities { get; set; } - public List? Properties { get; set; } + public List? Properties { get; set; } public bool HasNbt { get; set; } public Dictionary? Nbt { get; set; } @@ -18,7 +18,7 @@ public class BlockPredicateSubcomponent1206(DataTypes dataTypes, SubComponentReg HasBlocks = dataTypes.ReadNextBool(data); if (HasBlocks) - BlockSet = (BlockSetSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); + BlockSet = (BlockSetSubcomponent)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); HasProperities = dataTypes.ReadNextBool(data); @@ -27,7 +27,7 @@ public class BlockPredicateSubcomponent1206(DataTypes dataTypes, SubComponentReg Properties = new(); var numberOfProperties = dataTypes.ReadNextVarInt(data); for (var i = 0; i < numberOfProperties; i++) - Properties.Add((PropertySubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Property, data)); + Properties.Add((PropertySubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Property, data)); } HasNbt = dataTypes.ReadNextBool(data); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent.cs similarity index 91% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent.cs index a35eeec1..dbc7c40a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class BlockSetSubcomponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class BlockSetSubcomponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public int Type { get; set; } public string? TagName { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent.cs similarity index 83% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent.cs index 289d432c..7394e13d 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class DetailsSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class DetailsSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public int Amplifier { get; set; } public int Duration { get; set; } @@ -12,7 +12,7 @@ public class DetailsSubComponent1206(DataTypes dataTypes, SubComponentRegistry s public bool ShowParticles { get; set; } public bool ShowIcon { get; set; } public bool HasHiddenEffects { get; set; } - public DetailsSubComponent1206? Detail { get; set; } + public DetailsSubComponent? Detail { get; set; } protected override void Parse(Queue data) { @@ -24,7 +24,7 @@ public class DetailsSubComponent1206(DataTypes dataTypes, SubComponentRegistry s HasHiddenEffects = dataTypes.ReadNextBool(data); if(HasHiddenEffects) - Detail = (DetailsSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); + Detail = (DetailsSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); } public override Queue Serialize() diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent.cs similarity index 65% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent.cs index b7cd1117..a676cfca 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent.cs @@ -4,14 +4,14 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class EffectSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class EffectSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { - public PotionEffectSubComponent1206 TypeId { get; set; } + public PotionEffectSubComponent TypeId { get; set; } public float Probability { get; set; } protected override void Parse(Queue data) { - TypeId = (PotionEffectSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data); + TypeId = (PotionEffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data); Probability = dataTypes.ReadNextFloat(data); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/FireworkExplosionSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/FireworkExplosionSubComponent.cs new file mode 100644 index 00000000..e4c67cc7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/FireworkExplosionSubComponent.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; + +public class FireworkExplosionSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int Shape { get; set; } + public int NumberOfColors { get; set; } + public List Colors { get; set; } = []; + public int NumberOfFadeColors { get; set; } + public List FadeColors { get; set; } = []; + public bool HasTrail { get; set; } + public bool HasTwinkle { get; set; } + + protected override void Parse(Queue data) + { + Shape = dataTypes.ReadNextVarInt(data); + NumberOfColors = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfColors; i++) + Colors.Add(dataTypes.ReadNextInt(data)); + + NumberOfFadeColors = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfFadeColors; i++) + FadeColors.Add(dataTypes.ReadNextInt(data)); + + HasTrail = dataTypes.ReadNextBool(data); + HasTwinkle = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Shape)); + + data.AddRange(DataTypes.GetVarInt(NumberOfColors)); + if (NumberOfColors > 0) + { + if (NumberOfColors != Colors.Count) + throw new Exception("Can't serialize FireworkExplosionComponent because NumberOfColors and the length of Colors list differ!"); + + foreach (var color in Colors) + data.AddRange(DataTypes.GetInt(color)); + } + + data.AddRange(DataTypes.GetVarInt(NumberOfFadeColors)); + if (NumberOfFadeColors > 0) + { + if (NumberOfFadeColors != FadeColors.Count) + throw new Exception("Can't serialize FireworkExplosionComponent because NumberOfFadeColors and the length of FadeColors list differ!"); + + foreach (var fadeColor in FadeColors) + data.AddRange(DataTypes.GetInt(fadeColor)); + } + + data.AddRange(DataTypes.GetBool(HasTrail)); + data.AddRange(DataTypes.GetBool(HasTwinkle)); + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent.cs similarity index 65% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent.cs index c325e313..13cc55f9 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent.cs @@ -4,15 +4,15 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class PotionEffectSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class PotionEffectSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public int TypeId { get; set; } - public DetailsSubComponent1206 Details { get; set; } + public DetailsSubComponent Details { get; set; } protected override void Parse(Queue data) { TypeId = dataTypes.ReadNextVarInt(data); - Details = (DetailsSubComponent1206)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); + Details = (DetailsSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Details, data); } public override Queue Serialize() diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs similarity index 93% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs index 64742c5f..0b8e41eb 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs @@ -4,7 +4,7 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class PropertySubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class PropertySubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { public string? Name { get; set; } public bool IsExactMatch { get; set; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent.cs similarity index 80% rename from MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs rename to MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent.cs index e5830f4d..ca8807b5 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent.cs @@ -4,9 +4,9 @@ using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; -public class RuleSubComponent1206(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +public class RuleSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) { - public BlockSetSubcomponent1206 Blocks { get; set; } + public BlockSetSubcomponent Blocks { get; set; } public bool HasSpeed { get; set; } public float Speed { get; set; } public bool HasCorrectDropForBlocks { get; set; } @@ -14,7 +14,7 @@ public class RuleSubComponent1206(DataTypes dataTypes, SubComponentRegistry subC protected override void Parse(Queue data) { - Blocks = (BlockSetSubcomponent1206)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); + Blocks = (BlockSetSubcomponent)subComponentRegistry.ParseSubComponent(SubComponents.BlockSet, data); HasSpeed = dataTypes.ReadNextBool(data); if(HasSpeed) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs index 1c4e8d8d..5152c9cd 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs @@ -1,6 +1,6 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; -public class SubComponents +public abstract class SubComponents { public const string BlockPredicate = "BlockPredicate"; public const string BlockSet = "BlockSet"; @@ -10,4 +10,5 @@ public class SubComponents public const string PotionEffect = "PotionEffect"; public const string Details = "Details"; public const string Rule = "Rule"; + public const string FireworkExplosion = "FireworkExplosion"; } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs index 12c61695..ebf75e41 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -9,40 +9,61 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry public StructuredComponentsRegistry1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : base(dataTypes, itemPalette, subComponentRegistry) { - RegisterComponent(0, "minecraft:custom_data"); - RegisterComponent(1, "minecraft:max_stack_size"); - RegisterComponent(2, "minecraft:max_damage"); - RegisterComponent(3, "minecraft:damage"); + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); RegisterComponent(4, "minecraft:unbreakable"); - RegisterComponent(5, "minecraft:custom_name"); - RegisterComponent(6, "minecraft:item_name"); + RegisterComponent(5, "minecraft:custom_name"); + RegisterComponent(6, "minecraft:item_name"); RegisterComponent(7, "minecraft:lore"); - RegisterComponent(8, "minecraft:rarity"); - RegisterComponent(9, "minecraft:enchantments"); - RegisterComponent(10, "minecraft:can_place_on"); - RegisterComponent(11, "minecraft:can_break"); - RegisterComponent(12, "minecraft:attribute_modifiers"); - RegisterComponent(13, "minecraft:custom_model_data"); - RegisterComponent(14, "minecraft:hide_additional_tooltip"); - RegisterComponent(15, "minecraft:hide_tooltip"); - RegisterComponent(16, "minecraft:repair_cost"); - RegisterComponent(17, "minecraft:creative_slot_lock"); - RegisterComponent(18, "minecraft:enchantment_glint_override"); - RegisterComponent(19, "minecraft:intangible_projectile"); - RegisterComponent(20, "minecraft:food"); - RegisterComponent(21, "minecraft:fire_resistant"); - RegisterComponent(22, "minecraft:tool"); - RegisterComponent(23, "minecraft:stored_enchantments"); - RegisterComponent(24, "minecraft:dyed_color"); - RegisterComponent(25, "minecraft:map_color"); - RegisterComponent(26, "minecraft:map_id"); - RegisterComponent(27, "minecraft:map_decorations"); - RegisterComponent(28, "minecraft:map_post_processing"); - RegisterComponent(29, "minecraft:charged_projectiles"); - RegisterComponent(30, "minecraft:bundle_contents"); - RegisterComponent(31, "minecraft:potion_contents"); - RegisterComponent(32, "minecraft:suspicious_stew_effects"); - RegisterComponent(33, "minecraft:writable_book_content"); - RegisterComponent(34, "minecraft:written_book_content"); + RegisterComponent(8, "minecraft:rarity"); + RegisterComponent(9, "minecraft:enchantments"); + RegisterComponent(10, "minecraft:can_place_on"); + RegisterComponent(11, "minecraft:can_break"); + RegisterComponent(12, "minecraft:attribute_modifiers"); + RegisterComponent(13, "minecraft:custom_model_data"); + RegisterComponent(14, "minecraft:hide_additional_tooltip"); + RegisterComponent(15, "minecraft:hide_tooltip"); + RegisterComponent(16, "minecraft:repair_cost"); + RegisterComponent(17, "minecraft:creative_slot_lock"); + RegisterComponent(18, "minecraft:enchantment_glint_override"); + RegisterComponent(19, "minecraft:intangible_projectile"); + RegisterComponent(20, "minecraft:food"); + RegisterComponent(21, "minecraft:fire_resistant"); + RegisterComponent(22, "minecraft:tool"); + RegisterComponent(23, "minecraft:stored_enchantments"); + RegisterComponent(24, "minecraft:dyed_color"); + RegisterComponent(25, "minecraft:map_color"); + RegisterComponent(26, "minecraft:map_id"); + RegisterComponent(27, "minecraft:map_decorations"); + RegisterComponent(28, "minecraft:map_post_processing"); + RegisterComponent(29, "minecraft:charged_projectiles"); + RegisterComponent(30, "minecraft:bundle_contents"); + RegisterComponent(31, "minecraft:potion_contents"); + RegisterComponent(32, "minecraft:suspicious_stew_effects"); + RegisterComponent(33, "minecraft:writable_book_content"); + RegisterComponent(34, "minecraft:written_book_content"); + RegisterComponent(35, "minecraft:trim"); + RegisterComponent(36, "minecraft:debug_stick_state"); + RegisterComponent(37, "minecraft:entity_data"); + RegisterComponent(38, "minecraft:bucket_entity_data"); + RegisterComponent(39, "minecraft:block_entity_data"); + RegisterComponent(40, "minecraft:instrument"); + RegisterComponent(41, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(42, "minecraft:recipes"); + RegisterComponent(43, "minecraft:lodestone_tracker"); + RegisterComponent(44, "minecraft:firework_explosion"); + RegisterComponent(45, "minecraft:fireworks"); + RegisterComponent(46, "minecraft:profile"); + RegisterComponent(47, "minecraft:note_block_sound"); + RegisterComponent(48, "minecraft:banner_patterns"); + RegisterComponent(49, "minecraft:base_color"); + RegisterComponent(50, "minecraft:pot_decorations"); + RegisterComponent(51, "minecraft:container"); + RegisterComponent(52, "minecraft:block_state"); + RegisterComponent(53, "minecraft:bees"); + RegisterComponent(54, "minecraft:lock"); + RegisterComponent(55, "minecraft:container_loot"); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs index 91fa60ea..2e270842 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs @@ -1,3 +1,4 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -8,13 +9,14 @@ public class SubComponentRegistry1206 : SubComponentRegistry { public SubComponentRegistry1206(DataTypes dataTypes) : base(dataTypes) { - RegisterSubComponent(SubComponents.BlockPredicate); - RegisterSubComponent(SubComponents.BlockSet); - RegisterSubComponent(SubComponents.Property); - RegisterSubComponent(SubComponents.Attribute); - RegisterSubComponent(SubComponents.Effect); - RegisterSubComponent(SubComponents.PotionEffect); - RegisterSubComponent(SubComponents.Details); - RegisterSubComponent(SubComponents.Rule); + RegisterSubComponent(SubComponents.BlockPredicate); + RegisterSubComponent(SubComponents.BlockSet); + RegisterSubComponent(SubComponents.Property); + RegisterSubComponent(SubComponents.Attribute); + RegisterSubComponent(SubComponents.Effect); + RegisterSubComponent(SubComponents.PotionEffect); + RegisterSubComponent(SubComponents.Details); + RegisterSubComponent(SubComponents.Rule); + RegisterSubComponent(SubComponents.FireworkExplosion); } } \ No newline at end of file From 43c6620475d9f6b15a55fab2e030834f3bdc5070 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 01:38:43 +0000 Subject: [PATCH 015/484] Bump cross-spawn from 7.0.3 to 7.0.6 in /docs Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 7c3cb3be..77e37c43 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -1536,9 +1536,9 @@ cosmiconfig@^7.0.0: yaml "^1.10.0" cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" From 7bd213a154f263c6238c3912b2bf3e0bddb9db0c Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 4 Dec 2024 21:25:22 +0100 Subject: [PATCH 016/484] Fixed the potion component crash --- .../Protocol/Handlers/DataTypes.cs | 346 +++++++++--------- .../1_20_6/PotionContentsComponent.cs | 7 +- 2 files changed, 182 insertions(+), 171 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 45b74645..160e0fb8 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -733,190 +733,198 @@ namespace MinecraftClient.Protocol.Handlers public Dictionary ReadNextMetadata(Queue cache, ItemPalette itemPalette, EntityMetadataPalette metadataPalette) { - Dictionary data = new(); - byte key = ReadNextByte(cache); - byte terminteValue = protocolversion <= Protocol18Handler.MC_1_8_Version - ? (byte)0x7f // 1.8 (https://wiki.vg/index.php?title=Entity_metadata&oldid=6220#Entity_Metadata_Format) - : (byte)0xff; // 1.9+ - - while (key != terminteValue) + try { - int typeId = protocolversion <= Protocol18Handler.MC_1_8_Version - ? key >> 5 // 1.8 - : ReadNextVarInt(cache); // 1.9+ + Dictionary data = new(); + byte key = ReadNextByte(cache); + byte terminteValue = protocolversion <= Protocol18Handler.MC_1_8_Version + ? (byte)0x7f // 1.8 (https://wiki.vg/index.php?title=Entity_metadata&oldid=6220#Entity_Metadata_Format) + : (byte)0xff; // 1.9+ - EntityMetaDataType type; - try + while (key != terminteValue) { - type = metadataPalette.GetDataType(typeId); - } - catch (KeyNotFoundException) - { - throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + typeId + - ". Is this up to date for new MC Version?"); - } + int typeId = protocolversion <= Protocol18Handler.MC_1_8_Version + ? key >> 5 // 1.8 + : ReadNextVarInt(cache); // 1.9+ - if (protocolversion <= Protocol18Handler.MC_1_8_Version) - key = (byte)(key & 0x1f); + EntityMetaDataType type; + try + { + type = metadataPalette.GetDataType(typeId); + } + catch (KeyNotFoundException) + { + throw new System.IO.InvalidDataException("Unknown Metadata Type ID " + typeId + + ". Is this up to date for new MC Version?"); + } - // Value's data type is depended on Type - object? value = null; + if (protocolversion <= Protocol18Handler.MC_1_8_Version) + key = (byte)(key & 0x1f); - switch (type) - { - case EntityMetaDataType.Short: // 1.8 only - value = ReadNextShort(cache); - break; - case EntityMetaDataType.Int: // 1.8 only - value = ReadNextInt(cache); - break; - case EntityMetaDataType.Vector3Int: // 1.8 only - value = new List() - { - ReadNextInt(cache), - ReadNextInt(cache), - ReadNextInt(cache), - }; - break; - case EntityMetaDataType.Byte: // byte - value = ReadNextByte(cache); - break; - case EntityMetaDataType.VarInt: // VarInt - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.VarLong: // Long - value = ReadNextVarLong(cache); - break; - case EntityMetaDataType.Float: // Float - value = ReadNextFloat(cache); - break; - case EntityMetaDataType.String: // String - value = ReadNextString(cache); - break; - case EntityMetaDataType.Chat: // Chat - value = ReadNextChat(cache); - break; - case EntityMetaDataType.OptionalChat: // Optional Chat - if (ReadNextBool(cache)) + // Value's data type is depended on Type + object? value = null; + + switch (type) + { + case EntityMetaDataType.Short: // 1.8 only + value = ReadNextShort(cache); + break; + case EntityMetaDataType.Int: // 1.8 only + value = ReadNextInt(cache); + break; + case EntityMetaDataType.Vector3Int: // 1.8 only + value = new List() + { + ReadNextInt(cache), + ReadNextInt(cache), + ReadNextInt(cache), + }; + break; + case EntityMetaDataType.Byte: // byte + value = ReadNextByte(cache); + break; + case EntityMetaDataType.VarInt: // VarInt + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.VarLong: // Long + value = ReadNextVarLong(cache); + break; + case EntityMetaDataType.Float: // Float + value = ReadNextFloat(cache); + break; + case EntityMetaDataType.String: // String + value = ReadNextString(cache); + break; + case EntityMetaDataType.Chat: // Chat value = ReadNextChat(cache); - break; - case EntityMetaDataType.Slot: // Slot - value = ReadNextItemSlot(cache, itemPalette); - break; - case EntityMetaDataType.Boolean: // Boolean - value = ReadNextBool(cache); - break; - case EntityMetaDataType.Rotation: // Rotation (3x floats) - value = new List - { - ReadNextFloat(cache), - ReadNextFloat(cache), - ReadNextFloat(cache) - }; - break; - case EntityMetaDataType.Position: // Position - value = ReadNextLocation(cache); - break; - case EntityMetaDataType.OptionalPosition: // Optional Position - if (ReadNextBool(cache)) - { - value = ReadNextLocation(cache); - } - - break; - case EntityMetaDataType.Direction: // Direction (VarInt) - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.OptionalUuid: // Optional UUID - if (ReadNextBool(cache)) - { - value = ReadNextUUID(cache); - } - - break; - case EntityMetaDataType.BlockId: // BlockID (VarInt) - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.OptionalBlockId: // Optional BlockID (VarInt) - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.Nbt: // NBT - value = ReadNextNbt(cache); - break; - case EntityMetaDataType.Particle: // Particle - // Skip data only, not used - ReadParticleData(cache, itemPalette); - break; - case EntityMetaDataType.VillagerData: // Villager Data (3x VarInt) - value = new List - { - ReadNextVarInt(cache), - ReadNextVarInt(cache), - ReadNextVarInt(cache) - }; - break; - case EntityMetaDataType.OptionalVarInt: // Optional VarInt - - if (protocolversion < Protocol18Handler.MC_1_20_6_Version) - { + break; + case EntityMetaDataType.OptionalChat: // Optional Chat if (ReadNextBool(cache)) - value = ReadNextVarInt(cache); - } else value = ReadNextVarInt(cache); + value = ReadNextChat(cache); + break; + case EntityMetaDataType.Slot: // Slot + value = ReadNextItemSlot(cache, itemPalette); + break; + case EntityMetaDataType.Boolean: // Boolean + value = ReadNextBool(cache); + break; + case EntityMetaDataType.Rotation: // Rotation (3x floats) + value = new List + { + ReadNextFloat(cache), + ReadNextFloat(cache), + ReadNextFloat(cache) + }; + break; + case EntityMetaDataType.Position: // Position + value = ReadNextLocation(cache); + break; + case EntityMetaDataType.OptionalPosition: // Optional Position + if (ReadNextBool(cache)) + { + value = ReadNextLocation(cache); + } - break; - case EntityMetaDataType.Pose: // Pose - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.CatVariant: // Cat Variant - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.FrogVariant: // Frog Varint - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.GlobalPosition: // GlobalPos - // Dimension and blockPos, currently not in use - value = new Tuple(ReadNextString(cache), ReadNextLocation(cache)); - break; - case EntityMetaDataType.OptionalGlobalPosition: - // FIXME: wiki.vg is bool + string + location - // but minecraft-data is bool + string - if (ReadNextBool(cache)) - { + break; + case EntityMetaDataType.Direction: // Direction (VarInt) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.OptionalUuid: // Optional UUID + if (ReadNextBool(cache)) + { + value = ReadNextUUID(cache); + } + + break; + case EntityMetaDataType.BlockId: // BlockID (VarInt) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.OptionalBlockId: // Optional BlockID (VarInt) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.Nbt: // NBT + value = ReadNextNbt(cache); + break; + case EntityMetaDataType.Particle: // Particle + // Skip data only, not used + ReadParticleData(cache, itemPalette); + break; + case EntityMetaDataType.VillagerData: // Villager Data (3x VarInt) + value = new List + { + ReadNextVarInt(cache), + ReadNextVarInt(cache), + ReadNextVarInt(cache) + }; + break; + case EntityMetaDataType.OptionalVarInt: // Optional VarInt + + if (protocolversion < Protocol18Handler.MC_1_20_6_Version) + { + if (ReadNextBool(cache)) + value = ReadNextVarInt(cache); + } + else value = ReadNextVarInt(cache); + + break; + case EntityMetaDataType.Pose: // Pose + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.CatVariant: // Cat Variant + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.FrogVariant: // Frog Varint + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.GlobalPosition: // GlobalPos // Dimension and blockPos, currently not in use value = new Tuple(ReadNextString(cache), ReadNextLocation(cache)); - } + break; + case EntityMetaDataType.OptionalGlobalPosition: + // FIXME: wiki.vg is bool + string + location + // but minecraft-data is bool + string + if (ReadNextBool(cache)) + { + // Dimension and blockPos, currently not in use + value = new Tuple(ReadNextString(cache), ReadNextLocation(cache)); + } - break; - case EntityMetaDataType.PaintingVariant: // Painting Variant - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.SnifferState: // Sniffer state - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.Vector3: // Vector 3f - value = new List - { - ReadNextFloat(cache), - ReadNextFloat(cache), - ReadNextFloat(cache) - }; - break; - case EntityMetaDataType.Quaternion: // Quaternion - value = new List - { - ReadNextFloat(cache), - ReadNextFloat(cache), - ReadNextFloat(cache), - ReadNextFloat(cache) - }; - break; + break; + case EntityMetaDataType.PaintingVariant: // Painting Variant + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.SnifferState: // Sniffer state + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.Vector3: // Vector 3f + value = new List + { + ReadNextFloat(cache), + ReadNextFloat(cache), + ReadNextFloat(cache) + }; + break; + case EntityMetaDataType.Quaternion: // Quaternion + value = new List + { + ReadNextFloat(cache), + ReadNextFloat(cache), + ReadNextFloat(cache), + ReadNextFloat(cache) + }; + break; + } + + data[key] = value; + key = ReadNextByte(cache); } - data[key] = value; - key = ReadNextByte(cache); + return data; + } + catch(Exception ex) + { + return new Dictionary(); } - - return data; } /// diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs index be00c31f..715cacd3 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs @@ -10,6 +10,7 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { + public bool HasPotionId { get; set; } public int PotiononId { get; set; } public bool HasCustomColor { get; set; } public int CustomColor { get; set; } @@ -18,9 +19,10 @@ public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalett public override void Parse(Queue data) { - PotiononId = dataTypes.ReadNextVarInt(data); + HasPotionId = dataTypes.ReadNextBool(data); + PotiononId = HasPotionId ? dataTypes.ReadNextVarInt(data) : 0; // TODO: Find from the registry HasCustomColor = dataTypes.ReadNextBool(data); - CustomColor = dataTypes.ReadNextInt(data); + CustomColor = HasCustomColor ? dataTypes.ReadNextInt(data) : 0; // TODO: Find from the registry NumberOfCustomEffects = dataTypes.ReadNextVarInt(data); for(var i = 0; i < NumberOfCustomEffects; i++) @@ -30,6 +32,7 @@ public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalett public override Queue Serialize() { var data = new List(); + data.AddRange(DataTypes.GetBool(HasPotionId)); data.AddRange(DataTypes.GetVarInt(PotiononId)); data.AddRange(DataTypes.GetBool(HasCustomColor)); data.AddRange(DataTypes.GetInt(CustomColor)); From d0c9695a795c889e3fef7d87a4de9fc9a05543e0 Mon Sep 17 00:00:00 2001 From: vinicius Date: Thu, 5 Dec 2024 02:12:39 +0000 Subject: [PATCH 017/484] Fixed bug in `SetDimension` method of `World` class, where it would crash if joining a paper server. Added error handling. --- MinecraftClient/Mapping/World.cs | 32 ++++++++++++++++--- .../Protocol/Handlers/Protocol18.cs | 3 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 0b2e02f9..c499d13a 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -19,7 +19,7 @@ namespace MinecraftClient.Mapping /// /// The dimension info of the world /// - private static Dimension curDimension = new(); + private static Dimension curDimension= new(); private static readonly Dictionary dimensionList = new(); @@ -87,10 +87,32 @@ namespace MinecraftClient.Mapping /// /// The name of the dimension type /// The dimension type (NBT Tag Compound) - public static void SetDimension(string name) - { - curDimension = dimensionList[name]; // Should not fail - } + public static void SetDimension(string name) + { + // Try to get the dimension using the name as is + if (dimensionList.TryGetValue(name, out Dimension dimension)) + { + curDimension = dimension; + return; // Dimension found + } + + // If not found, check if name lacks 'minecraft:' prefix and try again + if (!name.StartsWith("minecraft:")) + { + string prefixedName = "minecraft:" + name; + if (dimensionList.TryGetValue(prefixedName, out dimension)) + { + curDimension = dimension; + return; // Dimension found with prefixed name + } + } + + // If still not found, dimension does not exist + throw new KeyNotFoundException($"Dimension '{name}' not found in dimensions dictionary."); + } + + + /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 6b0fa3db..d089fa00 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -660,7 +660,8 @@ namespace MinecraftClient.Protocol.Handlers { case >= MC_1_16_2_Version and <= MC_1_18_2_Version: World.StoreOneDimension(dimensionName, dimensionType!); - World.SetDimension(dimensionName); + // World.SetDimension(dimensionName); + World.SetDimension(dimensionName); break; default: World.SetDimension(dimensionTypeName!); From f83e7c570794277052c5c7d44a49110f379beb30 Mon Sep 17 00:00:00 2001 From: Anon Date: Fri, 6 Dec 2024 16:45:48 +0100 Subject: [PATCH 018/484] Preliminary 1.21 Support --- .../Inventory/EnchantmentMapping.cs | 2 +- .../Mapping/EntityMetadataPalette.cs | 2 +- MinecraftClient/Program.cs | 42 ++-- .../Handlers/ConfigurationPacketTypesIn.cs | 2 + .../Protocol/Handlers/DataTypes.cs | 24 +- .../Handlers/Packet/s2c/DeclareCommands.cs | 6 + .../PacketPalettes/PacketPalette121.cs | 234 ++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 5 +- .../Protocol/Handlers/PacketTypesIn.cs | 2 + .../Protocol/Handlers/Protocol18.cs | 83 +++++-- .../1_21/JukeBoxPlayableComponent.cs | 99 ++++++++ .../1_21/SoundEventSubComponent.cs | 45 ++++ .../Components/Subcomponents/SubComponents.cs | 1 + .../StructuredComponentsRegistry1206.cs | 2 +- .../StructuredComponentsRegistry121.cs | 71 ++++++ .../Subcomponents/SubComponentRegistry121.cs | 15 ++ .../StructuredComponentsHandler.cs | 2 + MinecraftClient/Protocol/ProtocolHandler.cs | 6 +- 18 files changed, 588 insertions(+), 55 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette121.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21/JukeBoxPlayableComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/SoundEventSubComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry121.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index 4f6fca47..e21e3cde 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -196,7 +196,7 @@ namespace MinecraftClient.Inventory { >= Protocol18Handler.MC_1_14_Version and < Protocol18Handler.MC_1_16_Version => enchantmentMappings114, >= Protocol18Handler.MC_1_16_Version and < Protocol18Handler.MC_1_19_Version => enchantmentMappings116, - >= Protocol18Handler.MC_1_19_Version and < Protocol18Handler.MC_1_20_6_Version => enchantmentMappings119, + >= Protocol18Handler.MC_1_19_Version and < Protocol18Handler.MC_1_21_Version => enchantmentMappings119, _ => enchantmentMappings }; diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 5b220474..db544f39 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_12_2_Version => new EntityMetadataPalette1122(), // 1.9 - 1.12.2 <= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2 <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 - <= Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.6 + + <= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.21 + _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 6ff4d63b..1b68583d 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -17,7 +17,6 @@ using MinecraftClient.Protocol.Session; using MinecraftClient.Scripting; using MinecraftClient.WinAPI; using Sentry; -using Tomlet; using static MinecraftClient.Settings; using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig; using static MinecraftClient.Settings.MainConfigHelper.MainConfig.AdvancedConfig; @@ -47,11 +46,11 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.20.6"; + public const string MCHighestVersion = "1.21"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; - private static IDisposable _sentrySdk; + private static IDisposable? _sentrySdk = null; private static bool useMcVersionOnce = false; private static string settingsIniPath = "MinecraftClient.ini"; @@ -74,6 +73,11 @@ namespace MinecraftClient options.EnableTracing = true; options.SendDefaultPii = false; }); + + AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) => + { + SentrySdk.CaptureException((Exception)eventArgs.ExceptionObject); + }; } Task.Run(() => @@ -208,7 +212,7 @@ namespace MinecraftClient } if (!Config.Main.Advanced.EnableSentry) - _sentrySdk.Dispose(); + _sentrySdk?.Dispose(); } //Other command-line arguments @@ -355,7 +359,7 @@ namespace MinecraftClient ConsoleColorModeType.vt100_8bit)).Append(i); } sb.Append(ColorHelper.GetResetEscapeCode()).Append(']'); - ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString())); + ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb)); } { // Test 24 bit color StringBuilder sb = new(); @@ -369,7 +373,7 @@ namespace MinecraftClient ConsoleColorModeType.vt100_24bit)).Append(i); } sb.Append(ColorHelper.GetResetEscapeCode()).Append(']'); - ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb.ToString())); + ConsoleIO.WriteLine(string.Format(Translations.debug_color_test, sb)); } } @@ -382,7 +386,7 @@ namespace MinecraftClient } // Setup exit cleaning code - ExitCleanUp.Add(() => { DoExit(0); }); + ExitCleanUp.Add(() => { DoExit(); }); //Asking the user to type in missing data such as Username and Password bool useBrowser = Config.Main.General.AccountType == LoginType.microsoft && Config.Main.General.Method == LoginMethod.browser; @@ -526,10 +530,10 @@ namespace MinecraftClient worldId = availableWorlds[worldIndex]; if (availableWorlds.Contains(worldId)) { - string RealmsAddress = ProtocolHandler.GetRealmsWorldServerAddress(worldId, InternalConfig.Username, session.PlayerID, session.ID); - if (RealmsAddress != "") + string realmsAddress = ProtocolHandler.GetRealmsWorldServerAddress(worldId, InternalConfig.Username, session.PlayerID, session.ID); + if (realmsAddress != "") { - addressInput = RealmsAddress; + addressInput = realmsAddress; isRealms = true; InternalConfig.MinecraftVersion = MCHighestVersion; } @@ -547,7 +551,7 @@ namespace MinecraftClient } else { - HandleFailure(Translations.error_realms_disabled, false, null); + HandleFailure(Translations.error_realms_disabled); return; } } @@ -560,7 +564,7 @@ namespace MinecraftClient if (InternalConfig.MinecraftVersion != "" && Settings.ToLowerIfNeed(InternalConfig.MinecraftVersion) != "auto") { - protocolversion = Protocol.ProtocolHandler.MCVer2ProtocolVersion(InternalConfig.MinecraftVersion); + protocolversion = ProtocolHandler.MCVer2ProtocolVersion(InternalConfig.MinecraftVersion); if (protocolversion != 0) ConsoleIO.WriteLineFormatted(string.Format(Translations.mcc_use_version, InternalConfig.MinecraftVersion, protocolversion)); @@ -584,7 +588,7 @@ namespace MinecraftClient ConsoleIO.WriteLine(Translations.mcc_retrieve); if (!ProtocolHandler.GetServerInfo(InternalConfig.ServerIP, InternalConfig.ServerPort, ref protocolversion, ref forgeInfo)) { - HandleFailure(Translations.error_ping, true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); + HandleFailure(Translations.error_ping, true, ChatBot.DisconnectReason.ConnectionLost); return; } } @@ -632,7 +636,7 @@ namespace MinecraftClient } else { - HandleFailure(Translations.error_forgeforce, true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); + HandleFailure(Translations.error_forgeforce, true, ChatBot.DisconnectReason.ConnectionLost); return; } } @@ -672,8 +676,7 @@ namespace MinecraftClient else { string failureMessage = Translations.error_login; - string failureReason = string.Empty; - failureReason = result switch + string failureReason = result switch { #pragma warning disable format // @formatter:off ProtocolHandler.LoginResult.AccountMigrated => Translations.error_login_migrated, @@ -714,6 +717,7 @@ namespace MinecraftClient /// Disconnect the current client from the server and restart it /// /// Optional delay, in seconds, before restarting + /// Optional, keep account and server settings public static void Restart(int delaySeconds = 0, bool keepAccountAndServerSettings = false) { ConsoleInteractive.ConsoleReader.StopReadThread(); @@ -734,7 +738,7 @@ namespace MinecraftClient public static void DoExit(int exitcode = 0) { - WriteBackSettings(true); + WriteBackSettings(); ConsoleInteractive.ConsoleSuggestion.ClearSuggestions(); ConsoleIO.WriteLineFormatted("§a" + string.Format(Translations.config_saving, settingsIniPath)); @@ -749,7 +753,7 @@ namespace MinecraftClient /// public static void Exit(int exitcode = 0) { - new Thread(new ThreadStart(() => { DoExit(exitcode); })).Start(); + new Thread(() => { DoExit(exitcode); }).Start(); } /// @@ -759,7 +763,7 @@ namespace MinecraftClient /// Error message to display and optionally pass to AutoRelog bot /// Specify if the error is related to an incompatible or unkown server version /// If set, the error message will be processed by the AutoRelog bot - public static void HandleFailure(string? errorMessage = null, bool versionError = false, ChatBots.AutoRelog.DisconnectReason? disconnectReason = null) + public static void HandleFailure(string? errorMessage = null, bool versionError = false, ChatBot.DisconnectReason? disconnectReason = null) { if (!String.IsNullOrEmpty(errorMessage)) { diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs index f6add9cf..0648601a 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs @@ -3,6 +3,7 @@ namespace MinecraftClient.Protocol.Handlers; public enum ConfigurationPacketTypesIn { CookieRequest, + CustomReportDetails, Disconnect, FeatureFlags, FinishConfiguration, @@ -14,6 +15,7 @@ public enum ConfigurationPacketTypesIn RemoveResourcePack, ResetChat, ResourcePack, + ServerLinks, StoreCookie, Transfer, UpdateTags, diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 160e0fb8..dc953c56 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -974,7 +974,7 @@ namespace MinecraftClient.Protocol.Handlers ReadDustParticle(cache); break; case 13: - // 1.20,6+ - minecraft:dust + // 1.20.6+ - minecraft:dust ReadDustParticle(cache); break; case 14: @@ -1038,7 +1038,7 @@ namespace MinecraftClient.Protocol.Handlers break; case 28: // 1.20.6+ - if (protocolversion > Protocol18Handler.MC_1_20_6_Version) + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) ReadNextVarInt(cache); // minecraft:falling_dust (BlockState) break; case 30: @@ -1053,7 +1053,7 @@ namespace MinecraftClient.Protocol.Handlers break; case 35: // 1.20.6+ - if (protocolversion > Protocol18Handler.MC_1_20_6_Version) + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) ReadNextFloat(cache); // minecraft:sculk_charge (Roll) break; case 36: @@ -1117,6 +1117,11 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) ReadNextItemSlot(cache, itemPalette); // minecraft:item (Item) break; + case 45: + // 1.21+ + if(protocolversion >= Protocol18Handler.MC_1_21_Version) + ReadVibration(cache); + break; case 99: // 1.20.6+ if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) @@ -1143,12 +1148,21 @@ namespace MinecraftClient.Protocol.Handlers ReadNextFloat(cache); // From red ReadNextFloat(cache); // From green ReadNextFloat(cache); // From blue - ReadNextFloat(cache); // Scale ReadNextFloat(cache); // To red ReadNextFloat(cache); // To green - ReadNextFloat(cache); // To Blue + ReadNextFloat(cache); // To blue + ReadNextFloat(cache); // Scale } + private void ReadVibration(Queue cache) + { + ReadNextVarInt(cache); // Position Source Type + ReadNextLocation(cache); // Block Position + ReadNextVarInt(cache); // Entity ID + ReadNextFloat(cache); // Entity eye height + ReadNextVarInt(cache); // Ticks + } + /// /// Read a single villager trade from a cache of bytes and remove it from the cache /// diff --git a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs index 6e4575ab..a0a0d117 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -10,6 +10,12 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c public static void Read(DataTypes dataTypes, Queue packetData, int protocolVersion) { + // TODO: Fix this + // It crashes in 1.20.6+ , could not figure out why + // it's hard to debug, so I'll just disable it for now + if(protocolVersion > Protocol18Handler.MC_1_20_4_Version) + return; + int count = dataTypes.ReadNextVarInt(packetData); Nodes = new CommandNode[count]; for (int i = 0; i < count; ++i) diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette121.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette121.cs new file mode 100644 index 00000000..fc8b64bb --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette121.cs @@ -0,0 +1,234 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette121 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Added in 1.19.4 + { 0x01, PacketTypesIn.SpawnEntity }, // Changed in 1.19 (Wiki name: Spawn Entity) + { 0x02, PacketTypesIn.SpawnExperienceOrb }, // (Wiki name: Spawn Exeprience Orb) + { 0x03, PacketTypesIn.EntityAnimation }, // (Wiki name: Entity Animation (clientbound)) + { 0x04, PacketTypesIn.Statistics }, // (Wiki name: Award Statistics) + { 0x05, PacketTypesIn.BlockChangedAck }, // Added 1.19 (Wiki name: Acknowledge Block Change) + { 0x06, PacketTypesIn.BlockBreakAnimation }, // (Wiki name: Set Block Destroy Stage) + { 0x07, PacketTypesIn.BlockEntityData }, // + { 0x08, PacketTypesIn.BlockAction }, // + { 0x09, PacketTypesIn.BlockChange }, // (Wiki name: Block Update) + { 0x0A, PacketTypesIn.BossBar }, // + { 0x0B, PacketTypesIn.ServerDifficulty }, // (Wiki name: Change Difficulty) + { 0x0C, PacketTypesIn.ChunkBatchFinished }, // Added in 1.20.2 + { 0x0D, PacketTypesIn.ChunkBatchStarted }, // Added in 1.20.2 + { 0x0E, PacketTypesIn.ChunksBiomes }, // Added in 1.19.4 + { 0x0F, PacketTypesIn.ClearTiles }, // + { 0x10, PacketTypesIn.TabComplete }, // (Wiki name: Command Suggestions Response) + { 0x11, PacketTypesIn.DeclareCommands }, // (Wiki name: Commands) + { 0x12, PacketTypesIn.CloseWindow }, // (Wiki name: Close Container (clientbound)) + { 0x13, PacketTypesIn.WindowItems }, // (Wiki name: Set Container Content) + { 0x14, PacketTypesIn.WindowProperty }, // (Wiki name: Set Container Property) + { 0x15, PacketTypesIn.SetSlot }, // (Wiki name: Set Container Slot) + { 0x16, PacketTypesIn.CookieRequest }, // Added in 1.20.6 + { 0x17, PacketTypesIn.SetCooldown }, // + { 0x18, PacketTypesIn.ChatSuggestions }, // Added in 1.19.1 + { 0x19, PacketTypesIn.PluginMessage }, // (Wiki name: Plugin Message (clientbound)) + { 0x1A, PacketTypesIn.DamageEvent }, // Added in 1.19.4 + { 0x1B, PacketTypesIn.DebugSample }, // Added in 1.20.6 + { 0x1C, PacketTypesIn.HideMessage }, // Added in 1.19.1 + { 0x1D, PacketTypesIn.Disconnect }, // + { 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Added in 1.19.3 (Wiki name: Disguised Chat Message) + { 0x1F, PacketTypesIn.EntityStatus }, // (Wiki name: Entity Event) + { 0x20, PacketTypesIn.Explosion }, // Changed in 1.19 (Location fields are now Double instead of Float) (Wiki name: Explosion) + { 0x21, PacketTypesIn.UnloadChunk }, // (Wiki name: Forget Chunk) + { 0x22, PacketTypesIn.ChangeGameState }, // (Wiki name: Game Event) + { 0x23, PacketTypesIn.OpenHorseWindow }, // (Wiki name: Horse Screen Open) + { 0x24, PacketTypesIn.HurtAnimation }, // Added in 1.19.4 + { 0x25, PacketTypesIn.InitializeWorldBorder }, // + { 0x26, PacketTypesIn.KeepAlive }, // + { 0x27, PacketTypesIn.ChunkData }, // + { 0x28, PacketTypesIn.Effect }, // (Wiki name: World Event) + { 0x29, PacketTypesIn.Particle }, // Changed in 1.19 (Wiki name: Level Particle) (No need to be implemented) + { 0x2A, PacketTypesIn.UpdateLight }, // (Wiki name: Light Update) + { 0x2B, PacketTypesIn.JoinGame }, // Changed in 1.20.2 (Wiki name: Login (play)) + { 0x2C, PacketTypesIn.MapData }, // (Wiki name: Map Item Data) + { 0x2D, PacketTypesIn.TradeList }, // (Wiki name: Merchant Offers) + { 0x2E, PacketTypesIn.EntityPosition }, // (Wiki name: Move Entity Position) + { 0x2F, PacketTypesIn.EntityPositionAndRotation }, // (Wiki name: Move Entity Position and Rotation) + { 0x30, PacketTypesIn.EntityRotation }, // (Wiki name: Move Entity Rotation) + { 0x31, PacketTypesIn.VehicleMove }, // (Wiki name: Move Vehicle) + { 0x32, PacketTypesIn.OpenBook }, // + { 0x33, PacketTypesIn.OpenWindow }, // (Wiki name: Open Screen) + { 0x34, PacketTypesIn.OpenSignEditor }, // + { 0x35, PacketTypesIn.Ping }, // (Wiki name: Ping (play)) + { 0x36, PacketTypesIn.PingResponse }, // Added in 1.20.2 + { 0x37, PacketTypesIn.CraftRecipeResponse }, // (Wiki name: Place Ghost Recipe) + { 0x38, PacketTypesIn.PlayerAbilities }, // + { 0x39, PacketTypesIn.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Player Chat Message) + { 0x3A, PacketTypesIn.EndCombatEvent }, // (Wiki name: End Combat) + { 0x3B, PacketTypesIn.EnterCombatEvent }, // (Wiki name: Enter Combat) + { 0x3C, PacketTypesIn.DeathCombatEvent }, // (Wiki name: Combat Death) + { 0x3D, PacketTypesIn.PlayerRemove }, // Added in 1.19.3 (Not used) + { 0x3E, PacketTypesIn.PlayerInfo }, // Changed in 1.19 (Heavy changes) + { 0x3F, PacketTypesIn.FacePlayer }, // (Wiki name: Player Look At) + { 0x40, PacketTypesIn.PlayerPositionAndLook }, // (Wiki name: Synchronize Player Position) + { 0x41, PacketTypesIn.UnlockRecipes }, // (Wiki name: Update Recipe Book) + { 0x42, PacketTypesIn.DestroyEntities }, // (Wiki name: Remove Entites) + { 0x43, PacketTypesIn.RemoveEntityEffect }, // + { 0x44, PacketTypesIn.ResetScore }, // Added in 1.20.3 + { 0x45, PacketTypesIn.RemoveResourcePack }, // Added in 1.20.3 + { 0x46, PacketTypesIn.ResourcePackSend }, // (Wiki name: Add Resource pack (play)) + { 0x47, PacketTypesIn.Respawn }, // Changed in 1.20.2 + { 0x48, PacketTypesIn.EntityHeadLook }, // (Wiki name: Set Head Rotation) + { 0x49, PacketTypesIn.MultiBlockChange }, // (Wiki name: Update Section Blocks) + { 0x4A, PacketTypesIn.SelectAdvancementTab }, // + { 0x4B, PacketTypesIn.ServerData }, // Added in 1.19 + { 0x4C, PacketTypesIn.ActionBar }, // (Wiki name: Set Action Bar Text) + { 0x4D, PacketTypesIn.WorldBorderCenter }, // (Wiki name: Set Border Center) + { 0x4E, PacketTypesIn.WorldBorderLerpSize }, // + { 0x4F, PacketTypesIn.WorldBorderSize }, // (Wiki name: Set World Border Size) + { 0x50, PacketTypesIn.WorldBorderWarningDelay }, // (Wiki name: Set World Border Warning Delay) + { 0x51, PacketTypesIn.WorldBorderWarningReach }, // (Wiki name: Set Border Warning Distance) + { 0x52, PacketTypesIn.Camera }, // (Wiki name: Set Camera) + { 0x53, PacketTypesIn.HeldItemChange }, // (Wiki name: Set Held Item) + { 0x54, PacketTypesIn.UpdateViewPosition }, // (Wiki name: Set Center Chunk) + { 0x55, PacketTypesIn.UpdateViewDistance }, // (Wiki name: Set Render Distance) + { 0x56, PacketTypesIn.SpawnPosition }, // (Wiki name: Set Default Spawn Position) + { 0x57, PacketTypesIn.DisplayScoreboard }, // (Wiki name: Set Display Objective) + { 0x58, PacketTypesIn.EntityMetadata }, // (Wiki name: Set Entity Metadata) + { 0x59, PacketTypesIn.AttachEntity }, // (Wiki name: Link Entities) + { 0x5A, PacketTypesIn.EntityVelocity }, // (Wiki name: Set Entity Velocity) + { 0x5B, PacketTypesIn.EntityEquipment }, // (Wiki name: Set Equipment) + { 0x5C, PacketTypesIn.SetExperience }, // Changed in 1.20.2 + { 0x5D, PacketTypesIn.UpdateHealth }, // (Wiki name: Set Health) + { 0x5E, PacketTypesIn.ScoreboardObjective }, // (Wiki name: Update Objectives) - Changed in 1.20.3 + { 0x5F, PacketTypesIn.SetPassengers }, // + { 0x60, PacketTypesIn.Teams }, // (Wiki name: Update Teams) + { 0x61, PacketTypesIn.UpdateScore }, // (Wiki name: Update Score) + { 0x62, PacketTypesIn.UpdateSimulationDistance }, // (Wiki name: Set Simulation Distance) + { 0x63, PacketTypesIn.SetTitleSubTitle }, // (Wiki name: Set Subtitle Test) + { 0x64, PacketTypesIn.TimeUpdate }, // (Wiki name: Set Time) + { 0x65, PacketTypesIn.SetTitleText }, // (Wiki name: Set Title) + { 0x66, PacketTypesIn.SetTitleTime }, // (Wiki name: Set Title Animation Times) + { 0x67, PacketTypesIn.EntitySoundEffect }, // (Wiki name: Sound Entity) + { 0x68, PacketTypesIn.SoundEffect }, // Changed in 1.19 (Added "Seed" field) (Wiki name: Sound Effect) (No need to be implemented) + { 0x69, PacketTypesIn.StartConfiguration }, // Added in 1.20.2 + { 0x6A, PacketTypesIn.StopSound }, // + { 0x6B, PacketTypesIn.StoreCookie }, // Added in 1.20.6 + { 0x6C, PacketTypesIn.SystemChat }, // Added in 1.19 (Wiki name: System Chat Message) + { 0x6D, PacketTypesIn.PlayerListHeaderAndFooter }, // (Wiki name: Set Tab List Header And Footer) + { 0x6E, PacketTypesIn.NBTQueryResponse }, // (Wiki name: Tag Query Response) + { 0x6F, PacketTypesIn.CollectItem }, // (Wiki name: Pickup Item) + { 0x70, PacketTypesIn.EntityTeleport }, // (Wiki name: Teleport Entity) + { 0x71, PacketTypesIn.SetTickingState }, // Added in 1.20.3 + { 0x72, PacketTypesIn.StepTick }, // Added in 1.20.3 + { 0x73, PacketTypesIn.Transfer }, // Added in 1.20.6 + { 0x74, PacketTypesIn.Advancements }, // (Wiki name: Update Advancements) (Unused) + { 0x75, PacketTypesIn.EntityProperties }, // (Wiki name: Update Attributes) + { 0x76, PacketTypesIn.EntityEffect }, // Changed in 1.19 (Added "Has Factor Data" and "Factor Codec" fields) (Wiki name: Entity Effect) + { 0x77, PacketTypesIn.DeclareRecipes }, // (Wiki name: Update Recipes) (Unused) + { 0x78, PacketTypesIn.Tags }, // (Wiki name: Update Tags) + { 0x79, PacketTypesIn.ProjectilePower }, // Added in 1.20.6 + { 0x7A, PacketTypesIn.CustomReportDetails }, // Added in 1.21 + { 0x7B, PacketTypesIn.ServerLinks } // Added in 1.21 + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // (Wiki name: Confirm Teleportation) + { 0x01, PacketTypesOut.QueryBlockNBT }, // (Wiki name: Query Block Entity Tag) + { 0x02, PacketTypesOut.SetDifficulty }, // (Wiki name: Change Difficulty) + { 0x03, PacketTypesOut.MessageAcknowledgment }, // Added in 1.19.1 + { 0x04, PacketTypesOut.ChatCommand }, // Added in 1.19 + { 0x05, PacketTypesOut.SignedChatCommand }, // Added in 1.20.6 + { 0x06, PacketTypesOut.ChatMessage }, // Changed in 1.19 (Completely changed) (Wiki name: Chat) + { 0x07, PacketTypesOut.PlayerSession }, // Added in 1.19.3 + { 0x08, PacketTypesOut.ChunkBatchReceived }, // Added in 1.20.2 + { 0x09, PacketTypesOut.ClientStatus }, // (Wiki name: Client Command) + { 0x0A, PacketTypesOut.ClientSettings }, // (Wiki name: Client Information) + { 0x0B, PacketTypesOut.TabComplete }, // (Wiki name: Command Suggestions Request) + { 0x0C, PacketTypesOut.AcknowledgeConfiguration }, // Added in 1.20.2 + { 0x0D, PacketTypesOut.ClickWindowButton }, // (Wiki name: Click Container Button) + { 0x0E, PacketTypesOut.ClickWindow }, // (Wiki name: Click Container) + { 0x0F, PacketTypesOut.CloseWindow }, // (Wiki name: Close Container (serverbound)) + { 0x10, PacketTypesOut.ChangeContainerSlotState }, // Added in 1.20.3 + { 0x11, PacketTypesOut.CookieResponse }, // Added in 1.20.6 + { 0x12, PacketTypesOut.PluginMessage }, // (Wiki name: Serverbound Plugin Message) + { 0x13, PacketTypesOut.DebugSampleSubscription }, // Added in 1.20.6 + { 0x14, PacketTypesOut.EditBook }, // + { 0x15, PacketTypesOut.EntityNBTRequest }, // (Wiki name: Query Entity Tag) + { 0x16, PacketTypesOut.InteractEntity }, // (Wiki name: Interact) + { 0x17, PacketTypesOut.GenerateStructure }, // (Wiki name: Jigsaw Generate) + { 0x18, PacketTypesOut.KeepAlive }, // (Wiki name: Serverbound Keep Alive (play)) + { 0x19, PacketTypesOut.LockDifficulty }, // + { 0x1A, PacketTypesOut.PlayerPosition }, // (Wiki name: Move Player Position) + { 0x1B, PacketTypesOut.PlayerPositionAndRotation }, // (Wiki name: Set Player Position and Rotation) + { 0x1C, PacketTypesOut.PlayerRotation }, // (Wiki name: Set Player Rotation) + { 0x1D, PacketTypesOut.PlayerMovement }, // (Wiki name: Set Player On Ground) + { 0x1E, PacketTypesOut.VehicleMove }, // (Wiki name: Move Vehicle (serverbound)) + { 0x1F, PacketTypesOut.SteerBoat }, // (Wiki name: Paddle Boat) + { 0x20, PacketTypesOut.PickItem }, // + { 0x21, PacketTypesOut.PingRequest }, // Added in 1.20.2 + { 0x22, PacketTypesOut.CraftRecipeRequest }, // (Wiki name: Place recipe) + { 0x23, PacketTypesOut.PlayerAbilities }, // + { 0x24, PacketTypesOut.PlayerDigging }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Player Action) + { 0x25, PacketTypesOut.EntityAction }, // (Wiki name: Player Command) + { 0x26, PacketTypesOut.SteerVehicle }, // (Wiki name: Player Input) + { 0x27, PacketTypesOut.Pong }, // (Wiki name: Pong (play)) + { 0x28, PacketTypesOut.SetDisplayedRecipe }, // (Wiki name: Recipe Book Change Settings) + { 0x29, PacketTypesOut.SetRecipeBookState }, // (Wiki name: Recipe Book Seen Recipe) + { 0x2A, PacketTypesOut.NameItem }, // (Wiki name: Rename Item) + { 0x2B, PacketTypesOut.ResourcePackStatus }, // (Wiki name: Resource Pack (serverbound)) + { 0x2C, PacketTypesOut.AdvancementTab }, // (Wiki name: Seen Advancements) + { 0x2D, PacketTypesOut.SelectTrade }, // + { 0x2E, PacketTypesOut.SetBeaconEffect }, // Changed in 1.19 (No need to be implemented yet) + { 0x2F, PacketTypesOut.HeldItemChange }, // (Wiki name: Set Carried Item (serverbound)) + { 0x30, PacketTypesOut.UpdateCommandBlock }, // (Wiki name: Program Command Block) + { 0x31, PacketTypesOut.UpdateCommandBlockMinecart }, // (Wiki name: Program Command Block Minecart) + { 0x32, PacketTypesOut.CreativeInventoryAction }, // (Wiki name: Set Creative Mode Slot) + { 0x33, PacketTypesOut.UpdateJigsawBlock }, // (Wiki name: Program Jigsaw Block) + { 0x34, PacketTypesOut.UpdateStructureBlock }, // (Wiki name: Program Structure Block) + { 0x35, PacketTypesOut.UpdateSign }, // (Wiki name: Update Sign) + { 0x36, PacketTypesOut.Animation }, // (Wiki name: Swing Arm) + { 0x37, PacketTypesOut.Spectate }, // (Wiki name: Teleport To Entity) + { 0x38, PacketTypesOut.PlayerBlockPlacement }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item On) + { 0x39, PacketTypesOut.UseItem }, // Changed in 1.19 (Added a "Sequence" field) (Wiki name: Use Item) + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, // Added in 1.21 (Not used) + { 0x10, ConfigurationPacketTypesIn.ServerLinks } // Added in 1.21 (Not used) + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 5deac47b..7d80d4ee 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,7 +48,7 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_20_6_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_Version => throw new NotImplementedException(Translations .exception_palette_packet), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), <= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(), @@ -68,7 +68,8 @@ namespace MinecraftClient.Protocol.Handlers <= Protocol18Handler.MC_1_20_Version => new PacketPalette1194(), <= Protocol18Handler.MC_1_20_2_Version => new PacketPalette1202(), <= Protocol18Handler.MC_1_20_4_Version => new PacketPalette1204(), - _ => new PacketPalette1206() + <= Protocol18Handler.MC_1_20_6_Version => new PacketPalette1206(), + _ => new PacketPalette121() }; p.SetForgeEnabled(forgeEnabled); diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 9eab7b39..d3feabb7 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -31,6 +31,7 @@ CombatEvent, // CookieRequest, // Added in 1.20.6 CraftRecipeResponse, // + CustomReportDetails, // Added in 1.21 (Not used) DamageEvent, // Added in 1.19.4 DeathCombatEvent, // DebugSample, // Added in 1.20.6 @@ -95,6 +96,7 @@ SelectAdvancementTab, // ServerData, // Added in 1.19 ServerDifficulty, // + ServerLinks, // Added in 1.21 (Not used) SetCompression, // For 1.8 or below SetCooldown, // SetDisplayChatPreview, // Added in 1.19 diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index b682551f..f8a8c427 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -72,8 +72,9 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_20_2_Version = 764; internal const int MC_1_20_4_Version = 765; internal const int MC_1_20_6_Version = 766; + internal const int MC_1_21_Version = 767; - private int compression_treshold = 0; + private int compression_treshold = -1; private int autocomplete_transaction_id = 0; private readonly Dictionary window_actions = new(); private CurrentState currentState = CurrentState.Login; @@ -123,21 +124,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_20_6_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_20_6_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_20_6_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -146,9 +147,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_20_6_Version when handler.GetTerrainEnabled() => + > MC_1_21_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), - MC_1_20_6_Version => new Palette1206(), + >= MC_1_20_6_Version => new Palette1206(), >= MC_1_20_4_Version => new Palette1204(), >= MC_1_20_Version => new Palette120(), MC_1_19_4_Version => new Palette1194(), @@ -165,9 +166,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_20_6_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), - MC_1_20_6_Version => new EntityPalette1206(), + >= MC_1_20_6_Version => new EntityPalette1206(), >= MC_1_20_4_Version => new EntityPalette1204(), >= MC_1_20_Version => new EntityPalette120(), MC_1_19_4_Version => new EntityPalette1194(), @@ -188,9 +189,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_20_6_Version when handler.GetInventoryEnabled() => + > MC_1_21_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), - MC_1_20_6_Version => new ItemPalette1206(), + >= MC_1_20_6_Version => new ItemPalette1206(), >= MC_1_20_4_Version => new ItemPalette1204(), >= MC_1_20_Version => new ItemPalette120(), MC_1_19_4_Version => new ItemPalette1194(), @@ -349,7 +350,7 @@ namespace MinecraftClient.Protocol.Handlers //Handle packet decompression if (protocolVersion >= MC_1_8_Version - && compression_treshold > 0) + && compression_treshold >= 0) { var sizeUncompressed = dataTypes.ReadNextVarInt(packetData); if (sizeUncompressed != 0) // != 0 means compressed, let's decompress @@ -457,7 +458,7 @@ namespace MinecraftClient.Protocol.Handlers } else { - // TODO: Implement proper parsing for 1.20.6 when there is a custom data pack on the server + // TODO: Implement proper parsing for 1.20.6 / 1.21 when there is a custom data pack on the server // THis is a temporary workaround to get the client to be useable asap var registryId = dataTypes.ReadNextString(packetData); @@ -2309,6 +2310,15 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { var entity = dataTypes.ReadNextEntity(packetData, entityPalette, false); + + if (protocolVersion >= MC_1_20_2_Version) + { + if (entity.Type == EntityType.Player) + handler.OnSpawnPlayer(entity.ID, entity.UUID, entity.Location, (byte)entity.Yaw, (byte)entity.Pitch); + + break; + } + handler.OnSpawnEntity(entity); } @@ -2526,7 +2536,10 @@ namespace MinecraftClient.Protocol.Handlers { 18, "generic.safe_fall_distance" }, { 19, "generic.scale" }, { 20, "zombie.spawn_reinforcements" }, - { 21, "generic.step_height" } + { 21, "generic.step_height" }, + { 22, "generic.submerged_mining_speed" }, + { 23, "generic.sweeping_damage_ratio" }, + { 24, "generic.water_movement_efficiency" } }; Dictionary keys = new(); @@ -2543,7 +2556,7 @@ namespace MinecraftClient.Protocol.Handlers var numberOfModifiers = dataTypes.ReadNextVarInt(packetData); for (var j = 0; j < numberOfModifiers; j++) { - dataTypes.ReadNextUUID(packetData); + var modifierId = protocolVersion < MC_1_21_Version ? dataTypes.ReadNextUUID(packetData).ToString() : dataTypes.ReadNextString(packetData); var amount = dataTypes.ReadNextDouble(packetData); var operation = dataTypes.ReadNextByte(packetData); switch (operation) @@ -2579,7 +2592,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_20_6_Version => throw new NotImplementedException(Translations + > MC_1_21_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, @@ -2669,28 +2682,41 @@ namespace MinecraftClient.Protocol.Handlers // Records for (var i = 0; i < explosionBlockCount; i++) - dataTypes.ReadData(3, packetData); + dataTypes.ReadNextByteArray(packetData, 3); // Maybe use in the future when the physics are implemented dataTypes.ReadNextFloat(packetData); // Player Motion X dataTypes.ReadNextFloat(packetData); // Player Motion Y dataTypes.ReadNextFloat(packetData); // Player Motion Z - if (protocolVersion >= MC_1_20_4_Version) + // Cut off here, there is an issue, the code bllow crashes on sound name reading + // I am unable to figure out what part of the code is reading more bytes than it should + // TODO: Fix + handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); + break; + + /*if (protocolVersion >= MC_1_20_4_Version) { - dataTypes.ReadNextVarInt(packetData); // Block Interaction - dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles - dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles + var blockInteraction = dataTypes.ReadNextVarInt(packetData); // Block Interaction + + if(explosionStrength >= 2.0 || blockInteraction != 0) + dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles + else + dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles // Explosion Sound dataTypes.ReadNextString(packetData); // Sound Name - var hasFixedRange = dataTypes.ReadNextBool(packetData); - if (hasFixedRange) - dataTypes.ReadNextFloat(packetData); // Range + + if (protocolVersion < MC_1_21_Version) + { + var hasFixedRange = dataTypes.ReadNextBool(packetData); + if (hasFixedRange) + dataTypes.ReadNextFloat(packetData); // Range + } } handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); - break; + break;*/ case PacketTypesIn.HeldItemChange: handler.OnHeldItemChange(dataTypes.ReadNextByte(packetData)); // Slot break; @@ -2919,7 +2945,7 @@ namespace MinecraftClient.Protocol.Handlers //The inner packet var thePacket = dataTypes.ConcatBytes(DataTypes.GetVarInt(packetId), packetData.ToArray()); - if (compression_treshold > 0) //Compression enabled? + if (compression_treshold >= 0) //Compression enabled? { thePacket = thePacket.Length >= compression_treshold ? dataTypes.ConcatBytes(DataTypes.GetVarInt(thePacket.Length), ZlibUtils.Compress(thePacket)) @@ -4060,6 +4086,13 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(DataTypes.GetVarInt(hand)); if (protocolVersion >= MC_1_19_Version) packet.AddRange(DataTypes.GetVarInt(sequenceId)); + + if (protocolVersion >= MC_1_21_Version) + { + packet.AddRange(dataTypes.GetFloat(LastYaw)); + packet.AddRange(dataTypes.GetFloat(LastPitch)); + } + SendPacket(PacketTypesOut.UseItem, packet); return true; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21/JukeBoxPlayableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21/JukeBoxPlayableComponent.cs new file mode 100644 index 00000000..d97b9cf8 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21/JukeBoxPlayableComponent.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; + +public class JukeBoxPlayableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool DirectMode { get; set; } + public string? SongName { get; set; } + public int? SongType { get; set; } + public SoundEventSubComponent? SoundEvent { get; set; } + public string? Description { get; set; } + public float? Duration { get; set; } + public int? Output { get; set; } + public bool ShowTooltip { get; set; } + + public override void Parse(Queue data) + { + DirectMode = dataTypes.ReadNextBool(data); + + if (!DirectMode) + SongName = dataTypes.ReadNextString(data); + + if (DirectMode) + { + SongType = dataTypes.ReadNextVarInt(data); + + if (SongType == 0) + { + SoundEvent = + (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data); + Description = dataTypes.ReadNextString(data); + Duration = dataTypes.ReadNextFloat(data); + Output = dataTypes.ReadNextVarInt(data); + } + } + + ShowTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + + data.AddRange(DataTypes.GetBool(DirectMode)); + + if (!DirectMode) + { + if (string.IsNullOrEmpty(SongName?.Trim())) + throw new ArgumentNullException($"Can not serialize JukeBoxPlayableComponent due to SongName being null or empty!"); + + data.AddRange(DataTypes.GetString(SongName)); + } + + if (DirectMode) + { + if(SongType is null) + throw new ArgumentNullException($"Can not serialize JukeBoxPlayableComponent due to SongType being null!"); + + data.AddRange(DataTypes.GetVarInt((int)SongType)); + + if (SongType == 0) + { + if (SoundEvent is null) + throw new ArgumentNullException( + $"Can not serialize JukeBoxPlayableComponent due to SoundEvent being null"); + + data.AddRange(SoundEvent.Serialize()); + + if (string.IsNullOrEmpty(Description?.Trim())) + throw new ArgumentNullException( + $"Can not serialize JukeBoxPlayableComponent due to Description being null or empty!"); + + data.AddRange(DataTypes.GetString(Description)); + + if (Duration is null) + throw new ArgumentNullException( + $"Can not serialize JukeBoxPlayableComponent due to Duration being null!"); + + data.AddRange(DataTypes.GetFloat((float)Duration)); + + if (Output is null) + throw new ArgumentNullException( + $"Can not serialize JukeBoxPlayableComponent due to Description being null!"); + + data.AddRange(DataTypes.GetVarInt((int)Output)); + } + } + + data.AddRange(DataTypes.GetBool(ShowTooltip)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/SoundEventSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/SoundEventSubComponent.cs new file mode 100644 index 00000000..cfa0f833 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/SoundEventSubComponent.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; + +public class SoundEventSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int Type { get; set; } + public string? SoundName { get; set; } + public bool HasFixedRange { get; set; } + public float FixedRange { get; set; } + + protected override void Parse(Queue data) + { + Type = dataTypes.ReadNextVarInt(data); + + if (Type != 0) return; + + SoundName = dataTypes.ReadNextString(data); + HasFixedRange = dataTypes.ReadNextBool(data); + + if (HasFixedRange) + FixedRange = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Type)); + + if (Type != 0) return new Queue(data); + + if (string.IsNullOrEmpty(SoundName?.Trim())) + throw new ArgumentNullException($"Can not serialize SoundEventSubComponent due to SoundName being null or empty!"); + + data.AddRange(DataTypes.GetString(SoundName)); + data.AddRange(DataTypes.GetBool(HasFixedRange)); + + if(HasFixedRange) + data.AddRange(DataTypes.GetFloat(FixedRange)); + + return new Queue(data); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs index 5152c9cd..9fdc974c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs @@ -11,4 +11,5 @@ public abstract class SubComponents public const string Details = "Details"; public const string Rule = "Rule"; public const string FireworkExplosion = "FireworkExplosion"; + public const string SoundEvent = "SoundEvent"; } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs index ebf75e41..afc5a134 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -25,7 +25,7 @@ public class StructuredComponentsRegistry1206 : StructuredComponentRegistry RegisterComponent(13, "minecraft:custom_model_data"); RegisterComponent(14, "minecraft:hide_additional_tooltip"); RegisterComponent(15, "minecraft:hide_tooltip"); - RegisterComponent(16, "minecraft:repair_cost"); + RegisterComponent(16, "minecraft:repair_cost"); RegisterComponent(17, "minecraft:creative_slot_lock"); RegisterComponent(18, "minecraft:enchantment_glint_override"); RegisterComponent(19, "minecraft:intangible_projectile"); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry121.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry121.cs new file mode 100644 index 00000000..076b49d0 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry121.cs @@ -0,0 +1,71 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry121 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry121(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) + { + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); + RegisterComponent(5, "minecraft:custom_name"); + RegisterComponent(6, "minecraft:item_name"); + RegisterComponent(7, "minecraft:lore"); + RegisterComponent(8, "minecraft:rarity"); + RegisterComponent(9, "minecraft:enchantments"); + RegisterComponent(10, "minecraft:can_place_on"); + RegisterComponent(11, "minecraft:can_break"); + RegisterComponent(12, "minecraft:attribute_modifiers"); + RegisterComponent(13, "minecraft:custom_model_data"); + RegisterComponent(14, "minecraft:hide_additional_tooltip"); + RegisterComponent(15, "minecraft:hide_tooltip"); + RegisterComponent(16, "minecraft:repair_cost"); + RegisterComponent(17, "minecraft:creative_slot_lock"); + RegisterComponent(18, "minecraft:enchantment_glint_override"); + RegisterComponent(19, "minecraft:intangible_projectile"); + RegisterComponent(20, "minecraft:food"); + RegisterComponent(21, "minecraft:fire_resistant"); + RegisterComponent(22, "minecraft:tool"); + RegisterComponent(23, "minecraft:stored_enchantments"); + RegisterComponent(24, "minecraft:dyed_color"); + RegisterComponent(25, "minecraft:map_color"); + RegisterComponent(26, "minecraft:map_id"); + RegisterComponent(27, "minecraft:map_decorations"); + RegisterComponent(28, "minecraft:map_post_processing"); + RegisterComponent(29, "minecraft:charged_projectiles"); + RegisterComponent(30, "minecraft:bundle_contents"); + RegisterComponent(31, "minecraft:potion_contents"); + RegisterComponent(32, "minecraft:suspicious_stew_effects"); + RegisterComponent(33, "minecraft:writable_book_content"); + RegisterComponent(34, "minecraft:written_book_content"); + RegisterComponent(35, "minecraft:trim"); + RegisterComponent(36, "minecraft:debug_stick_state"); + RegisterComponent(37, "minecraft:entity_data"); + RegisterComponent(38, "minecraft:bucket_entity_data"); + RegisterComponent(39, "minecraft:block_entity_data"); + RegisterComponent(40, "minecraft:instrument"); + RegisterComponent(41, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(42, "minecraft:jukebox_playable"); + RegisterComponent(43, "minecraft:recipes"); + RegisterComponent(44, "minecraft:lodestone_tracker"); + RegisterComponent(45, "minecraft:firework_explosion"); + RegisterComponent(46, "minecraft:fireworks"); + RegisterComponent(47, "minecraft:profile"); + RegisterComponent(48, "minecraft:note_block_sound"); + RegisterComponent(49, "minecraft:banner_patterns"); + RegisterComponent(50, "minecraft:base_color"); + RegisterComponent(51, "minecraft:pot_decorations"); + RegisterComponent(52, "minecraft:container"); + RegisterComponent(53, "minecraft:block_state"); + RegisterComponent(54, "minecraft:bees"); + RegisterComponent(55, "minecraft:lock"); + RegisterComponent(56, "minecraft:container_loot"); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs new file mode 100644 index 00000000..7515020f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs @@ -0,0 +1,15 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; + +public class SubComponentRegistry121 : SubComponentRegistry1206 +{ + public SubComponentRegistry121(DataTypes dataTypes) : base(dataTypes) + { + RegisterSubComponent(SubComponents.SoundEvent); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index 95502463..2fd0cb82 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -20,6 +20,7 @@ public class StructuredComponentsHandler var subcomponentRegistryType = protocolVersion switch { Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206), + Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") }; @@ -30,6 +31,7 @@ public class StructuredComponentsHandler var registryType = protocolVersion switch { Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), + Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") }; diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index a2ea85b5..b53354ee 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -153,7 +153,7 @@ namespace MinecraftClient.Protocol int[] suppoertedVersionsProtocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, - 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766 + 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -348,6 +348,9 @@ namespace MinecraftClient.Protocol case "1.20.5": case "1.20.6": return 766; + case "1.21": + case "1.21.1": + return 767; default: return 0; } @@ -428,6 +431,7 @@ namespace MinecraftClient.Protocol 764 => "1.20.2", 765 => "1.20.4", 766 => "1.20.6", + 767 => "1.21", _ => "0.0" }; } From 17d43958e1c16bc56bcf40dd0ce688467d6d30ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:36:30 +0000 Subject: [PATCH 019/484] Bump nanoid from 3.3.6 to 3.3.8 in /docs Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.6 to 3.3.8. - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/3.3.6...3.3.8) --- updated-dependencies: - dependency-name: nanoid dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index bfdff129..641f8d08 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3745,9 +3745,9 @@ multicast-dns@^7.2.5: thunky "^1.0.2" nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== nanomatch@^1.2.9: version "1.2.13" From 7152072598e2afb524d4345d58080a90eff40a7f Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Dec 2024 13:20:04 +0100 Subject: [PATCH 020/484] Ported to .NET 8 --- MinecraftClient/MinecraftClient.csproj | 3 +- .../Protocol/ProfileKey/KeysCache.cs | 2 - .../Protocol/Session/SessionCache.cs | 73 +++---------------- 3 files changed, 12 insertions(+), 66 deletions(-) diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 70470019..bd71f18a 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -1,6 +1,6 @@ - net7.0 + net8.0 Exe publish\ false @@ -34,6 +34,7 @@ + diff --git a/MinecraftClient/Protocol/ProfileKey/KeysCache.cs b/MinecraftClient/Protocol/ProfileKey/KeysCache.cs index 8d524fa8..9af643c7 100644 --- a/MinecraftClient/Protocol/ProfileKey/KeysCache.cs +++ b/MinecraftClient/Protocol/ProfileKey/KeysCache.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Runtime.Serialization.Formatters.Binary; using System.Timers; using static MinecraftClient.Settings; using static MinecraftClient.Settings.MainConfigHelper.MainConfig.AdvancedConfig; @@ -19,7 +18,6 @@ namespace MinecraftClient.Protocol.ProfileKey private static readonly Dictionary keys = new(); private static readonly Timer updatetimer = new(100); private static readonly List> pendingadds = new(); - private static readonly BinaryFormatter formatter = new(); /// /// Retrieve whether KeysCache contains a keys for the given login. diff --git a/MinecraftClient/Protocol/Session/SessionCache.cs b/MinecraftClient/Protocol/Session/SessionCache.cs index 956f6ab2..1b64fea0 100644 --- a/MinecraftClient/Protocol/Session/SessionCache.cs +++ b/MinecraftClient/Protocol/Session/SessionCache.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; using System.Timers; +using MessagePack; using static MinecraftClient.Settings; using static MinecraftClient.Settings.MainConfigHelper.MainConfig.AdvancedConfig; @@ -14,7 +13,6 @@ namespace MinecraftClient.Protocol.Session /// public static class SessionCache { - private const string SessionCacheFilePlaintext = "SessionCache.ini"; private const string SessionCacheFileSerialized = "SessionCache.db"; private static readonly string SessionCacheFileMinecraft = String.Concat( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @@ -28,7 +26,6 @@ namespace MinecraftClient.Protocol.Session private static readonly Dictionary sessions = new(); private static readonly Timer updatetimer = new(100); private static readonly List> pendingadds = new(); - private static readonly BinaryFormatter formatter = new(); /// /// Retrieve whether SessionCache contains a session for the given login. @@ -82,7 +79,7 @@ namespace MinecraftClient.Protocol.Session /// TRUE if session tokens are seeded from file public static bool InitializeDiskCache() { - cachemonitor = new FileMonitor(AppDomain.CurrentDomain.BaseDirectory, SessionCacheFilePlaintext, new FileSystemEventHandler(OnChanged)); + cachemonitor = new FileMonitor(AppDomain.CurrentDomain.BaseDirectory, SessionCacheFileSerialized, new FileSystemEventHandler(OnChanged)); updatetimer.Elapsed += HandlePending; return LoadFromDisk(); } @@ -121,7 +118,7 @@ namespace MinecraftClient.Protocol.Session /// True if data is successfully loaded private static bool LoadFromDisk() { - //Grab sessions in the Minecraft directory + // Grab sessions in the Minecraft directory if (File.Exists(SessionCacheFileMinecraft)) { if (Config.Logging.DebugMessages) @@ -168,7 +165,7 @@ namespace MinecraftClient.Protocol.Session } } - //Serialized session cache file in binary format + // Serialized session cache file in binary format if (File.Exists(SessionCacheFileSerialized)) { if (Config.Logging.DebugMessages) @@ -177,10 +174,8 @@ namespace MinecraftClient.Protocol.Session try { using FileStream fs = new(SessionCacheFileSerialized, FileMode.Open, FileAccess.Read, FileShare.Read); -#pragma warning disable SYSLIB0011 // BinaryFormatter.Deserialize() is obsolete - // Possible risk of information disclosure or remote code execution. The impact of this vulnerability is limited to the user side only. - Dictionary sessionsTemp = (Dictionary)formatter.Deserialize(fs); -#pragma warning restore SYSLIB0011 // BinaryFormatter.Deserialize() is obsolete + // Deserialize using MessagePack + Dictionary sessionsTemp = MessagePackSerializer.Deserialize>(fs); foreach (KeyValuePair item in sessionsTemp) { if (Config.Logging.DebugMessages) @@ -192,54 +187,12 @@ namespace MinecraftClient.Protocol.Session { ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_read_fail, ex.Message)); } - catch (SerializationException ex2) + catch (MessagePackSerializationException ex2) { ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_malformed, ex2.Message)); } } - //User-editable session cache file in text format - if (File.Exists(SessionCacheFilePlaintext)) - { - if (Config.Logging.DebugMessages) - ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_loading_session, SessionCacheFilePlaintext)); - - try - { - foreach (string line in FileMonitor.ReadAllLinesWithRetries(SessionCacheFilePlaintext)) - { - if (!line.Trim().StartsWith("#")) - { - string[] keyValue = line.Split('='); - if (keyValue.Length == 2) - { - try - { - string login = Settings.ToLowerIfNeed(keyValue[0]); - SessionToken session = SessionToken.FromString(keyValue[1]); - if (Config.Logging.DebugMessages) - ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_loaded, login, session.ID)); - sessions[login] = session; - } - catch (InvalidDataException e) - { - if (Config.Logging.DebugMessages) - ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_ignore_string, keyValue[1], e.Message)); - } - } - else if (Config.Logging.DebugMessages) - { - ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_ignore_line, line)); - } - } - } - } - catch (IOException e) - { - ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.cache_read_fail_plain, e.Message)); - } - } - return sessions.Count > 0; } @@ -251,17 +204,11 @@ namespace MinecraftClient.Protocol.Session if (Config.Logging.DebugMessages) ConsoleIO.WriteLineFormatted("§8" + Translations.cache_saving, acceptnewlines: true); - List sessionCacheLines = new() - { - "# Generated by MCC v" + Program.Version + " - Keep it secret & Edit at own risk!", - "# Login=SessionID,PlayerName,UUID,ClientID,RefreshToken,ServerIDhash,ServerPublicKey" - }; - foreach (KeyValuePair entry in sessions) - sessionCacheLines.Add(entry.Key + '=' + entry.Value.ToString()); - try { - FileMonitor.WriteAllLinesWithRetries(SessionCacheFilePlaintext, sessionCacheLines); + using FileStream fs = new(SessionCacheFileSerialized, FileMode.Create, FileAccess.Write, FileShare.None); + // Serialize using MessagePack + MessagePackSerializer.Serialize(fs, sessions); } catch (IOException e) { From a1acd559d6143b805bdf1bddfbc11c2d186aa866 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Dec 2024 20:05:17 +0100 Subject: [PATCH 021/484] Updated the pipeline --- .github/workflows/build-and-release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 8d500156..db5e6fb8 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -8,8 +8,8 @@ on: env: PROJECT: "MinecraftClient" - target-version: "net7.0" - compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=None" + target-version: "net8.0" + compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded" jobs: build: @@ -19,7 +19,7 @@ jobs: timeout-minutes: 15 strategy: matrix: - target: [win-x86, win-x64, win-arm, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64] + target: [win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64] steps: - name: Checkout From a5ab30f3daf3392cbc3e868d5e23cd3d2081ac60 Mon Sep 17 00:00:00 2001 From: breadbyte <14045257+breadbyte@users.noreply.github.com> Date: Wed, 25 Dec 2024 01:28:28 +0800 Subject: [PATCH 022/484] Fix session cache serializer failure --- MinecraftClient/Protocol/Session/SessionToken.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Session/SessionToken.cs b/MinecraftClient/Protocol/Session/SessionToken.cs index 812d3fa0..8687b99f 100644 --- a/MinecraftClient/Protocol/Session/SessionToken.cs +++ b/MinecraftClient/Protocol/Session/SessionToken.cs @@ -2,24 +2,34 @@ using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; +using MessagePack; using MinecraftClient.Scripting; using static MinecraftClient.Settings.MainConfigHelper.MainConfig.GeneralConfig; namespace MinecraftClient.Protocol.Session { [Serializable] + [MessagePackObject] public class SessionToken { private static readonly Regex JwtRegex = new("^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"); + [Key(0)] public string ID { get; set; } + [Key(1)] public string PlayerName { get; set; } + [Key(2)] public string PlayerID { get; set; } + [Key(3)] public string ClientID { get; set; } + [Key(4)] public string RefreshToken { get; set; } + [Key(5)] public string ServerIDhash { get; set; } + [Key(6)] public byte[]? ServerPublicKey { get; set; } - + + [IgnoreMember] public Task? SessionPreCheckTask = null; public SessionToken() From 8726a73b5feb91cb544c9cefe45191c02f557d7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:17:16 +0000 Subject: [PATCH 023/484] Bump serialize-javascript from 6.0.0 to 6.0.2 in /docs Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 6.0.0 to 6.0.2. - [Release notes](https://github.com/yahoo/serialize-javascript/releases) - [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2) --- updated-dependencies: - dependency-name: serialize-javascript dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 641f8d08..4cac4bf4 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -4425,14 +4425,7 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^6.0.1: +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== From 1cec3f739735e1a792120db90d7da9208b605ca7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 22:20:33 +0000 Subject: [PATCH 024/484] Bump prismjs from 1.29.0 to 1.30.0 in /docs Bumps [prismjs](https://github.com/PrismJS/prism) from 1.29.0 to 1.30.0. - [Release notes](https://github.com/PrismJS/prism/releases) - [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md) - [Commits](https://github.com/PrismJS/prism/compare/v1.29.0...v1.30.0) --- updated-dependencies: - dependency-name: prismjs dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 641f8d08..465f2eb7 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -4111,9 +4111,9 @@ pretty-error@^4.0.0: renderkid "^3.0.0" prismjs@^1.29.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" - integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + version "1.30.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9" + integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== process-nextick-args@~2.0.0: version "2.0.1" From 19781985f746ac8bbf0f897d03837b32feda0b90 Mon Sep 17 00:00:00 2001 From: Tasuku Bobcorn Date: Tue, 29 Apr 2025 13:56:38 +0800 Subject: [PATCH 025/484] Fix reading window items packet in versions below 1.17.1 --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index d089fa00..36368a16 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2121,7 +2121,7 @@ namespace MinecraftClient.Protocol.Handlers { var windowId = dataTypes.ReadNextByte(packetData); var stateId = -1; - var elements = 0; + int elements; if (protocolVersion >= MC_1_17_1_Version) { @@ -2132,7 +2132,7 @@ namespace MinecraftClient.Protocol.Handlers else { // Elements as Short - 1.17.0 and below - dataTypes.ReadNextShort(packetData); + elements = dataTypes.ReadNextShort(packetData); } Dictionary inventorySlots = new(); From 8b20973b02d8ab2c3878fa812dfeebe80cb03978 Mon Sep 17 00:00:00 2001 From: Anon Date: Thu, 22 May 2025 13:56:27 +0200 Subject: [PATCH 026/484] Temporarily removed WebSocket bot because of a false positive virus detection. I will make it in to a standalone bot later. --- MinecraftClient/ChatBots/WebSocketBot.cs | 1350 ---------------------- MinecraftClient/McClient.cs | 1 - MinecraftClient/Settings.cs | 15 +- 3 files changed, 6 insertions(+), 1360 deletions(-) delete mode 100644 MinecraftClient/ChatBots/WebSocketBot.cs diff --git a/MinecraftClient/ChatBots/WebSocketBot.cs b/MinecraftClient/ChatBots/WebSocketBot.cs deleted file mode 100644 index a2d71eb7..00000000 --- a/MinecraftClient/ChatBots/WebSocketBot.cs +++ /dev/null @@ -1,1350 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Net.WebSockets; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using MinecraftClient.CommandHandler; -using MinecraftClient.Inventory; -using MinecraftClient.Mapping; -using MinecraftClient.Scripting; -using Newtonsoft.Json; -using Tomlet.Attributes; - -namespace MinecraftClient.ChatBots; - -internal class SessionEventArgs : EventArgs -{ - public string SessionId { get; } - - public SessionEventArgs(string sessionId) - { - SessionId = sessionId; - } -} - -internal class MessageReceivedEventArgs : EventArgs -{ - public string SessionId { get; } - public string Message { get; } - - public MessageReceivedEventArgs(string sessionId, string message) - { - SessionId = sessionId; - Message = message; - } -} - -internal class WebSocketSession -{ - public string SessionId { get; set; } - public WebSocket WebSocket { get; set; } - - public WebSocketSession(string sessionId, WebSocket webSocket) - { - SessionId = sessionId; - WebSocket = webSocket; - } -} - -internal class WebSocketServer -{ - public readonly ConcurrentDictionary Sessions; - public event EventHandler? NewSession; - public event EventHandler? SessionDropped; - public event EventHandler? MessageReceived; - - private HttpListener? listener; - - public WebSocketServer() - { - Sessions = new ConcurrentDictionary(); - } - - public async Task Start(string ipAddress, int port) - { - listener = new HttpListener(); - listener.Prefixes.Add($"http://{ipAddress}:{port}/"); - listener.Start(); - - while (listener.IsListening) - { - var context = await listener.GetContextAsync(); - if (context.Request.IsWebSocketRequest) - { - var sessionGuid = Guid.NewGuid().ToString(); - var webSocketContext = await context.AcceptWebSocketAsync(null); - var webSocket = webSocketContext.WebSocket; - var webSocketSession = new WebSocketSession(sessionGuid, webSocket); - - NewSession?.Invoke(this, new SessionEventArgs(sessionGuid)); - Sessions.TryAdd(sessionGuid, webSocketSession); - _ = ProcessWebSocketSession(webSocketSession); - } - else - { - context.Response.StatusCode = 400; - context.Response.Close(); - } - } - } - - public async Task Stop() - { - foreach (var session in Sessions) - { - await session.Value.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server shutting down", - CancellationToken.None); - } - - Sessions.Clear(); - listener?.Stop(); - } - - private async Task ProcessWebSocketSession(WebSocketSession webSocketSession) - { - var buffer = new byte[1024]; - - try - { - while (webSocketSession.WebSocket.State == WebSocketState.Open) - { - var receiveResult = - await webSocketSession.WebSocket.ReceiveAsync(new ArraySegment(buffer), - CancellationToken.None); - - if (receiveResult.MessageType == WebSocketMessageType.Text) - { - var message = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count); - MessageReceived?.Invoke(this, new MessageReceivedEventArgs(webSocketSession.SessionId, message)); - } - else if (receiveResult.MessageType == WebSocketMessageType.Close) - { - await webSocketSession.WebSocket.CloseAsync( - WebSocketCloseStatus.NormalClosure, - "Connection closed by the client", - CancellationToken.None); - break; - } - } - } - finally - { - Sessions.TryRemove(webSocketSession.SessionId, out _); - SessionDropped?.Invoke(this, new SessionEventArgs(webSocketSession.SessionId)); - } - } - - public bool RenameSession(string oldSessionId, string newSessionId) - { - if (!Sessions.ContainsKey(oldSessionId) || Sessions.ContainsKey(newSessionId)) - return false; - - if (!Sessions.TryRemove(oldSessionId, out var webSocketSession)) - return false; - - webSocketSession.SessionId = newSessionId; - - if (Sessions.TryAdd(newSessionId, webSocketSession)) - return true; - - webSocketSession.SessionId = oldSessionId; - - if (!Sessions.TryAdd(oldSessionId, webSocketSession)) - throw new Exception("Failed to add back the old session after failed rename"); - - return false; - } - - public async Task SendToSession(string sessionId, string message) - { - try - { - if (Sessions.TryGetValue(sessionId, out var webSocketSession)) - { - var buffer = Encoding.UTF8.GetBytes(message); - await webSocketSession.WebSocket.SendAsync(new ArraySegment(buffer), WebSocketMessageType.Text, - true, - CancellationToken.None); - } - } - catch (WebSocketException ex) - { - if (ex.InnerException is SocketException { SocketErrorCode: SocketError.ConnectionReset }) - { - if (Sessions.ContainsKey(sessionId)) - Sessions.Remove(sessionId, out _); - } - } - } -} - -internal class WsChatBotCommand -{ - [JsonProperty("command")] public string Command { get; set; } = ""; - - [JsonProperty("requestId")] public string RequestId { get; set; } = ""; - - [JsonProperty("parameters")] public object[]? Parameters { get; set; } -} - -internal class WsCommandResponder -{ - private WebSocketBot _bot; - private string _sessionId; - private string _command; - private string _requestId; - - public WsCommandResponder(WebSocketBot bot, string sessionId, string command, string requestId) - { - _bot = bot; - _sessionId = sessionId; - _command = command; - _requestId = requestId; - } - - private void SendCommandResponse(bool success, string result, bool overrideAuth = false) - { - _bot.SendCommandResponse(_sessionId, success, _requestId, _command, result, overrideAuth); - } - - public void SendErrorResponse(string error, bool overrideAuth = false) - { - SendCommandResponse(false, error, overrideAuth); - } - - public void SendSuccessResponse(string result, bool overrideAuth = false) - { - SendCommandResponse(true, result, overrideAuth); - } - - public void SendSuccessResponse(bool overrideAuth = false) - { - SendSuccessResponse(JsonConvert.SerializeObject(true), overrideAuth); - } - - public string Quote(string text) - { - return $"\"{text}\""; - } -} - -internal class NbtData -{ - public NBT? nbt { get; set; } -} - -internal class NBT -{ - public Dictionary? nbt { get; set; } -} - -internal class NbtDictionaryConverter : JsonConverter> -{ - public override void WriteJson(JsonWriter writer, Dictionary? value, JsonSerializer serializer) - => throw new NotImplementedException(); - - public override Dictionary? ReadJson(JsonReader reader, Type objectType, - Dictionary? existingValue, bool hasExistingValue, JsonSerializer serializer) - { - var keyValuePairs = serializer.Deserialize>>(reader); - return new(keyValuePairs!); - } -} - -public class WebSocketBot : ChatBot -{ - private string? _ip; - private int _port; - private string? _password; - private WebSocketServer? _server; - private List _authenticatedSessions; - private List<(string, string)> _waitingEvents; - - public static Configs Config = new(); - - [TomlDoNotInlineObject] - public class Configs - { - [NonSerialized] private const string BotName = "Websocket"; - - public bool Enabled = false; - - [TomlInlineComment("$ChatBot.WebSocketBot.Ip$")] - public string? Ip = "127.0.0.1"; - - [TomlInlineComment("$ChatBot.WebSocketBot.Port$")] - public int Port = 8043; - - [TomlInlineComment("$ChatBot.WebSocketBot.Password$")] - public string? Password = Guid.NewGuid().ToString().Replace("-", "").Trim().ToLower(); - - [TomlInlineComment("$ChatBot.WebSocketBot.DebugMode$")] - public bool DebugMode = false; - - [TomlInlineComment("$ChatBot.WebSocketBot.AllowIpAlias$")] - public bool AllowIpAlias = false; - } - - public WebSocketBot() - { - _password = Config.Password; - _authenticatedSessions = new(); - _waitingEvents = new(); - - var match = Regex.Match(Config.Ip!, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"); - - // If AllowIpAlias is set to true in the config, then always ignore this check - if (!match.Success & !Config.AllowIpAlias!) - { - LogToConsole(Translations.bot_WebSocketBot_failed_to_start_ip); - return; - } - - if (Config.Port > 65535) - { - LogToConsole(string.Format(Translations.bot_WebSocketBot_failed_to_start_port, _port.ToString())); - return; - } - - _ip = Config.Ip; - _port = Config.Port; - } - - public override void Initialize() - { - Task.Run(() => - { - _authenticatedSessions.Clear(); - - if (_server != null) - { - SendEvent("OnWsRestarting", ""); - _server.Stop(); // If you await, this will freeze the task and the websocket won't work - _server = null; - } - - try - { - LogToConsole(Translations.bot_WebSocketBot_starting); - _server = new(); - _server.Start(_ip!, _port); // If you await, this will freeze the task and the websocket won't work - - LogToConsole(string.Format(Translations.bot_WebSocketBot_started, _ip, _port.ToString())); - - foreach (var (eventName, data) in _waitingEvents) - SendEvent(eventName, data); - } - catch (Exception e) - { - LogToConsole(string.Format(Translations.bot_WebSocketBot_failed_to_start_custom, e)); - return; - } - - _server.NewSession += (_, session) => - LogToConsole(string.Format(Translations.bot_WebSocketBot_new_session, session.SessionId)); - _server.SessionDropped += (_, session) => - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_disconnected, session.SessionId)); - - _server.MessageReceived += (_, messageObject) => - { - if (!ProcessWebsocketCommand(messageObject.SessionId, _password!, messageObject.Message)) - return; - - var command = messageObject.Message; - command = command.StartsWith('/') ? command[1..] : $"send {command}"; - - CmdResult response = new(); - PerformInternalCommand(command, ref response); - SendSessionEvent(messageObject.SessionId, "OnMccCommandResponse", $"{{\"response\": \"{response}\"}}"); - }; - }); - } - - private bool ProcessWebsocketCommand(string sessionId, string password, string message) - { - message = message.Trim(); - - if (string.IsNullOrEmpty(message)) - return false; - - if (message.StartsWith('{')) - { - try - { - if (Config.DebugMode) - LogDebugToConsole($"\n\n\tGot command\n\n\t{message}\n\n"); - - var cmd = JsonConvert.DeserializeObject(message)!; - var responder = new WsCommandResponder(this, sessionId, cmd.Command, cmd.RequestId); - - // Allow session name changing without authenticating for easier identification - if (cmd.Command.Equals("ChangeSessionId", StringComparison.OrdinalIgnoreCase)) - { - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expected 1 (newSessionid)!"), true); - return false; - } - - var newId = (cmd.Parameters[0] as string)!; - - switch (newId.Length) - { - case 0: - responder.SendErrorResponse(responder.Quote("Please provide a valid session ID!"), - true); - return false; - case > 32: - responder.SendErrorResponse( - responder.Quote("The session ID can't be longer than 32 characters!"), true); - return false; - } - - if (!_server!.RenameSession(sessionId, newId)) - { - responder.SendErrorResponse( - responder.Quote("Failed to change the session id to: '" + newId + "'"), - true); - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_id_failed_to_change, sessionId, - newId)); - return false; - } - - // If the session is authenticated, remove the old session id and add the new one - if (_authenticatedSessions.Contains(sessionId)) - { - _authenticatedSessions.Remove(sessionId); - _authenticatedSessions.Add(newId); - } - - // Update the responder to the new session id - responder = new WsCommandResponder(this, newId, cmd.Command, cmd.RequestId); - - responder.SendSuccessResponse( - responder.Quote("The session ID was successfully changed to: '" + newId + "'"), true); - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_id_changed, sessionId, newId)); - return false; - } - - // Authentication and session commands - if (password.Length != 0) - { - if (!_authenticatedSessions.Contains(sessionId)) - { - // Special case for authentication - if (cmd.Command.Equals("Authenticate", StringComparison.OrdinalIgnoreCase)) - { - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expected 1 (password)!"), true); - return false; - } - - var pass = (cmd.Parameters[0] as string)!; - - if (pass.Length == 0) - { - responder.SendErrorResponse( - responder.Quote( - "Please provide a valid password! (Example: 'Authenticate password123')"), - true); - return false; - } - - if (!pass.Equals(password)) - { - responder.SendErrorResponse(responder.Quote("Incorrect password provided!"), true); - return false; - } - - _authenticatedSessions.Add(sessionId); - responder.SendSuccessResponse(responder.Quote("Successfully authenticated!"), true); - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_authenticated, sessionId)); - return false; - } - - responder.SendErrorResponse( - responder.Quote("You must authenticate in order to send and receive data!"), true); - return false; - } - } - else - { - if (!_authenticatedSessions.Contains(sessionId)) - { - responder.SendSuccessResponse(responder.Quote("Successfully authenticated!")); - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_authenticated, sessionId)); - _authenticatedSessions.Add(sessionId); - return false; - } - } - - // Process other commands - switch (cmd.Command) - { - case "LogToConsole": - if (cmd.Parameters == null || cmd.Parameters.Length > 1 || cmd.Parameters.Length < 1) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting a single parameter!")); - return false; - } - - LogToConsole((cmd.Parameters[0] as string)!); - responder.SendSuccessResponse(); - break; - - case "LogDebugToConsole": - if (cmd.Parameters == null || cmd.Parameters.Length > 1 || cmd.Parameters.Length < 1) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting a single parameter!")); - return false; - } - - LogDebugToConsole((cmd.Parameters[0] as string)!); - responder.SendSuccessResponse(); - break; - - case "LogToConsoleTranslated": - if (cmd.Parameters == null || cmd.Parameters.Length > 1 || cmd.Parameters.Length < 1) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting a single parameter!")); - return false; - } - - LogToConsoleTranslated((cmd.Parameters[0] as string)!); - responder.SendSuccessResponse(); - break; - - case "LogDebugToConsoleTranslated": - if (cmd.Parameters!.Length > 1 || cmd.Parameters.Length < 1) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting a single parameter!")); - return false; - } - - LogDebugToConsoleTranslated((cmd.Parameters[0] as string)!); - responder.SendSuccessResponse(); - break; - - case "ReconnectToTheServer": - if (cmd.Parameters is not { Length: 2 }) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 2 parameters (extraAttempts, delaySeconds)!")); - return false; - } - - ReconnectToTheServer(Convert.ToInt32(cmd.Parameters[0]), Convert.ToInt32(cmd.Parameters[1])); - responder.SendSuccessResponse(); - break; - - case "DisconnectAndExit": - responder.SendSuccessResponse(); - DisconnectAndExit(); - break; - - case "SendPrivateMessage": - if (cmd.Parameters is not { Length: 2 }) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 2 parameters (player, message)!")); - return false; - } - - SendPrivateMessage((cmd.Parameters[0] as string)!, (cmd.Parameters[1] as string)!); - responder.SendSuccessResponse(); - break; - - case "RunScript": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (filename)!")); - return false; - } - - RunScript((cmd.Parameters[0] as string)!); - responder.SendSuccessResponse(); - break; - - case "GetTerrainEnabled": - responder.SendSuccessResponse(GetTerrainEnabled().ToString().ToLower()); - break; - - case "SetTerrainEnabled": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (enabled)!")); - return false; - } - - SetTerrainEnabled((bool)cmd.Parameters[0]); - responder.SendSuccessResponse(); - break; - - case "GetEntityHandlingEnabled": - responder.SendSuccessResponse(GetEntityHandlingEnabled().ToString().ToLower()); - break; - - case "Sneak": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (on)!")); - return false; - } - - Sneak((bool)cmd.Parameters[0]); - responder.SendSuccessResponse(); - break; - - case "SendEntityAction": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (actionType)!")); - return false; - } - - SendEntityAction(((Protocol.EntityActionType)(Convert.ToInt32(cmd.Parameters[0])))); - responder.SendSuccessResponse(); - break; - - case "DigBlock": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 3 || - cmd.Parameters.Length > 5) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 1 or 3 parameter(s) (location, swingArms?, lookAtBlock?)!")); - return false; - } - - var location = new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), Convert.ToInt32(cmd.Parameters[2])); - - if (location.DistanceSquared(GetCurrentLocation().EyesLocation()) > 25) - { - responder.SendErrorResponse( - responder.Quote("The block you're trying to dig is too far away!")); - return false; - } - - if (GetWorld().GetBlock(location).Type == Material.Air) - { - responder.SendErrorResponse(responder.Quote("The block you're trying to dig is is air!")); - return false; - } - - var result = cmd.Parameters.Length switch - { - // TODO Get blockFace direction from arguments - 3 => DigBlock(location, Direction.Down), - 4 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3]), - 5 => DigBlock(location, Direction.Down, (bool)cmd.Parameters[3], (bool)cmd.Parameters[4]), - _ => false - }; - - responder.SendSuccessResponse(JsonConvert.SerializeObject(result)); - break; - - case "SetSlot": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (slotNumber)!")); - return false; - } - - SetSlot(Convert.ToInt32(cmd.Parameters[0])); - responder.SendSuccessResponse(); - break; - - case "GetWorld": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetWorld())); - break; - - case "GetEntities": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetEntities())); - break; - - case "GetPlayersLatency": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetPlayersLatency())); - break; - - case "GetCurrentLocation": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetCurrentLocation())); - break; - - case "MoveToLocation": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 3 || - cmd.Parameters.Length > 8) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 1 or 7 parameter(s) (x, y, z, allowUnsafe?, allowDirectTeleport?, maxOffset?, minoffset?, timeout?)!")); - return false; - } - - var allowUnsafe = false; - var allowDirectTeleport = false; - var maxOffset = 0; - var minOffset = 0; - TimeSpan? timeout = null; - - if (cmd.Parameters.Length >= 4) - allowUnsafe = (bool)cmd.Parameters[3]; - - if (cmd.Parameters.Length >= 5) - allowDirectTeleport = (bool)cmd.Parameters[4]; - - if (cmd.Parameters.Length >= 6) - maxOffset = Convert.ToInt32(cmd.Parameters[5]); - - if (cmd.Parameters.Length >= 7) - minOffset = Convert.ToInt32(cmd.Parameters[6]); - - if (cmd.Parameters.Length == 8) - timeout = TimeSpan.FromSeconds(Convert.ToInt32(cmd.Parameters[7])); - - var canMove = MoveToLocation( - new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), - Convert.ToInt32(cmd.Parameters[2])), - allowUnsafe, - allowDirectTeleport, - maxOffset, - minOffset, - timeout); - - responder.SendSuccessResponse(JsonConvert.SerializeObject(canMove)); - break; - - case "ClientIsMoving": - responder.SendSuccessResponse(JsonConvert.SerializeObject(ClientIsMoving())); - break; - - case "LookAtLocation": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 3 || - cmd.Parameters.Length > 3) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 3 parameter(s) (x, y, z)!")); - return false; - } - - LookAtLocation(new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), Convert.ToInt32(cmd.Parameters[2]))); - responder.SendSuccessResponse(); - break; - - case "GetTimestamp": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetTimestamp())); - break; - - case "GetServerPort": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetServerPort())); - break; - - case "GetServerHost": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetServerHost())); - break; - - case "GetUsername": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetUsername())); - break; - - case "GetGamemode": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GameModeString(GetGamemode()))); - break; - - case "GetYaw": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetYaw())); - break; - - case "GetPitch": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetPitch())); - break; - - case "GetUserUUID": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetUserUUID())); - break; - - case "GetOnlinePlayers": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetOnlinePlayers())); - break; - - case "GetOnlinePlayersWithUUID": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetOnlinePlayersWithUUID())); - break; - - case "GetServerTPS": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetServerTPS())); - break; - - case "InteractEntity": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 2 || - cmd.Parameters.Length > 3) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting at least 2 and at most 3 parameter(s) (entityId, interactionType, hand?)!")); - return false; - } - - var interactionType = (InteractType)Convert.ToInt32(cmd.Parameters[1]); - var interactionHand = Hand.MainHand; - - if (cmd.Parameters.Length == 3) - interactionHand = (Hand)Convert.ToInt32(cmd.Parameters[2]); - - responder.SendSuccessResponse(JsonConvert.SerializeObject( - InteractEntity(Convert.ToInt32(cmd.Parameters[0]), interactionType, interactionHand))); - break; - - case "CreativeGive": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 3 || - cmd.Parameters.Length > 4) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting at least 3 and at most 4 parameter(s) (slotId, itemType, count, nbt?)!")); - return false; - } - - NBT? nbt = null; - - if (cmd.Parameters.Length == 4) - nbt = JsonConvert.DeserializeObject(cmd.Parameters[3].ToString()!, - new NbtDictionaryConverter())!; - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(CreativeGive( - Convert.ToInt32(cmd.Parameters[0]), - (ItemType)Convert.ToInt32(cmd.Parameters[1]), - Convert.ToInt32(cmd.Parameters[2]), - nbt == null ? new Dictionary() : nbt!.nbt!) - )); - - break; - - case "CreativeDelete": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting at 1 parameter (slotId)!")); - return false; - } - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(CreativeDelete(Convert.ToInt32(cmd.Parameters[0])))); - break; - - case "SendAnimation": - var hand = Hand.MainHand; - - if (cmd.Parameters is { Length: 1 }) - hand = (Hand)Convert.ToInt32(cmd.Parameters[0]); - - responder.SendSuccessResponse(JsonConvert.SerializeObject(SendAnimation(hand))); - break; - - case "SendPlaceBlock": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length < 4 || - cmd.Parameters.Length > 4) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting at least 4 and at most 5 parameters (x, y, z, blockFace, hand?)!")); - return false; - } - - var blockLocation = new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), Convert.ToInt32(cmd.Parameters[2])); - var blockFacingDirection = (Direction)Convert.ToInt32(cmd.Parameters[3]); - var handToUse = Hand.MainHand; - - if (cmd.Parameters.Length == 4) - handToUse = (Hand)Convert.ToInt32(cmd.Parameters[4]); - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(SendPlaceBlock(blockLocation, blockFacingDirection, - handToUse))); - break; - - case "UseItemInHand": - responder.SendSuccessResponse(JsonConvert.SerializeObject(UseItemInHand())); - break; - - case "GetInventoryEnabled": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetInventoryEnabled())); - break; - - case "GetPlayerInventory": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetPlayerInventory())); - break; - - case "GetInventories": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetInventories())); - break; - - case "WindowAction": - if (cmd.Parameters == null || cmd.Parameters.Length == 0 || cmd.Parameters.Length != 3) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 3 parameters (inventoryId, slotId, windowActionType)!")); - return false; - } - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(WindowAction( - Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), - (WindowActionType)Convert.ToInt32(cmd.Parameters[2]) - ))); - break; - - case "ChangeSlot": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (slotId)!")); - return false; - } - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(ChangeSlot((short)Convert.ToInt32(cmd.Parameters[0])))); - break; - - case "GetCurrentSlot": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetCurrentSlot())); - break; - - case "ClearInventories": - responder.SendSuccessResponse(JsonConvert.SerializeObject(ClearInventories())); - break; - - case "UpdateSign": - if (cmd.Parameters is not { Length: 7 }) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 1 parameter (x, y, z, line1, line2, line3, line4)!")); - return false; - } - - var signLocation = new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), Convert.ToInt32(cmd.Parameters[2])); - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(UpdateSign(signLocation, - (string)cmd.Parameters[3], - (string)cmd.Parameters[4], - (string)cmd.Parameters[5], - (string)cmd.Parameters[6] - ))); - break; - - case "SelectTrade": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (selectedSlot)!")); - return false; - } - - responder.SendSuccessResponse( - JsonConvert.SerializeObject(SelectTrade(Convert.ToInt32(cmd.Parameters[0])))); - break; - - case "UpdateCommandBlock": - if (cmd.Parameters is not { Length: 6 }) - { - responder.SendErrorResponse(responder.Quote( - "Invalid number of parameters, expecting 1 parameter (x, y, z, command, commandBlockMode, commandBlockFlags)!")); - return false; - } - - var commandBlockLocation = new Location(Convert.ToInt32(cmd.Parameters[0]), - Convert.ToInt32(cmd.Parameters[1]), Convert.ToInt32(cmd.Parameters[2])); - - responder.SendSuccessResponse( - UpdateCommandBlock(commandBlockLocation, - (string)cmd.Parameters[3], - (CommandBlockMode)Convert.ToInt32(cmd.Parameters[4]), - (CommandBlockFlags)Convert.ToInt32(cmd.Parameters[5]) - ).ToString().ToLower()); - break; - - case "CloseInventory": - if (cmd.Parameters is not { Length: 1 }) - { - responder.SendErrorResponse( - responder.Quote("Invalid number of parameters, expecting 1 parameter (inventoryId)!")); - return false; - } - - responder.SendSuccessResponse(CloseInventory(Convert.ToInt32(cmd.Parameters[0])).ToString() - .ToLower()); - break; - - case "GetMaxChatMessageLength": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetMaxChatMessageLength())); - break; - - case "Respawn": - responder.SendSuccessResponse(JsonConvert.SerializeObject(Respawn())); - break; - - case "GetProtocolVersion": - responder.SendSuccessResponse(JsonConvert.SerializeObject(GetProtocolVersion())); - break; - - default: - responder.SendErrorResponse( - responder.Quote($"Unknown command {cmd.Command} received!")); - break; - } - } - catch (Exception e) - { - LogDebugToConsole(e.Message); - SendSessionEvent(sessionId, "OnWsCommandResponse", - "{\"success\": false, \"message\": \"An error occured, possible reasons: mail-formed json, type conversion, internal error\", \"stackTrace\": \"" + - Json.EscapeString(e.ToString()) + "\"}", true); - return false; - } - - return false; - } - - if (password.Length != 0) - { - if (!_authenticatedSessions.Contains(sessionId)) - { - SendSessionEvent(sessionId, "OnWsCommandResponse", - "{\"error\": true, \"message\": \"You must authenticate in order to send and receive data!\"}", - true); - return false; - } - } - else - { - if (!_authenticatedSessions.Contains(sessionId)) - { - SendSessionEvent(sessionId, "OnWsCommandResponse", - "{\"success\": true, \"message\": \"Successfully authenticated!\"}", true); - LogToConsole(string.Format(Translations.bot_WebSocketBot_session_authenticated, sessionId)); - _authenticatedSessions.Add(sessionId); - } - } - - return true; - } - - public override void OnUnload() - { - if (_server != null) - { - SendEvent("OnWsConnectionClose", ""); - _server.Stop(); - _server = null; - } - - _authenticatedSessions.Clear(); - } - - // ========================================================================================== - // Bot Events - // ========================================================================================== - public override void AfterGameJoined() - { - // Workaround to wait until the WebSocket server has been started - // This would fire before the WS server is started, this causing a null exception. - _waitingEvents.Add(("OnGameJoined", "")); - } - - public override void OnBlockBreakAnimation(Entity entity, Location location, byte stage) - { - SendEvent("OnBlockBreakAnimation", new { entity, location, stage }); - } - - public override void OnEntityAnimation(Entity entity, byte animation) - { - SendEvent("OnEntityAnimation", new { entity, animation }); - } - - public override void GetText(string text) - { - text = GetVerbatim(text).Trim(); - - var message = ""; - var username = ""; - - if (IsPrivateMessage(text, ref message, ref username)) - SendEvent("OnChatPrivate", new { sender = username, message, rawText = text }); - else if (IsChatMessage(text, ref message, ref username)) - SendEvent("OnChatPublic", new { username, message, rawText = text }); - else if (IsTeleportRequest(text, ref username)) - SendEvent("OnTeleportRequest", new { sender = username, rawText = text }); - } - - public override void GetText(string text, string? json) - { - SendEvent("OnChatRaw", new { text, json }); - } - - public override bool OnDisconnect(DisconnectReason reason, string message) - { - var reasonString = reason switch - { - DisconnectReason.ConnectionLost => "Connection Lost", - DisconnectReason.UserLogout => "User Logout", - DisconnectReason.InGameKick => "In-Game Kick", - DisconnectReason.LoginRejected => "Login Rejected", - _ => "Unknown" - }; - - SendEvent("OnDisconnect", new { reason = reasonString, message }); - return false; - } - - public override void OnPlayerProperty(Dictionary prop) - { - SendEvent("OnPlayerProperty", prop); - } - - public override void OnServerTpsUpdate(double tps) - { - SendEvent("OnServerTpsUpdate", new { tps }); - } - - public override void OnTimeUpdate(long worldAge, long timeOfDay) - { - SendEvent("OnTimeUpdate", new { worldAge, timeOfDay }); - } - - public override void OnEntityMove(Entity entity) - { - SendEvent("OnEntityMove", entity); - } - - public override void OnInternalCommand(string commandName, string commandParams, CmdResult result) - { - SendEvent("OnInternalCommand", - new { command = commandName, parameters = commandParams, result = result.ToString().Replace("\"", "'") }); - } - - public override void OnEntitySpawn(Entity entity) - { - SendEvent("OnEntitySpawn", entity); - } - - public override void OnEntityDespawn(Entity entity) - { - SendEvent("OnEntityDespawn", entity); - } - - public override void OnHeldItemChange(byte slot) - { - SendEvent("OnHeldItemChange", new { itemSlot = slot }); - } - - public override void OnHealthUpdate(float health, int food) - { - SendEvent("OnHealthUpdate", new { health, food }); - } - - public override void OnExplosion(Location explode, float strength, int recordCount) - { - SendEvent("OnExplosion", new { location = explode, strength, recordCount }); - } - - public override void OnSetExperience(float experienceBar, int level, int totalExperience) - { - SendEvent("OnSetExperience", - new { experienceBar, level, totalExperience }); - } - - public override void OnGamemodeUpdate(string playerName, Guid uuid, int gameMode) - { - SendEvent("OnGamemodeUpdate", new { playerName, uuid, gameMode = GameModeString(gameMode) }); - } - - public override void OnLatencyUpdate(string playerName, Guid uuid, int latency) - { - SendEvent("OnLatencyUpdate", new { playerName, uuid, latency }); - } - - public override void OnMapData(int mapId, byte scale, bool trackingPosition, bool locked, List icons, - byte columnsUpdated, byte rowsUpdated, byte mapColumnX, byte mapRowZ, byte[]? colors) - { - SendEvent("OnMapData", - new - { - mapId, scale, trackingPosition, locked, icons, columnsUpdated, rowsUpdated, mapColumnX, mapRowZ, - colors - }); - } - - public override void OnTradeList(int windowId, List trades, VillagerInfo villagerInfo) - { - SendEvent("OnTradeList", new { windowId, trades, villagerInfo }); - } - - public override void OnTitle(int action, string titleText, string subtitleText, string actionBarText, int fadein, - int stay, int fadeout, string json_) - { - SendEvent("OnTitle", - new - { - action, titleText, subtitleText, actionBarText, - fadeIn = fadein, stay, rawJson = json_ - }); - } - - public override void OnEntityEquipment(Entity entity, int slot, Item? item) - { - SendEvent("OnEntityEquipment", new { entity, slot, item }); - } - - public override void OnEntityEffect(Entity entity, Effects effect, int amplifier, int duration, byte flags) - { - SendEvent("OnEntityEffect", new { entity, effect, amplifier, duration, flags }); - } - - public override void OnScoreboardObjective(string objectiveName, byte mode, string objectiveValue, int type, - string json_, int numberFormat) - { - SendEvent("OnScoreboardObjective", - new { objectiveName, mode, objectiveValue, type, rawJson = json_, numberFormat }); - } - - public override void OnUpdateScore(string entityName, int action, string objectiveName, string objectiveDisplayName, int value, int numberFormat) - { - SendEvent("OnUpdateScore", - new { entityName, action, objectiveName, objectiveDisplayName, type = value, numberFormat }); - } - - public override void OnInventoryUpdate(int inventoryId) - { - SendEvent("OnInventoryUpdate", new { inventoryId }); - } - - public override void OnInventoryOpen(int inventoryId) - { - SendEvent("OnInventoryOpen", new { inventoryId }); - } - - public override void OnInventoryClose(int inventoryId) - { - SendEvent("OnInventoryClose", new { inventoryId }); - } - - public override void OnPlayerJoin(Guid uuid, string name) - { - SendEvent("OnPlayerJoin", new { uuid, name }); - } - - public override void OnPlayerLeave(Guid uuid, string? name) - { - SendEvent("OnPlayerLeave", new { uuid, name = name ?? "null" }); - } - - public override void OnDeath() - { - SendEvent("OnDeath", ""); - } - - public override void OnRespawn() - { - SendEvent("OnRespawn", ""); - } - - public override void OnEntityHealth(Entity entity, float health) - { - SendEvent("OnEntityHealth", new { entity, health }); - } - - public override void OnEntityMetadata(Entity entity, Dictionary? metadata) - { - SendEvent("OnEntityMetadata", new { entity, metadata }); - } - - public override void OnPlayerStatus(byte statusId) - { - SendEvent("OnPlayerStatus", new { statusId }); - } - - public override void OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound) - { - SendEvent("OnNetworkPacket", new { packetId = packetID, isLogin, isInbound, packetData }); - } - - // ========================================================================================== - // Helper methods - // ========================================================================================== - - private void SendEvent(string type, object data, bool overrideAuth = false) - { - if (_server == null) - return; - - foreach (var (sessionId, _) in _server!.Sessions) - SendSessionEvent(sessionId, type, JsonConvert.SerializeObject(data), overrideAuth); - } - - private void SendEvent(string type, string data, bool overrideAuth = false) - { - if (_server == null) - return; - - foreach (var (sessionId, _) in _server.Sessions) - SendSessionEvent(sessionId, type, data, overrideAuth); - } - - private void SendSessionEvent(string sessionId, string type, string data, bool overrideAuth = false) - { - if (sessionId.Length > 0 && (overrideAuth || _authenticatedSessions.Contains(sessionId))) - { - _server?.SendToSession(sessionId, - $"{{\"event\": \"{type}\", \"data\": {(string.IsNullOrEmpty(data) ? "null" : $"\"{Json.EscapeString(data)}\"")}}}") - .Wait(); - - if (!(type.Contains("Entity") || type.Equals("OnTimeUpdate") || type.Equals("OnServerTpsUpdate")) && - Config.DebugMode) - LogDebugToConsole( - $"\n\n\tSending:\n\n\t{{\"event\": \"{type}\", \"data\": {(string.IsNullOrEmpty(data) - ? "null" - : $"\"{Json.EscapeString(data)}\"")}}}\n\n"); - } - } - - public void SendCommandResponse(string sessionId, bool success, string requestId, string command, - string result, bool overrideAuth = false) - { - SendSessionEvent(sessionId, "OnWsCommandResponse", - $"{{\"success\": {success.ToString().ToLower()}, \"requestId\": \"{requestId}\", \"command\": \"{command}\", \"result\": {(string.IsNullOrEmpty(result) ? "null" : result)}}}", - overrideAuth); - } - - private static string GameModeString(int gameMode) - { - return gameMode switch - { - 0 => "survival", - 1 => "creative", - 2 => "adventure", - 3 => "spectator", - _ => "unknown" - }; - } -} \ No newline at end of file diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index f005df55..e9e934e9 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -346,7 +346,6 @@ namespace MinecraftClient if (Config.ChatBot.ScriptScheduler.Enabled) { BotLoad(new ScriptScheduler()); } if (Config.ChatBot.TelegramBridge.Enabled) { BotLoad(new TelegramBridge()); } if (Config.ChatBot.ItemsCollector.Enabled) { BotLoad(new ItemsCollector()); } - if (Config.ChatBot.WebSocketBot.Enabled) { BotLoad(new WebSocketBot()); } //Add your ChatBot here by uncommenting and adapting //BotLoad(new ChatBots.YourBot()); } diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index d8d564c9..684e5a98 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -1429,19 +1429,16 @@ namespace MinecraftClient get { return ChatBots.TelegramBridge.Config; } set { ChatBots.TelegramBridge.Config = value; ChatBots.TelegramBridge.Config.OnSettingUpdate(); } } - + [TomlPrecedingComment("$ChatBot.ItemsCollector$")] public ChatBots.ItemsCollector.Configs ItemsCollector { get { return ChatBots.ItemsCollector.Config; } - set { ChatBots.ItemsCollector.Config = value; ChatBots.ItemsCollector.Config.OnSettingUpdate(); } - } - - [TomlPrecedingComment("$ChatBot.WebSocketBot$")] - public ChatBots.WebSocketBot.Configs WebSocketBot - { - get { return ChatBots.WebSocketBot.Config!; } - set { ChatBots.WebSocketBot.Config = value; } + set + { + ChatBots.ItemsCollector.Config = value; + ChatBots.ItemsCollector.Config.OnSettingUpdate(); + } } } } From 57483646b1df7ae8affe71ad84434e4ef1dc64fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 21:41:08 +0000 Subject: [PATCH 027/484] Bump js-yaml from 3.14.1 to 3.14.2 in /docs Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2. - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 3.14.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 6449375a..c68d5a08 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3390,9 +3390,9 @@ js-tokens@^4.0.0: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + version "3.14.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" + integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== dependencies: argparse "^1.0.7" esprima "^4.0.0" From fdd77b562e35b2d9f4e535c036df3066b65d9b71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 22:08:58 +0000 Subject: [PATCH 028/484] Bump node-forge from 1.3.1 to 1.3.2 in /docs Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2. - [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md) - [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2) --- updated-dependencies: - dependency-name: node-forge dependency-version: 1.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 6449375a..299ff891 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3785,9 +3785,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + version "1.3.2" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" + integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw== node-releases@^2.0.18: version "2.0.18" From df79e10f26d3a39c81749577ec0853affcb70d0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 23:07:27 +0000 Subject: [PATCH 029/484] Bump lodash from 4.17.21 to 4.17.23 in /docs Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 6449375a..3b27c0f8 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3497,9 +3497,9 @@ loader-utils@^2.0.0: json5 "^2.1.2" lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" + integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== log-symbols@^5.1.0: version "5.1.0" From e2ca8e082bdc5a412aae8b4c7cf21508915bd077 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 06:17:36 +0000 Subject: [PATCH 030/484] Bump webpack from 5.94.0 to 5.105.0 in /docs Bumps [webpack](https://github.com/webpack/webpack) from 5.94.0 to 5.105.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.94.0...v5.105.0) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.105.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 492 +++++++++++++++++++++++++------------------------ 1 file changed, 254 insertions(+), 238 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 6449375a..3ac9553a 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -107,7 +107,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -257,10 +257,26 @@ dependencies: "@types/ms" "*" -"@types/estree@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.31" @@ -305,7 +321,12 @@ dependencies: "@types/node" "*" -"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -815,125 +836,125 @@ dependencies: vue-demi "*" -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" - integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" -"@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== -"@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== -"@webassemblyjs/helper-buffer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" - integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== -"@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" - integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== -"@webassemblyjs/wasm-edit@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" - integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-opt" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" - "@webassemblyjs/wast-printer" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" -"@webassemblyjs/wasm-gen@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" - integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wasm-opt@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" - integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" - integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-api-error" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wast-printer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" - integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: - "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -954,21 +975,21 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-attributes@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" - integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== -acorn@^8.5.0, acorn@^8.7.1: +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +acorn@^8.5.0: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== -acorn@^8.8.2: - version "8.12.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -976,28 +997,13 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: +ajv-keywords@^5.0.0, ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.8.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" @@ -1008,6 +1014,16 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" @@ -1145,6 +1161,11 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -1233,16 +1254,6 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.10: - version "4.23.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== - dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" - node-releases "^2.0.18" - update-browserslist-db "^1.1.0" - browserslist@^4.21.4: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" @@ -1253,6 +1264,17 @@ browserslist@^4.21.4: node-releases "^2.0.6" update-browserslist-db "^1.0.9" +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -1322,10 +1344,10 @@ caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz#70cdae959096756a85713b36dd9cb82e62325639" integrity sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg== -caniuse-lite@^1.0.30001646: - version "1.0.30001655" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz#0ce881f5a19a2dcfda2ecd927df4d5c1684b982f" - integrity sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== chalk@^2.0.0: version "2.4.2" @@ -2324,10 +2346,10 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== -electron-to-chromium@^1.5.4: - version "1.5.13" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" - integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== emojis-list@^3.0.0: version "3.0.0" @@ -2339,13 +2361,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.17.1: - version "5.17.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" - integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== +enhanced-resolve@^5.19.0: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" entities@^2.0.0: version "2.2.0" @@ -2369,10 +2391,10 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-module-lexer@^1.2.1: - version "1.5.4" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" - integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== esbuild-android-64@0.15.12: version "0.15.12" @@ -2519,7 +2541,7 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escalade@^3.1.2: +escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== @@ -2709,10 +2731,10 @@ fast-glob@^3.2.11: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== fastq@^1.6.0: version "1.13.0" @@ -3402,11 +3424,6 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" @@ -3482,10 +3499,10 @@ linkify-it@^4.0.1: dependencies: uc.micro "^1.0.1" -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== loader-utils@^2.0.0: version "2.0.4" @@ -3789,10 +3806,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -node-releases@^2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" - integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== node-releases@^2.0.6: version "2.0.6" @@ -4013,10 +4030,10 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picocolors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -4351,24 +4368,6 @@ sass@^1.55.0: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - schema-utils@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" @@ -4379,6 +4378,16 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + section-matter@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" @@ -4425,7 +4434,7 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: +serialize-javascript@^6.0.0, serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== @@ -4742,21 +4751,26 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.0.0, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.3.10: - version "5.3.10" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" - integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== + +terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: - "@jridgewell/trace-mapping" "^0.3.20" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.26.0" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" terser@^5.10.0: version "5.15.1" @@ -4768,13 +4782,13 @@ terser@^5.10.0: commander "^2.20.0" source-map-support "~0.5.20" -terser@^5.26.0: - version "5.31.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" - integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== +terser@^5.31.1: + version "5.46.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.0.tgz#1b81e560d584bbdd74a8ede87b4d9477b0ff9695" + integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== dependencies: "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" + acorn "^8.15.0" commander "^2.20.0" source-map-support "~0.5.20" @@ -4884,13 +4898,13 @@ update-browserslist-db@^1.0.9: escalade "^3.1.1" picocolors "^1.0.0" -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.1" uri-js@^4.2.2: version "4.4.1" @@ -5040,10 +5054,10 @@ vuepress@^2.0.0-beta.53: dependencies: vuepress-vite "2.0.0-beta.53" -watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== +watchpack@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" + integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -5132,39 +5146,41 @@ webpack-sources@^2.2.0: source-list-map "^2.0.1" source-map "^0.6.1" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.74.0: - version "5.94.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" - integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== + version "5.105.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.0.tgz#38b5e6c5db8cbe81debbd16e089335ada05ea23a" + integrity sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw== dependencies: - "@types/estree" "^1.0.5" - "@webassemblyjs/ast" "^1.12.1" - "@webassemblyjs/wasm-edit" "^1.12.1" - "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.19.0" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.10" - watchpack "^2.4.1" - webpack-sources "^3.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.5.1" + webpack-sources "^3.3.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" From ff1c570a783fc4df1adb741d64e8efb0c7f2f5a7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:11:13 +0800 Subject: [PATCH 031/484] Handle non-interactive terminal environments gracefully When MCC runs in non-interactive terminals (e.g. CI runners, IDE embedded shells, piped input), several Console APIs throw exceptions because there is no real console attached. Changes: - Program.cs: Wrap Console.KeyAvailable / Console.ReadKey in HandleFailure() with try-catch so MCC does not crash on startup failure in headless environments. - Chunk.cs: Wrap Console.BufferWidth / BufferHeight in try-catch with fallback values (120x50) to prevent exceptions when rendering chunk maps without a console buffer. - Map.cs: Same treatment for the map rendering path - use safe fallback values when Console.BufferWidth/Height are unavailable. - ReplayHandler.cs: Replace Array.Reverse() (returns void in newer .NET) with .AsEnumerable().Reverse() to fix compilation with .NET 10 SDK where the void return breaks the fluent chain. Made-with: Cursor --- MinecraftClient/ChatBots/Map.cs | 9 ++++++--- MinecraftClient/Commands/Chunk.cs | 10 +++++++--- MinecraftClient/Program.cs | 8 +++++--- MinecraftClient/Protocol/ReplayHandler.cs | 6 +++--- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs index 25e75a74..c0c3aa8e 100644 --- a/MinecraftClient/ChatBots/Map.cs +++ b/MinecraftClient/ChatBots/Map.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -344,8 +344,11 @@ namespace MinecraftClient.ChatBots private static void RenderInConsole(McMap map) { StringBuilder sb = new(); - int consoleWidth = Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2; - int consoleHeight = Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1; + int safeBufWidth, safeBufHeight; + try { safeBufWidth = Console.BufferWidth; } catch { safeBufWidth = 120; } + try { safeBufHeight = Console.BufferHeight; } catch { safeBufHeight = 50; } + int consoleWidth = Math.Max(safeBufWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2; + int consoleHeight = Math.Max(safeBufHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1; int scaleX = (map.Width + consoleWidth - 1) / consoleWidth; int scaleY = (map.Height + consoleHeight - 1) / consoleHeight; int scale = Math.Max(scaleX, scaleY); diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs index cdc26e14..2068c662 100644 --- a/MinecraftClient/Commands/Chunk.cs +++ b/MinecraftClient/Commands/Chunk.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Brigadier.NET; using Brigadier.NET.Builder; @@ -100,11 +100,15 @@ namespace MinecraftClient.Commands sb.AppendLine(string.Format(Translations.cmd_chunk_chunk_pos, markChunkX, markChunkZ)); ; } - int consoleHeight = Math.Max(Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25); + int safeHeight; + int safeWidth; + try { safeHeight = Console.BufferHeight; } catch { safeHeight = 50; } + try { safeWidth = Console.BufferWidth; } catch { safeWidth = 120; } + int consoleHeight = Math.Max(Math.Max(safeHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25); if (consoleHeight % 2 == 0) --consoleHeight; - int consoleWidth = Math.Max(Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17); + int consoleWidth = Math.Max(Math.Max(safeWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17); if (consoleWidth % 2 == 0) --consoleWidth; diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 1b68583d..b8a1f788 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -768,8 +768,10 @@ namespace MinecraftClient if (!String.IsNullOrEmpty(errorMessage)) { ConsoleIO.Reset(); - while (Console.KeyAvailable) - Console.ReadKey(true); + try { + while (Console.KeyAvailable) + Console.ReadKey(true); + } catch { } ConsoleIO.WriteLine(errorMessage); if (disconnectReason.HasValue) diff --git a/MinecraftClient/Protocol/ReplayHandler.cs b/MinecraftClient/Protocol/ReplayHandler.cs index 75184e26..be567caf 100644 --- a/MinecraftClient/Protocol/ReplayHandler.cs +++ b/MinecraftClient/Protocol/ReplayHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -239,8 +239,8 @@ namespace MinecraftClient.Protocol // format: timestamp + packetLength + RawPacket List line = new(); int nowTime = Convert.ToInt32((lastPacketTime - recordStartTime).TotalMilliseconds); - line.AddRange(BitConverter.GetBytes((Int32)nowTime).Reverse().ToArray()); - line.AddRange(BitConverter.GetBytes((Int32)rawPacket.Count).Reverse().ToArray()); + line.AddRange(BitConverter.GetBytes((Int32)nowTime).AsEnumerable().Reverse().ToArray()); + line.AddRange(BitConverter.GetBytes((Int32)rawPacket.Count).AsEnumerable().Reverse().ToArray()); line.AddRange(rawPacket.ToArray()); // Write out to the file recordStream!.Write(line.ToArray()); From a7a95d991c9298d116383c9334475cc03e0d1501 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:12:06 +0800 Subject: [PATCH 032/484] Fix EntityProperties attribute ID mapping for 1.20.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 1.20.6 EntityProperties packet sends attribute IDs as VarInts instead of strings. The existing mapping dictionary had three issues: 1. IDs 5/6/7 used the wrong prefix "generic." but the official 1.20.6 registry uses "player." for these attributes: - 5: player.block_break_speed (was generic.block_break_speed) - 6: player.block_interaction_range (was generic.block_interaction_range) - 7: player.entity_interaction_range (was generic.entity_interaction_range) 2. IDs 22-24 (submerged_mining_speed, sweeping_damage_ratio, water_movement_efficiency) do not exist in the 1.20.6 attribute registry — they were introduced in 1.21. Their presence could cause incorrect attribute resolution. 3. Direct dictionary indexing (attributeDictionary[id]) throws KeyNotFoundException if the server sends an unknown attribute ID, crashing the packet handler. Replaced with TryGetValue and a safe fallback to "unknown". Made-with: Cursor --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index f552b2f9..a274b6e4 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2521,9 +2521,9 @@ namespace MinecraftClient.Protocol.Handlers { 2, "generic.attack_damage" }, { 3, "generic.attack_knockback" }, { 4, "generic.attack_speed" }, - { 5, "generic.block_break_speed" }, - { 6, "generic.block_interaction_range" }, - { 7, "generic.entity_interaction_range" }, + { 5, "player.block_break_speed" }, + { 6, "player.block_interaction_range" }, + { 7, "player.entity_interaction_range" }, { 8, "generic.fall_damage_multiplier" }, { 9, "generic.flying_speed" }, { 10, "generic.follow_range" }, @@ -2537,17 +2537,16 @@ namespace MinecraftClient.Protocol.Handlers { 18, "generic.safe_fall_distance" }, { 19, "generic.scale" }, { 20, "zombie.spawn_reinforcements" }, - { 21, "generic.step_height" }, - { 22, "generic.submerged_mining_speed" }, - { 23, "generic.sweeping_damage_ratio" }, - { 24, "generic.water_movement_efficiency" } + { 21, "generic.step_height" } }; Dictionary keys = new(); for (var i = 0; i < numberOfProperties; i++) { - var propertyKey = protocolVersion < MC_1_20_6_Version ? dataTypes.ReadNextString(packetData) - : attributeDictionary[dataTypes.ReadNextVarInt(packetData)]; + var propertyKey = protocolVersion < MC_1_20_6_Version + ? dataTypes.ReadNextString(packetData) + : (attributeDictionary.TryGetValue(dataTypes.ReadNextVarInt(packetData), out var attrName) + ? attrName : "unknown"); var propertyValue2 = dataTypes.ReadNextDouble(packetData); List op0 = new(); From 41a701b6b2d651d81cca3e477586a1c226dfea28 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:13:22 +0800 Subject: [PATCH 033/484] Fix RegistryData parsing and KnownDataPacks negotiation for 1.20.6 Two critical issues in the 1.20.6 configuration phase that could cause connection instability and packet desync: 1. RegistryData: The handler used an early `break` when it encountered a registryId other than "minecraft:dimension_type" or "minecraft:chat_type". This skipped reading the remaining entries for that registry, leaving unconsumed data in the packet buffer. Subsequent packet reads would start at the wrong offset, causing cascading parse failures and eventual disconnection. Fix: Always read all entries (entryId + hasData + optional NBT) for every registry, regardless of whether we process it. For dimension_type entries, if the server sends inline NBT data (i.e. non-vanilla dimensions from mods/datapacks), parse and store the dimension directly via World.StoreOneDimension(). Only fall back to hardcoded defaults when no dimension data was received. 2. KnownDataPacks: The client echoed back ALL packs the server listed, including non-vanilla ones. This told the server "I have these packs cached" when the client actually did not, so the server would skip sending full registry data for those packs. The result: incomplete registries for modded/datapack content. Fix: Filter the response to only include packs with the "minecraft" namespace. Non-vanilla packs are omitted, forcing the server to send their full registry data inline. Also adds supporting methods to World.cs: - SetDimensionIdMap(): Store VarInt ID -> dimension name mapping from RegistryData entries (needed by JoinGame/Respawn) - GetDimensionNameById(): Look up dimension name by numeric ID - HasAnyDimension(): Check if any dimensions were loaded from server-provided data Made-with: Cursor --- MinecraftClient/Mapping/World.cs | 22 ++++++++- .../Protocol/Handlers/Protocol18.cs | 48 ++++++++++--------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index b6240ffc..8add5c23 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -23,6 +23,11 @@ namespace MinecraftClient.Mapping private static readonly Dictionary dimensionList = new(); + /// + /// VarInt ID → dimension name mapping, populated from RegistryData in 1.20.6+ + /// + private static Dictionary dimensionIdMap = new(); + /// /// Chunk data parsing progress /// @@ -212,6 +217,21 @@ namespace MinecraftClient.Mapping StoreDimensionList(defaultRegistryCodec); } + public static void SetDimensionIdMap(Dictionary idMap) + { + dimensionIdMap = idMap; + } + + public static string GetDimensionNameById(int id) + { + return dimensionIdMap.TryGetValue(id, out var name) ? name : "minecraft:overworld"; + } + + public static bool HasAnyDimension() + { + return dimensionList.Count > 0; + } + /// /// Store one dimension - Directly used in 1.16.2 to 1.18.2 /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index a274b6e4..3a0abe27 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -458,40 +458,41 @@ namespace MinecraftClient.Protocol.Handlers } else { - // TODO: Implement proper parsing for 1.20.6 / 1.21 when there is a custom data pack on the server - // THis is a temporary workaround to get the client to be useable asap - var registryId = dataTypes.ReadNextString(packetData); var entryCount = dataTypes.ReadNextVarInt(packetData); - // Ignore other registries to save on time, we need only these 2 - if(registryId is not ("minecraft:dimension_type" or "minecraft:chat_type")) - break; + var isChat = registryId == "minecraft:chat_type"; + var isDimension = registryId == "minecraft:dimension_type"; - var avaliableChats = new Dictionary(); - var dimensionType = new Dictionary(); + var availableChats = isChat ? new Dictionary() : null; + var dimensionIdMap = isDimension ? new Dictionary() : null; for (var i = 0; i < entryCount; i++) { var entryId = dataTypes.ReadNextString(packetData); var hasData = dataTypes.ReadNextBool(packetData); - - if (hasData) - { - // TODO: Parse in case when the server data packs differ from the client - dataTypes.ReadNextNbt(packetData); - } - if (registryId == "minecraft:chat_type") - avaliableChats.Add(i, entryId); - else dimensionType.Add(i, entryId); + Dictionary? nbtData = null; + if (hasData) + nbtData = dataTypes.ReadNextNbt(packetData); + + if (isChat) + availableChats!.Add(i, entryId); + else if (isDimension) + { + dimensionIdMap!.Add(i, entryId); + if (nbtData != null && handler.GetTerrainEnabled()) + World.StoreOneDimension(entryId, nbtData); + } } - if (registryId == "minecraft:chat_type") - ChatParser.ReadChatType(avaliableChats); - else + if (isChat) + ChatParser.ReadChatType(availableChats!); + else if (isDimension) { - World.LoadDefaultDimensions1206Plus(); + World.SetDimensionIdMap(dimensionIdMap!); + if (!handler.GetTerrainEnabled() || !World.HasAnyDimension()) + World.LoadDefaultDimensions1206Plus(); } } @@ -531,7 +532,10 @@ namespace MinecraftClient.Protocol.Handlers knownDataPacks.Add((nameSpace, id, version)); } - SendKnownDataPacks(knownDataPacks); + var vanillaPacks = knownDataPacks + .Where(p => p.Item1 == "minecraft") + .ToList(); + SendKnownDataPacks(vanillaPacks); break; // Ignore other packets at this stage From bb18399523e65d257381210091358ac8406de56e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:13:57 +0800 Subject: [PATCH 034/484] Use dynamic dimension registry lookup in JoinGame and Respawn packets The JoinGame and Respawn packet handlers for 1.20.6+ used hardcoded switch expressions to map dimension type VarInt IDs to names: 0 => overworld, 1 => overworld_caves, 2 => the_end, 3 => the_nether This only works for vanilla servers with exactly 4 default dimensions. Modded servers (Forge/Fabric/NeoForge) or servers with custom datapacks can register additional dimensions with IDs beyond 0-3, causing the switch to fall through to the default "overworld" for any non-vanilla dimension. This means players in modded dimensions would have incorrect world parameters (height, lighting, etc.). Fix: Replace both hardcoded switch expressions with World.GetDimensionNameById(), which looks up the VarInt ID in the dimension ID map populated during the RegistryData phase. Also fixes two pre-existing issues in the SetDimension dispatch: - JoinGame (pre-1.20.2 path): The `case < MC_1_20_6_Version` guard was technically correct within its enclosing `if` block, but changed to `default` for clarity and future-proofing. - Respawn: The `case <= MC_1_20_6_Version` guard excluded protocol versions above 766 (e.g. 1.21 / protocol 767), meaning SetDimension was never called for those versions. Changed to `default` so all versions >= 1.19 properly update the dimension. Made-with: Cursor --- .../Protocol/Handlers/Protocol18.cs | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 3a0abe27..dab9f2e0 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -753,10 +753,9 @@ namespace MinecraftClient.Protocol.Handlers { case >= MC_1_16_2_Version and <= MC_1_18_2_Version: World.StoreOneDimension(dimensionName, dimensionType!); - // World.SetDimension(dimensionName); - World.SetDimension(dimensionName); + World.SetDimension(dimensionName); break; - case < MC_1_20_6_Version: + default: World.SetDimension(dimensionTypeName!); break; } @@ -808,17 +807,9 @@ namespace MinecraftClient.Protocol.Handlers { dataTypes.ReadNextBool(packetData); // Do limited crafting - // Dimension Type (string bellow 1.20.6, VarInt for 1.20.6+) var dimensionTypeName = protocolVersion < MC_1_20_6_Version - ? dataTypes.ReadNextString(packetData) // < 1.20.6 - : (dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry - { - 0 => "minecraft:overworld", - 1 => "minecraft:overworld_caves", - 2 => "minecraft:the_end", - 3 => "minecraft:the_nether", - _ => null - } ?? "minecraft:overworld"); + ? dataTypes.ReadNextString(packetData) + : World.GetDimensionNameById(dataTypes.ReadNextVarInt(packetData)); dataTypes.ReadNextString(packetData); // Dimension Name (World Name) - 1.16 and above @@ -1282,14 +1273,7 @@ namespace MinecraftClient.Protocol.Handlers switch (protocolVersion) { case >= MC_1_20_6_Version: - dimensionTypeNameRespawn = dataTypes.ReadNextVarInt(packetData) switch // 1.20.6+ // TODO: Use values from the registry - { - 0 => "minecraft:overworld", - 1 => "minecraft:overworld_caves", - 2 => "minecraft:the_end", - 3 => "minecraft:the_nether", - _ => null - } ?? "minecraft:overworld"; + dimensionTypeNameRespawn = World.GetDimensionNameById(dataTypes.ReadNextVarInt(packetData)); break; case >= MC_1_19_Version: dimensionTypeNameRespawn = @@ -1328,7 +1312,7 @@ namespace MinecraftClient.Protocol.Handlers World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); World.SetDimension(dimensionName); break; - case <= MC_1_20_6_Version: + default: World.SetDimension(dimensionTypeNameRespawn!); break; } From 8eac21b4a4133791562ef3f547a29f4582f8968e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:26:24 +0800 Subject: [PATCH 035/484] Wire up 1.20.6 structured components to Item and fix GetItemSlot serialization In 1.20.6+, items use structured components instead of NBT for metadata. Previously, ReadNextItemSlot parsed the components but never stored them on the Item instance, leaving DisplayName/Lores/Damage/Enchantments all empty. GetItemSlot also still used the pre-1.20.6 format (bool + VarInt + byte + NBT), causing the server to reject any item operation packets. Changes: Item.cs: - Add List? Components field to hold the raw component list for round-trip serialization - DisplayName property: read from CustomNameComponent (with ItemNameComponent as fallback) when Components is present - Lores property: read from LoreNameComponent1206 when Components is present - Damage property: read from DamageComponent when Components is present - Add EnchantmentList property: read from EnchantmentsComponent (covers both normal and StoredEnchantmentsComponent for enchanted books) - ToFullString(): use EnchantmentList with EnchantmentMapping for display when available, fall back to NBT path for older versions - Add CloneWithCount() method that preserves both NBT and Components DataTypes.cs - ReadNextItemSlot: - Assign parsed strcturedComponentsToAdd to item.Components DataTypes.cs - GetItemSlot: - Add 1.20.6+ branch: write VarInt(count) + VarInt(itemId) + component counts + serialized components (using each component's TypeId and Serialize() method) - Empty slot sends VarInt(0) per the 1.20.6 protocol spec StructuredComponent.cs: - Add int TypeId property (default -1) to store the registry type ID assigned during parsing, enabling round-trip serialization StructuredComponentRegistry.cs: - Set component.TypeId = id after instantiation in ParseComponent() McClient.cs: - Replace manual Item constructor calls (new Item(type, count, nbt)) with Item.CloneWithCount() to preserve Components during inventory operations like slot moves, stack splits, and right-click placement Made-with: Cursor --- MinecraftClient/Inventory/Item.cs | 89 +++++++++++++++++-- MinecraftClient/McClient.cs | 10 +-- .../Protocol/Handlers/DataTypes.cs | 58 ++++++++---- .../Core/StructuredComponent.cs | 7 +- .../Core/StructuredComponentRegistry.cs | 3 +- 5 files changed, 135 insertions(+), 32 deletions(-) diff --git a/MinecraftClient/Inventory/Item.cs b/MinecraftClient/Inventory/Item.cs index b9d86755..247d45ea 100644 --- a/MinecraftClient/Inventory/Item.cs +++ b/MinecraftClient/Inventory/Item.cs @@ -1,8 +1,10 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Protocol.Message; namespace MinecraftClient.Inventory @@ -32,6 +34,11 @@ namespace MinecraftClient.Inventory /// public Dictionary? NBT; + /// + /// 1.20.6+ structured components (raw list for round-trip serialization) + /// + public List? Components; + /// /// Create an item with ItemType, Count and Metadata /// @@ -50,6 +57,14 @@ namespace MinecraftClient.Inventory Data = data; } + /// + /// Create a shallow clone with a specific count (preserves NBT and Components). + /// + public Item CloneWithCount(int count) + { + return new Item(Type, count, Data, NBT) { Components = Components }; + } + /// /// Check if the item slot is empty /// @@ -60,12 +75,26 @@ namespace MinecraftClient.Inventory } /// - /// Retrieve item display name from NBT properties. NULL if no display name is defined. + /// Retrieve item display name. For 1.20.6+ reads from structured components + /// (CustomNameComponent, then ItemNameComponent as fallback); for older versions reads from NBT. /// public string? DisplayName { get { + if (Components != null) + { + var customName = Components.OfType().FirstOrDefault(); + if (customName != null && !string.IsNullOrEmpty(customName.CustomName)) + return customName.CustomName; + + var itemName = Components.OfType().FirstOrDefault(); + if (itemName != null && !string.IsNullOrEmpty(itemName.ItemName)) + return itemName.ItemName; + + return null; + } + if (NBT != null && NBT.ContainsKey("display")) { if (NBT["display"] is Dictionary displayProperties && @@ -82,12 +111,21 @@ namespace MinecraftClient.Inventory } /// - /// Retrieve item lores from NBT properties. Returns null if no lores is defined. + /// Retrieve item lores. For 1.20.6+ reads from LoreNameComponent1206; for older versions reads from NBT. /// public string[]? Lores { get { + if (Components != null) + { + var loreComponent = Components.OfType().FirstOrDefault(); + if (loreComponent != null && loreComponent.Lines.Count > 0) + return loreComponent.Lines.ToArray(); + + return null; + } + List lores = new(); if (NBT != null && NBT.ContainsKey("display")) { @@ -107,12 +145,21 @@ namespace MinecraftClient.Inventory } /// - /// Retrieve item damage from NBT properties. Returns 0 if no damage is defined. + /// Retrieve item damage. For 1.20.6+ reads from DamageComponent; for older versions reads from NBT. /// public int Damage { get { + if (Components != null) + { + var damageComponent = Components.OfType().FirstOrDefault(); + if (damageComponent != null) + return damageComponent.Damage; + + return 0; + } + if (NBT != null && NBT.ContainsKey("Damage")) { object damage = NBT["Damage"]; @@ -127,6 +174,26 @@ namespace MinecraftClient.Inventory } } + /// + /// Retrieve enchantments from structured components (1.20.6+). Returns null for older versions. + /// Both normal enchantments (EnchantmentsComponent) and stored enchantments + /// (StoredEnchantmentsComponent, e.g. enchanted books) are checked. + /// + public List? EnchantmentList + { + get + { + if (Components == null) + return null; + + var enchComp = Components.OfType().FirstOrDefault(); + if (enchComp != null && enchComp.Enchantments.Count > 0) + return enchComp.Enchantments; + + return null; + } + } + public static string GetTypeString(ItemType type) { string type_str = type.ToString(); @@ -152,8 +219,18 @@ namespace MinecraftClient.Inventory try { - if (NBT != null && (NBT.TryGetValue("Enchantments", out object? enchantments) || - NBT.TryGetValue("StoredEnchantments", out enchantments))) + var enchList = EnchantmentList; + if (enchList != null) + { + foreach (var ench in enchList) + { + string name = EnchantmentMapping.GetEnchantmentName(ench.Type); + string level = EnchantmentMapping.ConvertLevelToRomanNumbers(ench.Level); + sb.AppendFormat(" | {0} {1}", name, level); + } + } + else if (NBT != null && (NBT.TryGetValue("Enchantments", out object? enchantments) || + NBT.TryGetValue("StoredEnchantments", out enchantments))) { foreach (Dictionary enchantment in (object[])enchantments) { diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 96dcb615..e9b0b38c 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; @@ -1549,7 +1549,7 @@ namespace MinecraftClient /// Record changes private static void StoreInNewSlot(Container inventory, Item item, int slotId, int newSlotId, List> changedSlots) { - Item newItem = new(item.Type, item.Count, item.NBT); + Item newItem = item.CloneWithCount(item.Count); inventory.Items[newSlotId] = newItem; inventory.Items.Remove(slotId); @@ -1672,7 +1672,7 @@ namespace MinecraftClient { // Drop 1 item count from cursor Item itemTmp = playerInventory.Items[-1]; - Item itemClone = new(itemTmp.Type, 1, itemTmp.NBT); + Item itemClone = itemTmp.CloneWithCount(1); inventory.Items[slotId] = itemClone; playerInventory.Items[-1].Count--; } @@ -1701,14 +1701,14 @@ namespace MinecraftClient { // Can be evenly divided Item itemTmp = inventory.Items[slotId]; - playerInventory.Items[-1] = new Item(itemTmp.Type, itemTmp.Count / 2, itemTmp.NBT); + playerInventory.Items[-1] = itemTmp.CloneWithCount(itemTmp.Count / 2); inventory.Items[slotId].Count = itemTmp.Count / 2; } else { // Cannot be evenly divided. item count on cursor is always larger than item on inventory Item itemTmp = inventory.Items[slotId]; - playerInventory.Items[-1] = new Item(itemTmp.Type, (itemTmp.Count + 1) / 2, itemTmp.NBT); + playerInventory.Items[-1] = itemTmp.CloneWithCount((itemTmp.Count + 1) / 2); inventory.Items[slotId].Count = (itemTmp.Count - 1) / 2; } } diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index dc953c56..af09909c 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; @@ -450,15 +450,11 @@ namespace MinecraftClient.Protocol.Handlers } for (var i = 0; i < numberofComponentsToRemove; i++) - { - // TODO: Check what this does exactly - ReadNextVarInt(cache); // The type of component to remove - } - - // TODO: Wire up the strctured components in the Item class (extract info, update fields, etc..) - // Use strcturedComponentsToAdd - // Look at: https://wiki.vg/index.php?title=Slot_Data&oldid=19350#Structured_components - + ReadNextVarInt(cache); + + if (strcturedComponentsToAdd.Count > 0) + item.Components = strcturedComponentsToAdd; + return item; case >= Protocol18Handler.MC_1_13_Version: { @@ -1561,17 +1557,44 @@ namespace MinecraftClient.Protocol.Handlers /// Item slot representation public byte[] GetItemSlot(Item? item, ItemPalette itemPalette) { - // TODO: Wire up Structured components for 1.20.6 - List slotData = new(); - if (protocolversion > Protocol18Handler.MC_1_13_Version) + + if (protocolversion >= Protocol18Handler.MC_1_20_6_Version) { - // MC 1.13 and greater if (item == null || item.IsEmpty) - slotData.AddRange(GetBool(false)); // No item + { + slotData.AddRange(GetVarInt(0)); + } else { - slotData.AddRange(GetBool(true)); // Item is present + slotData.AddRange(GetVarInt(item.Count)); + slotData.AddRange(GetVarInt(itemPalette.ToId(item.Type))); + + if (item.Components != null && item.Components.Count > 0) + { + slotData.AddRange(GetVarInt(item.Components.Count)); + slotData.AddRange(GetVarInt(0)); // components to remove + foreach (var component in item.Components) + { + slotData.AddRange(GetVarInt(component.TypeId)); + var serialized = component.Serialize(); + slotData.AddRange(serialized); + } + } + else + { + slotData.AddRange(GetVarInt(0)); // no components to add + slotData.AddRange(GetVarInt(0)); // no components to remove + } + } + } + else if (protocolversion > Protocol18Handler.MC_1_13_Version) + { + if (item == null || item.IsEmpty) + slotData.AddRange(GetBool(false)); + else + { + slotData.AddRange(GetBool(true)); slotData.AddRange(GetVarInt(itemPalette.ToId(item.Type))); slotData.Add((byte)item.Count); slotData.AddRange(GetNbt(item.NBT)); @@ -1579,13 +1602,10 @@ namespace MinecraftClient.Protocol.Handlers } else { - // MC 1.12.2 and lower if (item == null || item.IsEmpty) slotData.AddRange(GetShort(-1)); else { - // For 1.8 - 1.12.2 we combine Item Id and Item Data to a single value using: (id << 16) | data - // Thus to get an ID we do a right shift by 16 bits slotData.AddRange(GetShort((short)(itemPalette.ToId(item.Type) >> 16))); slotData.Add((byte)item.Count); slotData.Add((byte)item.Data); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs index 7465740b..2c0b66e3 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs @@ -8,7 +8,12 @@ public abstract class StructuredComponent(DataTypes dataTypes, ItemPalette itemP protected DataTypes DataTypes { get; private set; } = dataTypes; protected SubComponentRegistry SubComponentRegistry { get; private set; } = subComponentRegistry; protected ItemPalette ItemPalette { get; private set; } = itemPalette; - + + /// + /// The registry type ID assigned during parsing, used for round-trip serialization. + /// + public int TypeId { get; set; } = -1; + public abstract void Parse(Queue data); public abstract Queue Serialize(); } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs index 11c48e1f..3ae07057 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs @@ -35,7 +35,8 @@ public abstract class StructuredComponentRegistry(DataTypes dataTypes, ItemPalet var component = Activator.CreateInstance(type, dataTypes, itemPalette, subComponentRegistry) as StructuredComponent ?? throw new InvalidOperationException($"Could not instantiate a parser for a structured component type {name}"); - + + component.TypeId = id; component.Parse(data); return component; } From 967f67190cc9f05c5d4d47d297252ef7cceb8522 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:45:51 +0800 Subject: [PATCH 036/484] Add FileInputBot for non-interactive debugging and fix NbtToString crash FileInputBot (ChatBots/FileInputBot.cs): - New ChatBot that monitors a text file (default: mcc_input.txt) for commands, enabling MCC control from Cursor Shell or any non-interactive environment where stdin is not available - Activated by setting MCC_FILE_INPUT env var (e.g. MCC_FILE_INPUT=1) - Polls every ~500ms for new lines appended to the file - Lines starting with "/" are sent as server chat/commands - Other lines are executed as MCC internal commands (same as console input) - File path overridable via MCC_INPUT_FILE env var McClient.cs: - Load FileInputBot when MCC_FILE_INPUT environment variable is set ChatParser.cs - NbtToString: - Fix InvalidCastException when NBT "text" or nameless root tag values are Int32 instead of String (happens with 1.20.6 SystemChat packets containing numeric values in the chat component tree) - Replace direct (string) casts with ?.ToString() ?? string.Empty Made-with: Cursor --- MinecraftClient/ChatBots/FileInputBot.cs | 105 ++++++++++++++++++ MinecraftClient/McClient.cs | 4 +- .../Protocol/Message/ChatParser.cs | 7 +- 3 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 MinecraftClient/ChatBots/FileInputBot.cs diff --git a/MinecraftClient/ChatBots/FileInputBot.cs b/MinecraftClient/ChatBots/FileInputBot.cs new file mode 100644 index 00000000..16c65cd8 --- /dev/null +++ b/MinecraftClient/ChatBots/FileInputBot.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; +using System.Threading; +using MinecraftClient.CommandHandler; +using MinecraftClient.Scripting; + +namespace MinecraftClient.ChatBots +{ + /// + /// Debug-only ChatBot that monitors a text file for commands. + /// Write lines to the file from any external tool (e.g. Cursor Shell) + /// and this bot will execute them as MCC internal commands. + /// + /// Usage from Cursor Shell: + /// Add-Content mcc_input.txt "inventory" + /// Add-Content mcc_input.txt "send /give @s diamond_sword 1" + /// + /// Lines starting with "/" are sent as server chat; others are treated + /// as MCC internal commands (same as typing in the MCC console). + /// + public class FileInputBot : ChatBot + { + private const string BotName = "FileInput"; + private string _filePath = string.Empty; + private long _lastPosition; + private int _tickCounter; + + public override void Initialize() + { + _filePath = Path.GetFullPath( + Environment.GetEnvironmentVariable("MCC_INPUT_FILE") ?? "mcc_input.txt"); + + if (File.Exists(_filePath)) + _lastPosition = new FileInfo(_filePath).Length; + else + File.WriteAllText(_filePath, ""); + + LogToConsole(BotName, $"Watching: {_filePath}"); + LogToConsole(BotName, "Write commands to this file to execute them."); + } + + public override void Update() + { + // Poll every ~500ms (Update is called every ~100ms) + if (++_tickCounter < 5) + return; + _tickCounter = 0; + + try + { + if (!File.Exists(_filePath)) + return; + + var info = new FileInfo(_filePath); + if (info.Length <= _lastPosition) + return; + + string newContent; + using (var fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + fs.Seek(_lastPosition, SeekOrigin.Begin); + using var reader = new StreamReader(fs); + newContent = reader.ReadToEnd(); + } + _lastPosition = info.Length; + + foreach (var rawLine in newContent.Split('\n')) + { + var line = rawLine.Trim(); + if (string.IsNullOrEmpty(line)) + continue; + + LogToConsole(BotName, $"> {line}"); + + if (line.StartsWith("/")) + { + SendText(line); + } + else + { + CmdResult result = new(); + if (PerformInternalCommand(line, ref result)) + { + if (!string.IsNullOrEmpty(result.ToString())) + LogToConsole(BotName, result.ToString()); + } + else + { + // Not an internal command — send as chat + SendText(line); + } + } + } + } + catch (IOException) + { + // File may be temporarily locked by the writer + } + catch (Exception ex) + { + LogToConsole(BotName, $"Error: {ex.Message}"); + } + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index e9b0b38c..c632569b 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -425,8 +425,8 @@ namespace MinecraftClient if (Config.ChatBot.ScriptScheduler.Enabled) { BotLoad(new ScriptScheduler()); } if (Config.ChatBot.TelegramBridge.Enabled) { BotLoad(new TelegramBridge()); } if (Config.ChatBot.ItemsCollector.Enabled) { BotLoad(new ItemsCollector()); } - //Add your ChatBot here by uncommenting and adapting - //BotLoad(new ChatBots.YourBot()); + if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MCC_FILE_INPUT"))) + BotLoad(new FileInputBot()); } /// diff --git a/MinecraftClient/Protocol/Message/ChatParser.cs b/MinecraftClient/Protocol/Message/ChatParser.cs index d3db4e38..f907eadd 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -510,8 +510,7 @@ namespace MinecraftClient.Protocol.Message { if (nbt.Count == 1 && nbt.TryGetValue("", out object? rootMessage)) { - // Nameless root tag - return (string)rootMessage; + return rootMessage?.ToString() ?? string.Empty; } string message = string.Empty; @@ -526,7 +525,7 @@ namespace MinecraftClient.Protocol.Message { case "text": { - message = (string)value; + message = value?.ToString() ?? string.Empty; } break; case "extra": From 99ac3d028ab9711ba43c32a83b1a9fe494eafc27 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 01:12:18 +0800 Subject: [PATCH 037/484] Dynamically parse minecraft:attribute registry from server RegistryData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 1.20.6+, EntityProperties packets reference attributes by VarInt registry IDs instead of string names. Previously, a hardcoded dictionary of 22 attribute entries (matching the vanilla 1.20.6 registry) was used to map these IDs back to names. This works for vanilla servers but would fail silently for modded servers that add custom attributes — any unknown ID would be reported as "unknown". This commit replaces the hardcoded attribute dictionary with dynamic registry parsing, following the same pattern already used for dimension_type and chat_type registries: - World.cs: Add static `attributeIdMap` field, `SetAttributeIdMap()` and `GetAttributeNameById()` methods for storing/querying attribute names by their VarInt registry IDs. - Protocol18.cs (RegistryData handler): When the server sends a `minecraft:attribute` registry during the Configuration phase, parse all entries and store the ID→name mapping. The `minecraft:` prefix is stripped from entry names to match the format used in EntityProperties packets (e.g. "minecraft:generic.armor" → "generic.armor"). - Protocol18.cs (EntityProperties handler): Remove the hardcoded 22-entry `attributeDictionary` and use `World.GetAttributeNameById()` instead. Unknown IDs still fall back to "unknown" for safety. Also closes issue #4 (Disconnect packet extra boolean) — verified that both Play and Configuration phase Disconnect handlers already use `ReadNextChat()` (NBT format since 1.20.4+), matching the 1.20.6 protocol spec. No code changes needed; updated tracking document to mark as closed. Made-with: Cursor --- MinecraftClient/Mapping/World.cs | 18 +++++++ .../Protocol/Handlers/Protocol18.cs | 52 ++++++++----------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 8add5c23..be666f4f 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -28,6 +28,11 @@ namespace MinecraftClient.Mapping /// private static Dictionary dimensionIdMap = new(); + /// + /// VarInt ID → attribute name mapping, populated from RegistryData (minecraft:attribute) in 1.20.6+ + /// + private static Dictionary attributeIdMap = new(); + /// /// Chunk data parsing progress /// @@ -232,6 +237,19 @@ namespace MinecraftClient.Mapping return dimensionList.Count > 0; } + public static void SetAttributeIdMap(Dictionary idMap) + { + attributeIdMap = idMap; + } + + /// + /// Get attribute name by its registry VarInt ID. Returns null if the ID is unknown. + /// + public static string? GetAttributeNameById(int id) + { + return attributeIdMap.TryGetValue(id, out var name) ? name : null; + } + /// /// Store one dimension - Directly used in 1.16.2 to 1.18.2 /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index dab9f2e0..7806af21 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -463,9 +463,11 @@ namespace MinecraftClient.Protocol.Handlers var isChat = registryId == "minecraft:chat_type"; var isDimension = registryId == "minecraft:dimension_type"; + var isAttribute = registryId == "minecraft:attribute"; var availableChats = isChat ? new Dictionary() : null; var dimensionIdMap = isDimension ? new Dictionary() : null; + var attributeIdMap = isAttribute ? new Dictionary() : null; for (var i = 0; i < entryCount; i++) { @@ -484,6 +486,14 @@ namespace MinecraftClient.Protocol.Handlers if (nbtData != null && handler.GetTerrainEnabled()) World.StoreOneDimension(entryId, nbtData); } + else if (isAttribute) + { + // Strip "minecraft:" prefix to match the format used in EntityProperties packets + var attrName = entryId.StartsWith("minecraft:") + ? entryId.Substring("minecraft:".Length) + : entryId; + attributeIdMap!.Add(i, attrName); + } } if (isChat) @@ -494,6 +504,8 @@ namespace MinecraftClient.Protocol.Handlers if (!handler.GetTerrainEnabled() || !World.HasAnyDimension()) World.LoadDefaultDimensions1206Plus(); } + else if (isAttribute) + World.SetAttributeIdMap(attributeIdMap!); } break; @@ -2502,39 +2514,19 @@ namespace MinecraftClient.Protocol.Handlers ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); - var attributeDictionary = new Dictionary - { - { 0, "generic.armor" }, - { 1, "generic.armor_toughness" }, - { 2, "generic.attack_damage" }, - { 3, "generic.attack_knockback" }, - { 4, "generic.attack_speed" }, - { 5, "player.block_break_speed" }, - { 6, "player.block_interaction_range" }, - { 7, "player.entity_interaction_range" }, - { 8, "generic.fall_damage_multiplier" }, - { 9, "generic.flying_speed" }, - { 10, "generic.follow_range" }, - { 11, "generic.gravity" }, - { 12, "generic.jump_strength" }, - { 13, "generic.knockback_resistance" }, - { 14, "generic.luck" }, - { 15, "generic.max_absorption" }, - { 16, "generic.max_health" }, - { 17, "generic.movement_speed" }, - { 18, "generic.safe_fall_distance" }, - { 19, "generic.scale" }, - { 20, "zombie.spawn_reinforcements" }, - { 21, "generic.step_height" } - }; - Dictionary keys = new(); for (var i = 0; i < numberOfProperties; i++) { - var propertyKey = protocolVersion < MC_1_20_6_Version - ? dataTypes.ReadNextString(packetData) - : (attributeDictionary.TryGetValue(dataTypes.ReadNextVarInt(packetData), out var attrName) - ? attrName : "unknown"); + string propertyKey; + if (protocolVersion < MC_1_20_6_Version) + { + propertyKey = dataTypes.ReadNextString(packetData); + } + else + { + var attrId = dataTypes.ReadNextVarInt(packetData); + propertyKey = World.GetAttributeNameById(attrId) ?? "unknown"; + } var propertyValue2 = dataTypes.ReadNextDouble(packetData); List op0 = new(); From b692b13bbcf19347e43cadec6942e53cd18a3b23 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 01:26:20 +0800 Subject: [PATCH 038/484] Fix EntityProperties crash and add default attribute registry fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the previous commit (99ac3d0) moved attribute lookup from a hardcoded dictionary to the dynamic RegistryData, MCC would crash immediately upon joining a vanilla 1.20.6 server with: System.ArgumentException: An item with the same key has already been added. Key: unknown Root cause: When KnownDataPacks negotiation tells the server that MCC already has the "minecraft" data pack, the server skips sending RegistryData for registries it considers "known" — including minecraft:attribute. This left the dynamic attribute map empty, so every VarInt attribute ID resolved to "unknown". The EntityProperties packet often contains multiple attributes (e.g. armor, max_health, movement_speed), and `keys.Add("unknown", ...)` on the second "unknown" attribute threw ArgumentException. Two fixes applied: 1. World.GetAttributeNameById(): When the dynamic attribute map is empty (server didn't send the registry), automatically load the vanilla 1.20.6 default attribute order (22 entries matching Attributes.java registration order). This mirrors the pattern used for dimensions where defaults are loaded when RegistryData is not sent. If a modded server sends a custom attribute registry, the dynamic map takes precedence. 2. Protocol18.cs EntityProperties handler: Change `keys.Add(propertyKey, propertyValue2)` to `keys[propertyKey] = propertyValue2` to tolerate duplicate keys defensively, in case an unknown attribute ID still appears. Tested: MCC now connects to a vanilla 1.20.6 offline-mode server, stays online for 6+ minutes with no crashes or disconnections. Verified: chat messages received, inventory listing (item names/counts correct), entity detection, TPS query, and health query all work correctly. Made-with: Cursor --- MinecraftClient/Mapping/World.cs | 34 +++++++++++++++++++ .../Protocol/Handlers/Protocol18.cs | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index be666f4f..c0999761 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -244,12 +244,46 @@ namespace MinecraftClient.Mapping /// /// Get attribute name by its registry VarInt ID. Returns null if the ID is unknown. + /// When KnownDataPacks negotiation tells the server we already have vanilla data, + /// the server skips sending the attribute registry. In that case we fall back to + /// the built-in vanilla 1.20.6 attribute order (22 entries). /// public static string? GetAttributeNameById(int id) { + if (attributeIdMap.Count == 0) + LoadDefaultAttributes(); return attributeIdMap.TryGetValue(id, out var name) ? name : null; } + private static void LoadDefaultAttributes() + { + attributeIdMap = new Dictionary + { + { 0, "generic.armor" }, + { 1, "generic.armor_toughness" }, + { 2, "generic.attack_damage" }, + { 3, "generic.attack_knockback" }, + { 4, "generic.attack_speed" }, + { 5, "player.block_break_speed" }, + { 6, "player.block_interaction_range" }, + { 7, "player.entity_interaction_range" }, + { 8, "generic.fall_damage_multiplier" }, + { 9, "generic.flying_speed" }, + { 10, "generic.follow_range" }, + { 11, "generic.gravity" }, + { 12, "generic.jump_strength" }, + { 13, "generic.knockback_resistance" }, + { 14, "generic.luck" }, + { 15, "generic.max_absorption" }, + { 16, "generic.max_health" }, + { 17, "generic.movement_speed" }, + { 18, "generic.safe_fall_distance" }, + { 19, "generic.scale" }, + { 20, "zombie.spawn_reinforcements" }, + { 21, "generic.step_height" } + }; + } + /// /// Store one dimension - Directly used in 1.16.2 to 1.18.2 /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 7806af21..e34306b7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2556,7 +2556,7 @@ namespace MinecraftClient.Protocol.Handlers if (op0.Count > 0) propertyValue2 += op0.Sum(); if (op1.Count > 0) propertyValue2 *= 1 + op1.Sum(); if (op2.Count > 0) propertyValue2 *= op2.Aggregate((a, _x) => a * _x); - keys.Add(propertyKey, propertyValue2); + keys[propertyKey] = propertyValue2; } handler.OnEntityProperties(entityId, keys); From 56f2426c1f618c031de0e4d9f96482a43a7d15b7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 01:37:56 +0800 Subject: [PATCH 039/484] Fix StructuredComponent serialization correctness for 1.20.6 Audited all 58 StructuredComponent subclasses against the official Minecraft 1.20.6 decompiled source to verify Parse()/Serialize() symmetry. Found and fixed four bugs across four components: 1. ContainerComponent: Parse() skipped null item slots (empty slots in a container) but Serialize() looped NumberOfItems times using Items[i], causing IndexOutOfRangeException when any slot was empty. The official ItemContainerContents uses OPTIONAL_STREAM_CODEC which serializes empty slots as VarInt(0). Fixed: Parse now stores all slots including nulls, Serialize uses Items.Count and iterates all entries. GetItemSlot(null) correctly writes VarInt(0) for empty slots. 2. ChargedProjectilesComponent: Used Items.OfType() in Serialize() which silently dropped null entries, causing the serialized count to differ from the written VarInt header. The official ChargedProjectiles uses STREAM_CODEC (non-optional, no empty slots allowed). Fixed: Items list is now List (non-nullable), Parse defensively skips nulls, Serialize writes Items.Count matching the actual list. 3. BundleContentsComponent: Same issue as ChargedProjectilesComponent. Applied the same fix pattern. 4. FoodComponentComponent: Two type mismatches vs the official FoodProperties.DIRECT_STREAM_CODEC: - Saturation was declared as bool and read with ReadNextBool (1 byte), but the protocol sends it as float (4 bytes). This caused all subsequent fields in the component to be read at wrong offsets, corrupting CanAlwaysEat, SecondsToEat, and the effects list. - NumberOfEffects was serialized with GetFloat() instead of GetVarInt(), writing 4 bytes of IEEE 754 float instead of a variable-length integer. Fixed both Parse and Serialize to use correct types. Also removed redundant NumberOfItems/NumberOfEffects fields from components where the count is derivable from the list length, and replaced ArgumentNullException with cleaner patterns. Tested end-to-end on vanilla 1.20.6 server: item receiving (diamond_sword, golden_apple, diamond_pickaxe), inventory slot movement (click to pick up and place), and inventory listing all work correctly with no server-side protocol errors. Made-with: Cursor --- .../1_20_6/BundleContentsComponent.cs | 24 +++++++++---------- .../1_20_6/ChargedProjectilesComponent.cs | 24 +++++++++---------- .../Components/1_20_6/ContainerComponent.cs | 19 +++++---------- .../1_20_6/FoodComponentComponent.cs | 23 +++++++----------- 4 files changed, 36 insertions(+), 54 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs index 063d1d20..5c5044f7 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Linq; using MinecraftClient.Inventory; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -10,28 +8,28 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class BundleContentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfItems { get; set; } - public List Items { get; set; } = []; + public List Items { get; set; } = []; public override void Parse(Queue data) { - NumberOfItems = dataTypes.ReadNextVarInt(data); + var count = dataTypes.ReadNextVarInt(data); - for (var i = 0; i < NumberOfItems; i++) - Items.Add(dataTypes.ReadNextItemSlot(data, itemPalette)); + for (var i = 0; i < count; i++) + { + var item = dataTypes.ReadNextItemSlot(data, itemPalette); + if (item != null) + Items.Add(item); + } } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + data.AddRange(DataTypes.GetVarInt(Items.Count)); - if (NumberOfItems != Items.Count) - throw new ArgumentNullException($"Cannot serialize BundleContentsComponent1206 because NumberOfItems != Items.Count!"); - - foreach (var item in Items.OfType()) + foreach (var item in Items) data.AddRange(DataTypes.GetItemSlot(item, itemPalette)); return new Queue(data); } -} \ No newline at end of file +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs index ef0875ef..7305ee8c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Linq; using MinecraftClient.Inventory; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -10,28 +8,28 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class ChargedProjectilesComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfItems { get; set; } - public List Items { get; set; } = []; + public List Items { get; set; } = []; public override void Parse(Queue data) { - NumberOfItems = dataTypes.ReadNextVarInt(data); + var count = dataTypes.ReadNextVarInt(data); - for (var i = 0; i < NumberOfItems; i++) - Items.Add(dataTypes.ReadNextItemSlot(data, itemPalette)); + for (var i = 0; i < count; i++) + { + var item = dataTypes.ReadNextItemSlot(data, itemPalette); + if (item != null) + Items.Add(item); + } } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfItems)); + data.AddRange(DataTypes.GetVarInt(Items.Count)); - if (NumberOfItems != Items.Count) - throw new ArgumentNullException($"Cannot serialize ChargedProjectilesComponent1206 because NumberOfItems != Items.Count!"); - - foreach (var item in Items.OfType()) + foreach (var item in Items) data.AddRange(DataTypes.GetItemSlot(item, itemPalette)); return new Queue(data); } -} \ No newline at end of file +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs index 2b050aff..053fc918 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs @@ -9,29 +9,22 @@ public class ContainerComponent(DataTypes dataTypes, ItemPalette itemPalette, Su : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfItems { get; set; } - public List Items { get; set; } = []; + public List Items { get; set; } = []; public override void Parse(Queue data) { NumberOfItems = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfItems; i++) - { - var item = dataTypes.ReadNextItemSlot(data, ItemPalette); - - if (item is null) - continue; - - Items.Add(item); - } + Items.Add(dataTypes.ReadNextItemSlot(data, ItemPalette)); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfItems)); - for (var i = 0; i < NumberOfItems; i++) - data.AddRange(DataTypes.GetItemSlot(Items[i], itemPalette)); + data.AddRange(DataTypes.GetVarInt(Items.Count)); + foreach (var item in Items) + data.AddRange(DataTypes.GetItemSlot(item, itemPalette)); return new Queue(data); } -} \ No newline at end of file +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs index f848750d..aac861c2 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs @@ -11,21 +11,20 @@ public class FoodComponentComponent(DataTypes dataTypes, ItemPalette itemPalette : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int Nutrition { get; set; } - public bool Saturation { get; set; } + public float Saturation { get; set; } public bool CanAlwaysEat { get; set; } public float SecondsToEat { get; set; } - public int NumberOfEffects { get; set; } public List Effects { get; set; } = new(); public override void Parse(Queue data) { Nutrition = dataTypes.ReadNextVarInt(data); - Saturation = dataTypes.ReadNextBool(data); + Saturation = dataTypes.ReadNextFloat(data); CanAlwaysEat = dataTypes.ReadNextBool(data); SecondsToEat = dataTypes.ReadNextFloat(data); - NumberOfEffects = dataTypes.ReadNextVarInt(data); + var numberOfEffects = dataTypes.ReadNextVarInt(data); - for(var i = 0; i < NumberOfEffects; i++) + for(var i = 0; i < numberOfEffects; i++) Effects.Add((EffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Effect, data)); } @@ -33,19 +32,13 @@ public class FoodComponentComponent(DataTypes dataTypes, ItemPalette itemPalette { var data = new List(); data.AddRange(DataTypes.GetVarInt(Nutrition)); - data.AddRange(DataTypes.GetBool(Saturation)); + data.AddRange(DataTypes.GetFloat(Saturation)); data.AddRange(DataTypes.GetBool(CanAlwaysEat)); data.AddRange(DataTypes.GetFloat(SecondsToEat)); - data.AddRange(DataTypes.GetFloat(NumberOfEffects)); + data.AddRange(DataTypes.GetVarInt(Effects.Count)); - if (NumberOfEffects > 0) - { - if(Effects.Count != NumberOfEffects) - throw new ArgumentNullException($"Can not serialize FoodComponent1206 due to NumberOfEffcets being different from the count of elements in the Effects list!"); - - foreach(var effect in Effects) - data.AddRange(effect.Serialize()); - } + foreach(var effect in Effects) + data.AddRange(effect.Serialize()); return new Queue(data); } From 1e2b853b14e241089f9637f5ad99efe9aa29384f Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 01:44:23 +0800 Subject: [PATCH 040/484] Fix PotionContentsComponent and InstrumentComponent serialization for 1.20.6 Both components had incorrect Parse/Serialize implementations that would cause packet deserialization misalignment when encountered in-game. PotionContentsComponent (3 bugs): - Serialize unconditionally wrote VarInt(PotionId) and Int(CustomColor) even when HasPotionId/HasCustomColor was false. The official format (PotionContents.STREAM_CODEC) uses Optional encoding: Bool(hasValue) followed by the value only when true. The extra bytes caused all subsequent fields in the packet to be read at wrong offsets. - Serialize omitted the VarInt(count) prefix for the custom effects list. The official codec uses ByteBufCodecs.list() which always writes a VarInt count header before the list elements. - Also fixed typo: PotiononId -> PotionId. InstrumentComponent (3 bugs): - The official Instrument.STREAM_CODEC uses ByteBufCodecs.holder() which encodes as VarInt(holderId): 0 = inline data, N>0 = registry ref (N-1). The SoundEvent field inside uses the same holder pattern. The old code unconditionally read SoundName (ResourceLocation) and HasFixedRange/ FixedRange even when SoundEventHolderId != 0 (registry reference case has no inline data). - UseDuration was read/written as Float, but the official codec uses ByteBufCodecs.VAR_INT. This caused a 4-byte vs variable-length mismatch that would shift all subsequent data. - HasFixedRange was read unconditionally when SoundEventHolderId == 0, but FixedRange was also read unconditionally. The official SoundEvent DIRECT_STREAM_CODEC uses Optional encoding: Bool(hasValue) followed by Float only when true. These components are used for potion items and goat horns respectively. Verified against official 1.20.6 decompiled source: - net.minecraft.world.item.alchemy.PotionContents (STREAM_CODEC) - net.minecraft.world.item.Instrument (STREAM_CODEC/DIRECT_STREAM_CODEC) - net.minecraft.sounds.SoundEvent (STREAM_CODEC/DIRECT_STREAM_CODEC) - net.minecraft.network.codec.ByteBufCodecs (holder/optional/list) Made-with: Cursor --- .../Components/1_20_6/InstrumentComponent.cs | 57 ++++++++++--------- .../1_20_6/PotionContentsComponent.cs | 39 +++++++------ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs index 87bb17be..ccfcf915 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/InstrumentComponent.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; @@ -8,60 +7,62 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class InstrumentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int InstrumentType { get; set; } - public int SoundEventType { get; set; } - public string? SoundName { get; set; } = null!; + // holder ID: 0 = inline instrument data, N>0 = registry reference (id = N-1) + public int InstrumentHolderId { get; set; } + + // Inline instrument fields (only when InstrumentHolderId == 0): + // holder ID for SoundEvent: 0 = inline sound, N>0 = registry reference (id = N-1) + public int SoundEventHolderId { get; set; } + // Inline SoundEvent fields (only when SoundEventHolderId == 0): + public string? SoundLocation { get; set; } public bool HasFixedRange { get; set; } public float FixedRange { get; set; } - public float UseDuration { get; set; } + + public int UseDuration { get; set; } public float Range { get; set; } public override void Parse(Queue data) { - InstrumentType = dataTypes.ReadNextVarInt(data); + InstrumentHolderId = dataTypes.ReadNextVarInt(data); - if (InstrumentType == 0) + if (InstrumentHolderId == 0) { - SoundEventType = dataTypes.ReadNextVarInt(data); - SoundName = dataTypes.ReadNextString(data); + SoundEventHolderId = dataTypes.ReadNextVarInt(data); - if (SoundEventType == 0) + if (SoundEventHolderId == 0) { + SoundLocation = dataTypes.ReadNextString(data); HasFixedRange = dataTypes.ReadNextBool(data); - FixedRange = dataTypes.ReadNextFloat(data); + if (HasFixedRange) + FixedRange = dataTypes.ReadNextFloat(data); } - UseDuration = dataTypes.ReadNextFloat(data); + UseDuration = dataTypes.ReadNextVarInt(data); Range = dataTypes.ReadNextFloat(data); } - - // TODO: Check, if we need to load in defaults from a registry } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(InstrumentType)); + data.AddRange(DataTypes.GetVarInt(InstrumentHolderId)); - if (InstrumentType == 0) + if (InstrumentHolderId == 0) { - data.AddRange(DataTypes.GetVarInt(SoundEventType)); + data.AddRange(DataTypes.GetVarInt(SoundEventHolderId)); - if (string.IsNullOrEmpty(SoundName)) - throw new NullReferenceException("Can't serialize InstrumentComponent because SoundName is empty!"); - - data.AddRange(DataTypes.GetString(SoundName)); - if (SoundEventType == 0) + if (SoundEventHolderId == 0) { + data.AddRange(DataTypes.GetString(SoundLocation ?? "")); data.AddRange(DataTypes.GetBool(HasFixedRange)); - data.AddRange(DataTypes.GetFloat(FixedRange)); + if (HasFixedRange) + data.AddRange(DataTypes.GetFloat(FixedRange)); } - - data.AddRange(DataTypes.GetFloat(UseDuration)); + + data.AddRange(DataTypes.GetVarInt(UseDuration)); data.AddRange(DataTypes.GetFloat(Range)); } - - // TODO: Check, if we need to load in defaults from a registry if InstrumentType != 0 and send them + return new Queue(data); } -} \ No newline at end of file +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs index 715cacd3..e8b3443e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; @@ -11,21 +10,23 @@ public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalett : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public bool HasPotionId { get; set; } - public int PotiononId { get; set; } + public int PotionId { get; set; } public bool HasCustomColor { get; set; } public int CustomColor { get; set; } - public int NumberOfCustomEffects { get; set; } public List Effects { get; set; } = new(); public override void Parse(Queue data) { HasPotionId = dataTypes.ReadNextBool(data); - PotiononId = HasPotionId ? dataTypes.ReadNextVarInt(data) : 0; // TODO: Find from the registry + if (HasPotionId) + PotionId = dataTypes.ReadNextVarInt(data); + HasCustomColor = dataTypes.ReadNextBool(data); - CustomColor = HasCustomColor ? dataTypes.ReadNextInt(data) : 0; // TODO: Find from the registry - NumberOfCustomEffects = dataTypes.ReadNextVarInt(data); - - for(var i = 0; i < NumberOfCustomEffects; i++) + if (HasCustomColor) + CustomColor = dataTypes.ReadNextInt(data); + + var numberOfEffects = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < numberOfEffects; i++) Effects.Add((PotionEffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, data)); } @@ -33,19 +34,17 @@ public class PotionContentsComponent(DataTypes dataTypes, ItemPalette itemPalett { var data = new List(); data.AddRange(DataTypes.GetBool(HasPotionId)); - data.AddRange(DataTypes.GetVarInt(PotiononId)); - data.AddRange(DataTypes.GetBool(HasCustomColor)); - data.AddRange(DataTypes.GetInt(CustomColor)); + if (HasPotionId) + data.AddRange(DataTypes.GetVarInt(PotionId)); - if (NumberOfCustomEffects > 0) - { - if(Effects.Count != NumberOfCustomEffects) - throw new ArgumentNullException($"Can not serialize PotionContentsComponentComponent1206 due to NumberOfCustomEffects being different from the count of elements in the Effects list!"); - - foreach(var effect in Effects) - data.AddRange(effect.Serialize()); - } + data.AddRange(DataTypes.GetBool(HasCustomColor)); + if (HasCustomColor) + data.AddRange(DataTypes.GetInt(CustomColor)); + + data.AddRange(DataTypes.GetVarInt(Effects.Count)); + foreach (var effect in Effects) + data.AddRange(effect.Serialize()); return new Queue(data); } -} \ No newline at end of file +} From 79a0dff8cd107b14557b47fc559455d3ba88e7c5 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 02:01:15 +0800 Subject: [PATCH 041/484] Fix enchantment name display for 1.20.6 structured components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EnchantmentsComponent (used by both regular and stored enchantments) was directly casting the registry VarInt ID to the Enchantments enum via (Enchantments)id. However, the Enchantments enum is ordered alphabetically (AquaAffinity=0, BaneOfArthropods=1, ..., Sharpness=32) while the 1.20.6 registry uses a completely different order (protection=0, fire_protection=1, ..., sharpness=13). This caused all enchantment names to display incorrectly (e.g. Sharpness V shown as "Unknown Enchantment with ID: 32"). Changes: - Parse now uses EnchantmentMapping.GetEnchantmentByRegistryId1206() to properly map registry IDs to enum values via the existing 1.20.6+ mapping table - Serialize now uses EnchantmentMapping.GetRegistryId1206ByEnchantment() to convert enum values back to registry IDs (reverse lookup) - Fixed translation key prefix: "Enchantments.minecraft." (wrong) -> "enchantment.minecraft." (matches en_us.json resource keys) - Fixed 3 long-standing typos in the Enchantments enum that prevented translation lookup from matching resource keys: - DepthStrieder -> DepthStrider (depth_strieder vs depth_strider) - Efficency -> Efficiency (efficency vs efficiency) - Loyality -> Loyalty (loyality vs loyalty) Verified on vanilla 1.20.6 server: items with sharpness, efficiency, unbreaking, fortune, mending, and bane_of_arthropods all display correct localized names (锋利, 效率, 耐久, 时运, 经验修补, 节肢杀手). Made-with: Cursor --- .../Inventory/EnchantmentMapping.cs | 48 +++++++++++++------ MinecraftClient/Inventory/Enchantments.cs | 8 ++-- .../1_20_6/EnchantmentsComponent.cs | 8 +++- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index e21e3cde..4d576bcf 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using MinecraftClient.Protocol.Handlers; @@ -21,7 +21,7 @@ namespace MinecraftClient.Inventory { 5, Enchantments.Respiration }, { 6, Enchantments.AquaAffinity }, { 7, Enchantments.Thorns }, - { 8, Enchantments.DepthStrieder }, + { 8, Enchantments.DepthStrider }, { 9, Enchantments.FrostWalker }, { 10, Enchantments.BindingCurse }, { 11, Enchantments.Sharpness }, @@ -31,7 +31,7 @@ namespace MinecraftClient.Inventory { 15, Enchantments.FireAspect }, { 16, Enchantments.Looting }, { 17, Enchantments.Sweeping }, - { 18, Enchantments.Efficency }, + { 18, Enchantments.Efficiency }, { 19, Enchantments.SilkTouch }, { 20, Enchantments.Unbreaking }, { 21, Enchantments.Fortune }, @@ -41,7 +41,7 @@ namespace MinecraftClient.Inventory { 25, Enchantments.Infinity }, { 26, Enchantments.LuckOfTheSea }, { 27, Enchantments.Lure }, - { 28, Enchantments.Loyality }, + { 28, Enchantments.Loyalty }, { 29, Enchantments.Impaling }, { 30, Enchantments.Riptide }, { 31, Enchantments.Channeling }, @@ -61,7 +61,7 @@ namespace MinecraftClient.Inventory { 5, Enchantments.Respiration }, { 6, Enchantments.AquaAffinity }, { 7, Enchantments.Thorns }, - { 8, Enchantments.DepthStrieder }, + { 8, Enchantments.DepthStrider }, { 9, Enchantments.FrostWalker }, { 10, Enchantments.BindingCurse }, { 11, Enchantments.SoulSpeed }, @@ -72,7 +72,7 @@ namespace MinecraftClient.Inventory { 16, Enchantments.FireAspect }, { 17, Enchantments.Looting }, { 18, Enchantments.Sweeping }, - { 19, Enchantments.Efficency }, + { 19, Enchantments.Efficiency }, { 20, Enchantments.SilkTouch }, { 21, Enchantments.Unbreaking }, { 22, Enchantments.Fortune }, @@ -82,7 +82,7 @@ namespace MinecraftClient.Inventory { 26, Enchantments.Infinity }, { 27, Enchantments.LuckOfTheSea }, { 28, Enchantments.Lure }, - { 29, Enchantments.Loyality }, + { 29, Enchantments.Loyalty }, { 30, Enchantments.Impaling }, { 31, Enchantments.Riptide }, { 32, Enchantments.Channeling }, @@ -105,7 +105,7 @@ namespace MinecraftClient.Inventory { 5, Enchantments.Respiration }, { 6, Enchantments.AquaAffinity }, { 7, Enchantments.Thorns }, - { 8, Enchantments.DepthStrieder }, + { 8, Enchantments.DepthStrider }, { 9, Enchantments.FrostWalker }, { 10, Enchantments.BindingCurse }, { 11, Enchantments.SoulSpeed }, @@ -117,7 +117,7 @@ namespace MinecraftClient.Inventory { 17, Enchantments.FireAspect }, { 18, Enchantments.Looting }, { 19, Enchantments.Sweeping }, - { 20, Enchantments.Efficency }, + { 20, Enchantments.Efficiency }, { 21, Enchantments.SilkTouch }, { 22, Enchantments.Unbreaking }, { 23, Enchantments.Fortune }, @@ -127,7 +127,7 @@ namespace MinecraftClient.Inventory { 27, Enchantments.Infinity }, { 28, Enchantments.LuckOfTheSea }, { 29, Enchantments.Lure }, - { 30, Enchantments.Loyality }, + { 30, Enchantments.Loyalty }, { 31, Enchantments.Impaling }, { 32, Enchantments.Riptide }, { 33, Enchantments.Channeling }, @@ -150,7 +150,7 @@ namespace MinecraftClient.Inventory { 5, Enchantments.Respiration }, { 6, Enchantments.AquaAffinity }, { 7, Enchantments.Thorns }, - { 8, Enchantments.DepthStrieder }, + { 8, Enchantments.DepthStrider }, { 9, Enchantments.FrostWalker }, { 10, Enchantments.BindingCurse }, { 11, Enchantments.SoulSpeed }, @@ -162,7 +162,7 @@ namespace MinecraftClient.Inventory { 17, Enchantments.FireAspect }, { 18, Enchantments.Looting }, { 19, Enchantments.Sweeping }, - { 20, Enchantments.Efficency }, + { 20, Enchantments.Efficiency }, { 21, Enchantments.SilkTouch }, { 22, Enchantments.Unbreaking }, { 23, Enchantments.Fortune }, @@ -172,7 +172,7 @@ namespace MinecraftClient.Inventory { 27, Enchantments.Infinity }, { 28, Enchantments.LuckOfTheSea }, { 29, Enchantments.Lure }, - { 30, Enchantments.Loyality }, + { 30, Enchantments.Loyalty }, { 31, Enchantments.Impaling }, { 32, Enchantments.Riptide }, { 33, Enchantments.Channeling }, @@ -206,9 +206,29 @@ namespace MinecraftClient.Inventory return value; } + private static Dictionary? reverseEnchantmentMappings; + + public static Enchantments GetEnchantmentByRegistryId1206(int id) + { + if (enchantmentMappings.TryGetValue((short)id, out var value)) + return value; + return (Enchantments)(-1); + } + + public static int GetRegistryId1206ByEnchantment(Enchantments enchantment) + { + if (reverseEnchantmentMappings == null) + { + reverseEnchantmentMappings = new Dictionary(); + foreach (var kvp in enchantmentMappings) + reverseEnchantmentMappings[kvp.Value] = kvp.Key; + } + return reverseEnchantmentMappings.TryGetValue(enchantment, out var id) ? id : -1; + } + public static string GetEnchantmentName(Enchantments enchantment) { - var translation = ChatParser.TranslateString("Enchantments.minecraft." + enchantment.ToString().ToUnderscoreCase()); + var translation = ChatParser.TranslateString("enchantment.minecraft." + enchantment.ToString().ToUnderscoreCase()); return string.IsNullOrEmpty(translation) ? $"Unknown Enchantment with ID: {(short)enchantment} (Probably not named in the code yet)" : translation; } diff --git a/MinecraftClient/Inventory/Enchantments.cs b/MinecraftClient/Inventory/Enchantments.cs index 13fdd595..4a089879 100644 --- a/MinecraftClient/Inventory/Enchantments.cs +++ b/MinecraftClient/Inventory/Enchantments.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Inventory +namespace MinecraftClient.Inventory { // Not implemented for 1.14 public enum Enchantments : short @@ -9,9 +9,9 @@ BlastProtection, Breach, Channeling, - DepthStrieder, + DepthStrider, Density, - Efficency, + Efficiency, FeatherFalling, FireAspect, FireProtection, @@ -23,7 +23,7 @@ Knockback, Looting, LuckOfTheSea, - Loyality, + Loyalty, Lure, Mending, Multishot, diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs index e38b41fd..bfc942a1 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs @@ -17,7 +17,11 @@ public class EnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, NumberOfEnchantments = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfEnchantments; i++) - Enchantments.Add(new Enchantment((Enchantments)dataTypes.ReadNextVarInt(data), dataTypes.ReadNextVarInt(data))); + { + var registryId = dataTypes.ReadNextVarInt(data); + var level = dataTypes.ReadNextVarInt(data); + Enchantments.Add(new Enchantment(EnchantmentMapping.GetEnchantmentByRegistryId1206(registryId), level)); + } ShowTooltip = dataTypes.ReadNextBool(data); } @@ -28,7 +32,7 @@ public class EnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, data.AddRange(DataTypes.GetVarInt(Enchantments.Count)); foreach (var enchantment in Enchantments) { - data.AddRange(DataTypes.GetVarInt((int)enchantment.Type)); + data.AddRange(DataTypes.GetVarInt(EnchantmentMapping.GetRegistryId1206ByEnchantment(enchantment.Type))); data.AddRange(DataTypes.GetVarInt(enchantment.Level)); } data.AddRange(DataTypes.GetBool(ShowTooltip)); From a36ba23ba617d9a2e1a3dfeb73d8ad3edecacd15 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:09:05 +0800 Subject: [PATCH 042/484] =?UTF-8?q?fix:=20StructuredComponents=20batch=201?= =?UTF-8?q?=20audit=20=E2=80=94=20TrimComponent,=20ProfileComponent,=20Wri?= =?UTF-8?q?ttenBookContent,=20and=20NBT=20serialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited all 8 high-complexity structured components against official 1.20.6 decompiled STREAM_CODEC definitions. Found and fixed bugs in 3 components plus a systemic NBT serialization issue: TrimComponent (ID 35): - Serialize had TrimPatternType and ShowInTooltip incorrectly nested inside the TrimMaterialType==0 branch; moved them outside to match Parse logic - Description fields (TrimMaterial.description, TrimPattern.description) were read/written as String but official codec uses ComponentSerialization (NBT Tag format); changed to ReadNextNbt/GetNbt ProfileComponent (ID 46): - Serialize was missing the HasUniqueId Bool prefix before UUID - Serialize only wrote properties when count > 0 but omitted the VarInt count prefix entirely when empty; now always writes VarInt count WrittenBookContentComponent (ID 34): - Page content uses Filterable where Component is NBT-encoded via ComponentSerialization.STREAM_CODEC, not plain String; changed Parse to use ReadNextNbt and Serialize to use GetNbt - Added RawContentNbt/FilteredContentNbt fields to BookPage record for round-trip NBT preservation - Removed unnecessary ChatParser.ParseText on title (it's a plain string) DataTypes.GetNbt: - Added TAG_String root support for 1.20.4+ (chat components like "Page 1" are encoded as TAG_String, not TAG_Compound) - Fixed root name handling: versions >= 1.20.2 omit the root compound name, but GetNbt was unconditionally writing it Components confirmed correct (no changes needed): - FoodComponentComponent (ID 20), ToolComponent (ID 22), InstrumentComponent (ID 40), PotionContentsComponent (ID 31), AttributeModifiersComponent (ID 12) Made-with: Cursor --- MinecraftClient/Inventory/BookPage.cs | 9 +++- .../Protocol/Handlers/DataTypes.cs | 27 ++++++++---- .../Components/1_20_6/ProfileComponent.cs | 26 +++++------- .../Components/1_20_6/TrimComponent.cs | 42 ++++++++++--------- .../1_20_6/WrittenBlookContentComponent.cs | 33 +++++++-------- 5 files changed, 77 insertions(+), 60 deletions(-) diff --git a/MinecraftClient/Inventory/BookPage.cs b/MinecraftClient/Inventory/BookPage.cs index c7ec7e44..9240d77e 100644 --- a/MinecraftClient/Inventory/BookPage.cs +++ b/MinecraftClient/Inventory/BookPage.cs @@ -1,3 +1,10 @@ +using System.Collections.Generic; + namespace MinecraftClient.Inventory; -public record BookPage(string RawContent, bool HasFilteredContent, string? FilteredContent); \ No newline at end of file +public record BookPage( + string RawContent, + bool HasFilteredContent, + string? FilteredContent, + Dictionary? RawContentNbt = null, + Dictionary? FilteredContentNbt = null); \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index af09909c..d36ab257 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1231,18 +1231,31 @@ namespace MinecraftClient.Protocol.Handlers if (root) { + if (protocolversion >= Protocol18Handler.MC_1_20_4_Version + && nbt.Count == 1 + && nbt.TryGetValue("", out var rootVal) && rootVal is string rootStr) + { + bytes.Add(8); // TAG_String + var strBytes = Encoding.UTF8.GetBytes(rootStr); + bytes.AddRange(GetUShort((ushort)strBytes.Length)); + bytes.AddRange(strBytes); + return bytes.ToArray(); + } + bytes.Add(10); // TAG_Compound - // NBT root name - string? rootName = null; + if (protocolversion < Protocol18Handler.MC_1_20_2_Version) + { + string? rootName = null; - if (nbt.ContainsKey("")) - rootName = nbt[""] as string; + if (nbt.ContainsKey("")) + rootName = nbt[""] as string; - rootName ??= ""; + rootName ??= ""; - bytes.AddRange(GetUShort((ushort)rootName.Length)); - bytes.AddRange(Encoding.ASCII.GetBytes(rootName)); + bytes.AddRange(GetUShort((ushort)rootName.Length)); + bytes.AddRange(Encoding.ASCII.GetBytes(rootName)); + } } foreach (var item in nbt) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs index fc8dc441..17853fbd 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ProfileComponent.cs @@ -51,26 +51,22 @@ public class ProfileComponent(DataTypes dataTypes, ItemPalette itemPalette, SubC data.AddRange(DataTypes.GetString(Name)); } + data.AddRange(DataTypes.GetBool(HasUniqueId)); if (HasUniqueId) data.AddRange(DataTypes.GetUUID(Uuid)); - if (NumberOfProperties > 0) + data.AddRange(DataTypes.GetVarInt(ProfileProperties.Count)); + foreach (var profileProperty in ProfileProperties) { - if(NumberOfProperties != ProfileProperties.Count) - throw new Exception("Can't serialize the ProfileComponent because the NumberOfProperties and ProfileProperties.Count differ!"); - - foreach (var profileProperty in ProfileProperties) + data.AddRange(DataTypes.GetString(profileProperty.Name)); + data.AddRange(DataTypes.GetString(profileProperty.Value)); + data.AddRange(DataTypes.GetBool(profileProperty.HasSignature)); + if (profileProperty.HasSignature) { - data.AddRange(DataTypes.GetString(profileProperty.Name)); - data.AddRange(DataTypes.GetString(profileProperty.Value)); - data.AddRange(DataTypes.GetBool(profileProperty.HasSignature)); - if (profileProperty.HasSignature) - { - if(string.IsNullOrEmpty(profileProperty.Signature)) - throw new NullReferenceException("Can't serialize the ProfileComponent because HasSignature is true, but the Signature is null/empty!"); - - data.AddRange(DataTypes.GetString(profileProperty.Signature)); - } + if(string.IsNullOrEmpty(profileProperty.Signature)) + throw new NullReferenceException("Can't serialize the ProfileComponent because HasSignature is true, but the Signature is null/empty!"); + + data.AddRange(DataTypes.GetString(profileProperty.Signature)); } } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs index 25d30c4a..374f1962 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/TrimComponent.cs @@ -15,10 +15,12 @@ public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComp public float ItemModelIndex { get; set; } public int NumberOfOverrides { get; set; } public List? Overrides { get; set; } + public Dictionary? DescriptionNbt { get; set; } public string Description { get; set; } = null!; public int TrimPatternType { get; set; } public string TrimPatternTypeAssetName { get; set; } = null!; public int TemplateItem { get; set; } + public Dictionary? TrimPatternTypeDescriptionNbt { get; set; } public string TrimPatternTypeDescription { get; set; } = null!; public bool Decal { get; set; } public bool ShowInTooltip { get; set; } @@ -43,7 +45,8 @@ public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComp dataTypes.ReadNextString(data))); } - Description = ChatParser.ParseText(dataTypes.ReadNextString(data)); + DescriptionNbt = dataTypes.ReadNextNbt(data); + Description = ChatParser.ParseText(DescriptionNbt); } TrimPatternType = dataTypes.ReadNextVarInt(data); @@ -52,7 +55,8 @@ public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComp { TrimPatternTypeAssetName = dataTypes.ReadNextString(data); TemplateItem = dataTypes.ReadNextVarInt(data); - TrimPatternTypeDescription = dataTypes.ReadNextString(data); + TrimPatternTypeDescriptionNbt = dataTypes.ReadNextNbt(data); + TrimPatternTypeDescription = ChatParser.ParseText(TrimPatternTypeDescriptionNbt); Decal = dataTypes.ReadNextBool(data); } @@ -67,8 +71,8 @@ public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComp if (TrimMaterialType == 0) { - if (string.IsNullOrEmpty(AssetName) || string.IsNullOrEmpty(Description)) - throw new NullReferenceException("Can't serialize the TrimComponent because the Asset Name or Description are null!"); + if (string.IsNullOrEmpty(AssetName)) + throw new NullReferenceException("Can't serialize the TrimComponent because the Asset Name is null!"); data.AddRange(DataTypes.GetString(AssetName)); data.AddRange(DataTypes.GetVarInt(Ingredient)); @@ -85,22 +89,22 @@ public class TrimComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComp data.AddRange(DataTypes.GetString(assetName)); } } - data.AddRange(DataTypes.GetString(Description)); - - data.AddRange(DataTypes.GetVarInt(TrimPatternType)); - if (TrimPatternType == 0) - { - if (string.IsNullOrEmpty(TrimPatternTypeAssetName) || string.IsNullOrEmpty(TrimPatternTypeDescription)) - throw new NullReferenceException("Can't serialize the TrimComponent because the TrimPatternTypeAssetName or TrimPatternTypeDescription are null!"); - - data.AddRange(DataTypes.GetString(TrimPatternTypeAssetName)); - data.AddRange(DataTypes.GetVarInt(TemplateItem)); - data.AddRange(DataTypes.GetString(TrimPatternTypeDescription)); - data.AddRange(DataTypes.GetBool(Decal)); - } - - data.AddRange(DataTypes.GetBool(ShowInTooltip)); + data.AddRange(DataTypes.GetNbt(DescriptionNbt)); } + + data.AddRange(DataTypes.GetVarInt(TrimPatternType)); + if (TrimPatternType == 0) + { + if (string.IsNullOrEmpty(TrimPatternTypeAssetName)) + throw new NullReferenceException("Can't serialize the TrimComponent because the TrimPatternTypeAssetName is null!"); + + data.AddRange(DataTypes.GetString(TrimPatternTypeAssetName)); + data.AddRange(DataTypes.GetVarInt(TemplateItem)); + data.AddRange(DataTypes.GetNbt(TrimPatternTypeDescriptionNbt)); + data.AddRange(DataTypes.GetBool(Decal)); + } + + data.AddRange(DataTypes.GetBool(ShowInTooltip)); return new Queue(data); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs index bf315b3d..1f7cc905 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs @@ -20,7 +20,7 @@ public class WrittenBlookContentComponent(DataTypes dataTypes, ItemPalette itemP public override void Parse(Queue data) { - RawTitle = ChatParser.ParseText(dataTypes.ReadNextString(data)); + RawTitle = dataTypes.ReadNextString(data); HasFilteredTitle = dataTypes.ReadNextBool(data); if (HasFilteredTitle) @@ -32,14 +32,19 @@ public class WrittenBlookContentComponent(DataTypes dataTypes, ItemPalette itemP for (var i = 0; i < NumberOfPages; i++) { - var rawContent = ChatParser.ParseText(dataTypes.ReadNextString(data)); + var rawContentNbt = dataTypes.ReadNextNbt(data); + var rawContent = ChatParser.ParseText(rawContentNbt); var hasFilteredContent = dataTypes.ReadNextBool(data); - var filteredContent = null as string; + Dictionary? filteredContentNbt = null; + string? filteredContent = null; - if(hasFilteredContent) - filteredContent = dataTypes.ReadNextString(data); + if (hasFilteredContent) + { + filteredContentNbt = dataTypes.ReadNextNbt(data); + filteredContent = ChatParser.ParseText(filteredContentNbt); + } - Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent)); + Pages.Add(new BookPage(rawContent, hasFilteredContent, filteredContent, rawContentNbt, filteredContentNbt)); } Resolved = dataTypes.ReadNextBool(data); @@ -55,30 +60,22 @@ public class WrittenBlookContentComponent(DataTypes dataTypes, ItemPalette itemP if (HasFilteredTitle) { if(FilteredTitle is null) - throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because HasFilteredTitle is true but FilteredTitle is null!"); + throw new InvalidOperationException("Can not serialize WrittenBookContentComponent because HasFilteredTitle is true but FilteredTitle is null!"); data.AddRange(DataTypes.GetString(FilteredTitle)); } data.AddRange(DataTypes.GetString(Author)); data.AddRange(DataTypes.GetVarInt(Generation)); - data.AddRange(DataTypes.GetVarInt(NumberOfPages)); - - if (NumberOfPages != Pages.Count) - throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because NumberOfPages != Pages.Count!"); + data.AddRange(DataTypes.GetVarInt(Pages.Count)); foreach (var page in Pages) { - data.AddRange(DataTypes.GetString(page.RawContent)); + data.AddRange(DataTypes.GetNbt(page.RawContentNbt)); data.AddRange(DataTypes.GetBool(page.HasFilteredContent)); if (page.HasFilteredContent) - { - if(page.FilteredContent is null) - throw new InvalidOperationException("Can not setialize WrittenBlookContentComponent1206 because page.HasFilteredContent = true, but FilteredContent is null!"); - - data.AddRange(DataTypes.GetString(page.FilteredContent)); - } + data.AddRange(DataTypes.GetNbt(page.FilteredContentNbt)); } data.AddRange(DataTypes.GetBool(Resolved)); return new Queue(data); From 4944497f5a92e1a7e899351f59c4b7e518b033f9 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:19:08 +0800 Subject: [PATCH 043/484] =?UTF-8?q?fix:=20StructuredComponents=20batch=202?= =?UTF-8?q?=20audit=20=E2=80=94=20BlockPredicate=20and=20PropertySubCompon?= =?UTF-8?q?ent=20serialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited all 8 batch-2 components (enchantments, stored_enchantments, can_place_on, can_break, lodestone_tracker, firework_explosion, fireworks, banner_patterns, suspicious_stew_effects, bees) against official 1.20.6 decompiled STREAM_CODEC definitions. Found and fixed 3 bugs in BlockPredicate/PropertySubComponent: 1. BlockPredicateSubcomponent.Serialize(): missing HasNbt bool write. Parse reads the bool but Serialize skipped writing it, causing all subsequent fields to be offset by one byte. 2. BlockPredicateSubcomponent.Serialize(): missing Properties list count VarInt write. Parse reads VarInt count before iterating, but Serialize only wrote the elements without the preceding count. 3. PropertySubComponent: RangedMatcher min/max values must use Optional encoding (Bool prefix + conditional String), matching the official ByteBufCodecs.either(ExactMatcher, RangedMatcher) where RangedMatcher uses ByteBufCodecs.optional(STRING_UTF8) for both min and max fields. Previously read/wrote plain Strings unconditionally. Remaining 6 components (enchantments, stored_enchantments, lodestone_tracker, firework_explosion, fireworks, banner_patterns, suspicious_stew_effects, bees) verified correct — no changes needed. Made-with: Cursor --- .../1_20_6/BlockPredicateSubcomponent.cs | 4 +++- .../1_20_6/PropertySubComponent.cs | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs index 9a562840..c8bf2369 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs @@ -50,18 +50,20 @@ public class BlockPredicateSubcomponent(DataTypes dataTypes, SubComponentRegistr data.AddRange(BlockSet.Serialize()); } - // Properites + // Properties data.AddRange(DataTypes.GetBool(HasProperities)); if (HasProperities) { if(Properties == null || Properties.Count == 0) throw new ArgumentNullException($"Can not serialize a BlockPredicate when the Properties is empty but HasProperties is true!"); + data.AddRange(DataTypes.GetVarInt(Properties.Count)); foreach (var property in Properties) data.AddRange(property.Serialize()); } // NBT + data.AddRange(DataTypes.GetBool(HasNbt)); if (HasNbt) { if(Nbt == null) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs index 0b8e41eb..6170dffa 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs @@ -18,11 +18,13 @@ public class PropertySubComponent(DataTypes dataTypes, SubComponentRegistry subC IsExactMatch = dataTypes.ReadNextBool(data); if (IsExactMatch) - ExactValue = dataTypes.ReadNextString(data); - else // Ranged Match { - MinValue = dataTypes.ReadNextString(data); - MaxValue = dataTypes.ReadNextString(data); + ExactValue = dataTypes.ReadNextString(data); + } + else + { + MinValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; + MaxValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; } } @@ -45,11 +47,13 @@ public class PropertySubComponent(DataTypes dataTypes, SubComponentRegistry subC } else { - if (string.IsNullOrEmpty(MinValue?.Trim()) || string.IsNullOrEmpty(MaxValue?.Trim())) - throw new ArgumentNullException($"Can not serialize a Property sub-component if the MinValue or MaxValue is null or empty when the type is not Exact Match!"); + data.AddRange(DataTypes.GetBool(MinValue != null)); + if (MinValue != null) + data.AddRange(DataTypes.GetString(MinValue)); - data.AddRange(DataTypes.GetString(MinValue)); - data.AddRange(DataTypes.GetString(MaxValue)); + data.AddRange(DataTypes.GetBool(MaxValue != null)); + if (MaxValue != null) + data.AddRange(DataTypes.GetString(MaxValue)); } return new Queue(data); From c6893433716757b3d4fd1bd9ea75e44df3d430e7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:25:28 +0800 Subject: [PATCH 044/484] =?UTF-8?q?fix:=20StructuredComponents=20batch=203?= =?UTF-8?q?=20audit=20=E2=80=94=20EnchantmentGlintOverrideComponent=20type?= =?UTF-8?q?=20correction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited all 14 simple binary components (batch 3): max_stack_size, max_damage, damage, unbreakable, rarity, custom_model_data, repair_cost, enchantment_glint_override, ominous_bottle_amplifier, dyed_color, map_color, map_id, map_post_processing, base_color. Found and fixed 1 bug: - EnchantmentGlintOverrideComponent: was reading/writing VarInt but the official STREAM_CODEC uses ByteBufCodecs.BOOL (single byte boolean). Changed property type from int to bool, Parse from ReadNextVarInt to ReadNextBool, and Serialize from GetVarInt to GetBool. All other 13 components matched the official 1.20.6 STREAM_CODEC definitions exactly. Verified in-game: connected to 1.20.6 vanilla server, received items with enchantment_glint_override=true/false, dyed_color, map_color, map_id, base_color, unbreakable, rarity, custom_model_data, repair_cost, damage, max_damage. All parsed and serialized correctly with no errors. Made-with: Cursor --- .../Components/1_20_6/EnchantmentGlintOverrideComponent.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs index bdeb1d24..af5ff63c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs @@ -7,17 +7,17 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class EnchantmentGlintOverrideComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int HasGlint { get; set; } + public bool HasGlint { get; set; } public override void Parse(Queue data) { - HasGlint = dataTypes.ReadNextVarInt(data); + HasGlint = dataTypes.ReadNextBool(data); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(HasGlint)); + data.AddRange(DataTypes.GetBool(HasGlint)); return new Queue(data); } } \ No newline at end of file From 5e416d6b72440e7a0242f692619de06b2ec5ebf1 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:33:50 +0800 Subject: [PATCH 045/484] =?UTF-8?q?fix:=20StructuredComponents=20batch=204?= =?UTF-8?q?=20audit=20=E2=80=94=20CustomName,=20ItemName,=20Lore=20use=20N?= =?UTF-8?q?BT=20encoding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 1.20.6+, ComponentSerialization.STREAM_CODEC uses ByteBufCodecs.fromCodecWithRegistries (NBT tag format), not plain string. The previous implementation incorrectly used ReadNextString/GetString for custom_name (5), item_name (6), and lore (7) components. Fixed all three to use ReadNextNbt/GetNbt, preserving raw NBT data for round-trip serialization while still extracting readable text via ChatParser.ParseText(Dictionary). Other batch 4 components (custom_data, entity_data, bucket_entity_data, block_entity_data, debug_stick_state, map_decorations, recipes, lock, container_loot, intangible_projectile — all NBT; hide_additional_tooltip, hide_tooltip, fire_resistant, creative_slot_lock — all Unit/Empty; note_block_sound — ResourceLocation string) were verified correct. Made-with: Cursor --- .../Components/1_20_6/CustomNameComponent.cs | 6 ++++-- .../Components/1_20_6/ItemNameComponent.cs | 6 ++++-- .../Components/1_20_6/LoreComponent.cs | 15 +++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs index 024b7a43..f4f2fc92 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs @@ -9,16 +9,18 @@ public class CustomNameComponent(DataTypes dataTypes, ItemPalette itemPalette, S : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string CustomName { get; set; } = string.Empty; + public Dictionary? CustomNameNbt { get; set; } public override void Parse(Queue data) { - CustomName = ChatParser.ParseText(dataTypes.ReadNextString(data)); + CustomNameNbt = dataTypes.ReadNextNbt(data); + CustomName = ChatParser.ParseText(CustomNameNbt); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetString(CustomName)); + data.AddRange(DataTypes.GetNbt(CustomNameNbt)); return new Queue(data); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs index a7c8bda3..6fc8ae3e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs @@ -9,16 +9,18 @@ public class ItemNameComponent(DataTypes dataTypes, ItemPalette itemPalette, Sub : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public string ItemName { get; set; } = string.Empty; + public Dictionary? ItemNameNbt { get; set; } public override void Parse(Queue data) { - ItemName = ChatParser.ParseText(dataTypes.ReadNextString(data)); + ItemNameNbt = dataTypes.ReadNextNbt(data); + ItemName = ChatParser.ParseText(ItemNameNbt); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetString(ItemName)); + data.AddRange(DataTypes.GetNbt(ItemNameNbt)); return new Queue(data); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs index 8aa711ef..aaca1b72 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs @@ -10,6 +10,7 @@ public class LoreNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, { public int NumberOfLines { get; set; } public List Lines { get; set; } = []; + public List> LinesNbt { get; set; } = []; public override void Parse(Queue data) { @@ -18,18 +19,20 @@ public class LoreNameComponent1206(DataTypes dataTypes, ItemPalette itemPalette, if (NumberOfLines <= 0) return; for (var i = 0; i < NumberOfLines; i++) - Lines.Add(ChatParser.ParseText(dataTypes.ReadNextString(data))); + { + var lineNbt = dataTypes.ReadNextNbt(data); + LinesNbt.Add(lineNbt); + Lines.Add(ChatParser.ParseText(lineNbt)); + } } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(Lines.Count)); + data.AddRange(DataTypes.GetVarInt(LinesNbt.Count)); - if (Lines.Count <= 0) return new Queue(data); - - foreach (var line in Lines) - data.AddRange(DataTypes.GetString(line)); + foreach (var lineNbt in LinesNbt) + data.AddRange(DataTypes.GetNbt(lineNbt)); return new Queue(data); } From cc10f4effab476f872b984c353187ee040e0da23 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 00:45:50 +0800 Subject: [PATCH 046/484] =?UTF-8?q?refactor:=20StructuredComponents=20batc?= =?UTF-8?q?h=205=20audit=20=E2=80=94=20remove=20redundant=20count=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited batch 5 components (ChargedProjectiles, BundleContents, Container, WritableBookContent, BlockState, PotDecorations) against official 1.20.6 decompiled STREAM_CODEC definitions. All network encodings were correct. Removed redundant NumberOfItems/NumberOfPages/NumberOfProperties fields from ContainerComponent, WritableBlookContentComponent, BlockStateComponent, and PotDecorationsComponent. Serialize now uses the actual collection .Count instead of a potentially stale cached value, matching the pattern already used by ContainerComponent's Serialize and other components. Also modernized loop style (foreach with deconstruction where applicable) and fixed a typo in an exception message ("setialize" -> "serialize"). Made-with: Cursor --- .../Components/1_20_6/BlockStateComponent.cs | 13 ++++++------- .../Components/1_20_6/ContainerComponent.cs | 5 ++--- .../Components/1_20_6/PotDecorationsComponent.cs | 11 +++++------ .../1_20_6/WritableBlookContentComponent.cs | 12 ++++-------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs index be3950fe..8037d07c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BlockStateComponent.cs @@ -7,24 +7,23 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class BlockStateComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfProperties { get; set; } public List<(string, string)> Properties { get; set; } = []; public override void Parse(Queue data) { - NumberOfProperties = dataTypes.ReadNextVarInt(data); - for(var i = 0; i < NumberOfProperties; i++) + var count = dataTypes.ReadNextVarInt(data); + for(var i = 0; i < count; i++) Properties.Add((dataTypes.ReadNextString(data), dataTypes.ReadNextString(data))); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfProperties)); - for (var i = 0; i < NumberOfProperties; i++) + data.AddRange(DataTypes.GetVarInt(Properties.Count)); + foreach (var (key, value) in Properties) { - data.AddRange(DataTypes.GetString(Properties[i].Item1)); - data.AddRange(DataTypes.GetString(Properties[i].Item2)); + data.AddRange(DataTypes.GetString(key)); + data.AddRange(DataTypes.GetString(value)); } return new Queue(data); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs index 053fc918..c132e06f 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ContainerComponent.cs @@ -8,13 +8,12 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class ContainerComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfItems { get; set; } public List Items { get; set; } = []; public override void Parse(Queue data) { - NumberOfItems = dataTypes.ReadNextVarInt(data); - for (var i = 0; i < NumberOfItems; i++) + var count = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < count; i++) Items.Add(dataTypes.ReadNextItemSlot(data, ItemPalette)); } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs index 74607228..0acc10e6 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotDecorationsComponent.cs @@ -7,22 +7,21 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class PotDecorationsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfItems { get; set; } public List Items { get; set; } = []; public override void Parse(Queue data) { - NumberOfItems = dataTypes.ReadNextVarInt(data); - for(var i = 0; i < NumberOfItems; i++) + var count = dataTypes.ReadNextVarInt(data); + for(var i = 0; i < count; i++) Items.Add(dataTypes.ReadNextVarInt(data)); } public override Queue Serialize() { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfItems)); - for(var i = 0; i < NumberOfItems; i++) - data.AddRange(DataTypes.GetVarInt(Items[i])); + data.AddRange(DataTypes.GetVarInt(Items.Count)); + foreach (var item in Items) + data.AddRange(DataTypes.GetVarInt(item)); return new Queue(data); } } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs index 9c782d55..e22c714a 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs @@ -8,14 +8,13 @@ namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_2 public class WritableBlookContentComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { - public int NumberOfPages { get; set; } public List Pages { get; set; } = []; public override void Parse(Queue data) { - NumberOfPages = dataTypes.ReadNextVarInt(data); + var count = dataTypes.ReadNextVarInt(data); - for (var i = 0; i < NumberOfPages; i++) + for (var i = 0; i < count; i++) { var rawContent = dataTypes.ReadNextString(data); var hasFilteredContent = dataTypes.ReadNextBool(data); @@ -32,10 +31,7 @@ public class WritableBlookContentComponent(DataTypes dataTypes, ItemPalette item { var data = new List(); - data.AddRange(DataTypes.GetVarInt(NumberOfPages)); - - if (NumberOfPages != Pages.Count) - throw new InvalidOperationException("Can not setialize WritableBlookContentComponent1206 because NumberOfPages != Pages.Count!"); + data.AddRange(DataTypes.GetVarInt(Pages.Count)); foreach (var page in Pages) { @@ -45,7 +41,7 @@ public class WritableBlookContentComponent(DataTypes dataTypes, ItemPalette item if (page.HasFilteredContent) { if(page.FilteredContent is null) - throw new InvalidOperationException("Can not setialize WritableBlookContentComponent1206 because page.HasFilteredContent = true, but FilteredContent is null!"); + throw new InvalidOperationException("Can not serialize WritableBlookContentComponent because page.HasFilteredContent = true, but FilteredContent is null!"); data.AddRange(DataTypes.GetString(page.FilteredContent)); } From 2fb09342a3a05bfb57a5ebd03c7c2df2ece86438 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 01:22:16 +0800 Subject: [PATCH 047/484] feat: add ItemPalette121 and new 1.21 music disc item types Add ItemPalette121.cs with item ID mappings for MC 1.21 (protocol 767). Add three new music disc entries to ItemType enum: MusicDiscCreator, MusicDiscCreatorMusicBox, and MusicDiscPrecipice, introduced in 1.21. Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette121.cs | 1351 +++++++++++++++++ MinecraftClient/Inventory/ItemType.cs | 5 +- 2 files changed, 1355 insertions(+), 1 deletion(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs new file mode 100644 index 00000000..6759d899 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs @@ -0,0 +1,1351 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette121 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette121() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.MangrovePlanks; + mappings[44] = ItemType.BambooPlanks; + mappings[45] = ItemType.CrimsonPlanks; + mappings[46] = ItemType.WarpedPlanks; + mappings[47] = ItemType.BambooMosaic; + mappings[48] = ItemType.OakSapling; + mappings[49] = ItemType.SpruceSapling; + mappings[50] = ItemType.BirchSapling; + mappings[51] = ItemType.JungleSapling; + mappings[52] = ItemType.AcaciaSapling; + mappings[53] = ItemType.CherrySapling; + mappings[54] = ItemType.DarkOakSapling; + mappings[55] = ItemType.MangrovePropagule; + mappings[56] = ItemType.Bedrock; + mappings[57] = ItemType.Sand; + mappings[58] = ItemType.SuspiciousSand; + mappings[59] = ItemType.SuspiciousGravel; + mappings[60] = ItemType.RedSand; + mappings[61] = ItemType.Gravel; + mappings[62] = ItemType.CoalOre; + mappings[63] = ItemType.DeepslateCoalOre; + mappings[64] = ItemType.IronOre; + mappings[65] = ItemType.DeepslateIronOre; + mappings[66] = ItemType.CopperOre; + mappings[67] = ItemType.DeepslateCopperOre; + mappings[68] = ItemType.GoldOre; + mappings[69] = ItemType.DeepslateGoldOre; + mappings[70] = ItemType.RedstoneOre; + mappings[71] = ItemType.DeepslateRedstoneOre; + mappings[72] = ItemType.EmeraldOre; + mappings[73] = ItemType.DeepslateEmeraldOre; + mappings[74] = ItemType.LapisOre; + mappings[75] = ItemType.DeepslateLapisOre; + mappings[76] = ItemType.DiamondOre; + mappings[77] = ItemType.DeepslateDiamondOre; + mappings[78] = ItemType.NetherGoldOre; + mappings[79] = ItemType.NetherQuartzOre; + mappings[80] = ItemType.AncientDebris; + mappings[81] = ItemType.CoalBlock; + mappings[82] = ItemType.RawIronBlock; + mappings[83] = ItemType.RawCopperBlock; + mappings[84] = ItemType.RawGoldBlock; + mappings[85] = ItemType.HeavyCore; + mappings[86] = ItemType.AmethystBlock; + mappings[87] = ItemType.BuddingAmethyst; + mappings[88] = ItemType.IronBlock; + mappings[89] = ItemType.CopperBlock; + mappings[90] = ItemType.GoldBlock; + mappings[91] = ItemType.DiamondBlock; + mappings[92] = ItemType.NetheriteBlock; + mappings[93] = ItemType.ExposedCopper; + mappings[94] = ItemType.WeatheredCopper; + mappings[95] = ItemType.OxidizedCopper; + mappings[96] = ItemType.ChiseledCopper; + mappings[97] = ItemType.ExposedChiseledCopper; + mappings[98] = ItemType.WeatheredChiseledCopper; + mappings[99] = ItemType.OxidizedChiseledCopper; + mappings[100] = ItemType.CutCopper; + mappings[101] = ItemType.ExposedCutCopper; + mappings[102] = ItemType.WeatheredCutCopper; + mappings[103] = ItemType.OxidizedCutCopper; + mappings[104] = ItemType.CutCopperStairs; + mappings[105] = ItemType.ExposedCutCopperStairs; + mappings[106] = ItemType.WeatheredCutCopperStairs; + mappings[107] = ItemType.OxidizedCutCopperStairs; + mappings[108] = ItemType.CutCopperSlab; + mappings[109] = ItemType.ExposedCutCopperSlab; + mappings[110] = ItemType.WeatheredCutCopperSlab; + mappings[111] = ItemType.OxidizedCutCopperSlab; + mappings[112] = ItemType.WaxedCopperBlock; + mappings[113] = ItemType.WaxedExposedCopper; + mappings[114] = ItemType.WaxedWeatheredCopper; + mappings[115] = ItemType.WaxedOxidizedCopper; + mappings[116] = ItemType.WaxedChiseledCopper; + mappings[117] = ItemType.WaxedExposedChiseledCopper; + mappings[118] = ItemType.WaxedWeatheredChiseledCopper; + mappings[119] = ItemType.WaxedOxidizedChiseledCopper; + mappings[120] = ItemType.WaxedCutCopper; + mappings[121] = ItemType.WaxedExposedCutCopper; + mappings[122] = ItemType.WaxedWeatheredCutCopper; + mappings[123] = ItemType.WaxedOxidizedCutCopper; + mappings[124] = ItemType.WaxedCutCopperStairs; + mappings[125] = ItemType.WaxedExposedCutCopperStairs; + mappings[126] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[127] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[128] = ItemType.WaxedCutCopperSlab; + mappings[129] = ItemType.WaxedExposedCutCopperSlab; + mappings[130] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[131] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[132] = ItemType.OakLog; + mappings[133] = ItemType.SpruceLog; + mappings[134] = ItemType.BirchLog; + mappings[135] = ItemType.JungleLog; + mappings[136] = ItemType.AcaciaLog; + mappings[137] = ItemType.CherryLog; + mappings[138] = ItemType.DarkOakLog; + mappings[139] = ItemType.MangroveLog; + mappings[140] = ItemType.MangroveRoots; + mappings[141] = ItemType.MuddyMangroveRoots; + mappings[142] = ItemType.CrimsonStem; + mappings[143] = ItemType.WarpedStem; + mappings[144] = ItemType.BambooBlock; + mappings[145] = ItemType.StrippedOakLog; + mappings[146] = ItemType.StrippedSpruceLog; + mappings[147] = ItemType.StrippedBirchLog; + mappings[148] = ItemType.StrippedJungleLog; + mappings[149] = ItemType.StrippedAcaciaLog; + mappings[150] = ItemType.StrippedCherryLog; + mappings[151] = ItemType.StrippedDarkOakLog; + mappings[152] = ItemType.StrippedMangroveLog; + mappings[153] = ItemType.StrippedCrimsonStem; + mappings[154] = ItemType.StrippedWarpedStem; + mappings[155] = ItemType.StrippedOakWood; + mappings[156] = ItemType.StrippedSpruceWood; + mappings[157] = ItemType.StrippedBirchWood; + mappings[158] = ItemType.StrippedJungleWood; + mappings[159] = ItemType.StrippedAcaciaWood; + mappings[160] = ItemType.StrippedCherryWood; + mappings[161] = ItemType.StrippedDarkOakWood; + mappings[162] = ItemType.StrippedMangroveWood; + mappings[163] = ItemType.StrippedCrimsonHyphae; + mappings[164] = ItemType.StrippedWarpedHyphae; + mappings[165] = ItemType.StrippedBambooBlock; + mappings[166] = ItemType.OakWood; + mappings[167] = ItemType.SpruceWood; + mappings[168] = ItemType.BirchWood; + mappings[169] = ItemType.JungleWood; + mappings[170] = ItemType.AcaciaWood; + mappings[171] = ItemType.CherryWood; + mappings[172] = ItemType.DarkOakWood; + mappings[173] = ItemType.MangroveWood; + mappings[174] = ItemType.CrimsonHyphae; + mappings[175] = ItemType.WarpedHyphae; + mappings[176] = ItemType.OakLeaves; + mappings[177] = ItemType.SpruceLeaves; + mappings[178] = ItemType.BirchLeaves; + mappings[179] = ItemType.JungleLeaves; + mappings[180] = ItemType.AcaciaLeaves; + mappings[181] = ItemType.CherryLeaves; + mappings[182] = ItemType.DarkOakLeaves; + mappings[183] = ItemType.MangroveLeaves; + mappings[184] = ItemType.AzaleaLeaves; + mappings[185] = ItemType.FloweringAzaleaLeaves; + mappings[186] = ItemType.Sponge; + mappings[187] = ItemType.WetSponge; + mappings[188] = ItemType.Glass; + mappings[189] = ItemType.TintedGlass; + mappings[190] = ItemType.LapisBlock; + mappings[191] = ItemType.Sandstone; + mappings[192] = ItemType.ChiseledSandstone; + mappings[193] = ItemType.CutSandstone; + mappings[194] = ItemType.Cobweb; + mappings[195] = ItemType.ShortGrass; + mappings[196] = ItemType.Fern; + mappings[197] = ItemType.Azalea; + mappings[198] = ItemType.FloweringAzalea; + mappings[199] = ItemType.DeadBush; + mappings[200] = ItemType.Seagrass; + mappings[201] = ItemType.SeaPickle; + mappings[202] = ItemType.WhiteWool; + mappings[203] = ItemType.OrangeWool; + mappings[204] = ItemType.MagentaWool; + mappings[205] = ItemType.LightBlueWool; + mappings[206] = ItemType.YellowWool; + mappings[207] = ItemType.LimeWool; + mappings[208] = ItemType.PinkWool; + mappings[209] = ItemType.GrayWool; + mappings[210] = ItemType.LightGrayWool; + mappings[211] = ItemType.CyanWool; + mappings[212] = ItemType.PurpleWool; + mappings[213] = ItemType.BlueWool; + mappings[214] = ItemType.BrownWool; + mappings[215] = ItemType.GreenWool; + mappings[216] = ItemType.RedWool; + mappings[217] = ItemType.BlackWool; + mappings[218] = ItemType.Dandelion; + mappings[219] = ItemType.Poppy; + mappings[220] = ItemType.BlueOrchid; + mappings[221] = ItemType.Allium; + mappings[222] = ItemType.AzureBluet; + mappings[223] = ItemType.RedTulip; + mappings[224] = ItemType.OrangeTulip; + mappings[225] = ItemType.WhiteTulip; + mappings[226] = ItemType.PinkTulip; + mappings[227] = ItemType.OxeyeDaisy; + mappings[228] = ItemType.Cornflower; + mappings[229] = ItemType.LilyOfTheValley; + mappings[230] = ItemType.WitherRose; + mappings[231] = ItemType.Torchflower; + mappings[232] = ItemType.PitcherPlant; + mappings[233] = ItemType.SporeBlossom; + mappings[234] = ItemType.BrownMushroom; + mappings[235] = ItemType.RedMushroom; + mappings[236] = ItemType.CrimsonFungus; + mappings[237] = ItemType.WarpedFungus; + mappings[238] = ItemType.CrimsonRoots; + mappings[239] = ItemType.WarpedRoots; + mappings[240] = ItemType.NetherSprouts; + mappings[241] = ItemType.WeepingVines; + mappings[242] = ItemType.TwistingVines; + mappings[243] = ItemType.SugarCane; + mappings[244] = ItemType.Kelp; + mappings[245] = ItemType.MossCarpet; + mappings[246] = ItemType.PinkPetals; + mappings[247] = ItemType.MossBlock; + mappings[248] = ItemType.HangingRoots; + mappings[249] = ItemType.BigDripleaf; + mappings[250] = ItemType.SmallDripleaf; + mappings[251] = ItemType.Bamboo; + mappings[252] = ItemType.OakSlab; + mappings[253] = ItemType.SpruceSlab; + mappings[254] = ItemType.BirchSlab; + mappings[255] = ItemType.JungleSlab; + mappings[256] = ItemType.AcaciaSlab; + mappings[257] = ItemType.CherrySlab; + mappings[258] = ItemType.DarkOakSlab; + mappings[259] = ItemType.MangroveSlab; + mappings[260] = ItemType.BambooSlab; + mappings[261] = ItemType.BambooMosaicSlab; + mappings[262] = ItemType.CrimsonSlab; + mappings[263] = ItemType.WarpedSlab; + mappings[264] = ItemType.StoneSlab; + mappings[265] = ItemType.SmoothStoneSlab; + mappings[266] = ItemType.SandstoneSlab; + mappings[267] = ItemType.CutSandstoneSlab; + mappings[268] = ItemType.PetrifiedOakSlab; + mappings[269] = ItemType.CobblestoneSlab; + mappings[270] = ItemType.BrickSlab; + mappings[271] = ItemType.StoneBrickSlab; + mappings[272] = ItemType.MudBrickSlab; + mappings[273] = ItemType.NetherBrickSlab; + mappings[274] = ItemType.QuartzSlab; + mappings[275] = ItemType.RedSandstoneSlab; + mappings[276] = ItemType.CutRedSandstoneSlab; + mappings[277] = ItemType.PurpurSlab; + mappings[278] = ItemType.PrismarineSlab; + mappings[279] = ItemType.PrismarineBrickSlab; + mappings[280] = ItemType.DarkPrismarineSlab; + mappings[281] = ItemType.SmoothQuartz; + mappings[282] = ItemType.SmoothRedSandstone; + mappings[283] = ItemType.SmoothSandstone; + mappings[284] = ItemType.SmoothStone; + mappings[285] = ItemType.Bricks; + mappings[286] = ItemType.Bookshelf; + mappings[287] = ItemType.ChiseledBookshelf; + mappings[288] = ItemType.DecoratedPot; + mappings[289] = ItemType.MossyCobblestone; + mappings[290] = ItemType.Obsidian; + mappings[291] = ItemType.Torch; + mappings[292] = ItemType.EndRod; + mappings[293] = ItemType.ChorusPlant; + mappings[294] = ItemType.ChorusFlower; + mappings[295] = ItemType.PurpurBlock; + mappings[296] = ItemType.PurpurPillar; + mappings[297] = ItemType.PurpurStairs; + mappings[298] = ItemType.Spawner; + mappings[299] = ItemType.Chest; + mappings[300] = ItemType.CraftingTable; + mappings[301] = ItemType.Farmland; + mappings[302] = ItemType.Furnace; + mappings[303] = ItemType.Ladder; + mappings[304] = ItemType.CobblestoneStairs; + mappings[305] = ItemType.Snow; + mappings[306] = ItemType.Ice; + mappings[307] = ItemType.SnowBlock; + mappings[308] = ItemType.Cactus; + mappings[309] = ItemType.Clay; + mappings[310] = ItemType.Jukebox; + mappings[311] = ItemType.OakFence; + mappings[312] = ItemType.SpruceFence; + mappings[313] = ItemType.BirchFence; + mappings[314] = ItemType.JungleFence; + mappings[315] = ItemType.AcaciaFence; + mappings[316] = ItemType.CherryFence; + mappings[317] = ItemType.DarkOakFence; + mappings[318] = ItemType.MangroveFence; + mappings[319] = ItemType.BambooFence; + mappings[320] = ItemType.CrimsonFence; + mappings[321] = ItemType.WarpedFence; + mappings[322] = ItemType.Pumpkin; + mappings[323] = ItemType.CarvedPumpkin; + mappings[324] = ItemType.JackOLantern; + mappings[325] = ItemType.Netherrack; + mappings[326] = ItemType.SoulSand; + mappings[327] = ItemType.SoulSoil; + mappings[328] = ItemType.Basalt; + mappings[329] = ItemType.PolishedBasalt; + mappings[330] = ItemType.SmoothBasalt; + mappings[331] = ItemType.SoulTorch; + mappings[332] = ItemType.Glowstone; + mappings[333] = ItemType.InfestedStone; + mappings[334] = ItemType.InfestedCobblestone; + mappings[335] = ItemType.InfestedStoneBricks; + mappings[336] = ItemType.InfestedMossyStoneBricks; + mappings[337] = ItemType.InfestedCrackedStoneBricks; + mappings[338] = ItemType.InfestedChiseledStoneBricks; + mappings[339] = ItemType.InfestedDeepslate; + mappings[340] = ItemType.StoneBricks; + mappings[341] = ItemType.MossyStoneBricks; + mappings[342] = ItemType.CrackedStoneBricks; + mappings[343] = ItemType.ChiseledStoneBricks; + mappings[344] = ItemType.PackedMud; + mappings[345] = ItemType.MudBricks; + mappings[346] = ItemType.DeepslateBricks; + mappings[347] = ItemType.CrackedDeepslateBricks; + mappings[348] = ItemType.DeepslateTiles; + mappings[349] = ItemType.CrackedDeepslateTiles; + mappings[350] = ItemType.ChiseledDeepslate; + mappings[351] = ItemType.ReinforcedDeepslate; + mappings[352] = ItemType.BrownMushroomBlock; + mappings[353] = ItemType.RedMushroomBlock; + mappings[354] = ItemType.MushroomStem; + mappings[355] = ItemType.IronBars; + mappings[356] = ItemType.Chain; + mappings[357] = ItemType.GlassPane; + mappings[358] = ItemType.Melon; + mappings[359] = ItemType.Vine; + mappings[360] = ItemType.GlowLichen; + mappings[361] = ItemType.BrickStairs; + mappings[362] = ItemType.StoneBrickStairs; + mappings[363] = ItemType.MudBrickStairs; + mappings[364] = ItemType.Mycelium; + mappings[365] = ItemType.LilyPad; + mappings[366] = ItemType.NetherBricks; + mappings[367] = ItemType.CrackedNetherBricks; + mappings[368] = ItemType.ChiseledNetherBricks; + mappings[369] = ItemType.NetherBrickFence; + mappings[370] = ItemType.NetherBrickStairs; + mappings[371] = ItemType.Sculk; + mappings[372] = ItemType.SculkVein; + mappings[373] = ItemType.SculkCatalyst; + mappings[374] = ItemType.SculkShrieker; + mappings[375] = ItemType.EnchantingTable; + mappings[376] = ItemType.EndPortalFrame; + mappings[377] = ItemType.EndStone; + mappings[378] = ItemType.EndStoneBricks; + mappings[379] = ItemType.DragonEgg; + mappings[380] = ItemType.SandstoneStairs; + mappings[381] = ItemType.EnderChest; + mappings[382] = ItemType.EmeraldBlock; + mappings[383] = ItemType.OakStairs; + mappings[384] = ItemType.SpruceStairs; + mappings[385] = ItemType.BirchStairs; + mappings[386] = ItemType.JungleStairs; + mappings[387] = ItemType.AcaciaStairs; + mappings[388] = ItemType.CherryStairs; + mappings[389] = ItemType.DarkOakStairs; + mappings[390] = ItemType.MangroveStairs; + mappings[391] = ItemType.BambooStairs; + mappings[392] = ItemType.BambooMosaicStairs; + mappings[393] = ItemType.CrimsonStairs; + mappings[394] = ItemType.WarpedStairs; + mappings[395] = ItemType.CommandBlock; + mappings[396] = ItemType.Beacon; + mappings[397] = ItemType.CobblestoneWall; + mappings[398] = ItemType.MossyCobblestoneWall; + mappings[399] = ItemType.BrickWall; + mappings[400] = ItemType.PrismarineWall; + mappings[401] = ItemType.RedSandstoneWall; + mappings[402] = ItemType.MossyStoneBrickWall; + mappings[403] = ItemType.GraniteWall; + mappings[404] = ItemType.StoneBrickWall; + mappings[405] = ItemType.MudBrickWall; + mappings[406] = ItemType.NetherBrickWall; + mappings[407] = ItemType.AndesiteWall; + mappings[408] = ItemType.RedNetherBrickWall; + mappings[409] = ItemType.SandstoneWall; + mappings[410] = ItemType.EndStoneBrickWall; + mappings[411] = ItemType.DioriteWall; + mappings[412] = ItemType.BlackstoneWall; + mappings[413] = ItemType.PolishedBlackstoneWall; + mappings[414] = ItemType.PolishedBlackstoneBrickWall; + mappings[415] = ItemType.CobbledDeepslateWall; + mappings[416] = ItemType.PolishedDeepslateWall; + mappings[417] = ItemType.DeepslateBrickWall; + mappings[418] = ItemType.DeepslateTileWall; + mappings[419] = ItemType.Anvil; + mappings[420] = ItemType.ChippedAnvil; + mappings[421] = ItemType.DamagedAnvil; + mappings[422] = ItemType.ChiseledQuartzBlock; + mappings[423] = ItemType.QuartzBlock; + mappings[424] = ItemType.QuartzBricks; + mappings[425] = ItemType.QuartzPillar; + mappings[426] = ItemType.QuartzStairs; + mappings[427] = ItemType.WhiteTerracotta; + mappings[428] = ItemType.OrangeTerracotta; + mappings[429] = ItemType.MagentaTerracotta; + mappings[430] = ItemType.LightBlueTerracotta; + mappings[431] = ItemType.YellowTerracotta; + mappings[432] = ItemType.LimeTerracotta; + mappings[433] = ItemType.PinkTerracotta; + mappings[434] = ItemType.GrayTerracotta; + mappings[435] = ItemType.LightGrayTerracotta; + mappings[436] = ItemType.CyanTerracotta; + mappings[437] = ItemType.PurpleTerracotta; + mappings[438] = ItemType.BlueTerracotta; + mappings[439] = ItemType.BrownTerracotta; + mappings[440] = ItemType.GreenTerracotta; + mappings[441] = ItemType.RedTerracotta; + mappings[442] = ItemType.BlackTerracotta; + mappings[443] = ItemType.Barrier; + mappings[444] = ItemType.Light; + mappings[445] = ItemType.HayBlock; + mappings[446] = ItemType.WhiteCarpet; + mappings[447] = ItemType.OrangeCarpet; + mappings[448] = ItemType.MagentaCarpet; + mappings[449] = ItemType.LightBlueCarpet; + mappings[450] = ItemType.YellowCarpet; + mappings[451] = ItemType.LimeCarpet; + mappings[452] = ItemType.PinkCarpet; + mappings[453] = ItemType.GrayCarpet; + mappings[454] = ItemType.LightGrayCarpet; + mappings[455] = ItemType.CyanCarpet; + mappings[456] = ItemType.PurpleCarpet; + mappings[457] = ItemType.BlueCarpet; + mappings[458] = ItemType.BrownCarpet; + mappings[459] = ItemType.GreenCarpet; + mappings[460] = ItemType.RedCarpet; + mappings[461] = ItemType.BlackCarpet; + mappings[462] = ItemType.Terracotta; + mappings[463] = ItemType.PackedIce; + mappings[464] = ItemType.DirtPath; + mappings[465] = ItemType.Sunflower; + mappings[466] = ItemType.Lilac; + mappings[467] = ItemType.RoseBush; + mappings[468] = ItemType.Peony; + mappings[469] = ItemType.TallGrass; + mappings[470] = ItemType.LargeFern; + mappings[471] = ItemType.WhiteStainedGlass; + mappings[472] = ItemType.OrangeStainedGlass; + mappings[473] = ItemType.MagentaStainedGlass; + mappings[474] = ItemType.LightBlueStainedGlass; + mappings[475] = ItemType.YellowStainedGlass; + mappings[476] = ItemType.LimeStainedGlass; + mappings[477] = ItemType.PinkStainedGlass; + mappings[478] = ItemType.GrayStainedGlass; + mappings[479] = ItemType.LightGrayStainedGlass; + mappings[480] = ItemType.CyanStainedGlass; + mappings[481] = ItemType.PurpleStainedGlass; + mappings[482] = ItemType.BlueStainedGlass; + mappings[483] = ItemType.BrownStainedGlass; + mappings[484] = ItemType.GreenStainedGlass; + mappings[485] = ItemType.RedStainedGlass; + mappings[486] = ItemType.BlackStainedGlass; + mappings[487] = ItemType.WhiteStainedGlassPane; + mappings[488] = ItemType.OrangeStainedGlassPane; + mappings[489] = ItemType.MagentaStainedGlassPane; + mappings[490] = ItemType.LightBlueStainedGlassPane; + mappings[491] = ItemType.YellowStainedGlassPane; + mappings[492] = ItemType.LimeStainedGlassPane; + mappings[493] = ItemType.PinkStainedGlassPane; + mappings[494] = ItemType.GrayStainedGlassPane; + mappings[495] = ItemType.LightGrayStainedGlassPane; + mappings[496] = ItemType.CyanStainedGlassPane; + mappings[497] = ItemType.PurpleStainedGlassPane; + mappings[498] = ItemType.BlueStainedGlassPane; + mappings[499] = ItemType.BrownStainedGlassPane; + mappings[500] = ItemType.GreenStainedGlassPane; + mappings[501] = ItemType.RedStainedGlassPane; + mappings[502] = ItemType.BlackStainedGlassPane; + mappings[503] = ItemType.Prismarine; + mappings[504] = ItemType.PrismarineBricks; + mappings[505] = ItemType.DarkPrismarine; + mappings[506] = ItemType.PrismarineStairs; + mappings[507] = ItemType.PrismarineBrickStairs; + mappings[508] = ItemType.DarkPrismarineStairs; + mappings[509] = ItemType.SeaLantern; + mappings[510] = ItemType.RedSandstone; + mappings[511] = ItemType.ChiseledRedSandstone; + mappings[512] = ItemType.CutRedSandstone; + mappings[513] = ItemType.RedSandstoneStairs; + mappings[514] = ItemType.RepeatingCommandBlock; + mappings[515] = ItemType.ChainCommandBlock; + mappings[516] = ItemType.MagmaBlock; + mappings[517] = ItemType.NetherWartBlock; + mappings[518] = ItemType.WarpedWartBlock; + mappings[519] = ItemType.RedNetherBricks; + mappings[520] = ItemType.BoneBlock; + mappings[521] = ItemType.StructureVoid; + mappings[522] = ItemType.ShulkerBox; + mappings[523] = ItemType.WhiteShulkerBox; + mappings[524] = ItemType.OrangeShulkerBox; + mappings[525] = ItemType.MagentaShulkerBox; + mappings[526] = ItemType.LightBlueShulkerBox; + mappings[527] = ItemType.YellowShulkerBox; + mappings[528] = ItemType.LimeShulkerBox; + mappings[529] = ItemType.PinkShulkerBox; + mappings[530] = ItemType.GrayShulkerBox; + mappings[531] = ItemType.LightGrayShulkerBox; + mappings[532] = ItemType.CyanShulkerBox; + mappings[533] = ItemType.PurpleShulkerBox; + mappings[534] = ItemType.BlueShulkerBox; + mappings[535] = ItemType.BrownShulkerBox; + mappings[536] = ItemType.GreenShulkerBox; + mappings[537] = ItemType.RedShulkerBox; + mappings[538] = ItemType.BlackShulkerBox; + mappings[539] = ItemType.WhiteGlazedTerracotta; + mappings[540] = ItemType.OrangeGlazedTerracotta; + mappings[541] = ItemType.MagentaGlazedTerracotta; + mappings[542] = ItemType.LightBlueGlazedTerracotta; + mappings[543] = ItemType.YellowGlazedTerracotta; + mappings[544] = ItemType.LimeGlazedTerracotta; + mappings[545] = ItemType.PinkGlazedTerracotta; + mappings[546] = ItemType.GrayGlazedTerracotta; + mappings[547] = ItemType.LightGrayGlazedTerracotta; + mappings[548] = ItemType.CyanGlazedTerracotta; + mappings[549] = ItemType.PurpleGlazedTerracotta; + mappings[550] = ItemType.BlueGlazedTerracotta; + mappings[551] = ItemType.BrownGlazedTerracotta; + mappings[552] = ItemType.GreenGlazedTerracotta; + mappings[553] = ItemType.RedGlazedTerracotta; + mappings[554] = ItemType.BlackGlazedTerracotta; + mappings[555] = ItemType.WhiteConcrete; + mappings[556] = ItemType.OrangeConcrete; + mappings[557] = ItemType.MagentaConcrete; + mappings[558] = ItemType.LightBlueConcrete; + mappings[559] = ItemType.YellowConcrete; + mappings[560] = ItemType.LimeConcrete; + mappings[561] = ItemType.PinkConcrete; + mappings[562] = ItemType.GrayConcrete; + mappings[563] = ItemType.LightGrayConcrete; + mappings[564] = ItemType.CyanConcrete; + mappings[565] = ItemType.PurpleConcrete; + mappings[566] = ItemType.BlueConcrete; + mappings[567] = ItemType.BrownConcrete; + mappings[568] = ItemType.GreenConcrete; + mappings[569] = ItemType.RedConcrete; + mappings[570] = ItemType.BlackConcrete; + mappings[571] = ItemType.WhiteConcretePowder; + mappings[572] = ItemType.OrangeConcretePowder; + mappings[573] = ItemType.MagentaConcretePowder; + mappings[574] = ItemType.LightBlueConcretePowder; + mappings[575] = ItemType.YellowConcretePowder; + mappings[576] = ItemType.LimeConcretePowder; + mappings[577] = ItemType.PinkConcretePowder; + mappings[578] = ItemType.GrayConcretePowder; + mappings[579] = ItemType.LightGrayConcretePowder; + mappings[580] = ItemType.CyanConcretePowder; + mappings[581] = ItemType.PurpleConcretePowder; + mappings[582] = ItemType.BlueConcretePowder; + mappings[583] = ItemType.BrownConcretePowder; + mappings[584] = ItemType.GreenConcretePowder; + mappings[585] = ItemType.RedConcretePowder; + mappings[586] = ItemType.BlackConcretePowder; + mappings[587] = ItemType.TurtleEgg; + mappings[588] = ItemType.SnifferEgg; + mappings[589] = ItemType.DeadTubeCoralBlock; + mappings[590] = ItemType.DeadBrainCoralBlock; + mappings[591] = ItemType.DeadBubbleCoralBlock; + mappings[592] = ItemType.DeadFireCoralBlock; + mappings[593] = ItemType.DeadHornCoralBlock; + mappings[594] = ItemType.TubeCoralBlock; + mappings[595] = ItemType.BrainCoralBlock; + mappings[596] = ItemType.BubbleCoralBlock; + mappings[597] = ItemType.FireCoralBlock; + mappings[598] = ItemType.HornCoralBlock; + mappings[599] = ItemType.TubeCoral; + mappings[600] = ItemType.BrainCoral; + mappings[601] = ItemType.BubbleCoral; + mappings[602] = ItemType.FireCoral; + mappings[603] = ItemType.HornCoral; + mappings[604] = ItemType.DeadBrainCoral; + mappings[605] = ItemType.DeadBubbleCoral; + mappings[606] = ItemType.DeadFireCoral; + mappings[607] = ItemType.DeadHornCoral; + mappings[608] = ItemType.DeadTubeCoral; + mappings[609] = ItemType.TubeCoralFan; + mappings[610] = ItemType.BrainCoralFan; + mappings[611] = ItemType.BubbleCoralFan; + mappings[612] = ItemType.FireCoralFan; + mappings[613] = ItemType.HornCoralFan; + mappings[614] = ItemType.DeadTubeCoralFan; + mappings[615] = ItemType.DeadBrainCoralFan; + mappings[616] = ItemType.DeadBubbleCoralFan; + mappings[617] = ItemType.DeadFireCoralFan; + mappings[618] = ItemType.DeadHornCoralFan; + mappings[619] = ItemType.BlueIce; + mappings[620] = ItemType.Conduit; + mappings[621] = ItemType.PolishedGraniteStairs; + mappings[622] = ItemType.SmoothRedSandstoneStairs; + mappings[623] = ItemType.MossyStoneBrickStairs; + mappings[624] = ItemType.PolishedDioriteStairs; + mappings[625] = ItemType.MossyCobblestoneStairs; + mappings[626] = ItemType.EndStoneBrickStairs; + mappings[627] = ItemType.StoneStairs; + mappings[628] = ItemType.SmoothSandstoneStairs; + mappings[629] = ItemType.SmoothQuartzStairs; + mappings[630] = ItemType.GraniteStairs; + mappings[631] = ItemType.AndesiteStairs; + mappings[632] = ItemType.RedNetherBrickStairs; + mappings[633] = ItemType.PolishedAndesiteStairs; + mappings[634] = ItemType.DioriteStairs; + mappings[635] = ItemType.CobbledDeepslateStairs; + mappings[636] = ItemType.PolishedDeepslateStairs; + mappings[637] = ItemType.DeepslateBrickStairs; + mappings[638] = ItemType.DeepslateTileStairs; + mappings[639] = ItemType.PolishedGraniteSlab; + mappings[640] = ItemType.SmoothRedSandstoneSlab; + mappings[641] = ItemType.MossyStoneBrickSlab; + mappings[642] = ItemType.PolishedDioriteSlab; + mappings[643] = ItemType.MossyCobblestoneSlab; + mappings[644] = ItemType.EndStoneBrickSlab; + mappings[645] = ItemType.SmoothSandstoneSlab; + mappings[646] = ItemType.SmoothQuartzSlab; + mappings[647] = ItemType.GraniteSlab; + mappings[648] = ItemType.AndesiteSlab; + mappings[649] = ItemType.RedNetherBrickSlab; + mappings[650] = ItemType.PolishedAndesiteSlab; + mappings[651] = ItemType.DioriteSlab; + mappings[652] = ItemType.CobbledDeepslateSlab; + mappings[653] = ItemType.PolishedDeepslateSlab; + mappings[654] = ItemType.DeepslateBrickSlab; + mappings[655] = ItemType.DeepslateTileSlab; + mappings[656] = ItemType.Scaffolding; + mappings[657] = ItemType.Redstone; + mappings[658] = ItemType.RedstoneTorch; + mappings[659] = ItemType.RedstoneBlock; + mappings[660] = ItemType.Repeater; + mappings[661] = ItemType.Comparator; + mappings[662] = ItemType.Piston; + mappings[663] = ItemType.StickyPiston; + mappings[664] = ItemType.SlimeBlock; + mappings[665] = ItemType.HoneyBlock; + mappings[666] = ItemType.Observer; + mappings[667] = ItemType.Hopper; + mappings[668] = ItemType.Dispenser; + mappings[669] = ItemType.Dropper; + mappings[670] = ItemType.Lectern; + mappings[671] = ItemType.Target; + mappings[672] = ItemType.Lever; + mappings[673] = ItemType.LightningRod; + mappings[674] = ItemType.DaylightDetector; + mappings[675] = ItemType.SculkSensor; + mappings[676] = ItemType.CalibratedSculkSensor; + mappings[677] = ItemType.TripwireHook; + mappings[678] = ItemType.TrappedChest; + mappings[679] = ItemType.Tnt; + mappings[680] = ItemType.RedstoneLamp; + mappings[681] = ItemType.NoteBlock; + mappings[682] = ItemType.StoneButton; + mappings[683] = ItemType.PolishedBlackstoneButton; + mappings[684] = ItemType.OakButton; + mappings[685] = ItemType.SpruceButton; + mappings[686] = ItemType.BirchButton; + mappings[687] = ItemType.JungleButton; + mappings[688] = ItemType.AcaciaButton; + mappings[689] = ItemType.CherryButton; + mappings[690] = ItemType.DarkOakButton; + mappings[691] = ItemType.MangroveButton; + mappings[692] = ItemType.BambooButton; + mappings[693] = ItemType.CrimsonButton; + mappings[694] = ItemType.WarpedButton; + mappings[695] = ItemType.StonePressurePlate; + mappings[696] = ItemType.PolishedBlackstonePressurePlate; + mappings[697] = ItemType.LightWeightedPressurePlate; + mappings[698] = ItemType.HeavyWeightedPressurePlate; + mappings[699] = ItemType.OakPressurePlate; + mappings[700] = ItemType.SprucePressurePlate; + mappings[701] = ItemType.BirchPressurePlate; + mappings[702] = ItemType.JunglePressurePlate; + mappings[703] = ItemType.AcaciaPressurePlate; + mappings[704] = ItemType.CherryPressurePlate; + mappings[705] = ItemType.DarkOakPressurePlate; + mappings[706] = ItemType.MangrovePressurePlate; + mappings[707] = ItemType.BambooPressurePlate; + mappings[708] = ItemType.CrimsonPressurePlate; + mappings[709] = ItemType.WarpedPressurePlate; + mappings[710] = ItemType.IronDoor; + mappings[711] = ItemType.OakDoor; + mappings[712] = ItemType.SpruceDoor; + mappings[713] = ItemType.BirchDoor; + mappings[714] = ItemType.JungleDoor; + mappings[715] = ItemType.AcaciaDoor; + mappings[716] = ItemType.CherryDoor; + mappings[717] = ItemType.DarkOakDoor; + mappings[718] = ItemType.MangroveDoor; + mappings[719] = ItemType.BambooDoor; + mappings[720] = ItemType.CrimsonDoor; + mappings[721] = ItemType.WarpedDoor; + mappings[722] = ItemType.CopperDoor; + mappings[723] = ItemType.ExposedCopperDoor; + mappings[724] = ItemType.WeatheredCopperDoor; + mappings[725] = ItemType.OxidizedCopperDoor; + mappings[726] = ItemType.WaxedCopperDoor; + mappings[727] = ItemType.WaxedExposedCopperDoor; + mappings[728] = ItemType.WaxedWeatheredCopperDoor; + mappings[729] = ItemType.WaxedOxidizedCopperDoor; + mappings[730] = ItemType.IronTrapdoor; + mappings[731] = ItemType.OakTrapdoor; + mappings[732] = ItemType.SpruceTrapdoor; + mappings[733] = ItemType.BirchTrapdoor; + mappings[734] = ItemType.JungleTrapdoor; + mappings[735] = ItemType.AcaciaTrapdoor; + mappings[736] = ItemType.CherryTrapdoor; + mappings[737] = ItemType.DarkOakTrapdoor; + mappings[738] = ItemType.MangroveTrapdoor; + mappings[739] = ItemType.BambooTrapdoor; + mappings[740] = ItemType.CrimsonTrapdoor; + mappings[741] = ItemType.WarpedTrapdoor; + mappings[742] = ItemType.CopperTrapdoor; + mappings[743] = ItemType.ExposedCopperTrapdoor; + mappings[744] = ItemType.WeatheredCopperTrapdoor; + mappings[745] = ItemType.OxidizedCopperTrapdoor; + mappings[746] = ItemType.WaxedCopperTrapdoor; + mappings[747] = ItemType.WaxedExposedCopperTrapdoor; + mappings[748] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[749] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[750] = ItemType.OakFenceGate; + mappings[751] = ItemType.SpruceFenceGate; + mappings[752] = ItemType.BirchFenceGate; + mappings[753] = ItemType.JungleFenceGate; + mappings[754] = ItemType.AcaciaFenceGate; + mappings[755] = ItemType.CherryFenceGate; + mappings[756] = ItemType.DarkOakFenceGate; + mappings[757] = ItemType.MangroveFenceGate; + mappings[758] = ItemType.BambooFenceGate; + mappings[759] = ItemType.CrimsonFenceGate; + mappings[760] = ItemType.WarpedFenceGate; + mappings[761] = ItemType.PoweredRail; + mappings[762] = ItemType.DetectorRail; + mappings[763] = ItemType.Rail; + mappings[764] = ItemType.ActivatorRail; + mappings[765] = ItemType.Saddle; + mappings[766] = ItemType.Minecart; + mappings[767] = ItemType.ChestMinecart; + mappings[768] = ItemType.FurnaceMinecart; + mappings[769] = ItemType.TntMinecart; + mappings[770] = ItemType.HopperMinecart; + mappings[771] = ItemType.CarrotOnAStick; + mappings[772] = ItemType.WarpedFungusOnAStick; + mappings[773] = ItemType.Elytra; + mappings[774] = ItemType.OakBoat; + mappings[775] = ItemType.OakChestBoat; + mappings[776] = ItemType.SpruceBoat; + mappings[777] = ItemType.SpruceChestBoat; + mappings[778] = ItemType.BirchBoat; + mappings[779] = ItemType.BirchChestBoat; + mappings[780] = ItemType.JungleBoat; + mappings[781] = ItemType.JungleChestBoat; + mappings[782] = ItemType.AcaciaBoat; + mappings[783] = ItemType.AcaciaChestBoat; + mappings[784] = ItemType.CherryBoat; + mappings[785] = ItemType.CherryChestBoat; + mappings[786] = ItemType.DarkOakBoat; + mappings[787] = ItemType.DarkOakChestBoat; + mappings[788] = ItemType.MangroveBoat; + mappings[789] = ItemType.MangroveChestBoat; + mappings[790] = ItemType.BambooRaft; + mappings[791] = ItemType.BambooChestRaft; + mappings[792] = ItemType.StructureBlock; + mappings[793] = ItemType.Jigsaw; + mappings[794] = ItemType.TurtleHelmet; + mappings[795] = ItemType.TurtleScute; + mappings[796] = ItemType.ArmadilloScute; + mappings[797] = ItemType.WolfArmor; + mappings[798] = ItemType.FlintAndSteel; + mappings[799] = ItemType.Bowl; + mappings[800] = ItemType.Apple; + mappings[801] = ItemType.Bow; + mappings[802] = ItemType.Arrow; + mappings[803] = ItemType.Coal; + mappings[804] = ItemType.Charcoal; + mappings[805] = ItemType.Diamond; + mappings[806] = ItemType.Emerald; + mappings[807] = ItemType.LapisLazuli; + mappings[808] = ItemType.Quartz; + mappings[809] = ItemType.AmethystShard; + mappings[810] = ItemType.RawIron; + mappings[811] = ItemType.IronIngot; + mappings[812] = ItemType.RawCopper; + mappings[813] = ItemType.CopperIngot; + mappings[814] = ItemType.RawGold; + mappings[815] = ItemType.GoldIngot; + mappings[816] = ItemType.NetheriteIngot; + mappings[817] = ItemType.NetheriteScrap; + mappings[818] = ItemType.WoodenSword; + mappings[819] = ItemType.WoodenShovel; + mappings[820] = ItemType.WoodenPickaxe; + mappings[821] = ItemType.WoodenAxe; + mappings[822] = ItemType.WoodenHoe; + mappings[823] = ItemType.StoneSword; + mappings[824] = ItemType.StoneShovel; + mappings[825] = ItemType.StonePickaxe; + mappings[826] = ItemType.StoneAxe; + mappings[827] = ItemType.StoneHoe; + mappings[828] = ItemType.GoldenSword; + mappings[829] = ItemType.GoldenShovel; + mappings[830] = ItemType.GoldenPickaxe; + mappings[831] = ItemType.GoldenAxe; + mappings[832] = ItemType.GoldenHoe; + mappings[833] = ItemType.IronSword; + mappings[834] = ItemType.IronShovel; + mappings[835] = ItemType.IronPickaxe; + mappings[836] = ItemType.IronAxe; + mappings[837] = ItemType.IronHoe; + mappings[838] = ItemType.DiamondSword; + mappings[839] = ItemType.DiamondShovel; + mappings[840] = ItemType.DiamondPickaxe; + mappings[841] = ItemType.DiamondAxe; + mappings[842] = ItemType.DiamondHoe; + mappings[843] = ItemType.NetheriteSword; + mappings[844] = ItemType.NetheriteShovel; + mappings[845] = ItemType.NetheritePickaxe; + mappings[846] = ItemType.NetheriteAxe; + mappings[847] = ItemType.NetheriteHoe; + mappings[848] = ItemType.Stick; + mappings[849] = ItemType.MushroomStew; + mappings[850] = ItemType.String; + mappings[851] = ItemType.Feather; + mappings[852] = ItemType.Gunpowder; + mappings[853] = ItemType.WheatSeeds; + mappings[854] = ItemType.Wheat; + mappings[855] = ItemType.Bread; + mappings[856] = ItemType.LeatherHelmet; + mappings[857] = ItemType.LeatherChestplate; + mappings[858] = ItemType.LeatherLeggings; + mappings[859] = ItemType.LeatherBoots; + mappings[860] = ItemType.ChainmailHelmet; + mappings[861] = ItemType.ChainmailChestplate; + mappings[862] = ItemType.ChainmailLeggings; + mappings[863] = ItemType.ChainmailBoots; + mappings[864] = ItemType.IronHelmet; + mappings[865] = ItemType.IronChestplate; + mappings[866] = ItemType.IronLeggings; + mappings[867] = ItemType.IronBoots; + mappings[868] = ItemType.DiamondHelmet; + mappings[869] = ItemType.DiamondChestplate; + mappings[870] = ItemType.DiamondLeggings; + mappings[871] = ItemType.DiamondBoots; + mappings[872] = ItemType.GoldenHelmet; + mappings[873] = ItemType.GoldenChestplate; + mappings[874] = ItemType.GoldenLeggings; + mappings[875] = ItemType.GoldenBoots; + mappings[876] = ItemType.NetheriteHelmet; + mappings[877] = ItemType.NetheriteChestplate; + mappings[878] = ItemType.NetheriteLeggings; + mappings[879] = ItemType.NetheriteBoots; + mappings[880] = ItemType.Flint; + mappings[881] = ItemType.Porkchop; + mappings[882] = ItemType.CookedPorkchop; + mappings[883] = ItemType.Painting; + mappings[884] = ItemType.GoldenApple; + mappings[885] = ItemType.EnchantedGoldenApple; + mappings[886] = ItemType.OakSign; + mappings[887] = ItemType.SpruceSign; + mappings[888] = ItemType.BirchSign; + mappings[889] = ItemType.JungleSign; + mappings[890] = ItemType.AcaciaSign; + mappings[891] = ItemType.CherrySign; + mappings[892] = ItemType.DarkOakSign; + mappings[893] = ItemType.MangroveSign; + mappings[894] = ItemType.BambooSign; + mappings[895] = ItemType.CrimsonSign; + mappings[896] = ItemType.WarpedSign; + mappings[897] = ItemType.OakHangingSign; + mappings[898] = ItemType.SpruceHangingSign; + mappings[899] = ItemType.BirchHangingSign; + mappings[900] = ItemType.JungleHangingSign; + mappings[901] = ItemType.AcaciaHangingSign; + mappings[902] = ItemType.CherryHangingSign; + mappings[903] = ItemType.DarkOakHangingSign; + mappings[904] = ItemType.MangroveHangingSign; + mappings[905] = ItemType.BambooHangingSign; + mappings[906] = ItemType.CrimsonHangingSign; + mappings[907] = ItemType.WarpedHangingSign; + mappings[908] = ItemType.Bucket; + mappings[909] = ItemType.WaterBucket; + mappings[910] = ItemType.LavaBucket; + mappings[911] = ItemType.PowderSnowBucket; + mappings[912] = ItemType.Snowball; + mappings[913] = ItemType.Leather; + mappings[914] = ItemType.MilkBucket; + mappings[915] = ItemType.PufferfishBucket; + mappings[916] = ItemType.SalmonBucket; + mappings[917] = ItemType.CodBucket; + mappings[918] = ItemType.TropicalFishBucket; + mappings[919] = ItemType.AxolotlBucket; + mappings[920] = ItemType.TadpoleBucket; + mappings[921] = ItemType.Brick; + mappings[922] = ItemType.ClayBall; + mappings[923] = ItemType.DriedKelpBlock; + mappings[924] = ItemType.Paper; + mappings[925] = ItemType.Book; + mappings[926] = ItemType.SlimeBall; + mappings[927] = ItemType.Egg; + mappings[928] = ItemType.Compass; + mappings[929] = ItemType.RecoveryCompass; + mappings[930] = ItemType.Bundle; + mappings[931] = ItemType.FishingRod; + mappings[932] = ItemType.Clock; + mappings[933] = ItemType.Spyglass; + mappings[934] = ItemType.GlowstoneDust; + mappings[935] = ItemType.Cod; + mappings[936] = ItemType.Salmon; + mappings[937] = ItemType.TropicalFish; + mappings[938] = ItemType.Pufferfish; + mappings[939] = ItemType.CookedCod; + mappings[940] = ItemType.CookedSalmon; + mappings[941] = ItemType.InkSac; + mappings[942] = ItemType.GlowInkSac; + mappings[943] = ItemType.CocoaBeans; + mappings[944] = ItemType.WhiteDye; + mappings[945] = ItemType.OrangeDye; + mappings[946] = ItemType.MagentaDye; + mappings[947] = ItemType.LightBlueDye; + mappings[948] = ItemType.YellowDye; + mappings[949] = ItemType.LimeDye; + mappings[950] = ItemType.PinkDye; + mappings[951] = ItemType.GrayDye; + mappings[952] = ItemType.LightGrayDye; + mappings[953] = ItemType.CyanDye; + mappings[954] = ItemType.PurpleDye; + mappings[955] = ItemType.BlueDye; + mappings[956] = ItemType.BrownDye; + mappings[957] = ItemType.GreenDye; + mappings[958] = ItemType.RedDye; + mappings[959] = ItemType.BlackDye; + mappings[960] = ItemType.BoneMeal; + mappings[961] = ItemType.Bone; + mappings[962] = ItemType.Sugar; + mappings[963] = ItemType.Cake; + mappings[964] = ItemType.WhiteBed; + mappings[965] = ItemType.OrangeBed; + mappings[966] = ItemType.MagentaBed; + mappings[967] = ItemType.LightBlueBed; + mappings[968] = ItemType.YellowBed; + mappings[969] = ItemType.LimeBed; + mappings[970] = ItemType.PinkBed; + mappings[971] = ItemType.GrayBed; + mappings[972] = ItemType.LightGrayBed; + mappings[973] = ItemType.CyanBed; + mappings[974] = ItemType.PurpleBed; + mappings[975] = ItemType.BlueBed; + mappings[976] = ItemType.BrownBed; + mappings[977] = ItemType.GreenBed; + mappings[978] = ItemType.RedBed; + mappings[979] = ItemType.BlackBed; + mappings[980] = ItemType.Cookie; + mappings[981] = ItemType.Crafter; + mappings[982] = ItemType.FilledMap; + mappings[983] = ItemType.Shears; + mappings[984] = ItemType.MelonSlice; + mappings[985] = ItemType.DriedKelp; + mappings[986] = ItemType.PumpkinSeeds; + mappings[987] = ItemType.MelonSeeds; + mappings[988] = ItemType.Beef; + mappings[989] = ItemType.CookedBeef; + mappings[990] = ItemType.Chicken; + mappings[991] = ItemType.CookedChicken; + mappings[992] = ItemType.RottenFlesh; + mappings[993] = ItemType.EnderPearl; + mappings[994] = ItemType.BlazeRod; + mappings[995] = ItemType.GhastTear; + mappings[996] = ItemType.GoldNugget; + mappings[997] = ItemType.NetherWart; + mappings[998] = ItemType.Potion; + mappings[999] = ItemType.GlassBottle; + mappings[1000] = ItemType.SpiderEye; + mappings[1001] = ItemType.FermentedSpiderEye; + mappings[1002] = ItemType.BlazePowder; + mappings[1003] = ItemType.MagmaCream; + mappings[1004] = ItemType.BrewingStand; + mappings[1005] = ItemType.Cauldron; + mappings[1006] = ItemType.EnderEye; + mappings[1007] = ItemType.GlisteringMelonSlice; + mappings[1008] = ItemType.ArmadilloSpawnEgg; + mappings[1009] = ItemType.AllaySpawnEgg; + mappings[1010] = ItemType.AxolotlSpawnEgg; + mappings[1011] = ItemType.BatSpawnEgg; + mappings[1012] = ItemType.BeeSpawnEgg; + mappings[1013] = ItemType.BlazeSpawnEgg; + mappings[1014] = ItemType.BoggedSpawnEgg; + mappings[1015] = ItemType.BreezeSpawnEgg; + mappings[1016] = ItemType.CatSpawnEgg; + mappings[1017] = ItemType.CamelSpawnEgg; + mappings[1018] = ItemType.CaveSpiderSpawnEgg; + mappings[1019] = ItemType.ChickenSpawnEgg; + mappings[1020] = ItemType.CodSpawnEgg; + mappings[1021] = ItemType.CowSpawnEgg; + mappings[1022] = ItemType.CreeperSpawnEgg; + mappings[1023] = ItemType.DolphinSpawnEgg; + mappings[1024] = ItemType.DonkeySpawnEgg; + mappings[1025] = ItemType.DrownedSpawnEgg; + mappings[1026] = ItemType.ElderGuardianSpawnEgg; + mappings[1027] = ItemType.EnderDragonSpawnEgg; + mappings[1028] = ItemType.EndermanSpawnEgg; + mappings[1029] = ItemType.EndermiteSpawnEgg; + mappings[1030] = ItemType.EvokerSpawnEgg; + mappings[1031] = ItemType.FoxSpawnEgg; + mappings[1032] = ItemType.FrogSpawnEgg; + mappings[1033] = ItemType.GhastSpawnEgg; + mappings[1034] = ItemType.GlowSquidSpawnEgg; + mappings[1035] = ItemType.GoatSpawnEgg; + mappings[1036] = ItemType.GuardianSpawnEgg; + mappings[1037] = ItemType.HoglinSpawnEgg; + mappings[1038] = ItemType.HorseSpawnEgg; + mappings[1039] = ItemType.HuskSpawnEgg; + mappings[1040] = ItemType.IronGolemSpawnEgg; + mappings[1041] = ItemType.LlamaSpawnEgg; + mappings[1042] = ItemType.MagmaCubeSpawnEgg; + mappings[1043] = ItemType.MooshroomSpawnEgg; + mappings[1044] = ItemType.MuleSpawnEgg; + mappings[1045] = ItemType.OcelotSpawnEgg; + mappings[1046] = ItemType.PandaSpawnEgg; + mappings[1047] = ItemType.ParrotSpawnEgg; + mappings[1048] = ItemType.PhantomSpawnEgg; + mappings[1049] = ItemType.PigSpawnEgg; + mappings[1050] = ItemType.PiglinSpawnEgg; + mappings[1051] = ItemType.PiglinBruteSpawnEgg; + mappings[1052] = ItemType.PillagerSpawnEgg; + mappings[1053] = ItemType.PolarBearSpawnEgg; + mappings[1054] = ItemType.PufferfishSpawnEgg; + mappings[1055] = ItemType.RabbitSpawnEgg; + mappings[1056] = ItemType.RavagerSpawnEgg; + mappings[1057] = ItemType.SalmonSpawnEgg; + mappings[1058] = ItemType.SheepSpawnEgg; + mappings[1059] = ItemType.ShulkerSpawnEgg; + mappings[1060] = ItemType.SilverfishSpawnEgg; + mappings[1061] = ItemType.SkeletonSpawnEgg; + mappings[1062] = ItemType.SkeletonHorseSpawnEgg; + mappings[1063] = ItemType.SlimeSpawnEgg; + mappings[1064] = ItemType.SnifferSpawnEgg; + mappings[1065] = ItemType.SnowGolemSpawnEgg; + mappings[1066] = ItemType.SpiderSpawnEgg; + mappings[1067] = ItemType.SquidSpawnEgg; + mappings[1068] = ItemType.StraySpawnEgg; + mappings[1069] = ItemType.StriderSpawnEgg; + mappings[1070] = ItemType.TadpoleSpawnEgg; + mappings[1071] = ItemType.TraderLlamaSpawnEgg; + mappings[1072] = ItemType.TropicalFishSpawnEgg; + mappings[1073] = ItemType.TurtleSpawnEgg; + mappings[1074] = ItemType.VexSpawnEgg; + mappings[1075] = ItemType.VillagerSpawnEgg; + mappings[1076] = ItemType.VindicatorSpawnEgg; + mappings[1077] = ItemType.WanderingTraderSpawnEgg; + mappings[1078] = ItemType.WardenSpawnEgg; + mappings[1079] = ItemType.WitchSpawnEgg; + mappings[1080] = ItemType.WitherSpawnEgg; + mappings[1081] = ItemType.WitherSkeletonSpawnEgg; + mappings[1082] = ItemType.WolfSpawnEgg; + mappings[1083] = ItemType.ZoglinSpawnEgg; + mappings[1084] = ItemType.ZombieSpawnEgg; + mappings[1085] = ItemType.ZombieHorseSpawnEgg; + mappings[1086] = ItemType.ZombieVillagerSpawnEgg; + mappings[1087] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1088] = ItemType.ExperienceBottle; + mappings[1089] = ItemType.FireCharge; + mappings[1090] = ItemType.WindCharge; + mappings[1091] = ItemType.WritableBook; + mappings[1092] = ItemType.WrittenBook; + mappings[1093] = ItemType.Mace; + mappings[1094] = ItemType.ItemFrame; + mappings[1095] = ItemType.GlowItemFrame; + mappings[1096] = ItemType.FlowerPot; + mappings[1097] = ItemType.Carrot; + mappings[1098] = ItemType.Potato; + mappings[1099] = ItemType.BakedPotato; + mappings[1100] = ItemType.PoisonousPotato; + mappings[1101] = ItemType.Map; + mappings[1102] = ItemType.GoldenCarrot; + mappings[1103] = ItemType.SkeletonSkull; + mappings[1104] = ItemType.WitherSkeletonSkull; + mappings[1105] = ItemType.PlayerHead; + mappings[1106] = ItemType.ZombieHead; + mappings[1107] = ItemType.CreeperHead; + mappings[1108] = ItemType.DragonHead; + mappings[1109] = ItemType.PiglinHead; + mappings[1110] = ItemType.NetherStar; + mappings[1111] = ItemType.PumpkinPie; + mappings[1112] = ItemType.FireworkRocket; + mappings[1113] = ItemType.FireworkStar; + mappings[1114] = ItemType.EnchantedBook; + mappings[1115] = ItemType.NetherBrick; + mappings[1116] = ItemType.PrismarineShard; + mappings[1117] = ItemType.PrismarineCrystals; + mappings[1118] = ItemType.Rabbit; + mappings[1119] = ItemType.CookedRabbit; + mappings[1120] = ItemType.RabbitStew; + mappings[1121] = ItemType.RabbitFoot; + mappings[1122] = ItemType.RabbitHide; + mappings[1123] = ItemType.ArmorStand; + mappings[1124] = ItemType.IronHorseArmor; + mappings[1125] = ItemType.GoldenHorseArmor; + mappings[1126] = ItemType.DiamondHorseArmor; + mappings[1127] = ItemType.LeatherHorseArmor; + mappings[1128] = ItemType.Lead; + mappings[1129] = ItemType.NameTag; + mappings[1130] = ItemType.CommandBlockMinecart; + mappings[1131] = ItemType.Mutton; + mappings[1132] = ItemType.CookedMutton; + mappings[1133] = ItemType.WhiteBanner; + mappings[1134] = ItemType.OrangeBanner; + mappings[1135] = ItemType.MagentaBanner; + mappings[1136] = ItemType.LightBlueBanner; + mappings[1137] = ItemType.YellowBanner; + mappings[1138] = ItemType.LimeBanner; + mappings[1139] = ItemType.PinkBanner; + mappings[1140] = ItemType.GrayBanner; + mappings[1141] = ItemType.LightGrayBanner; + mappings[1142] = ItemType.CyanBanner; + mappings[1143] = ItemType.PurpleBanner; + mappings[1144] = ItemType.BlueBanner; + mappings[1145] = ItemType.BrownBanner; + mappings[1146] = ItemType.GreenBanner; + mappings[1147] = ItemType.RedBanner; + mappings[1148] = ItemType.BlackBanner; + mappings[1149] = ItemType.EndCrystal; + mappings[1150] = ItemType.ChorusFruit; + mappings[1151] = ItemType.PoppedChorusFruit; + mappings[1152] = ItemType.TorchflowerSeeds; + mappings[1153] = ItemType.PitcherPod; + mappings[1154] = ItemType.Beetroot; + mappings[1155] = ItemType.BeetrootSeeds; + mappings[1156] = ItemType.BeetrootSoup; + mappings[1157] = ItemType.DragonBreath; + mappings[1158] = ItemType.SplashPotion; + mappings[1159] = ItemType.SpectralArrow; + mappings[1160] = ItemType.TippedArrow; + mappings[1161] = ItemType.LingeringPotion; + mappings[1162] = ItemType.Shield; + mappings[1163] = ItemType.TotemOfUndying; + mappings[1164] = ItemType.ShulkerShell; + mappings[1165] = ItemType.IronNugget; + mappings[1166] = ItemType.KnowledgeBook; + mappings[1167] = ItemType.DebugStick; + mappings[1168] = ItemType.MusicDisc13; + mappings[1169] = ItemType.MusicDiscCat; + mappings[1170] = ItemType.MusicDiscBlocks; + mappings[1171] = ItemType.MusicDiscChirp; + mappings[1172] = ItemType.MusicDiscCreator; + mappings[1173] = ItemType.MusicDiscCreatorMusicBox; + mappings[1174] = ItemType.MusicDiscFar; + mappings[1175] = ItemType.MusicDiscMall; + mappings[1176] = ItemType.MusicDiscMellohi; + mappings[1177] = ItemType.MusicDiscStal; + mappings[1178] = ItemType.MusicDiscStrad; + mappings[1179] = ItemType.MusicDiscWard; + mappings[1180] = ItemType.MusicDisc11; + mappings[1181] = ItemType.MusicDiscWait; + mappings[1182] = ItemType.MusicDiscOtherside; + mappings[1183] = ItemType.MusicDiscRelic; + mappings[1184] = ItemType.MusicDisc5; + mappings[1185] = ItemType.MusicDiscPigstep; + mappings[1186] = ItemType.MusicDiscPrecipice; + mappings[1187] = ItemType.DiscFragment5; + mappings[1188] = ItemType.Trident; + mappings[1189] = ItemType.PhantomMembrane; + mappings[1190] = ItemType.NautilusShell; + mappings[1191] = ItemType.HeartOfTheSea; + mappings[1192] = ItemType.Crossbow; + mappings[1193] = ItemType.SuspiciousStew; + mappings[1194] = ItemType.Loom; + mappings[1195] = ItemType.FlowerBannerPattern; + mappings[1196] = ItemType.CreeperBannerPattern; + mappings[1197] = ItemType.SkullBannerPattern; + mappings[1198] = ItemType.MojangBannerPattern; + mappings[1199] = ItemType.GlobeBannerPattern; + mappings[1200] = ItemType.PiglinBannerPattern; + mappings[1201] = ItemType.FlowBannerPattern; + mappings[1202] = ItemType.GusterBannerPattern; + mappings[1203] = ItemType.GoatHorn; + mappings[1204] = ItemType.Composter; + mappings[1205] = ItemType.Barrel; + mappings[1206] = ItemType.Smoker; + mappings[1207] = ItemType.BlastFurnace; + mappings[1208] = ItemType.CartographyTable; + mappings[1209] = ItemType.FletchingTable; + mappings[1210] = ItemType.Grindstone; + mappings[1211] = ItemType.SmithingTable; + mappings[1212] = ItemType.Stonecutter; + mappings[1213] = ItemType.Bell; + mappings[1214] = ItemType.Lantern; + mappings[1215] = ItemType.SoulLantern; + mappings[1216] = ItemType.SweetBerries; + mappings[1217] = ItemType.GlowBerries; + mappings[1218] = ItemType.Campfire; + mappings[1219] = ItemType.SoulCampfire; + mappings[1220] = ItemType.Shroomlight; + mappings[1221] = ItemType.Honeycomb; + mappings[1222] = ItemType.BeeNest; + mappings[1223] = ItemType.Beehive; + mappings[1224] = ItemType.HoneyBottle; + mappings[1225] = ItemType.HoneycombBlock; + mappings[1226] = ItemType.Lodestone; + mappings[1227] = ItemType.CryingObsidian; + mappings[1228] = ItemType.Blackstone; + mappings[1229] = ItemType.BlackstoneSlab; + mappings[1230] = ItemType.BlackstoneStairs; + mappings[1231] = ItemType.GildedBlackstone; + mappings[1232] = ItemType.PolishedBlackstone; + mappings[1233] = ItemType.PolishedBlackstoneSlab; + mappings[1234] = ItemType.PolishedBlackstoneStairs; + mappings[1235] = ItemType.ChiseledPolishedBlackstone; + mappings[1236] = ItemType.PolishedBlackstoneBricks; + mappings[1237] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1238] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1239] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1240] = ItemType.RespawnAnchor; + mappings[1241] = ItemType.Candle; + mappings[1242] = ItemType.WhiteCandle; + mappings[1243] = ItemType.OrangeCandle; + mappings[1244] = ItemType.MagentaCandle; + mappings[1245] = ItemType.LightBlueCandle; + mappings[1246] = ItemType.YellowCandle; + mappings[1247] = ItemType.LimeCandle; + mappings[1248] = ItemType.PinkCandle; + mappings[1249] = ItemType.GrayCandle; + mappings[1250] = ItemType.LightGrayCandle; + mappings[1251] = ItemType.CyanCandle; + mappings[1252] = ItemType.PurpleCandle; + mappings[1253] = ItemType.BlueCandle; + mappings[1254] = ItemType.BrownCandle; + mappings[1255] = ItemType.GreenCandle; + mappings[1256] = ItemType.RedCandle; + mappings[1257] = ItemType.BlackCandle; + mappings[1258] = ItemType.SmallAmethystBud; + mappings[1259] = ItemType.MediumAmethystBud; + mappings[1260] = ItemType.LargeAmethystBud; + mappings[1261] = ItemType.AmethystCluster; + mappings[1262] = ItemType.PointedDripstone; + mappings[1263] = ItemType.OchreFroglight; + mappings[1264] = ItemType.VerdantFroglight; + mappings[1265] = ItemType.PearlescentFroglight; + mappings[1266] = ItemType.Frogspawn; + mappings[1267] = ItemType.EchoShard; + mappings[1268] = ItemType.Brush; + mappings[1269] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1270] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1271] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1272] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1273] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1274] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1275] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1276] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1277] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1278] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1279] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1280] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1281] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1282] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1283] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1284] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1285] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1286] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1287] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1288] = ItemType.AnglerPotterySherd; + mappings[1289] = ItemType.ArcherPotterySherd; + mappings[1290] = ItemType.ArmsUpPotterySherd; + mappings[1291] = ItemType.BladePotterySherd; + mappings[1292] = ItemType.BrewerPotterySherd; + mappings[1293] = ItemType.BurnPotterySherd; + mappings[1294] = ItemType.DangerPotterySherd; + mappings[1295] = ItemType.ExplorerPotterySherd; + mappings[1296] = ItemType.FlowPotterySherd; + mappings[1297] = ItemType.FriendPotterySherd; + mappings[1298] = ItemType.GusterPotterySherd; + mappings[1299] = ItemType.HeartPotterySherd; + mappings[1300] = ItemType.HeartbreakPotterySherd; + mappings[1301] = ItemType.HowlPotterySherd; + mappings[1302] = ItemType.MinerPotterySherd; + mappings[1303] = ItemType.MournerPotterySherd; + mappings[1304] = ItemType.PlentyPotterySherd; + mappings[1305] = ItemType.PrizePotterySherd; + mappings[1306] = ItemType.ScrapePotterySherd; + mappings[1307] = ItemType.SheafPotterySherd; + mappings[1308] = ItemType.ShelterPotterySherd; + mappings[1309] = ItemType.SkullPotterySherd; + mappings[1310] = ItemType.SnortPotterySherd; + mappings[1311] = ItemType.CopperGrate; + mappings[1312] = ItemType.ExposedCopperGrate; + mappings[1313] = ItemType.WeatheredCopperGrate; + mappings[1314] = ItemType.OxidizedCopperGrate; + mappings[1315] = ItemType.WaxedCopperGrate; + mappings[1316] = ItemType.WaxedExposedCopperGrate; + mappings[1317] = ItemType.WaxedWeatheredCopperGrate; + mappings[1318] = ItemType.WaxedOxidizedCopperGrate; + mappings[1319] = ItemType.CopperBulb; + mappings[1320] = ItemType.ExposedCopperBulb; + mappings[1321] = ItemType.WeatheredCopperBulb; + mappings[1322] = ItemType.OxidizedCopperBulb; + mappings[1323] = ItemType.WaxedCopperBulb; + mappings[1324] = ItemType.WaxedExposedCopperBulb; + mappings[1325] = ItemType.WaxedWeatheredCopperBulb; + mappings[1326] = ItemType.WaxedOxidizedCopperBulb; + mappings[1327] = ItemType.TrialSpawner; + mappings[1328] = ItemType.TrialKey; + mappings[1329] = ItemType.OminousTrialKey; + mappings[1330] = ItemType.Vault; + mappings[1331] = ItemType.OminousBottle; + mappings[1332] = ItemType.BreezeRod; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index bfe150d1..299eeb3e 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Inventory +namespace MinecraftClient.Inventory { /// /// Generated using the --generator flag on the client @@ -774,11 +774,14 @@ MusicDiscBlocks, MusicDiscCat, MusicDiscChirp, + MusicDiscCreator, + MusicDiscCreatorMusicBox, MusicDiscFar, MusicDiscMall, MusicDiscMellohi, MusicDiscOtherside, MusicDiscPigstep, + MusicDiscPrecipice, MusicDiscRelic, MusicDiscStal, MusicDiscStrad, From c23c229eb2d0350cfd32bff07cbd4c919d3887f3 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 01:22:25 +0800 Subject: [PATCH 048/484] feat: protocol 767 (1.21) packet handling and AttributeSubComponent update - Add AttributeSubComponent121 that uses ResourceLocation(string) instead of UUID+Name, matching the 1.21 attribute modifier wire format change. Register it in SubComponentRegistry121 via new ReplaceSubComponent method. - Add ProjectilePower packet handler: reads 1 double (accelerationPower) for 1.21+, or 3 doubles (xPower/yPower/zPower) for 1.20.6. - Add CustomReportDetails and ServerLinks packet handlers in both Play and Configuration phases, consuming all fields to prevent byte offset errors on 1.21 servers. Made-with: Cursor --- .../Protocol/Handlers/Protocol18.cs | 61 ++++++++++++++++++- .../1_21/AttributeSubComponent121.cs | 38 ++++++++++++ .../Core/SubComponentRegistry.cs | 5 ++ .../Subcomponents/SubComponentRegistry121.cs | 1 + 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/AttributeSubComponent121.cs diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e34306b7..77dc845c 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -191,6 +191,7 @@ namespace MinecraftClient.Protocol.Handlers // Item palette > MC_1_21_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_Version => new ItemPalette121(), >= MC_1_20_6_Version => new ItemPalette1206(), >= MC_1_20_4_Version => new ItemPalette1204(), >= MC_1_20_Version => new ItemPalette120(), @@ -550,6 +551,28 @@ namespace MinecraftClient.Protocol.Handlers SendKnownDataPacks(vanillaPacks); break; + case ConfigurationPacketTypesIn.CustomReportDetails: + var cfgDetailsCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < cfgDetailsCount; i++) + { + dataTypes.ReadNextString(packetData); // Title + dataTypes.ReadNextString(packetData); // Description + } + break; + + case ConfigurationPacketTypesIn.ServerLinks: + var cfgLinksCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < cfgLinksCount; i++) + { + var cfgIsBuiltIn = dataTypes.ReadNextBool(packetData); + if (cfgIsBuiltIn) + dataTypes.ReadNextVarInt(packetData); // Known type ID + else + dataTypes.ReadNextChat(packetData); // Component label + dataTypes.ReadNextString(packetData); // URL + } + break; + // Ignore other packets at this stage default: return true; @@ -2827,7 +2850,43 @@ namespace MinecraftClient.Protocol.Handlers McClient.Instance?.Transfer(host, port); break; - + + case PacketTypesIn.ProjectilePower: + dataTypes.ReadNextVarInt(packetData); // Entity ID + if (protocolVersion >= MC_1_21_Version) + { + dataTypes.ReadNextDouble(packetData); // Acceleration Power + } + else + { + dataTypes.ReadNextDouble(packetData); // X Power + dataTypes.ReadNextDouble(packetData); // Y Power + dataTypes.ReadNextDouble(packetData); // Z Power + } + break; + + case PacketTypesIn.CustomReportDetails: + var detailsCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < detailsCount; i++) + { + dataTypes.ReadNextString(packetData); // Title + dataTypes.ReadNextString(packetData); // Description + } + break; + + case PacketTypesIn.ServerLinks: + var linksCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < linksCount; i++) + { + var isBuiltIn = dataTypes.ReadNextBool(packetData); + if (isBuiltIn) + dataTypes.ReadNextVarInt(packetData); // Known type ID + else + dataTypes.ReadNextChat(packetData); // Component label + dataTypes.ReadNextString(packetData); // URL + } + break; + default: return false; //Ignored packet } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/AttributeSubComponent121.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/AttributeSubComponent121.cs new file mode 100644 index 00000000..6357e47f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_21/AttributeSubComponent121.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; + +public class AttributeSubComponent121(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int TypeId { get; set; } + public string? ResourceLocation { get; set; } + public double Value { get; set; } + public int Operation { get; set; } + public int Slot { get; set; } + + protected override void Parse(Queue data) + { + TypeId = dataTypes.ReadNextVarInt(data); + ResourceLocation = dataTypes.ReadNextString(data); + Value = dataTypes.ReadNextDouble(data); + Operation = dataTypes.ReadNextVarInt(data); + Slot = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(TypeId)); + + if (string.IsNullOrEmpty(ResourceLocation?.Trim())) + throw new ArgumentNullException($"Can not serialize AttributeSubComponent121 due to ResourceLocation being null or empty!"); + + data.AddRange(DataTypes.GetString(ResourceLocation)); + data.AddRange(DataTypes.GetDouble(Value)); + data.AddRange(DataTypes.GetVarInt(Operation)); + data.AddRange(DataTypes.GetVarInt(Slot)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs index 90123fe6..49665709 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs @@ -16,6 +16,11 @@ public abstract class SubComponentRegistry(DataTypes dataTypes) _subComponentParsers.Add(name, typeof(T)); } + protected void ReplaceSubComponent(string name) where T : SubComponent + { + _subComponentParsers[name] = typeof(T); + } + public SubComponent ParseSubComponent(string name, Queue data) { if(!_subComponentParsers.TryGetValue(name, out var subComponentParserType)) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs index 7515020f..2afd2852 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry121.cs @@ -10,6 +10,7 @@ public class SubComponentRegistry121 : SubComponentRegistry1206 { public SubComponentRegistry121(DataTypes dataTypes) : base(dataTypes) { + ReplaceSubComponent(SubComponents.Attribute); RegisterSubComponent(SubComponents.SoundEvent); } } \ No newline at end of file From ee02974abe37a54e91ac088ebab33b1470df1649 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 01:29:18 +0800 Subject: [PATCH 049/484] fix: Explosion packet parsing and update attribute fallback for 1.21 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the Explosion packet handler that was truncating reads at the knockback fields, leaving BlockInteraction, particles, and SoundEvent bytes unconsumed for 1.20.4+. The old commented-out code had three bugs: conditional particle read (should always read both small and large), reading SoundEvent as a plain string (it's a Holder encoded as VarInt id + optional inline DIRECT_STREAM_CODEC), and an incorrect fixedRange version gate. Verified against decompiled ClientboundExplodePacket from both 1.20.6 and 1.21.1 — the wire format is identical across versions. Update LoadDefaultAttributes() fallback to match the 1.21.1 registry order (31 attributes), adding 9 new entries: burning_time, explosion_knockback_resistance, mining_efficiency, movement_efficiency, oxygen_bonus, sneaking_speed, submerged_mining_speed, sweeping_damage_ratio, and water_movement_efficiency. This fallback is only used when the server omits the attribute RegistryData packet. Made-with: Cursor --- MinecraftClient/Mapping/World.cs | 42 ++++++++++++------- .../Protocol/Handlers/Protocol18.cs | 31 +++++--------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index c0999761..0a83ff97 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -257,6 +257,9 @@ namespace MinecraftClient.Mapping private static void LoadDefaultAttributes() { + // Fallback for when the server doesn't send attribute registry via RegistryData. + // Matches 1.21.1 Attributes.java registration order. + // For 1.20.6+ servers, SetAttributeIdMap() overrides this with the actual registry. attributeIdMap = new Dictionary { { 0, "generic.armor" }, @@ -266,21 +269,30 @@ namespace MinecraftClient.Mapping { 4, "generic.attack_speed" }, { 5, "player.block_break_speed" }, { 6, "player.block_interaction_range" }, - { 7, "player.entity_interaction_range" }, - { 8, "generic.fall_damage_multiplier" }, - { 9, "generic.flying_speed" }, - { 10, "generic.follow_range" }, - { 11, "generic.gravity" }, - { 12, "generic.jump_strength" }, - { 13, "generic.knockback_resistance" }, - { 14, "generic.luck" }, - { 15, "generic.max_absorption" }, - { 16, "generic.max_health" }, - { 17, "generic.movement_speed" }, - { 18, "generic.safe_fall_distance" }, - { 19, "generic.scale" }, - { 20, "zombie.spawn_reinforcements" }, - { 21, "generic.step_height" } + { 7, "generic.burning_time" }, + { 8, "generic.explosion_knockback_resistance" }, + { 9, "player.entity_interaction_range" }, + { 10, "generic.fall_damage_multiplier" }, + { 11, "generic.flying_speed" }, + { 12, "generic.follow_range" }, + { 13, "generic.gravity" }, + { 14, "generic.jump_strength" }, + { 15, "generic.knockback_resistance" }, + { 16, "generic.luck" }, + { 17, "generic.max_absorption" }, + { 18, "generic.max_health" }, + { 19, "player.mining_efficiency" }, + { 20, "generic.movement_efficiency" }, + { 21, "generic.movement_speed" }, + { 22, "generic.oxygen_bonus" }, + { 23, "generic.safe_fall_distance" }, + { 24, "generic.scale" }, + { 25, "player.sneaking_speed" }, + { 26, "zombie.spawn_reinforcements" }, + { 27, "generic.step_height" }, + { 28, "player.submerged_mining_speed" }, + { 29, "player.sweeping_damage_ratio" }, + { 30, "generic.water_movement_efficiency" } }; } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 77dc845c..735ce498 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2687,39 +2687,30 @@ namespace MinecraftClient.Protocol.Handlers for (var i = 0; i < explosionBlockCount; i++) dataTypes.ReadNextByteArray(packetData, 3); - // Maybe use in the future when the physics are implemented dataTypes.ReadNextFloat(packetData); // Player Motion X dataTypes.ReadNextFloat(packetData); // Player Motion Y dataTypes.ReadNextFloat(packetData); // Player Motion Z - // Cut off here, there is an issue, the code bllow crashes on sound name reading - // I am unable to figure out what part of the code is reading more bytes than it should - // TODO: Fix - handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); - break; - - /*if (protocolVersion >= MC_1_20_4_Version) + if (protocolVersion >= MC_1_20_4_Version) { - var blockInteraction = dataTypes.ReadNextVarInt(packetData); // Block Interaction - - if(explosionStrength >= 2.0 || blockInteraction != 0) - dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles - else - dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles + dataTypes.ReadNextVarInt(packetData); // Block Interaction (enum ordinal) + dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles + dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles - // Explosion Sound - dataTypes.ReadNextString(packetData); // Sound Name - - if (protocolVersion < MC_1_21_Version) + // Explosion Sound: Holder via ByteBufCodecs.holder() + // VarInt id: 0 = inline (read DIRECT_STREAM_CODEC), >0 = registry ref (id-1) + var soundHolderId = dataTypes.ReadNextVarInt(packetData); + if (soundHolderId == 0) { + dataTypes.ReadNextString(packetData); // Sound ResourceLocation var hasFixedRange = dataTypes.ReadNextBool(packetData); if (hasFixedRange) - dataTypes.ReadNextFloat(packetData); // Range + dataTypes.ReadNextFloat(packetData); // Fixed range } } handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); - break;*/ + break; case PacketTypesIn.HeldItemChange: handler.OnHeldItemChange(dataTypes.ReadNextByte(packetData)); // Slot break; From e1cb18c6f8c4c2014848be0aa170a69d9ed5faf7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 01:43:48 +0800 Subject: [PATCH 050/484] fix: add EntityMetadataPalette1206 for correct 1.20.6+ entity metadata parsing 1.20.6 introduced three new EntityDataSerializer types compared to 1.20.4: - PARTICLES (id 18) - list of particles, inserted after PARTICLE - WOLF_VARIANT (id 23) - wolf variant holder, inserted after CAT_VARIANT - ARMADILLO_STATE (id 28) - armadillo state, inserted after SNIFFER_STATE These insertions shifted subsequent serializer IDs, causing the 1.19.4 palette (EntityMetadataPalette1194) to misidentify metadata types on 1.20.6+ servers. This could lead to incorrect byte consumption and potential packet parse failures when entities with affected metadata types (e.g. wolves, armadillos, area effect clouds with particles) were present. Changes: - Add Particles, WolfVariant, ArmadilloState to EntityMetaDataType enum - Create EntityMetadataPalette1206 with correct 31-entry ID mapping - Route 1.20.6+ to the new palette in EntityMetadataPalette.GetPalette() - Add read logic for the three new types in DataTypes.cs Verified on 1.21.1 vanilla server: cat, wolf, frog, armadillo, painting entities all spawn without metadata parse errors. Made-with: Cursor --- MinecraftClient/Mapping/EntityMetaDataType.cs | 12 +++++ .../Mapping/EntityMetadataPalette.cs | 3 +- .../EntityMetadataPalette1206.cs | 51 +++++++++++++++++++ .../Protocol/Handlers/DataTypes.cs | 14 ++++- 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs diff --git a/MinecraftClient/Mapping/EntityMetaDataType.cs b/MinecraftClient/Mapping/EntityMetaDataType.cs index db24f77b..53afecfa 100644 --- a/MinecraftClient/Mapping/EntityMetaDataType.cs +++ b/MinecraftClient/Mapping/EntityMetaDataType.cs @@ -36,6 +36,10 @@ public enum EntityMetaDataType Nbt, Particle, /// + /// List of Particle (1.20.6+) + /// + Particles, + /// /// VarInt x3 /// VillagerData, @@ -48,6 +52,10 @@ public enum EntityMetaDataType /// VarInt /// CatVariant, + /// + /// VarInt (1.20.6+) + /// + WolfVariant, FrogVariant, /// /// String + Position @@ -66,6 +74,10 @@ public enum EntityMetaDataType /// SnifferState, /// + /// VarInt (1.20.6+) + /// + ArmadilloState, + /// /// Float x3 /// Vector3, diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index db544f39..e7e5c978 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,8 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_12_2_Version => new EntityMetadataPalette1122(), // 1.9 - 1.12.2 <= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2 <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 - <= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.21 + + < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 + <= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs new file mode 100644 index 00000000..67b61cc3 --- /dev/null +++ b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityMetadataPalettes; + +/// +/// For 1.20.6+ +/// Added PARTICLES (id 18), WOLF_VARIANT (id 23), ARMADILLO_STATE (id 28) +/// compared to 1.19.4 palette. +/// +public class EntityMetadataPalette1206 : EntityMetadataPalette +{ + private readonly Dictionary entityMetadataMappings = new() + { + { 0, EntityMetaDataType.Byte }, + { 1, EntityMetaDataType.VarInt }, + { 2, EntityMetaDataType.VarLong }, + { 3, EntityMetaDataType.Float }, + { 4, EntityMetaDataType.String }, + { 5, EntityMetaDataType.Chat }, + { 6, EntityMetaDataType.OptionalChat }, + { 7, EntityMetaDataType.Slot }, + { 8, EntityMetaDataType.Boolean }, + { 9, EntityMetaDataType.Rotation }, + { 10, EntityMetaDataType.Position }, + { 11, EntityMetaDataType.OptionalPosition }, + { 12, EntityMetaDataType.Direction }, + { 13, EntityMetaDataType.OptionalUuid }, + { 14, EntityMetaDataType.BlockId }, + { 15, EntityMetaDataType.OptionalBlockId }, + { 16, EntityMetaDataType.Nbt }, + { 17, EntityMetaDataType.Particle }, + { 18, EntityMetaDataType.Particles }, + { 19, EntityMetaDataType.VillagerData }, + { 20, EntityMetaDataType.OptionalVarInt }, + { 21, EntityMetaDataType.Pose }, + { 22, EntityMetaDataType.CatVariant }, + { 23, EntityMetaDataType.WolfVariant }, + { 24, EntityMetaDataType.FrogVariant }, + { 25, EntityMetaDataType.OptionalGlobalPosition }, + { 26, EntityMetaDataType.PaintingVariant }, + { 27, EntityMetaDataType.SnifferState }, + { 28, EntityMetaDataType.ArmadilloState }, + { 29, EntityMetaDataType.Vector3 }, + { 30, EntityMetaDataType.Quaternion }, + }; + + public override Dictionary GetEntityMetadataMappingsList() + { + return entityMetadataMappings; + } +} diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index d36ab257..271d98f8 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -842,9 +842,13 @@ namespace MinecraftClient.Protocol.Handlers value = ReadNextNbt(cache); break; case EntityMetaDataType.Particle: // Particle - // Skip data only, not used ReadParticleData(cache, itemPalette); break; + case EntityMetaDataType.Particles: // List of Particle (1.20.6+) + int particleCount = ReadNextVarInt(cache); + for (int i = 0; i < particleCount; i++) + ReadParticleData(cache, itemPalette); + break; case EntityMetaDataType.VillagerData: // Villager Data (3x VarInt) value = new List { @@ -869,7 +873,10 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.CatVariant: // Cat Variant value = ReadNextVarInt(cache); break; - case EntityMetaDataType.FrogVariant: // Frog Varint + case EntityMetaDataType.WolfVariant: // Wolf Variant (1.20.6+) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.FrogVariant: // Frog Variant value = ReadNextVarInt(cache); break; case EntityMetaDataType.GlobalPosition: // GlobalPos @@ -892,6 +899,9 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.SnifferState: // Sniffer state value = ReadNextVarInt(cache); break; + case EntityMetaDataType.ArmadilloState: // Armadillo state (1.20.6+) + value = ReadNextVarInt(cache); + break; case EntityMetaDataType.Vector3: // Vector 3f value = new List { From 76098329765af12d4919b3909385b538ddb0b815 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 01:49:14 +0800 Subject: [PATCH 051/484] chore: add reusable version adaptation scripts Add tools/ directory with Python scripts for comparing Minecraft version registries and generating MCC palette files: - diff_registries.py: Compare Items/EntityTypes/Blocks/DataComponents/ EntityDataSerializers between two decompiled MC versions, reporting which palettes need updating with ID shift analysis. - gen_item_palette.py: Generate ItemPaletteXXX.cs from Items.java field declaration order, with name validation against ItemType.cs. - gen_entity_metadata_palette.py: Generate EntityMetadataPaletteXXX.cs from EntityDataSerializers.java registration order. - README.md: Usage documentation for all scripts. Made-with: Cursor --- .../skills/mcc-version-adaptation/SKILL.md | 130 +++++++++++ .gitignore | 3 + tools/README.md | 47 ++++ tools/diff_registries.py | 221 ++++++++++++++++++ tools/gen_entity_metadata_palette.py | 142 +++++++++++ tools/gen_item_palette.py | 124 ++++++++++ 6 files changed, 667 insertions(+) create mode 100644 .cursor/skills/mcc-version-adaptation/SKILL.md create mode 100644 tools/README.md create mode 100644 tools/diff_registries.py create mode 100644 tools/gen_entity_metadata_palette.py create mode 100644 tools/gen_item_palette.py diff --git a/.cursor/skills/mcc-version-adaptation/SKILL.md b/.cursor/skills/mcc-version-adaptation/SKILL.md new file mode 100644 index 00000000..b7f26464 --- /dev/null +++ b/.cursor/skills/mcc-version-adaptation/SKILL.md @@ -0,0 +1,130 @@ +--- +name: mcc-version-adaptation +description: Adapt MCC palettes and protocol handling for a new Minecraft version. Use when the user wants to add support for a new MC version, compare version registries, update item/entity/block/metadata palettes, or fix protocol mismatches between MC versions. +--- + +# MCC Version Adaptation + +Systematic workflow for updating Minecraft Console Client to support a new Minecraft version, focusing on palette/registry changes and entity metadata. + +## Prerequisites + +- Decompiled server source for both the old and new MC versions in `$MCC_REPO/MinecraftOfficial/-decompiled/` +- If missing, decompile first: + ```bash + cd $MCC_REPO/MinecraftOfficial + java -jar MinecraftDecompiler.jar --version --side SERVER \ + --decompile --output -remapped.jar --decompiled-output -decompiled + ``` + +## Step 1: Run Registry Diff + +```bash +python3 $MCC_REPO/tools/diff_registries.py +``` + +This compares five registries and reports which need palette updates: + +| Registry | MCC File | When to Update | +|----------|----------|----------------| +| Items.java | `ItemPalettes/ItemPaletteXXX.cs` | New/removed/reordered items | +| EntityType.java | `EntityPalettes/EntityPaletteXXX.cs` | New/removed/reordered entity types | +| Blocks.java | `BlockPalettes/BlockPaletteXXX.cs` | New/removed/reordered blocks | +| DataComponents.java | `StructuredComponents/StructuredComponentsRegistryXXX.cs` | New/reordered components | +| EntityDataSerializers.java | `EntityMetadataPalettes/EntityMetadataPaletteXXX.cs` | New/reordered serializer types | + +## Step 2: Generate Updated Palettes + +For registries marked "PALETTE UPDATE NEEDED": + +### Item Palette +```bash +python3 $MCC_REPO/tools/gen_item_palette.py +# e.g., gen_item_palette.py 1.21.1 121 +``` +- If new items are reported missing from `ItemType.cs`, add them to the enum in alphabetical order. +- The script auto-generates the C# palette file. + +### Entity Metadata Palette +```bash +python3 $MCC_REPO/tools/gen_entity_metadata_palette.py +# e.g., gen_entity_metadata_palette.py 1.20.6 1206 +``` +- If new serializer types appear as UNMAPPED, add them to both: + 1. The script's `FIELD_TO_ENUM` dictionary + 2. MCC's `EntityMetaDataType.cs` enum + 3. `DataTypes.cs` read logic (add a `case` to consume the correct bytes) + +### Entity/Block Palettes +No generator script yet — these change rarely. When needed, manually create by following the pattern of existing palette files, using `register("name", ...)` call order from the decompiled source. + +### DataComponents / StructuredComponents +Compare `DataComponents.java` registration order. If new components appear, update `StructuredComponentsRegistryXXX.cs`. For new component types, implement corresponding reader in `StructuredComponents/Components/`. + +## Step 3: Update Version Routing + +After creating palette files, update version selection logic: + +| Palette Type | Routing Location | +|-------------|-----------------| +| Item | `Protocol18.cs` → `itemPalette` switch expression | +| Entity | `Protocol18.cs` → `entityPalette` switch expression | +| Block | `Protocol18.cs` → `blockPalette` initialization | +| EntityMetadata | `EntityMetadataPalette.cs` → `GetPalette()` switch | +| DataComponents | `StructuredComponentsRegistry.cs` → factory/routing | + +Pattern: add a new `>= MC_X_Y_Z_Version => new XxxPaletteXYZ()` case. + +## Step 4: Check Variant Encoding Changes + +For entity types that use variant serializers (Cat, Wolf, Frog, Painting), check if the codec changed between versions by inspecting: + +- `EntityDataSerializers.java` — look at how each `*_VARIANT` field is constructed +- Key codecs: + - `ByteBufCodecs.holderRegistry()` → wire format: `VarInt(registry_id)` + - `ByteBufCodecs.holder()` → wire format: `VarInt(id+1)` for registered, `VarInt(0) + inline_data` for direct +- If codec changed, update `DataTypes.cs` entity metadata reading logic accordingly. + +## Step 5: Handle New EntityDataSerializer Types + +When new serializer types are added (detected in Step 1): + +1. Add enum value to `EntityMetaDataType.cs` with XML doc comment +2. Add read logic in `DataTypes.cs` `ReadNextMetadata()`: + - Determine byte consumption from the decompiled codec + - Examples: VarInt read, list of particles, etc. +3. Create the new palette file (Step 2) +4. Update palette routing (Step 3) + +## Step 6: Compile and Verify + +```bash +dotnet build $MCC_REPO/MinecraftClient.sln -c Release +``` + +Then connect to a test server of the target version (see `mcc-dev-workflow` skill) and verify: +- Successful connection +- `/give` new items → check inventory +- Summon entities (especially variant types) → no metadata parse errors +- Particle effects → no crashes + +## Key Source Files Reference + +| Decompiled Java Source | Purpose | +|----------------------|---------| +| `world/item/Items.java` | Item registry (field declaration order = ID) | +| `world/entity/EntityType.java` | Entity type registry (`register()` call order = ID) | +| `world/level/block/Blocks.java` | Block registry (`register()` call order = ID) | +| `core/component/DataComponents.java` | Data component registry | +| `network/syncher/EntityDataSerializers.java` | Entity metadata type registry (static block order = ID) | + +## Common Pitfalls + +- **ID order matters**: IDs are determined by declaration/registration order, not alphabetical. Always use the decompiled source as ground truth. +- **Cross-version jumps**: When MCC skips versions (e.g., 1.20.4→1.20.6), registries from ALL intermediate versions may have changed. Always diff against the actual last-supported version, not the latest palette. +- **EntityMetadata type shifts**: A single new serializer type shifts all subsequent IDs, causing widespread metadata parse failures. Symptoms: entity rendering glitches, disconnections, or silent data corruption. +- **CUT_STANDSTONE_SLAB**: This is an intentional typo in Minecraft source (should be SANDSTONE). MCC's `ItemType.cs` uses `CutSandstoneSlab` — the gen script handles this via the OVERRIDES dict. + +## Reusable Scripts + +All scripts are in `$MCC_REPO/tools/`. See `tools/README.md` for detailed usage. diff --git a/.gitignore b/.gitignore index fc8f35e0..2ebfd2d8 100644 --- a/.gitignore +++ b/.gitignore @@ -387,6 +387,9 @@ FodyWeavers.xsd !.vscode/extensions.json *.code-workspace +# Cursor files +!.cursor/ + # Local History for Visual Studio Code .history/ diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 00000000..cce914df --- /dev/null +++ b/tools/README.md @@ -0,0 +1,47 @@ +# MCC Version Adaptation Tools + +Scripts for analyzing Minecraft version differences and generating MCC palette files. + +Requires: Python 3.10+, decompiled MC server source in `MinecraftOfficial/-decompiled/`. + +## Decompiling a new MC version + +```bash +cd MinecraftOfficial +java -jar MinecraftDecompiler.jar --version 1.21.4 --side SERVER \ + --decompile --output 1.21.4-remapped.jar --decompiled-output 1.21.4-decompiled +``` + +## diff_registries.py — Compare registries between versions + +Compares Items, EntityTypes, Blocks, DataComponents, and EntityDataSerializers between two MC versions. Reports whether each palette needs updating, lists added/removed entries, and shows ID shift statistics. + +```bash +python3 tools/diff_registries.py 1.20.6 1.21.1 +``` + +Output indicates for each registry: +- **IDENTICAL** → reuse existing palette +- **PALETTE UPDATE NEEDED** → create new palette file + update version routing + +## gen_item_palette.py — Generate ItemPalette C# file + +Reads `Items.java` field declaration order to generate a complete `ItemPaletteXXX.cs`. + +```bash +python3 tools/gen_item_palette.py 1.21.1 121 +# → MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs +``` + +Also validates each item name against `ItemType.cs` and warns about missing enum values. + +## gen_entity_metadata_palette.py — Generate EntityMetadataPalette C# file + +Reads `EntityDataSerializers.java` static block registration order to generate `EntityMetadataPaletteXXX.cs`. + +```bash +python3 tools/gen_entity_metadata_palette.py 1.20.6 1206 +# → MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs +``` + +The script maps Java field names to MCC's `EntityMetaDataType` enum. If a new serializer type appears that isn't in the mapping table, it will warn you to update both the script's `FIELD_TO_ENUM` dict and MCC's `EntityMetaDataType.cs` enum. diff --git a/tools/diff_registries.py b/tools/diff_registries.py new file mode 100644 index 00000000..cc26c31f --- /dev/null +++ b/tools/diff_registries.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python3 +""" +Compare Minecraft registry data between two decompiled server versions. + +Compares Items, EntityTypes, Blocks, DataComponents, and EntityDataSerializers +to determine which MCC palettes need updating for a new MC version. + +Usage: + python3 tools/diff_registries.py + +Example: + python3 tools/diff_registries.py 1.20.6 1.21.1 +""" + +import re +import sys +import os +from pathlib import Path + +DECOMPILED_ROOT = Path(__file__).resolve().parent.parent / "MinecraftOfficial" + + +def find_java_file(version_dir: Path, *possible_paths: str) -> Path | None: + for p in possible_paths: + full = version_dir / p + if full.exists(): + return full + return None + + +def extract_field_names(filepath: Path, pattern: str) -> list[str]: + """Extract field names from public static final declarations.""" + results = [] + with open(filepath) as f: + for line in f: + m = re.match(pattern, line) + if m: + results.append(m.group(1)) + return results + + +def extract_register_multiline(filepath: Path) -> list[str]: + """Extract register("name", ...) calls, handling multiline Java formatting.""" + with open(filepath) as f: + content = f.read() + flat = re.sub(r'\s+', ' ', content) + return re.findall(r'(?:= |return )register\(\s*"([^"]+)"', flat) + + +def extract_static_register_order(filepath: Path) -> list[str]: + """Extract registerSerializer(FIELD_NAME) calls from the static {} block.""" + results = [] + in_static = False + with open(filepath) as f: + for line in f: + if 'static {' in line: + in_static = True + continue + if in_static and 'registerSerializer(' in line: + m = re.search(r'registerSerializer\((\w+)\)', line) + if m: + results.append(m.group(1)) + if in_static and '}' in line and 'registerSerializer' not in line: + break + return results + + +def compare_lists(old: list[str], new: list[str], label: str): + """Compare two ordered lists and report differences.""" + set_old, set_new = set(old), set(new) + added = sorted(set_new - set_old) + removed = sorted(set_old - set_new) + + print(f"\n{'='*60}") + print(f" {label}") + print(f"{'='*60}") + print(f" Old: {len(old)} entries, New: {len(new)} entries") + + if not added and not removed: + if old == new: + print(f" Result: IDENTICAL — no palette update needed") + else: + print(f" Result: Same set but DIFFERENT ORDER — palette update needed!") + for i, (a, b) in enumerate(zip(old, new)): + if a != b: + print(f" First diff at index {i}: old={a}, new={b}") + break + return False + + if added: + print(f" Added ({len(added)}): {added}") + for item in added: + idx = new.index(item) + prev_name = new[idx - 1] if idx > 0 else "(start)" + next_name = new[idx + 1] if idx < len(new) - 1 else "(end)" + print(f" \"{item}\" at index {idx}, between \"{prev_name}\" and \"{next_name}\"") + if removed: + print(f" Removed ({len(removed)}): {removed}") + + common_old = [x for x in old if x in set_new] + common_new = [x for x in new if x in set_old] + if common_old != common_new: + print(f" Common items REORDERED — palette update needed!") + else: + print(f" Common items have same relative order") + + # ID shift analysis + id_old = {name: i for i, name in enumerate(old)} + id_new = {name: i for i, name in enumerate(new)} + shifted = [(n, id_old[n], id_new[n]) for n in sorted(set_old & set_new) if id_old[n] != id_new[n]] + if shifted: + from collections import Counter + deltas = Counter(new_id - old_id for _, old_id, new_id in shifted) + print(f" {len(shifted)} entries with changed IDs, delta distribution: {sorted(deltas.items())}") + + print(f" Result: PALETTE UPDATE NEEDED") + return True + + +def diff_items(old_dir: Path, new_dir: Path): + old_f = find_java_file(old_dir, "net/minecraft/world/item/Items.java") + new_f = find_java_file(new_dir, "net/minecraft/world/item/Items.java") + if not old_f or not new_f: + print(" [SKIP] Items.java not found") + return + pattern = r'\s+public static final Item (\w+)\s*=' + old = extract_field_names(old_f, pattern) + new = extract_field_names(new_f, pattern) + compare_lists(old, new, "Items.java (Item registry)") + + +def diff_entity_types(old_dir: Path, new_dir: Path): + old_f = find_java_file(old_dir, "net/minecraft/world/entity/EntityType.java") + new_f = find_java_file(new_dir, "net/minecraft/world/entity/EntityType.java") + if not old_f or not new_f: + print(" [SKIP] EntityType.java not found") + return + old = extract_register_multiline(old_f) + new = extract_register_multiline(new_f) + compare_lists(old, new, "EntityType.java (Entity registry)") + + +def diff_blocks(old_dir: Path, new_dir: Path): + old_f = find_java_file(old_dir, "net/minecraft/world/level/block/Blocks.java") + new_f = find_java_file(new_dir, "net/minecraft/world/level/block/Blocks.java") + if not old_f or not new_f: + print(" [SKIP] Blocks.java not found") + return + old = extract_register_multiline(old_f) + new = extract_register_multiline(new_f) + compare_lists(old, new, "Blocks.java (Block registry)") + + +def diff_data_components(old_dir: Path, new_dir: Path): + old_f = find_java_file(old_dir, "net/minecraft/core/component/DataComponents.java") + new_f = find_java_file(new_dir, "net/minecraft/core/component/DataComponents.java") + if not old_f or not new_f: + print(" [SKIP] DataComponents.java not found") + return + old = extract_register_multiline(old_f) + new = extract_register_multiline(new_f) + needs_update = compare_lists(old, new, "DataComponents.java (StructuredComponents registry)") + if needs_update or True: + print("\n Registration order (new version):") + for i, name in enumerate(new): + marker = " <-- NEW" if name not in set(old) else "" + print(f" {i}: {name}{marker}") + + +def diff_entity_data_serializers(old_dir: Path, new_dir: Path): + old_f = find_java_file(old_dir, "net/minecraft/network/syncher/EntityDataSerializers.java") + new_f = find_java_file(new_dir, "net/minecraft/network/syncher/EntityDataSerializers.java") + if not old_f or not new_f: + print(" [SKIP] EntityDataSerializers.java not found") + return + old = extract_static_register_order(old_f) + new = extract_static_register_order(new_f) + needs_update = compare_lists(old, new, "EntityDataSerializers.java (EntityMetadata palette)") + print("\n Registration order (new version):") + for i, name in enumerate(new): + marker = " <-- NEW" if name not in set(old) else "" + print(f" {i}: {name}{marker}") + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + + old_ver, new_ver = sys.argv[1], sys.argv[2] + old_dir = DECOMPILED_ROOT / f"{old_ver}-decompiled" + new_dir = DECOMPILED_ROOT / f"{new_ver}-decompiled" + + for d, v in [(old_dir, old_ver), (new_dir, new_ver)]: + if not d.exists(): + print(f"Error: {d} not found. Decompile {v} first:") + print(f" cd MinecraftOfficial && java -jar MinecraftDecompiler.jar " + f"--version {v} --side SERVER --decompile " + f"--output {v}-remapped.jar --decompiled-output {v}-decompiled") + sys.exit(1) + + print(f"Comparing MC {old_ver} → {new_ver}") + print(f"Old: {old_dir}") + print(f"New: {new_dir}") + + diff_items(old_dir, new_dir) + diff_entity_types(old_dir, new_dir) + diff_blocks(old_dir, new_dir) + diff_data_components(old_dir, new_dir) + diff_entity_data_serializers(old_dir, new_dir) + + print(f"\n{'='*60}") + print(" Summary") + print(f"{'='*60}") + print(" Review each section above. For any marked 'PALETTE UPDATE NEEDED',") + print(" create a new palette file in MCC and update the version routing.") + print(" For 'IDENTICAL' sections, the existing palette can be reused.") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_entity_metadata_palette.py b/tools/gen_entity_metadata_palette.py new file mode 100644 index 00000000..ab914cf8 --- /dev/null +++ b/tools/gen_entity_metadata_palette.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +""" +Generate an MCC EntityMetadataPalette C# file from decompiled EntityDataSerializers.java. + +Reads the static {} block registration order to determine serializer IDs, +then maps Java field names to MCC's EntityMetaDataType enum values. + +Usage: + python3 tools/gen_entity_metadata_palette.py + +Example: + python3 tools/gen_entity_metadata_palette.py 1.20.6 1206 + # Generates EntityMetadataPalette1206.cs +""" + +import re +import sys +from pathlib import Path + +DECOMPILED_ROOT = Path(__file__).resolve().parent.parent / "MinecraftOfficial" +OUTPUT_DIR = (Path(__file__).resolve().parent.parent / + "MinecraftClient" / "Mapping" / "EntityMetadataPalettes") + +# Java field name → MCC EntityMetaDataType enum name +FIELD_TO_ENUM = { + "BYTE": "Byte", + "INT": "VarInt", + "LONG": "VarLong", + "FLOAT": "Float", + "STRING": "String", + "COMPONENT": "Chat", + "OPTIONAL_COMPONENT": "OptionalChat", + "ITEM_STACK": "Slot", + "BOOLEAN": "Boolean", + "ROTATIONS": "Rotation", + "BLOCK_POS": "Position", + "OPTIONAL_BLOCK_POS": "OptionalPosition", + "DIRECTION": "Direction", + "OPTIONAL_UUID": "OptionalUuid", + "BLOCK_STATE": "BlockId", + "OPTIONAL_BLOCK_STATE": "OptionalBlockId", + "COMPOUND_TAG": "Nbt", + "PARTICLE": "Particle", + "PARTICLES": "Particles", + "VILLAGER_DATA": "VillagerData", + "OPTIONAL_UNSIGNED_INT": "OptionalVarInt", + "POSE": "Pose", + "CAT_VARIANT": "CatVariant", + "WOLF_VARIANT": "WolfVariant", + "FROG_VARIANT": "FrogVariant", + "OPTIONAL_GLOBAL_POS": "OptionalGlobalPosition", + "PAINTING_VARIANT": "PaintingVariant", + "SNIFFER_STATE": "SnifferState", + "ARMADILLO_STATE": "ArmadilloState", + "VECTOR3": "Vector3", + "QUATERNION": "Quaternion", +} + + +def extract_static_register_order(filepath: Path) -> list[str]: + results = [] + in_static = False + with open(filepath) as f: + for line in f: + if 'static {' in line: + in_static = True + continue + if in_static and 'registerSerializer(' in line: + m = re.search(r'registerSerializer\((\w+)\)', line) + if m: + results.append(m.group(1)) + if in_static and '}' in line and 'registerSerializer' not in line: + break + return results + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + + mc_version = sys.argv[1] + class_suffix = sys.argv[2] + version_dir = DECOMPILED_ROOT / f"{mc_version}-decompiled" + eds_java = version_dir / "net" / "minecraft" / "network" / "syncher" / "EntityDataSerializers.java" + + if not eds_java.exists(): + print(f"Error: {eds_java} not found") + sys.exit(1) + + fields = extract_static_register_order(eds_java) + print(f"Found {len(fields)} entity data serializers in MC {mc_version}:") + + unmapped = [] + mappings = [] + for i, field in enumerate(fields): + if field in FIELD_TO_ENUM: + enum_name = FIELD_TO_ENUM[field] + mappings.append((i, enum_name)) + print(f" {i}: {field} -> EntityMetaDataType.{enum_name}") + else: + unmapped.append((i, field)) + print(f" {i}: {field} -> ??? UNMAPPED") + + if unmapped: + print(f"\nWARNING: {len(unmapped)} unmapped fields:") + for idx, field in unmapped: + print(f" [{idx}] {field}") + print("\nAdd entries to FIELD_TO_ENUM in this script and to EntityMetaDataType.cs enum.") + + class_name = f"EntityMetadataPalette{class_suffix}" + output_path = OUTPUT_DIR / f"{class_name}.cs" + + lines = [ + "using System.Collections.Generic;", + "", + f"namespace MinecraftClient.Mapping.EntityMetadataPalettes;", + "", + f"public class {class_name} : EntityMetadataPalette", + "{", + " private readonly Dictionary entityMetadataMappings = new()", + " {", + ] + for idx, enum_name in mappings: + lines.append(f" {{ {idx}, EntityMetaDataType.{enum_name} }},") + lines += [ + " };", + "", + " public override Dictionary GetEntityMetadataMappingsList()", + " {", + " return entityMetadataMappings;", + " }", + "}", + "", + ] + + output_path.write_text("\n".join(lines)) + print(f"\nGenerated {output_path} with {len(mappings)} mappings") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_item_palette.py b/tools/gen_item_palette.py new file mode 100644 index 00000000..92643977 --- /dev/null +++ b/tools/gen_item_palette.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +""" +Generate an MCC ItemPalette C# file from decompiled Items.java. + +Reads public static final Item field declarations (which define item IDs +by declaration order) and generates a complete C# palette class. + +Usage: + python3 tools/gen_item_palette.py + +Example: + python3 tools/gen_item_palette.py 1.21.1 121 + # Generates ItemPalette121.cs + +The determines the class name (ItemPalette) and +should match MCC's naming convention (e.g., 121 for 1.21, 1206 for 1.20.6). +""" + +import re +import sys +from pathlib import Path + +DECOMPILED_ROOT = Path(__file__).resolve().parent.parent / "MinecraftOfficial" +OUTPUT_DIR = Path(__file__).resolve().parent.parent / "MinecraftClient" / "Inventory" / "ItemPalettes" + +# Java field name → C# ItemType enum name +# Most conversions are automatic (SCREAMING_SNAKE → PascalCase). +# Add manual overrides here for irregular names. +OVERRIDES = { + "CUT_STANDSTONE_SLAB": "CutSandstoneSlab", # Mojang typo in source +} + + +def java_to_csharp_name(java_name: str) -> str: + """Convert SCREAMING_SNAKE_CASE Java field name to PascalCase C# enum name.""" + if java_name in OVERRIDES: + return OVERRIDES[java_name] + return "".join(word.capitalize() for word in java_name.lower().split("_")) + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + + mc_version = sys.argv[1] + class_suffix = sys.argv[2] + version_dir = DECOMPILED_ROOT / f"{mc_version}-decompiled" + items_java = version_dir / "net" / "minecraft" / "world" / "item" / "Items.java" + + if not items_java.exists(): + print(f"Error: {items_java} not found") + sys.exit(1) + + pattern = re.compile(r'\s+public static final Item (\w+)\s*=') + field_names = [] + with open(items_java) as f: + for line in f: + m = pattern.match(line) + if m: + field_names.append(m.group(1)) + + print(f"Found {len(field_names)} items in MC {mc_version}") + + # Verify enum name conversion against existing ItemType.cs + item_type_cs = OUTPUT_DIR.parent / "ItemType.cs" + known_enums = set() + if item_type_cs.exists(): + with open(item_type_cs) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m and m.group(1) not in ("Null", "Unknown"): + known_enums.add(m.group(1)) + + missing = [] + mappings = [] + for i, name in enumerate(field_names): + cs_name = java_to_csharp_name(name) + mappings.append((i, cs_name)) + if known_enums and cs_name not in known_enums: + missing.append((i, name, cs_name)) + + if missing: + print(f"\nWARNING: {len(missing)} items not found in ItemType.cs enum:") + for idx, java_name, cs_name in missing: + print(f" [{idx}] {java_name} -> {cs_name}") + print("\nYou need to add these to ItemType.cs before the palette will compile.") + print("Insert them in alphabetical order within the enum.") + + class_name = f"ItemPalette{class_suffix}" + output_path = OUTPUT_DIR / f"{class_name}.cs" + + lines = [ + "using System.Collections.Generic;", + "", + "namespace MinecraftClient.Inventory.ItemPalettes", + "{", + f" public class {class_name} : ItemPalette", + " {", + " private static readonly Dictionary mappings = new();", + "", + f" static {class_name}()", + " {", + ] + for idx, cs_name in mappings: + lines.append(f" mappings[{idx}] = ItemType.{cs_name};") + lines += [ + " }", + "", + " protected override Dictionary GetDict()", + " {", + " return mappings;", + " }", + " }", + "}", + "", + ] + + output_path.write_text("\n".join(lines)) + print(f"Generated {output_path} with {len(mappings)} mappings") + + +if __name__ == "__main__": + main() From 896263acc8006a9a03670b4ae5c8251faf5c9fd9 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 02:35:52 +0800 Subject: [PATCH 052/484] fix: resolve entity tracking, container interaction, and enchantment mapping issues for 1.21 - SpawnEntity packet handler now registers non-player entities via OnSpawnEntity for protocol >= 1.20.2 (previously only players were tracked, causing 'entity near' to find nothing) - PlaceBlock gains lookAtBlock option that sends a position/rotation update before the block placement packet, fixing containers not opening via useblock - Enchantment registry IDs are now dynamically parsed from server RegistryData (minecraft:enchantment), fixing incorrect enchantment name display in 1.21 - AttributeModifiersComponent uses base SubComponent type to avoid InvalidCastException when parsing 1.21-specific attribute subcomponents Made-with: Cursor --- MinecraftClient/Commands/Useblock.cs | 4 +- .../Inventory/EnchantmentMapping.cs | 77 ++++++++++++++++++- MinecraftClient/McClient.cs | 13 +++- .../Protocol/Handlers/Protocol18.cs | 9 ++- .../1_20_6/AttributeModifiersComponent.cs | 5 +- 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/MinecraftClient/Commands/Useblock.cs b/MinecraftClient/Commands/Useblock.cs index 994e34ae..2df6a92f 100644 --- a/MinecraftClient/Commands/Useblock.cs +++ b/MinecraftClient/Commands/Useblock.cs @@ -1,4 +1,4 @@ -using Brigadier.NET; +using Brigadier.NET; using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; using MinecraftClient.Mapping; @@ -48,7 +48,7 @@ namespace MinecraftClient.Commands Location current = handler.GetCurrentLocation(); block = block.ToAbsolute(current).ToFloor(); Location blockCenter = block.ToCenter(); - bool res = handler.PlaceBlock(block, Direction.Down); + bool res = handler.PlaceBlock(block, Direction.Down, lookAtBlock: true); return r.SetAndReturn(string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed"), res); } } diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index 4d576bcf..cf25ea94 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -207,9 +207,74 @@ namespace MinecraftClient.Inventory } private static Dictionary? reverseEnchantmentMappings; + private static Dictionary? dynamicEnchantmentIdMap; + + private static readonly Dictionary nameToEnchantment = new() + { + { "protection", Enchantments.Protection }, + { "fire_protection", Enchantments.FireProtection }, + { "feather_falling", Enchantments.FeatherFalling }, + { "blast_protection", Enchantments.BlastProtection }, + { "projectile_protection", Enchantments.ProjectileProtection }, + { "respiration", Enchantments.Respiration }, + { "aqua_affinity", Enchantments.AquaAffinity }, + { "thorns", Enchantments.Thorns }, + { "depth_strider", Enchantments.DepthStrider }, + { "frost_walker", Enchantments.FrostWalker }, + { "binding_curse", Enchantments.BindingCurse }, + { "soul_speed", Enchantments.SoulSpeed }, + { "swift_sneak", Enchantments.SwiftSneak }, + { "sharpness", Enchantments.Sharpness }, + { "smite", Enchantments.Smite }, + { "bane_of_arthropods", Enchantments.BaneOfArthropods }, + { "knockback", Enchantments.Knockback }, + { "fire_aspect", Enchantments.FireAspect }, + { "looting", Enchantments.Looting }, + { "sweeping_edge", Enchantments.Sweeping }, + { "efficiency", Enchantments.Efficiency }, + { "silk_touch", Enchantments.SilkTouch }, + { "unbreaking", Enchantments.Unbreaking }, + { "fortune", Enchantments.Fortune }, + { "power", Enchantments.Power }, + { "punch", Enchantments.Punch }, + { "flame", Enchantments.Flame }, + { "infinity", Enchantments.Infinity }, + { "luck_of_the_sea", Enchantments.LuckOfTheSea }, + { "lure", Enchantments.Lure }, + { "loyalty", Enchantments.Loyalty }, + { "impaling", Enchantments.Impaling }, + { "riptide", Enchantments.Riptide }, + { "channeling", Enchantments.Channeling }, + { "multishot", Enchantments.Multishot }, + { "quick_charge", Enchantments.QuickCharge }, + { "piercing", Enchantments.Piercing }, + { "density", Enchantments.Density }, + { "breach", Enchantments.Breach }, + { "wind_burst", Enchantments.WindBurst }, + { "mending", Enchantments.Mending }, + { "vanishing_curse", Enchantments.VanishingCurse }, + }; + + /// + /// Set the dynamic enchantment ID map from server RegistryData. + /// Called during configuration phase when receiving minecraft:enchantment registry. + /// + public static void SetDynamicEnchantmentIdMap(Dictionary idMap) + { + dynamicEnchantmentIdMap = new Dictionary(); + foreach (var kvp in idMap) + { + var name = kvp.Value.StartsWith("minecraft:") ? kvp.Value.Substring("minecraft:".Length) : kvp.Value; + if (nameToEnchantment.TryGetValue(name, out var enchantment)) + dynamicEnchantmentIdMap[kvp.Key] = enchantment; + } + reverseEnchantmentMappings = null; + } public static Enchantments GetEnchantmentByRegistryId1206(int id) { + if (dynamicEnchantmentIdMap != null && dynamicEnchantmentIdMap.TryGetValue(id, out var dynValue)) + return dynValue; if (enchantmentMappings.TryGetValue((short)id, out var value)) return value; return (Enchantments)(-1); @@ -220,8 +285,16 @@ namespace MinecraftClient.Inventory if (reverseEnchantmentMappings == null) { reverseEnchantmentMappings = new Dictionary(); - foreach (var kvp in enchantmentMappings) - reverseEnchantmentMappings[kvp.Value] = kvp.Key; + if (dynamicEnchantmentIdMap != null) + { + foreach (var kvp in dynamicEnchantmentIdMap) + reverseEnchantmentMappings[kvp.Value] = (short)kvp.Key; + } + else + { + foreach (var kvp in enchantmentMappings) + reverseEnchantmentMappings[kvp.Value] = kvp.Key; + } } return reverseEnchantmentMappings.TryGetValue(enchantment, out var id) ? id : -1; } diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index c632569b..86d205d1 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2392,10 +2392,19 @@ namespace MinecraftClient /// /// Location to place block to /// Block face (e.g. Direction.Down when clicking on the block below to place this block) + /// Also look at the block before interacting /// TRUE if successfully placed - public bool PlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand) + public bool PlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand, bool lookAtBlock = false) { - return InvokeOnMainThread(() => handler.SendPlayerBlockPlacement((int)hand, location, blockFace, sequenceId++)); + return InvokeOnMainThread(() => + { + if (lookAtBlock) + { + UpdateLocation(GetCurrentLocation(), location.ToCenter()); + handler.SendLocationUpdate(GetCurrentLocation(), Movement.IsOnGround(world, GetCurrentLocation()), _yaw, _pitch); + } + return handler.SendPlayerBlockPlacement((int)hand, location, blockFace, sequenceId++); + }); } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 735ce498..3f5590a9 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -465,10 +465,12 @@ namespace MinecraftClient.Protocol.Handlers var isChat = registryId == "minecraft:chat_type"; var isDimension = registryId == "minecraft:dimension_type"; var isAttribute = registryId == "minecraft:attribute"; + var isEnchantment = registryId == "minecraft:enchantment"; var availableChats = isChat ? new Dictionary() : null; var dimensionIdMap = isDimension ? new Dictionary() : null; var attributeIdMap = isAttribute ? new Dictionary() : null; + var enchantmentIdMap = isEnchantment ? new Dictionary() : null; for (var i = 0; i < entryCount; i++) { @@ -489,12 +491,13 @@ namespace MinecraftClient.Protocol.Handlers } else if (isAttribute) { - // Strip "minecraft:" prefix to match the format used in EntityProperties packets var attrName = entryId.StartsWith("minecraft:") ? entryId.Substring("minecraft:".Length) : entryId; attributeIdMap!.Add(i, attrName); } + else if (isEnchantment) + enchantmentIdMap!.Add(i, entryId); } if (isChat) @@ -507,6 +510,8 @@ namespace MinecraftClient.Protocol.Handlers } else if (isAttribute) World.SetAttributeIdMap(attributeIdMap!); + else if (isEnchantment) + EnchantmentMapping.SetDynamicEnchantmentIdMap(enchantmentIdMap!); } break; @@ -2339,6 +2344,8 @@ namespace MinecraftClient.Protocol.Handlers { if (entity.Type == EntityType.Player) handler.OnSpawnPlayer(entity.ID, entity.UUID, entity.Location, (byte)entity.Yaw, (byte)entity.Pitch); + else + handler.OnSpawnEntity(entity); break; } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs index d969d1b4..3cac3667 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using MinecraftClient.Inventory.ItemPalettes; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; -using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; @@ -11,7 +10,7 @@ public class AttributeModifiersComponent(DataTypes dataTypes, ItemPalette itemPa : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) { public int NumberOfAttributes { get; set; } - public List Attributes { get; set; } = new(); + public List Attributes { get; set; } = new(); public bool ShowInTooltip { get; set; } public override void Parse(Queue data) @@ -19,7 +18,7 @@ public class AttributeModifiersComponent(DataTypes dataTypes, ItemPalette itemPa NumberOfAttributes = dataTypes.ReadNextVarInt(data); for (var i = 0; i < NumberOfAttributes; i++) - Attributes.Add((AttributeSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); + Attributes.Add(subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); ShowInTooltip = dataTypes.ReadNextBool(data); } From df833ae2a882fdde9160ccc6e5c65a104820c8ca Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 03:02:43 +0800 Subject: [PATCH 053/484] feat: add palettes and version constants for MC 1.21.2 (protocol 768) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add item, entity, block, and metadata palettes for Minecraft 1.21.2: - ItemPalette1212: 1375 items (42 new: pale oak set, colored bundles, creaking heart/spawn egg, banner patterns) - EntityPalette1212: 150 entity types (boats split into per-wood-type entries, generic boat/chest_boat removed; added creaking, creaking_transient, pale oak boats) - Palette1212 (blocks): 1084 block types with state IDs generated from official 1.21.2 data reports (24 new pale oak blocks, creaking heart, pale moss variants) - EntityMetadataPalette: reuses 1206 (serializers unchanged in 1.21.2) Updated version infrastructure: - Protocol18.cs: MC_1_21_2_Version = 768, palette switch routing - ProtocolHandler.cs: version mapping 1.21.2 <-> 768 - Program.cs: MCHighestVersion bumped to 1.21.2 - ItemType.cs, EntityType.cs, Material.cs: new enum entries Note: packet palette, structured components, and protocol handler changes for 1.21.2 are not yet implemented — this commit covers palette/registry groundwork only. Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1212.cs | 1393 +++++++++++++ MinecraftClient/Inventory/ItemType.cs | 42 + .../Mapping/BlockPalettes/Palette1212.cs | 1811 +++++++++++++++++ .../Mapping/EntityMetadataPalette.cs | 2 +- .../EntityPalettes/EntityPalette1212.cs | 168 ++ MinecraftClient/Mapping/EntityType.cs | 24 +- MinecraftClient/Mapping/Material.cs | 26 +- MinecraftClient/Program.cs | 2 +- .../Protocol/Handlers/Protocol18.cs | 10 +- MinecraftClient/Protocol/ProtocolHandler.cs | 7 +- 10 files changed, 3476 insertions(+), 9 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1212.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1212.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1212.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1212.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1212.cs new file mode 100644 index 00000000..42edc7fd --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1212.cs @@ -0,0 +1,1393 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1212 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1212() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Azalea; + mappings[205] = ItemType.FloweringAzalea; + mappings[206] = ItemType.DeadBush; + mappings[207] = ItemType.Seagrass; + mappings[208] = ItemType.SeaPickle; + mappings[209] = ItemType.WhiteWool; + mappings[210] = ItemType.OrangeWool; + mappings[211] = ItemType.MagentaWool; + mappings[212] = ItemType.LightBlueWool; + mappings[213] = ItemType.YellowWool; + mappings[214] = ItemType.LimeWool; + mappings[215] = ItemType.PinkWool; + mappings[216] = ItemType.GrayWool; + mappings[217] = ItemType.LightGrayWool; + mappings[218] = ItemType.CyanWool; + mappings[219] = ItemType.PurpleWool; + mappings[220] = ItemType.BlueWool; + mappings[221] = ItemType.BrownWool; + mappings[222] = ItemType.GreenWool; + mappings[223] = ItemType.RedWool; + mappings[224] = ItemType.BlackWool; + mappings[225] = ItemType.Dandelion; + mappings[226] = ItemType.Poppy; + mappings[227] = ItemType.BlueOrchid; + mappings[228] = ItemType.Allium; + mappings[229] = ItemType.AzureBluet; + mappings[230] = ItemType.RedTulip; + mappings[231] = ItemType.OrangeTulip; + mappings[232] = ItemType.WhiteTulip; + mappings[233] = ItemType.PinkTulip; + mappings[234] = ItemType.OxeyeDaisy; + mappings[235] = ItemType.Cornflower; + mappings[236] = ItemType.LilyOfTheValley; + mappings[237] = ItemType.WitherRose; + mappings[238] = ItemType.Torchflower; + mappings[239] = ItemType.PitcherPlant; + mappings[240] = ItemType.SporeBlossom; + mappings[241] = ItemType.BrownMushroom; + mappings[242] = ItemType.RedMushroom; + mappings[243] = ItemType.CrimsonFungus; + mappings[244] = ItemType.WarpedFungus; + mappings[245] = ItemType.CrimsonRoots; + mappings[246] = ItemType.WarpedRoots; + mappings[247] = ItemType.NetherSprouts; + mappings[248] = ItemType.WeepingVines; + mappings[249] = ItemType.TwistingVines; + mappings[250] = ItemType.SugarCane; + mappings[251] = ItemType.Kelp; + mappings[252] = ItemType.PinkPetals; + mappings[253] = ItemType.MossCarpet; + mappings[254] = ItemType.MossBlock; + mappings[255] = ItemType.PaleMossCarpet; + mappings[256] = ItemType.PaleHangingMoss; + mappings[257] = ItemType.PaleMossBlock; + mappings[258] = ItemType.HangingRoots; + mappings[259] = ItemType.BigDripleaf; + mappings[260] = ItemType.SmallDripleaf; + mappings[261] = ItemType.Bamboo; + mappings[262] = ItemType.OakSlab; + mappings[263] = ItemType.SpruceSlab; + mappings[264] = ItemType.BirchSlab; + mappings[265] = ItemType.JungleSlab; + mappings[266] = ItemType.AcaciaSlab; + mappings[267] = ItemType.CherrySlab; + mappings[268] = ItemType.DarkOakSlab; + mappings[269] = ItemType.PaleOakSlab; + mappings[270] = ItemType.MangroveSlab; + mappings[271] = ItemType.BambooSlab; + mappings[272] = ItemType.BambooMosaicSlab; + mappings[273] = ItemType.CrimsonSlab; + mappings[274] = ItemType.WarpedSlab; + mappings[275] = ItemType.StoneSlab; + mappings[276] = ItemType.SmoothStoneSlab; + mappings[277] = ItemType.SandstoneSlab; + mappings[278] = ItemType.CutSandstoneSlab; + mappings[279] = ItemType.PetrifiedOakSlab; + mappings[280] = ItemType.CobblestoneSlab; + mappings[281] = ItemType.BrickSlab; + mappings[282] = ItemType.StoneBrickSlab; + mappings[283] = ItemType.MudBrickSlab; + mappings[284] = ItemType.NetherBrickSlab; + mappings[285] = ItemType.QuartzSlab; + mappings[286] = ItemType.RedSandstoneSlab; + mappings[287] = ItemType.CutRedSandstoneSlab; + mappings[288] = ItemType.PurpurSlab; + mappings[289] = ItemType.PrismarineSlab; + mappings[290] = ItemType.PrismarineBrickSlab; + mappings[291] = ItemType.DarkPrismarineSlab; + mappings[292] = ItemType.SmoothQuartz; + mappings[293] = ItemType.SmoothRedSandstone; + mappings[294] = ItemType.SmoothSandstone; + mappings[295] = ItemType.SmoothStone; + mappings[296] = ItemType.Bricks; + mappings[297] = ItemType.Bookshelf; + mappings[298] = ItemType.ChiseledBookshelf; + mappings[299] = ItemType.DecoratedPot; + mappings[300] = ItemType.MossyCobblestone; + mappings[301] = ItemType.Obsidian; + mappings[302] = ItemType.Torch; + mappings[303] = ItemType.EndRod; + mappings[304] = ItemType.ChorusPlant; + mappings[305] = ItemType.ChorusFlower; + mappings[306] = ItemType.PurpurBlock; + mappings[307] = ItemType.PurpurPillar; + mappings[308] = ItemType.PurpurStairs; + mappings[309] = ItemType.Spawner; + mappings[310] = ItemType.CreakingHeart; + mappings[311] = ItemType.Chest; + mappings[312] = ItemType.CraftingTable; + mappings[313] = ItemType.Farmland; + mappings[314] = ItemType.Furnace; + mappings[315] = ItemType.Ladder; + mappings[316] = ItemType.CobblestoneStairs; + mappings[317] = ItemType.Snow; + mappings[318] = ItemType.Ice; + mappings[319] = ItemType.SnowBlock; + mappings[320] = ItemType.Cactus; + mappings[321] = ItemType.Clay; + mappings[322] = ItemType.Jukebox; + mappings[323] = ItemType.OakFence; + mappings[324] = ItemType.SpruceFence; + mappings[325] = ItemType.BirchFence; + mappings[326] = ItemType.JungleFence; + mappings[327] = ItemType.AcaciaFence; + mappings[328] = ItemType.CherryFence; + mappings[329] = ItemType.DarkOakFence; + mappings[330] = ItemType.PaleOakFence; + mappings[331] = ItemType.MangroveFence; + mappings[332] = ItemType.BambooFence; + mappings[333] = ItemType.CrimsonFence; + mappings[334] = ItemType.WarpedFence; + mappings[335] = ItemType.Pumpkin; + mappings[336] = ItemType.CarvedPumpkin; + mappings[337] = ItemType.JackOLantern; + mappings[338] = ItemType.Netherrack; + mappings[339] = ItemType.SoulSand; + mappings[340] = ItemType.SoulSoil; + mappings[341] = ItemType.Basalt; + mappings[342] = ItemType.PolishedBasalt; + mappings[343] = ItemType.SmoothBasalt; + mappings[344] = ItemType.SoulTorch; + mappings[345] = ItemType.Glowstone; + mappings[346] = ItemType.InfestedStone; + mappings[347] = ItemType.InfestedCobblestone; + mappings[348] = ItemType.InfestedStoneBricks; + mappings[349] = ItemType.InfestedMossyStoneBricks; + mappings[350] = ItemType.InfestedCrackedStoneBricks; + mappings[351] = ItemType.InfestedChiseledStoneBricks; + mappings[352] = ItemType.InfestedDeepslate; + mappings[353] = ItemType.StoneBricks; + mappings[354] = ItemType.MossyStoneBricks; + mappings[355] = ItemType.CrackedStoneBricks; + mappings[356] = ItemType.ChiseledStoneBricks; + mappings[357] = ItemType.PackedMud; + mappings[358] = ItemType.MudBricks; + mappings[359] = ItemType.DeepslateBricks; + mappings[360] = ItemType.CrackedDeepslateBricks; + mappings[361] = ItemType.DeepslateTiles; + mappings[362] = ItemType.CrackedDeepslateTiles; + mappings[363] = ItemType.ChiseledDeepslate; + mappings[364] = ItemType.ReinforcedDeepslate; + mappings[365] = ItemType.BrownMushroomBlock; + mappings[366] = ItemType.RedMushroomBlock; + mappings[367] = ItemType.MushroomStem; + mappings[368] = ItemType.IronBars; + mappings[369] = ItemType.Chain; + mappings[370] = ItemType.GlassPane; + mappings[371] = ItemType.Melon; + mappings[372] = ItemType.Vine; + mappings[373] = ItemType.GlowLichen; + mappings[374] = ItemType.BrickStairs; + mappings[375] = ItemType.StoneBrickStairs; + mappings[376] = ItemType.MudBrickStairs; + mappings[377] = ItemType.Mycelium; + mappings[378] = ItemType.LilyPad; + mappings[379] = ItemType.NetherBricks; + mappings[380] = ItemType.CrackedNetherBricks; + mappings[381] = ItemType.ChiseledNetherBricks; + mappings[382] = ItemType.NetherBrickFence; + mappings[383] = ItemType.NetherBrickStairs; + mappings[384] = ItemType.Sculk; + mappings[385] = ItemType.SculkVein; + mappings[386] = ItemType.SculkCatalyst; + mappings[387] = ItemType.SculkShrieker; + mappings[388] = ItemType.EnchantingTable; + mappings[389] = ItemType.EndPortalFrame; + mappings[390] = ItemType.EndStone; + mappings[391] = ItemType.EndStoneBricks; + mappings[392] = ItemType.DragonEgg; + mappings[393] = ItemType.SandstoneStairs; + mappings[394] = ItemType.EnderChest; + mappings[395] = ItemType.EmeraldBlock; + mappings[396] = ItemType.OakStairs; + mappings[397] = ItemType.SpruceStairs; + mappings[398] = ItemType.BirchStairs; + mappings[399] = ItemType.JungleStairs; + mappings[400] = ItemType.AcaciaStairs; + mappings[401] = ItemType.CherryStairs; + mappings[402] = ItemType.DarkOakStairs; + mappings[403] = ItemType.PaleOakStairs; + mappings[404] = ItemType.MangroveStairs; + mappings[405] = ItemType.BambooStairs; + mappings[406] = ItemType.BambooMosaicStairs; + mappings[407] = ItemType.CrimsonStairs; + mappings[408] = ItemType.WarpedStairs; + mappings[409] = ItemType.CommandBlock; + mappings[410] = ItemType.Beacon; + mappings[411] = ItemType.CobblestoneWall; + mappings[412] = ItemType.MossyCobblestoneWall; + mappings[413] = ItemType.BrickWall; + mappings[414] = ItemType.PrismarineWall; + mappings[415] = ItemType.RedSandstoneWall; + mappings[416] = ItemType.MossyStoneBrickWall; + mappings[417] = ItemType.GraniteWall; + mappings[418] = ItemType.StoneBrickWall; + mappings[419] = ItemType.MudBrickWall; + mappings[420] = ItemType.NetherBrickWall; + mappings[421] = ItemType.AndesiteWall; + mappings[422] = ItemType.RedNetherBrickWall; + mappings[423] = ItemType.SandstoneWall; + mappings[424] = ItemType.EndStoneBrickWall; + mappings[425] = ItemType.DioriteWall; + mappings[426] = ItemType.BlackstoneWall; + mappings[427] = ItemType.PolishedBlackstoneWall; + mappings[428] = ItemType.PolishedBlackstoneBrickWall; + mappings[429] = ItemType.CobbledDeepslateWall; + mappings[430] = ItemType.PolishedDeepslateWall; + mappings[431] = ItemType.DeepslateBrickWall; + mappings[432] = ItemType.DeepslateTileWall; + mappings[433] = ItemType.Anvil; + mappings[434] = ItemType.ChippedAnvil; + mappings[435] = ItemType.DamagedAnvil; + mappings[436] = ItemType.ChiseledQuartzBlock; + mappings[437] = ItemType.QuartzBlock; + mappings[438] = ItemType.QuartzBricks; + mappings[439] = ItemType.QuartzPillar; + mappings[440] = ItemType.QuartzStairs; + mappings[441] = ItemType.WhiteTerracotta; + mappings[442] = ItemType.OrangeTerracotta; + mappings[443] = ItemType.MagentaTerracotta; + mappings[444] = ItemType.LightBlueTerracotta; + mappings[445] = ItemType.YellowTerracotta; + mappings[446] = ItemType.LimeTerracotta; + mappings[447] = ItemType.PinkTerracotta; + mappings[448] = ItemType.GrayTerracotta; + mappings[449] = ItemType.LightGrayTerracotta; + mappings[450] = ItemType.CyanTerracotta; + mappings[451] = ItemType.PurpleTerracotta; + mappings[452] = ItemType.BlueTerracotta; + mappings[453] = ItemType.BrownTerracotta; + mappings[454] = ItemType.GreenTerracotta; + mappings[455] = ItemType.RedTerracotta; + mappings[456] = ItemType.BlackTerracotta; + mappings[457] = ItemType.Barrier; + mappings[458] = ItemType.Light; + mappings[459] = ItemType.HayBlock; + mappings[460] = ItemType.WhiteCarpet; + mappings[461] = ItemType.OrangeCarpet; + mappings[462] = ItemType.MagentaCarpet; + mappings[463] = ItemType.LightBlueCarpet; + mappings[464] = ItemType.YellowCarpet; + mappings[465] = ItemType.LimeCarpet; + mappings[466] = ItemType.PinkCarpet; + mappings[467] = ItemType.GrayCarpet; + mappings[468] = ItemType.LightGrayCarpet; + mappings[469] = ItemType.CyanCarpet; + mappings[470] = ItemType.PurpleCarpet; + mappings[471] = ItemType.BlueCarpet; + mappings[472] = ItemType.BrownCarpet; + mappings[473] = ItemType.GreenCarpet; + mappings[474] = ItemType.RedCarpet; + mappings[475] = ItemType.BlackCarpet; + mappings[476] = ItemType.Terracotta; + mappings[477] = ItemType.PackedIce; + mappings[478] = ItemType.DirtPath; + mappings[479] = ItemType.Sunflower; + mappings[480] = ItemType.Lilac; + mappings[481] = ItemType.RoseBush; + mappings[482] = ItemType.Peony; + mappings[483] = ItemType.TallGrass; + mappings[484] = ItemType.LargeFern; + mappings[485] = ItemType.WhiteStainedGlass; + mappings[486] = ItemType.OrangeStainedGlass; + mappings[487] = ItemType.MagentaStainedGlass; + mappings[488] = ItemType.LightBlueStainedGlass; + mappings[489] = ItemType.YellowStainedGlass; + mappings[490] = ItemType.LimeStainedGlass; + mappings[491] = ItemType.PinkStainedGlass; + mappings[492] = ItemType.GrayStainedGlass; + mappings[493] = ItemType.LightGrayStainedGlass; + mappings[494] = ItemType.CyanStainedGlass; + mappings[495] = ItemType.PurpleStainedGlass; + mappings[496] = ItemType.BlueStainedGlass; + mappings[497] = ItemType.BrownStainedGlass; + mappings[498] = ItemType.GreenStainedGlass; + mappings[499] = ItemType.RedStainedGlass; + mappings[500] = ItemType.BlackStainedGlass; + mappings[501] = ItemType.WhiteStainedGlassPane; + mappings[502] = ItemType.OrangeStainedGlassPane; + mappings[503] = ItemType.MagentaStainedGlassPane; + mappings[504] = ItemType.LightBlueStainedGlassPane; + mappings[505] = ItemType.YellowStainedGlassPane; + mappings[506] = ItemType.LimeStainedGlassPane; + mappings[507] = ItemType.PinkStainedGlassPane; + mappings[508] = ItemType.GrayStainedGlassPane; + mappings[509] = ItemType.LightGrayStainedGlassPane; + mappings[510] = ItemType.CyanStainedGlassPane; + mappings[511] = ItemType.PurpleStainedGlassPane; + mappings[512] = ItemType.BlueStainedGlassPane; + mappings[513] = ItemType.BrownStainedGlassPane; + mappings[514] = ItemType.GreenStainedGlassPane; + mappings[515] = ItemType.RedStainedGlassPane; + mappings[516] = ItemType.BlackStainedGlassPane; + mappings[517] = ItemType.Prismarine; + mappings[518] = ItemType.PrismarineBricks; + mappings[519] = ItemType.DarkPrismarine; + mappings[520] = ItemType.PrismarineStairs; + mappings[521] = ItemType.PrismarineBrickStairs; + mappings[522] = ItemType.DarkPrismarineStairs; + mappings[523] = ItemType.SeaLantern; + mappings[524] = ItemType.RedSandstone; + mappings[525] = ItemType.ChiseledRedSandstone; + mappings[526] = ItemType.CutRedSandstone; + mappings[527] = ItemType.RedSandstoneStairs; + mappings[528] = ItemType.RepeatingCommandBlock; + mappings[529] = ItemType.ChainCommandBlock; + mappings[530] = ItemType.MagmaBlock; + mappings[531] = ItemType.NetherWartBlock; + mappings[532] = ItemType.WarpedWartBlock; + mappings[533] = ItemType.RedNetherBricks; + mappings[534] = ItemType.BoneBlock; + mappings[535] = ItemType.StructureVoid; + mappings[536] = ItemType.ShulkerBox; + mappings[537] = ItemType.WhiteShulkerBox; + mappings[538] = ItemType.OrangeShulkerBox; + mappings[539] = ItemType.MagentaShulkerBox; + mappings[540] = ItemType.LightBlueShulkerBox; + mappings[541] = ItemType.YellowShulkerBox; + mappings[542] = ItemType.LimeShulkerBox; + mappings[543] = ItemType.PinkShulkerBox; + mappings[544] = ItemType.GrayShulkerBox; + mappings[545] = ItemType.LightGrayShulkerBox; + mappings[546] = ItemType.CyanShulkerBox; + mappings[547] = ItemType.PurpleShulkerBox; + mappings[548] = ItemType.BlueShulkerBox; + mappings[549] = ItemType.BrownShulkerBox; + mappings[550] = ItemType.GreenShulkerBox; + mappings[551] = ItemType.RedShulkerBox; + mappings[552] = ItemType.BlackShulkerBox; + mappings[553] = ItemType.WhiteGlazedTerracotta; + mappings[554] = ItemType.OrangeGlazedTerracotta; + mappings[555] = ItemType.MagentaGlazedTerracotta; + mappings[556] = ItemType.LightBlueGlazedTerracotta; + mappings[557] = ItemType.YellowGlazedTerracotta; + mappings[558] = ItemType.LimeGlazedTerracotta; + mappings[559] = ItemType.PinkGlazedTerracotta; + mappings[560] = ItemType.GrayGlazedTerracotta; + mappings[561] = ItemType.LightGrayGlazedTerracotta; + mappings[562] = ItemType.CyanGlazedTerracotta; + mappings[563] = ItemType.PurpleGlazedTerracotta; + mappings[564] = ItemType.BlueGlazedTerracotta; + mappings[565] = ItemType.BrownGlazedTerracotta; + mappings[566] = ItemType.GreenGlazedTerracotta; + mappings[567] = ItemType.RedGlazedTerracotta; + mappings[568] = ItemType.BlackGlazedTerracotta; + mappings[569] = ItemType.WhiteConcrete; + mappings[570] = ItemType.OrangeConcrete; + mappings[571] = ItemType.MagentaConcrete; + mappings[572] = ItemType.LightBlueConcrete; + mappings[573] = ItemType.YellowConcrete; + mappings[574] = ItemType.LimeConcrete; + mappings[575] = ItemType.PinkConcrete; + mappings[576] = ItemType.GrayConcrete; + mappings[577] = ItemType.LightGrayConcrete; + mappings[578] = ItemType.CyanConcrete; + mappings[579] = ItemType.PurpleConcrete; + mappings[580] = ItemType.BlueConcrete; + mappings[581] = ItemType.BrownConcrete; + mappings[582] = ItemType.GreenConcrete; + mappings[583] = ItemType.RedConcrete; + mappings[584] = ItemType.BlackConcrete; + mappings[585] = ItemType.WhiteConcretePowder; + mappings[586] = ItemType.OrangeConcretePowder; + mappings[587] = ItemType.MagentaConcretePowder; + mappings[588] = ItemType.LightBlueConcretePowder; + mappings[589] = ItemType.YellowConcretePowder; + mappings[590] = ItemType.LimeConcretePowder; + mappings[591] = ItemType.PinkConcretePowder; + mappings[592] = ItemType.GrayConcretePowder; + mappings[593] = ItemType.LightGrayConcretePowder; + mappings[594] = ItemType.CyanConcretePowder; + mappings[595] = ItemType.PurpleConcretePowder; + mappings[596] = ItemType.BlueConcretePowder; + mappings[597] = ItemType.BrownConcretePowder; + mappings[598] = ItemType.GreenConcretePowder; + mappings[599] = ItemType.RedConcretePowder; + mappings[600] = ItemType.BlackConcretePowder; + mappings[601] = ItemType.TurtleEgg; + mappings[602] = ItemType.SnifferEgg; + mappings[603] = ItemType.DeadTubeCoralBlock; + mappings[604] = ItemType.DeadBrainCoralBlock; + mappings[605] = ItemType.DeadBubbleCoralBlock; + mappings[606] = ItemType.DeadFireCoralBlock; + mappings[607] = ItemType.DeadHornCoralBlock; + mappings[608] = ItemType.TubeCoralBlock; + mappings[609] = ItemType.BrainCoralBlock; + mappings[610] = ItemType.BubbleCoralBlock; + mappings[611] = ItemType.FireCoralBlock; + mappings[612] = ItemType.HornCoralBlock; + mappings[613] = ItemType.TubeCoral; + mappings[614] = ItemType.BrainCoral; + mappings[615] = ItemType.BubbleCoral; + mappings[616] = ItemType.FireCoral; + mappings[617] = ItemType.HornCoral; + mappings[618] = ItemType.DeadBrainCoral; + mappings[619] = ItemType.DeadBubbleCoral; + mappings[620] = ItemType.DeadFireCoral; + mappings[621] = ItemType.DeadHornCoral; + mappings[622] = ItemType.DeadTubeCoral; + mappings[623] = ItemType.TubeCoralFan; + mappings[624] = ItemType.BrainCoralFan; + mappings[625] = ItemType.BubbleCoralFan; + mappings[626] = ItemType.FireCoralFan; + mappings[627] = ItemType.HornCoralFan; + mappings[628] = ItemType.DeadTubeCoralFan; + mappings[629] = ItemType.DeadBrainCoralFan; + mappings[630] = ItemType.DeadBubbleCoralFan; + mappings[631] = ItemType.DeadFireCoralFan; + mappings[632] = ItemType.DeadHornCoralFan; + mappings[633] = ItemType.BlueIce; + mappings[634] = ItemType.Conduit; + mappings[635] = ItemType.PolishedGraniteStairs; + mappings[636] = ItemType.SmoothRedSandstoneStairs; + mappings[637] = ItemType.MossyStoneBrickStairs; + mappings[638] = ItemType.PolishedDioriteStairs; + mappings[639] = ItemType.MossyCobblestoneStairs; + mappings[640] = ItemType.EndStoneBrickStairs; + mappings[641] = ItemType.StoneStairs; + mappings[642] = ItemType.SmoothSandstoneStairs; + mappings[643] = ItemType.SmoothQuartzStairs; + mappings[644] = ItemType.GraniteStairs; + mappings[645] = ItemType.AndesiteStairs; + mappings[646] = ItemType.RedNetherBrickStairs; + mappings[647] = ItemType.PolishedAndesiteStairs; + mappings[648] = ItemType.DioriteStairs; + mappings[649] = ItemType.CobbledDeepslateStairs; + mappings[650] = ItemType.PolishedDeepslateStairs; + mappings[651] = ItemType.DeepslateBrickStairs; + mappings[652] = ItemType.DeepslateTileStairs; + mappings[653] = ItemType.PolishedGraniteSlab; + mappings[654] = ItemType.SmoothRedSandstoneSlab; + mappings[655] = ItemType.MossyStoneBrickSlab; + mappings[656] = ItemType.PolishedDioriteSlab; + mappings[657] = ItemType.MossyCobblestoneSlab; + mappings[658] = ItemType.EndStoneBrickSlab; + mappings[659] = ItemType.SmoothSandstoneSlab; + mappings[660] = ItemType.SmoothQuartzSlab; + mappings[661] = ItemType.GraniteSlab; + mappings[662] = ItemType.AndesiteSlab; + mappings[663] = ItemType.RedNetherBrickSlab; + mappings[664] = ItemType.PolishedAndesiteSlab; + mappings[665] = ItemType.DioriteSlab; + mappings[666] = ItemType.CobbledDeepslateSlab; + mappings[667] = ItemType.PolishedDeepslateSlab; + mappings[668] = ItemType.DeepslateBrickSlab; + mappings[669] = ItemType.DeepslateTileSlab; + mappings[670] = ItemType.Scaffolding; + mappings[671] = ItemType.Redstone; + mappings[672] = ItemType.RedstoneTorch; + mappings[673] = ItemType.RedstoneBlock; + mappings[674] = ItemType.Repeater; + mappings[675] = ItemType.Comparator; + mappings[676] = ItemType.Piston; + mappings[677] = ItemType.StickyPiston; + mappings[678] = ItemType.SlimeBlock; + mappings[679] = ItemType.HoneyBlock; + mappings[680] = ItemType.Observer; + mappings[681] = ItemType.Hopper; + mappings[682] = ItemType.Dispenser; + mappings[683] = ItemType.Dropper; + mappings[684] = ItemType.Lectern; + mappings[685] = ItemType.Target; + mappings[686] = ItemType.Lever; + mappings[687] = ItemType.LightningRod; + mappings[688] = ItemType.DaylightDetector; + mappings[689] = ItemType.SculkSensor; + mappings[690] = ItemType.CalibratedSculkSensor; + mappings[691] = ItemType.TripwireHook; + mappings[692] = ItemType.TrappedChest; + mappings[693] = ItemType.Tnt; + mappings[694] = ItemType.RedstoneLamp; + mappings[695] = ItemType.NoteBlock; + mappings[696] = ItemType.StoneButton; + mappings[697] = ItemType.PolishedBlackstoneButton; + mappings[698] = ItemType.OakButton; + mappings[699] = ItemType.SpruceButton; + mappings[700] = ItemType.BirchButton; + mappings[701] = ItemType.JungleButton; + mappings[702] = ItemType.AcaciaButton; + mappings[703] = ItemType.CherryButton; + mappings[704] = ItemType.DarkOakButton; + mappings[705] = ItemType.PaleOakButton; + mappings[706] = ItemType.MangroveButton; + mappings[707] = ItemType.BambooButton; + mappings[708] = ItemType.CrimsonButton; + mappings[709] = ItemType.WarpedButton; + mappings[710] = ItemType.StonePressurePlate; + mappings[711] = ItemType.PolishedBlackstonePressurePlate; + mappings[712] = ItemType.LightWeightedPressurePlate; + mappings[713] = ItemType.HeavyWeightedPressurePlate; + mappings[714] = ItemType.OakPressurePlate; + mappings[715] = ItemType.SprucePressurePlate; + mappings[716] = ItemType.BirchPressurePlate; + mappings[717] = ItemType.JunglePressurePlate; + mappings[718] = ItemType.AcaciaPressurePlate; + mappings[719] = ItemType.CherryPressurePlate; + mappings[720] = ItemType.DarkOakPressurePlate; + mappings[721] = ItemType.PaleOakPressurePlate; + mappings[722] = ItemType.MangrovePressurePlate; + mappings[723] = ItemType.BambooPressurePlate; + mappings[724] = ItemType.CrimsonPressurePlate; + mappings[725] = ItemType.WarpedPressurePlate; + mappings[726] = ItemType.IronDoor; + mappings[727] = ItemType.OakDoor; + mappings[728] = ItemType.SpruceDoor; + mappings[729] = ItemType.BirchDoor; + mappings[730] = ItemType.JungleDoor; + mappings[731] = ItemType.AcaciaDoor; + mappings[732] = ItemType.CherryDoor; + mappings[733] = ItemType.DarkOakDoor; + mappings[734] = ItemType.PaleOakDoor; + mappings[735] = ItemType.MangroveDoor; + mappings[736] = ItemType.BambooDoor; + mappings[737] = ItemType.CrimsonDoor; + mappings[738] = ItemType.WarpedDoor; + mappings[739] = ItemType.CopperDoor; + mappings[740] = ItemType.ExposedCopperDoor; + mappings[741] = ItemType.WeatheredCopperDoor; + mappings[742] = ItemType.OxidizedCopperDoor; + mappings[743] = ItemType.WaxedCopperDoor; + mappings[744] = ItemType.WaxedExposedCopperDoor; + mappings[745] = ItemType.WaxedWeatheredCopperDoor; + mappings[746] = ItemType.WaxedOxidizedCopperDoor; + mappings[747] = ItemType.IronTrapdoor; + mappings[748] = ItemType.OakTrapdoor; + mappings[749] = ItemType.SpruceTrapdoor; + mappings[750] = ItemType.BirchTrapdoor; + mappings[751] = ItemType.JungleTrapdoor; + mappings[752] = ItemType.AcaciaTrapdoor; + mappings[753] = ItemType.CherryTrapdoor; + mappings[754] = ItemType.DarkOakTrapdoor; + mappings[755] = ItemType.PaleOakTrapdoor; + mappings[756] = ItemType.MangroveTrapdoor; + mappings[757] = ItemType.BambooTrapdoor; + mappings[758] = ItemType.CrimsonTrapdoor; + mappings[759] = ItemType.WarpedTrapdoor; + mappings[760] = ItemType.CopperTrapdoor; + mappings[761] = ItemType.ExposedCopperTrapdoor; + mappings[762] = ItemType.WeatheredCopperTrapdoor; + mappings[763] = ItemType.OxidizedCopperTrapdoor; + mappings[764] = ItemType.WaxedCopperTrapdoor; + mappings[765] = ItemType.WaxedExposedCopperTrapdoor; + mappings[766] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[767] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[768] = ItemType.OakFenceGate; + mappings[769] = ItemType.SpruceFenceGate; + mappings[770] = ItemType.BirchFenceGate; + mappings[771] = ItemType.JungleFenceGate; + mappings[772] = ItemType.AcaciaFenceGate; + mappings[773] = ItemType.CherryFenceGate; + mappings[774] = ItemType.DarkOakFenceGate; + mappings[775] = ItemType.PaleOakFenceGate; + mappings[776] = ItemType.MangroveFenceGate; + mappings[777] = ItemType.BambooFenceGate; + mappings[778] = ItemType.CrimsonFenceGate; + mappings[779] = ItemType.WarpedFenceGate; + mappings[780] = ItemType.PoweredRail; + mappings[781] = ItemType.DetectorRail; + mappings[782] = ItemType.Rail; + mappings[783] = ItemType.ActivatorRail; + mappings[784] = ItemType.Saddle; + mappings[785] = ItemType.Minecart; + mappings[786] = ItemType.ChestMinecart; + mappings[787] = ItemType.FurnaceMinecart; + mappings[788] = ItemType.TntMinecart; + mappings[789] = ItemType.HopperMinecart; + mappings[790] = ItemType.CarrotOnAStick; + mappings[791] = ItemType.WarpedFungusOnAStick; + mappings[792] = ItemType.PhantomMembrane; + mappings[793] = ItemType.Elytra; + mappings[794] = ItemType.OakBoat; + mappings[795] = ItemType.OakChestBoat; + mappings[796] = ItemType.SpruceBoat; + mappings[797] = ItemType.SpruceChestBoat; + mappings[798] = ItemType.BirchBoat; + mappings[799] = ItemType.BirchChestBoat; + mappings[800] = ItemType.JungleBoat; + mappings[801] = ItemType.JungleChestBoat; + mappings[802] = ItemType.AcaciaBoat; + mappings[803] = ItemType.AcaciaChestBoat; + mappings[804] = ItemType.CherryBoat; + mappings[805] = ItemType.CherryChestBoat; + mappings[806] = ItemType.DarkOakBoat; + mappings[807] = ItemType.DarkOakChestBoat; + mappings[808] = ItemType.PaleOakBoat; + mappings[809] = ItemType.PaleOakChestBoat; + mappings[810] = ItemType.MangroveBoat; + mappings[811] = ItemType.MangroveChestBoat; + mappings[812] = ItemType.BambooRaft; + mappings[813] = ItemType.BambooChestRaft; + mappings[814] = ItemType.StructureBlock; + mappings[815] = ItemType.Jigsaw; + mappings[816] = ItemType.TurtleHelmet; + mappings[817] = ItemType.TurtleScute; + mappings[818] = ItemType.ArmadilloScute; + mappings[819] = ItemType.WolfArmor; + mappings[820] = ItemType.FlintAndSteel; + mappings[821] = ItemType.Bowl; + mappings[822] = ItemType.Apple; + mappings[823] = ItemType.Bow; + mappings[824] = ItemType.Arrow; + mappings[825] = ItemType.Coal; + mappings[826] = ItemType.Charcoal; + mappings[827] = ItemType.Diamond; + mappings[828] = ItemType.Emerald; + mappings[829] = ItemType.LapisLazuli; + mappings[830] = ItemType.Quartz; + mappings[831] = ItemType.AmethystShard; + mappings[832] = ItemType.RawIron; + mappings[833] = ItemType.IronIngot; + mappings[834] = ItemType.RawCopper; + mappings[835] = ItemType.CopperIngot; + mappings[836] = ItemType.RawGold; + mappings[837] = ItemType.GoldIngot; + mappings[838] = ItemType.NetheriteIngot; + mappings[839] = ItemType.NetheriteScrap; + mappings[840] = ItemType.WoodenSword; + mappings[841] = ItemType.WoodenShovel; + mappings[842] = ItemType.WoodenPickaxe; + mappings[843] = ItemType.WoodenAxe; + mappings[844] = ItemType.WoodenHoe; + mappings[845] = ItemType.StoneSword; + mappings[846] = ItemType.StoneShovel; + mappings[847] = ItemType.StonePickaxe; + mappings[848] = ItemType.StoneAxe; + mappings[849] = ItemType.StoneHoe; + mappings[850] = ItemType.GoldenSword; + mappings[851] = ItemType.GoldenShovel; + mappings[852] = ItemType.GoldenPickaxe; + mappings[853] = ItemType.GoldenAxe; + mappings[854] = ItemType.GoldenHoe; + mappings[855] = ItemType.IronSword; + mappings[856] = ItemType.IronShovel; + mappings[857] = ItemType.IronPickaxe; + mappings[858] = ItemType.IronAxe; + mappings[859] = ItemType.IronHoe; + mappings[860] = ItemType.DiamondSword; + mappings[861] = ItemType.DiamondShovel; + mappings[862] = ItemType.DiamondPickaxe; + mappings[863] = ItemType.DiamondAxe; + mappings[864] = ItemType.DiamondHoe; + mappings[865] = ItemType.NetheriteSword; + mappings[866] = ItemType.NetheriteShovel; + mappings[867] = ItemType.NetheritePickaxe; + mappings[868] = ItemType.NetheriteAxe; + mappings[869] = ItemType.NetheriteHoe; + mappings[870] = ItemType.Stick; + mappings[871] = ItemType.MushroomStew; + mappings[872] = ItemType.String; + mappings[873] = ItemType.Feather; + mappings[874] = ItemType.Gunpowder; + mappings[875] = ItemType.WheatSeeds; + mappings[876] = ItemType.Wheat; + mappings[877] = ItemType.Bread; + mappings[878] = ItemType.LeatherHelmet; + mappings[879] = ItemType.LeatherChestplate; + mappings[880] = ItemType.LeatherLeggings; + mappings[881] = ItemType.LeatherBoots; + mappings[882] = ItemType.ChainmailHelmet; + mappings[883] = ItemType.ChainmailChestplate; + mappings[884] = ItemType.ChainmailLeggings; + mappings[885] = ItemType.ChainmailBoots; + mappings[886] = ItemType.IronHelmet; + mappings[887] = ItemType.IronChestplate; + mappings[888] = ItemType.IronLeggings; + mappings[889] = ItemType.IronBoots; + mappings[890] = ItemType.DiamondHelmet; + mappings[891] = ItemType.DiamondChestplate; + mappings[892] = ItemType.DiamondLeggings; + mappings[893] = ItemType.DiamondBoots; + mappings[894] = ItemType.GoldenHelmet; + mappings[895] = ItemType.GoldenChestplate; + mappings[896] = ItemType.GoldenLeggings; + mappings[897] = ItemType.GoldenBoots; + mappings[898] = ItemType.NetheriteHelmet; + mappings[899] = ItemType.NetheriteChestplate; + mappings[900] = ItemType.NetheriteLeggings; + mappings[901] = ItemType.NetheriteBoots; + mappings[902] = ItemType.Flint; + mappings[903] = ItemType.Porkchop; + mappings[904] = ItemType.CookedPorkchop; + mappings[905] = ItemType.Painting; + mappings[906] = ItemType.GoldenApple; + mappings[907] = ItemType.EnchantedGoldenApple; + mappings[908] = ItemType.OakSign; + mappings[909] = ItemType.SpruceSign; + mappings[910] = ItemType.BirchSign; + mappings[911] = ItemType.JungleSign; + mappings[912] = ItemType.AcaciaSign; + mappings[913] = ItemType.CherrySign; + mappings[914] = ItemType.DarkOakSign; + mappings[915] = ItemType.PaleOakSign; + mappings[916] = ItemType.MangroveSign; + mappings[917] = ItemType.BambooSign; + mappings[918] = ItemType.CrimsonSign; + mappings[919] = ItemType.WarpedSign; + mappings[920] = ItemType.OakHangingSign; + mappings[921] = ItemType.SpruceHangingSign; + mappings[922] = ItemType.BirchHangingSign; + mappings[923] = ItemType.JungleHangingSign; + mappings[924] = ItemType.AcaciaHangingSign; + mappings[925] = ItemType.CherryHangingSign; + mappings[926] = ItemType.DarkOakHangingSign; + mappings[927] = ItemType.PaleOakHangingSign; + mappings[928] = ItemType.MangroveHangingSign; + mappings[929] = ItemType.BambooHangingSign; + mappings[930] = ItemType.CrimsonHangingSign; + mappings[931] = ItemType.WarpedHangingSign; + mappings[932] = ItemType.Bucket; + mappings[933] = ItemType.WaterBucket; + mappings[934] = ItemType.LavaBucket; + mappings[935] = ItemType.PowderSnowBucket; + mappings[936] = ItemType.Snowball; + mappings[937] = ItemType.Leather; + mappings[938] = ItemType.MilkBucket; + mappings[939] = ItemType.PufferfishBucket; + mappings[940] = ItemType.SalmonBucket; + mappings[941] = ItemType.CodBucket; + mappings[942] = ItemType.TropicalFishBucket; + mappings[943] = ItemType.AxolotlBucket; + mappings[944] = ItemType.TadpoleBucket; + mappings[945] = ItemType.Brick; + mappings[946] = ItemType.ClayBall; + mappings[947] = ItemType.DriedKelpBlock; + mappings[948] = ItemType.Paper; + mappings[949] = ItemType.Book; + mappings[950] = ItemType.SlimeBall; + mappings[951] = ItemType.Egg; + mappings[952] = ItemType.Compass; + mappings[953] = ItemType.RecoveryCompass; + mappings[954] = ItemType.Bundle; + mappings[955] = ItemType.WhiteBundle; + mappings[956] = ItemType.OrangeBundle; + mappings[957] = ItemType.MagentaBundle; + mappings[958] = ItemType.LightBlueBundle; + mappings[959] = ItemType.YellowBundle; + mappings[960] = ItemType.LimeBundle; + mappings[961] = ItemType.PinkBundle; + mappings[962] = ItemType.GrayBundle; + mappings[963] = ItemType.LightGrayBundle; + mappings[964] = ItemType.CyanBundle; + mappings[965] = ItemType.PurpleBundle; + mappings[966] = ItemType.BlueBundle; + mappings[967] = ItemType.BrownBundle; + mappings[968] = ItemType.GreenBundle; + mappings[969] = ItemType.RedBundle; + mappings[970] = ItemType.BlackBundle; + mappings[971] = ItemType.FishingRod; + mappings[972] = ItemType.Clock; + mappings[973] = ItemType.Spyglass; + mappings[974] = ItemType.GlowstoneDust; + mappings[975] = ItemType.Cod; + mappings[976] = ItemType.Salmon; + mappings[977] = ItemType.TropicalFish; + mappings[978] = ItemType.Pufferfish; + mappings[979] = ItemType.CookedCod; + mappings[980] = ItemType.CookedSalmon; + mappings[981] = ItemType.InkSac; + mappings[982] = ItemType.GlowInkSac; + mappings[983] = ItemType.CocoaBeans; + mappings[984] = ItemType.WhiteDye; + mappings[985] = ItemType.OrangeDye; + mappings[986] = ItemType.MagentaDye; + mappings[987] = ItemType.LightBlueDye; + mappings[988] = ItemType.YellowDye; + mappings[989] = ItemType.LimeDye; + mappings[990] = ItemType.PinkDye; + mappings[991] = ItemType.GrayDye; + mappings[992] = ItemType.LightGrayDye; + mappings[993] = ItemType.CyanDye; + mappings[994] = ItemType.PurpleDye; + mappings[995] = ItemType.BlueDye; + mappings[996] = ItemType.BrownDye; + mappings[997] = ItemType.GreenDye; + mappings[998] = ItemType.RedDye; + mappings[999] = ItemType.BlackDye; + mappings[1000] = ItemType.BoneMeal; + mappings[1001] = ItemType.Bone; + mappings[1002] = ItemType.Sugar; + mappings[1003] = ItemType.Cake; + mappings[1004] = ItemType.WhiteBed; + mappings[1005] = ItemType.OrangeBed; + mappings[1006] = ItemType.MagentaBed; + mappings[1007] = ItemType.LightBlueBed; + mappings[1008] = ItemType.YellowBed; + mappings[1009] = ItemType.LimeBed; + mappings[1010] = ItemType.PinkBed; + mappings[1011] = ItemType.GrayBed; + mappings[1012] = ItemType.LightGrayBed; + mappings[1013] = ItemType.CyanBed; + mappings[1014] = ItemType.PurpleBed; + mappings[1015] = ItemType.BlueBed; + mappings[1016] = ItemType.BrownBed; + mappings[1017] = ItemType.GreenBed; + mappings[1018] = ItemType.RedBed; + mappings[1019] = ItemType.BlackBed; + mappings[1020] = ItemType.Cookie; + mappings[1021] = ItemType.Crafter; + mappings[1022] = ItemType.FilledMap; + mappings[1023] = ItemType.Shears; + mappings[1024] = ItemType.MelonSlice; + mappings[1025] = ItemType.DriedKelp; + mappings[1026] = ItemType.PumpkinSeeds; + mappings[1027] = ItemType.MelonSeeds; + mappings[1028] = ItemType.Beef; + mappings[1029] = ItemType.CookedBeef; + mappings[1030] = ItemType.Chicken; + mappings[1031] = ItemType.CookedChicken; + mappings[1032] = ItemType.RottenFlesh; + mappings[1033] = ItemType.EnderPearl; + mappings[1034] = ItemType.BlazeRod; + mappings[1035] = ItemType.GhastTear; + mappings[1036] = ItemType.GoldNugget; + mappings[1037] = ItemType.NetherWart; + mappings[1038] = ItemType.GlassBottle; + mappings[1039] = ItemType.Potion; + mappings[1040] = ItemType.SpiderEye; + mappings[1041] = ItemType.FermentedSpiderEye; + mappings[1042] = ItemType.BlazePowder; + mappings[1043] = ItemType.MagmaCream; + mappings[1044] = ItemType.BrewingStand; + mappings[1045] = ItemType.Cauldron; + mappings[1046] = ItemType.EnderEye; + mappings[1047] = ItemType.GlisteringMelonSlice; + mappings[1048] = ItemType.ArmadilloSpawnEgg; + mappings[1049] = ItemType.AllaySpawnEgg; + mappings[1050] = ItemType.AxolotlSpawnEgg; + mappings[1051] = ItemType.BatSpawnEgg; + mappings[1052] = ItemType.BeeSpawnEgg; + mappings[1053] = ItemType.BlazeSpawnEgg; + mappings[1054] = ItemType.BoggedSpawnEgg; + mappings[1055] = ItemType.BreezeSpawnEgg; + mappings[1056] = ItemType.CatSpawnEgg; + mappings[1057] = ItemType.CamelSpawnEgg; + mappings[1058] = ItemType.CaveSpiderSpawnEgg; + mappings[1059] = ItemType.ChickenSpawnEgg; + mappings[1060] = ItemType.CodSpawnEgg; + mappings[1061] = ItemType.CowSpawnEgg; + mappings[1062] = ItemType.CreeperSpawnEgg; + mappings[1063] = ItemType.DolphinSpawnEgg; + mappings[1064] = ItemType.DonkeySpawnEgg; + mappings[1065] = ItemType.DrownedSpawnEgg; + mappings[1066] = ItemType.ElderGuardianSpawnEgg; + mappings[1067] = ItemType.EnderDragonSpawnEgg; + mappings[1068] = ItemType.EndermanSpawnEgg; + mappings[1069] = ItemType.EndermiteSpawnEgg; + mappings[1070] = ItemType.EvokerSpawnEgg; + mappings[1071] = ItemType.FoxSpawnEgg; + mappings[1072] = ItemType.FrogSpawnEgg; + mappings[1073] = ItemType.GhastSpawnEgg; + mappings[1074] = ItemType.GlowSquidSpawnEgg; + mappings[1075] = ItemType.GoatSpawnEgg; + mappings[1076] = ItemType.GuardianSpawnEgg; + mappings[1077] = ItemType.HoglinSpawnEgg; + mappings[1078] = ItemType.HorseSpawnEgg; + mappings[1079] = ItemType.HuskSpawnEgg; + mappings[1080] = ItemType.IronGolemSpawnEgg; + mappings[1081] = ItemType.LlamaSpawnEgg; + mappings[1082] = ItemType.MagmaCubeSpawnEgg; + mappings[1083] = ItemType.MooshroomSpawnEgg; + mappings[1084] = ItemType.MuleSpawnEgg; + mappings[1085] = ItemType.OcelotSpawnEgg; + mappings[1086] = ItemType.PandaSpawnEgg; + mappings[1087] = ItemType.ParrotSpawnEgg; + mappings[1088] = ItemType.PhantomSpawnEgg; + mappings[1089] = ItemType.PigSpawnEgg; + mappings[1090] = ItemType.PiglinSpawnEgg; + mappings[1091] = ItemType.PiglinBruteSpawnEgg; + mappings[1092] = ItemType.PillagerSpawnEgg; + mappings[1093] = ItemType.PolarBearSpawnEgg; + mappings[1094] = ItemType.PufferfishSpawnEgg; + mappings[1095] = ItemType.RabbitSpawnEgg; + mappings[1096] = ItemType.RavagerSpawnEgg; + mappings[1097] = ItemType.SalmonSpawnEgg; + mappings[1098] = ItemType.SheepSpawnEgg; + mappings[1099] = ItemType.ShulkerSpawnEgg; + mappings[1100] = ItemType.SilverfishSpawnEgg; + mappings[1101] = ItemType.SkeletonSpawnEgg; + mappings[1102] = ItemType.SkeletonHorseSpawnEgg; + mappings[1103] = ItemType.SlimeSpawnEgg; + mappings[1104] = ItemType.SnifferSpawnEgg; + mappings[1105] = ItemType.SnowGolemSpawnEgg; + mappings[1106] = ItemType.SpiderSpawnEgg; + mappings[1107] = ItemType.SquidSpawnEgg; + mappings[1108] = ItemType.StraySpawnEgg; + mappings[1109] = ItemType.StriderSpawnEgg; + mappings[1110] = ItemType.TadpoleSpawnEgg; + mappings[1111] = ItemType.TraderLlamaSpawnEgg; + mappings[1112] = ItemType.TropicalFishSpawnEgg; + mappings[1113] = ItemType.TurtleSpawnEgg; + mappings[1114] = ItemType.VexSpawnEgg; + mappings[1115] = ItemType.VillagerSpawnEgg; + mappings[1116] = ItemType.VindicatorSpawnEgg; + mappings[1117] = ItemType.WanderingTraderSpawnEgg; + mappings[1118] = ItemType.WardenSpawnEgg; + mappings[1119] = ItemType.WitchSpawnEgg; + mappings[1120] = ItemType.WitherSpawnEgg; + mappings[1121] = ItemType.WitherSkeletonSpawnEgg; + mappings[1122] = ItemType.WolfSpawnEgg; + mappings[1123] = ItemType.ZoglinSpawnEgg; + mappings[1124] = ItemType.CreakingSpawnEgg; + mappings[1125] = ItemType.ZombieSpawnEgg; + mappings[1126] = ItemType.ZombieHorseSpawnEgg; + mappings[1127] = ItemType.ZombieVillagerSpawnEgg; + mappings[1128] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1129] = ItemType.ExperienceBottle; + mappings[1130] = ItemType.FireCharge; + mappings[1131] = ItemType.WindCharge; + mappings[1132] = ItemType.WritableBook; + mappings[1133] = ItemType.WrittenBook; + mappings[1134] = ItemType.BreezeRod; + mappings[1135] = ItemType.Mace; + mappings[1136] = ItemType.ItemFrame; + mappings[1137] = ItemType.GlowItemFrame; + mappings[1138] = ItemType.FlowerPot; + mappings[1139] = ItemType.Carrot; + mappings[1140] = ItemType.Potato; + mappings[1141] = ItemType.BakedPotato; + mappings[1142] = ItemType.PoisonousPotato; + mappings[1143] = ItemType.Map; + mappings[1144] = ItemType.GoldenCarrot; + mappings[1145] = ItemType.SkeletonSkull; + mappings[1146] = ItemType.WitherSkeletonSkull; + mappings[1147] = ItemType.PlayerHead; + mappings[1148] = ItemType.ZombieHead; + mappings[1149] = ItemType.CreeperHead; + mappings[1150] = ItemType.DragonHead; + mappings[1151] = ItemType.PiglinHead; + mappings[1152] = ItemType.NetherStar; + mappings[1153] = ItemType.PumpkinPie; + mappings[1154] = ItemType.FireworkRocket; + mappings[1155] = ItemType.FireworkStar; + mappings[1156] = ItemType.EnchantedBook; + mappings[1157] = ItemType.NetherBrick; + mappings[1158] = ItemType.PrismarineShard; + mappings[1159] = ItemType.PrismarineCrystals; + mappings[1160] = ItemType.Rabbit; + mappings[1161] = ItemType.CookedRabbit; + mappings[1162] = ItemType.RabbitStew; + mappings[1163] = ItemType.RabbitFoot; + mappings[1164] = ItemType.RabbitHide; + mappings[1165] = ItemType.ArmorStand; + mappings[1166] = ItemType.IronHorseArmor; + mappings[1167] = ItemType.GoldenHorseArmor; + mappings[1168] = ItemType.DiamondHorseArmor; + mappings[1169] = ItemType.LeatherHorseArmor; + mappings[1170] = ItemType.Lead; + mappings[1171] = ItemType.NameTag; + mappings[1172] = ItemType.CommandBlockMinecart; + mappings[1173] = ItemType.Mutton; + mappings[1174] = ItemType.CookedMutton; + mappings[1175] = ItemType.WhiteBanner; + mappings[1176] = ItemType.OrangeBanner; + mappings[1177] = ItemType.MagentaBanner; + mappings[1178] = ItemType.LightBlueBanner; + mappings[1179] = ItemType.YellowBanner; + mappings[1180] = ItemType.LimeBanner; + mappings[1181] = ItemType.PinkBanner; + mappings[1182] = ItemType.GrayBanner; + mappings[1183] = ItemType.LightGrayBanner; + mappings[1184] = ItemType.CyanBanner; + mappings[1185] = ItemType.PurpleBanner; + mappings[1186] = ItemType.BlueBanner; + mappings[1187] = ItemType.BrownBanner; + mappings[1188] = ItemType.GreenBanner; + mappings[1189] = ItemType.RedBanner; + mappings[1190] = ItemType.BlackBanner; + mappings[1191] = ItemType.EndCrystal; + mappings[1192] = ItemType.ChorusFruit; + mappings[1193] = ItemType.PoppedChorusFruit; + mappings[1194] = ItemType.TorchflowerSeeds; + mappings[1195] = ItemType.PitcherPod; + mappings[1196] = ItemType.Beetroot; + mappings[1197] = ItemType.BeetrootSeeds; + mappings[1198] = ItemType.BeetrootSoup; + mappings[1199] = ItemType.DragonBreath; + mappings[1200] = ItemType.SplashPotion; + mappings[1201] = ItemType.SpectralArrow; + mappings[1202] = ItemType.TippedArrow; + mappings[1203] = ItemType.LingeringPotion; + mappings[1204] = ItemType.Shield; + mappings[1205] = ItemType.TotemOfUndying; + mappings[1206] = ItemType.ShulkerShell; + mappings[1207] = ItemType.IronNugget; + mappings[1208] = ItemType.KnowledgeBook; + mappings[1209] = ItemType.DebugStick; + mappings[1210] = ItemType.MusicDisc13; + mappings[1211] = ItemType.MusicDiscCat; + mappings[1212] = ItemType.MusicDiscBlocks; + mappings[1213] = ItemType.MusicDiscChirp; + mappings[1214] = ItemType.MusicDiscCreator; + mappings[1215] = ItemType.MusicDiscCreatorMusicBox; + mappings[1216] = ItemType.MusicDiscFar; + mappings[1217] = ItemType.MusicDiscMall; + mappings[1218] = ItemType.MusicDiscMellohi; + mappings[1219] = ItemType.MusicDiscStal; + mappings[1220] = ItemType.MusicDiscStrad; + mappings[1221] = ItemType.MusicDiscWard; + mappings[1222] = ItemType.MusicDisc11; + mappings[1223] = ItemType.MusicDiscWait; + mappings[1224] = ItemType.MusicDiscOtherside; + mappings[1225] = ItemType.MusicDiscRelic; + mappings[1226] = ItemType.MusicDisc5; + mappings[1227] = ItemType.MusicDiscPigstep; + mappings[1228] = ItemType.MusicDiscPrecipice; + mappings[1229] = ItemType.DiscFragment5; + mappings[1230] = ItemType.Trident; + mappings[1231] = ItemType.NautilusShell; + mappings[1232] = ItemType.HeartOfTheSea; + mappings[1233] = ItemType.Crossbow; + mappings[1234] = ItemType.SuspiciousStew; + mappings[1235] = ItemType.Loom; + mappings[1236] = ItemType.FlowerBannerPattern; + mappings[1237] = ItemType.CreeperBannerPattern; + mappings[1238] = ItemType.SkullBannerPattern; + mappings[1239] = ItemType.MojangBannerPattern; + mappings[1240] = ItemType.GlobeBannerPattern; + mappings[1241] = ItemType.PiglinBannerPattern; + mappings[1242] = ItemType.FlowBannerPattern; + mappings[1243] = ItemType.GusterBannerPattern; + mappings[1244] = ItemType.FieldMasonedBannerPattern; + mappings[1245] = ItemType.BordureIndentedBannerPattern; + mappings[1246] = ItemType.GoatHorn; + mappings[1247] = ItemType.Composter; + mappings[1248] = ItemType.Barrel; + mappings[1249] = ItemType.Smoker; + mappings[1250] = ItemType.BlastFurnace; + mappings[1251] = ItemType.CartographyTable; + mappings[1252] = ItemType.FletchingTable; + mappings[1253] = ItemType.Grindstone; + mappings[1254] = ItemType.SmithingTable; + mappings[1255] = ItemType.Stonecutter; + mappings[1256] = ItemType.Bell; + mappings[1257] = ItemType.Lantern; + mappings[1258] = ItemType.SoulLantern; + mappings[1259] = ItemType.SweetBerries; + mappings[1260] = ItemType.GlowBerries; + mappings[1261] = ItemType.Campfire; + mappings[1262] = ItemType.SoulCampfire; + mappings[1263] = ItemType.Shroomlight; + mappings[1264] = ItemType.Honeycomb; + mappings[1265] = ItemType.BeeNest; + mappings[1266] = ItemType.Beehive; + mappings[1267] = ItemType.HoneyBottle; + mappings[1268] = ItemType.HoneycombBlock; + mappings[1269] = ItemType.Lodestone; + mappings[1270] = ItemType.CryingObsidian; + mappings[1271] = ItemType.Blackstone; + mappings[1272] = ItemType.BlackstoneSlab; + mappings[1273] = ItemType.BlackstoneStairs; + mappings[1274] = ItemType.GildedBlackstone; + mappings[1275] = ItemType.PolishedBlackstone; + mappings[1276] = ItemType.PolishedBlackstoneSlab; + mappings[1277] = ItemType.PolishedBlackstoneStairs; + mappings[1278] = ItemType.ChiseledPolishedBlackstone; + mappings[1279] = ItemType.PolishedBlackstoneBricks; + mappings[1280] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1281] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1282] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1283] = ItemType.RespawnAnchor; + mappings[1284] = ItemType.Candle; + mappings[1285] = ItemType.WhiteCandle; + mappings[1286] = ItemType.OrangeCandle; + mappings[1287] = ItemType.MagentaCandle; + mappings[1288] = ItemType.LightBlueCandle; + mappings[1289] = ItemType.YellowCandle; + mappings[1290] = ItemType.LimeCandle; + mappings[1291] = ItemType.PinkCandle; + mappings[1292] = ItemType.GrayCandle; + mappings[1293] = ItemType.LightGrayCandle; + mappings[1294] = ItemType.CyanCandle; + mappings[1295] = ItemType.PurpleCandle; + mappings[1296] = ItemType.BlueCandle; + mappings[1297] = ItemType.BrownCandle; + mappings[1298] = ItemType.GreenCandle; + mappings[1299] = ItemType.RedCandle; + mappings[1300] = ItemType.BlackCandle; + mappings[1301] = ItemType.SmallAmethystBud; + mappings[1302] = ItemType.MediumAmethystBud; + mappings[1303] = ItemType.LargeAmethystBud; + mappings[1304] = ItemType.AmethystCluster; + mappings[1305] = ItemType.PointedDripstone; + mappings[1306] = ItemType.OchreFroglight; + mappings[1307] = ItemType.VerdantFroglight; + mappings[1308] = ItemType.PearlescentFroglight; + mappings[1309] = ItemType.Frogspawn; + mappings[1310] = ItemType.EchoShard; + mappings[1311] = ItemType.Brush; + mappings[1312] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1313] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1314] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1315] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1316] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1317] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1318] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1319] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1320] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1321] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1322] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1323] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1324] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1325] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1326] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1327] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1328] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1329] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1330] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1331] = ItemType.AnglerPotterySherd; + mappings[1332] = ItemType.ArcherPotterySherd; + mappings[1333] = ItemType.ArmsUpPotterySherd; + mappings[1334] = ItemType.BladePotterySherd; + mappings[1335] = ItemType.BrewerPotterySherd; + mappings[1336] = ItemType.BurnPotterySherd; + mappings[1337] = ItemType.DangerPotterySherd; + mappings[1338] = ItemType.ExplorerPotterySherd; + mappings[1339] = ItemType.FlowPotterySherd; + mappings[1340] = ItemType.FriendPotterySherd; + mappings[1341] = ItemType.GusterPotterySherd; + mappings[1342] = ItemType.HeartPotterySherd; + mappings[1343] = ItemType.HeartbreakPotterySherd; + mappings[1344] = ItemType.HowlPotterySherd; + mappings[1345] = ItemType.MinerPotterySherd; + mappings[1346] = ItemType.MournerPotterySherd; + mappings[1347] = ItemType.PlentyPotterySherd; + mappings[1348] = ItemType.PrizePotterySherd; + mappings[1349] = ItemType.ScrapePotterySherd; + mappings[1350] = ItemType.SheafPotterySherd; + mappings[1351] = ItemType.ShelterPotterySherd; + mappings[1352] = ItemType.SkullPotterySherd; + mappings[1353] = ItemType.SnortPotterySherd; + mappings[1354] = ItemType.CopperGrate; + mappings[1355] = ItemType.ExposedCopperGrate; + mappings[1356] = ItemType.WeatheredCopperGrate; + mappings[1357] = ItemType.OxidizedCopperGrate; + mappings[1358] = ItemType.WaxedCopperGrate; + mappings[1359] = ItemType.WaxedExposedCopperGrate; + mappings[1360] = ItemType.WaxedWeatheredCopperGrate; + mappings[1361] = ItemType.WaxedOxidizedCopperGrate; + mappings[1362] = ItemType.CopperBulb; + mappings[1363] = ItemType.ExposedCopperBulb; + mappings[1364] = ItemType.WeatheredCopperBulb; + mappings[1365] = ItemType.OxidizedCopperBulb; + mappings[1366] = ItemType.WaxedCopperBulb; + mappings[1367] = ItemType.WaxedExposedCopperBulb; + mappings[1368] = ItemType.WaxedWeatheredCopperBulb; + mappings[1369] = ItemType.WaxedOxidizedCopperBulb; + mappings[1370] = ItemType.TrialSpawner; + mappings[1371] = ItemType.TrialKey; + mappings[1372] = ItemType.OminousTrialKey; + mappings[1373] = ItemType.Vault; + mappings[1374] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 299eeb3e..318eb1fa 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -121,6 +121,7 @@ namespace MinecraftClient.Inventory BlackStainedGlassPane, BlackTerracotta, BlackWool, + BlackBundle, Blackstone, BlackstoneSlab, BlackstoneStairs, @@ -145,6 +146,7 @@ namespace MinecraftClient.Inventory BlueStainedGlassPane, BlueTerracotta, BlueWool, + BlueBundle, BoggedSpawnEgg, BoltArmorTrimSmithingTemplate, Bone, @@ -152,6 +154,7 @@ namespace MinecraftClient.Inventory BoneMeal, Book, Bookshelf, + BordureIndentedBannerPattern, Bow, Bowl, BrainCoral, @@ -182,6 +185,7 @@ namespace MinecraftClient.Inventory BrownStainedGlassPane, BrownTerracotta, BrownWool, + BrownBundle, Brush, BubbleCoral, BubbleCoralBlock, @@ -298,6 +302,8 @@ namespace MinecraftClient.Inventory CrackedStoneBricks, Crafter, CraftingTable, + CreakingHeart, + CreakingSpawnEgg, CreeperBannerPattern, CreeperHead, CreeperSpawnEgg, @@ -339,6 +345,7 @@ namespace MinecraftClient.Inventory CyanStainedGlassPane, CyanTerracotta, CyanWool, + CyanBundle, DamagedAnvil, Dandelion, DangerPotterySherd, @@ -472,6 +479,7 @@ namespace MinecraftClient.Inventory Feather, FermentedSpiderEye, Fern, + FieldMasonedBannerPattern, FilledMap, FireCharge, FireCoral, @@ -548,6 +556,7 @@ namespace MinecraftClient.Inventory GrayStainedGlassPane, GrayTerracotta, GrayWool, + GrayBundle, GreenBanner, GreenBed, GreenCandle, @@ -561,6 +570,7 @@ namespace MinecraftClient.Inventory GreenStainedGlassPane, GreenTerracotta, GreenWool, + GreenBundle, Grindstone, GuardianSpawnEgg, Gunpowder, @@ -668,6 +678,7 @@ namespace MinecraftClient.Inventory LightBlueStainedGlassPane, LightBlueTerracotta, LightBlueWool, + LightBlueBundle, LightGrayBanner, LightGrayBed, LightGrayCandle, @@ -681,6 +692,7 @@ namespace MinecraftClient.Inventory LightGrayStainedGlassPane, LightGrayTerracotta, LightGrayWool, + LightGrayBundle, LightWeightedPressurePlate, LightningRod, Lilac, @@ -699,6 +711,7 @@ namespace MinecraftClient.Inventory LimeStainedGlassPane, LimeTerracotta, LimeWool, + LimeBundle, LingeringPotion, LlamaSpawnEgg, Lodestone, @@ -717,6 +730,7 @@ namespace MinecraftClient.Inventory MagentaStainedGlassPane, MagentaTerracotta, MagentaWool, + MagentaBundle, MagmaBlock, MagmaCream, MagmaCubeSpawnEgg, @@ -855,6 +869,7 @@ namespace MinecraftClient.Inventory OrangeTerracotta, OrangeTulip, OrangeWool, + OrangeBundle, OxeyeDaisy, OxidizedChiseledCopper, OxidizedCopper, @@ -868,6 +883,26 @@ namespace MinecraftClient.Inventory PackedIce, PackedMud, Painting, + PaleHangingMoss, + PaleMossBlock, + PaleMossCarpet, + PaleOakBoat, + PaleOakButton, + PaleOakChestBoat, + PaleOakDoor, + PaleOakFence, + PaleOakFenceGate, + PaleOakHangingSign, + PaleOakLeaves, + PaleOakLog, + PaleOakPlanks, + PaleOakPressurePlate, + PaleOakSapling, + PaleOakSign, + PaleOakSlab, + PaleOakStairs, + PaleOakTrapdoor, + PaleOakWood, PandaSpawnEgg, Paper, ParrotSpawnEgg, @@ -897,6 +932,7 @@ namespace MinecraftClient.Inventory PinkTerracotta, PinkTulip, PinkWool, + PinkBundle, Piston, PitcherPlant, PitcherPod, @@ -970,6 +1006,7 @@ namespace MinecraftClient.Inventory PurpleStainedGlassPane, PurpleTerracotta, PurpleWool, + PurpleBundle, PurpurBlock, PurpurPillar, PurpurSlab, @@ -1020,6 +1057,7 @@ namespace MinecraftClient.Inventory RedTerracotta, RedTulip, RedWool, + RedBundle, Redstone, RedstoneBlock, RedstoneLamp, @@ -1167,6 +1205,8 @@ namespace MinecraftClient.Inventory StrippedMangroveWood, StrippedOakLog, StrippedOakWood, + StrippedPaleOakLog, + StrippedPaleOakWood, StrippedSpruceLog, StrippedSpruceWood, StrippedWarpedHyphae, @@ -1312,6 +1352,7 @@ namespace MinecraftClient.Inventory WhiteTerracotta, WhiteTulip, WhiteWool, + WhiteBundle, WildArmorTrimSmithingTemplate, WindCharge, WitchSpawnEgg, @@ -1341,6 +1382,7 @@ namespace MinecraftClient.Inventory YellowStainedGlassPane, YellowTerracotta, YellowWool, + YellowBundle, ZoglinSpawnEgg, ZombieHead, ZombieHorseSpawnEgg, diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1212.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1212.cs new file mode 100644 index 00000000..e46c7650 --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1212.cs @@ -0,0 +1,1811 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1212 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1212() + { + for (int i = 8938; i <= 8961; i++) + materials[i] = Material.AcaciaButton; + for (int i = 12419; i <= 12482; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 12035; i <= 12066; i++) + materials[i] = Material.AcaciaFence; + for (int i = 11747; i <= 11778; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5118; i <= 5181; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 5888; i <= 5889; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 4450; i <= 4481; i++) + materials[i] = Material.AcaciaSign; + for (int i = 11521; i <= 11526; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 10139; i <= 10218; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 6383; i <= 6446; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 5718; i <= 5725; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 4870; i <= 4877; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 9575; i <= 9598; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2122] = Material.Allium; + materials[21500] = Material.AmethystBlock; + for (int i = 21502; i <= 21513; i++) + materials[i] = Material.AmethystCluster; + materials[19917] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 14605; i <= 14610; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 14231; i <= 14310; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 17221; i <= 17544; i++) + materials[i] = Material.AndesiteWall; + for (int i = 9362; i <= 9365; i++) + materials[i] = Material.Anvil; + for (int i = 7047; i <= 7050; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 7043; i <= 7046; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[25293] = Material.Azalea; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + materials[2123] = Material.AzureBluet; + for (int i = 13414; i <= 13425; i++) + materials[i] = Material.Bamboo; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 9058; i <= 9081; i++) + materials[i] = Material.BambooButton; + for (int i = 12739; i <= 12802; i++) + materials[i] = Material.BambooDoor; + for (int i = 12195; i <= 12226; i++) + materials[i] = Material.BambooFence; + for (int i = 11907; i <= 11938; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 5630; i <= 5693; i++) + materials[i] = Material.BambooHangingSign; + materials[28] = Material.BambooMosaic; + for (int i = 11557; i <= 11562; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 10619; i <= 10698; i++) + materials[i] = Material.BambooMosaicStairs; + materials[27] = Material.BambooPlanks; + for (int i = 5898; i <= 5899; i++) + materials[i] = Material.BambooPressurePlate; + materials[13413] = Material.BambooSapling; + for (int i = 4642; i <= 4673; i++) + materials[i] = Material.BambooSign; + for (int i = 11551; i <= 11556; i++) + materials[i] = Material.BambooSlab; + for (int i = 10539; i <= 10618; i++) + materials[i] = Material.BambooStairs; + for (int i = 6703; i <= 6766; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 5782; i <= 5789; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 4918; i <= 4925; i++) + materials[i] = Material.BambooWallSign; + for (int i = 18877; i <= 18888; i++) + materials[i] = Material.Barrel; + for (int i = 10700; i <= 10701; i++) + materials[i] = Material.Barrier; + for (int i = 6018; i <= 6020; i++) + materials[i] = Material.Basalt; + materials[8148] = Material.Beacon; + materials[85] = Material.Bedrock; + for (int i = 19866; i <= 19889; i++) + materials[i] = Material.BeeNest; + for (int i = 19890; i <= 19913; i++) + materials[i] = Material.Beehive; + for (int i = 12978; i <= 12981; i++) + materials[i] = Material.Beetroots; + for (int i = 18940; i <= 18971; i++) + materials[i] = Material.Bell; + for (int i = 25313; i <= 25344; i++) + materials[i] = Material.BigDripleaf; + for (int i = 25345; i <= 25352; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 8890; i <= 8913; i++) + materials[i] = Material.BirchButton; + for (int i = 12291; i <= 12354; i++) + materials[i] = Material.BirchDoor; + for (int i = 11971; i <= 12002; i++) + materials[i] = Material.BirchFence; + for (int i = 11683; i <= 11714; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 5054; i <= 5117; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 5884; i <= 5885; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 4418; i <= 4449; i++) + materials[i] = Material.BirchSign; + for (int i = 11509; i <= 11514; i++) + materials[i] = Material.BirchSlab; + for (int i = 7976; i <= 8055; i++) + materials[i] = Material.BirchStairs; + for (int i = 6255; i <= 6318; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 5710; i <= 5717; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 4862; i <= 4869; i++) + materials[i] = Material.BirchWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 11334; i <= 11349; i++) + materials[i] = Material.BlackBanner; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 21450; i <= 21465; i++) + materials[i] = Material.BlackCandle; + for (int i = 21498; i <= 21499; i++) + materials[i] = Material.BlackCandleCake; + materials[11078] = Material.BlackCarpet; + materials[13212] = Material.BlackConcrete; + materials[13228] = Material.BlackConcretePowder; + for (int i = 13193; i <= 13196; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 13127; i <= 13132; i++) + materials[i] = Material.BlackShulkerBox; + materials[6126] = Material.BlackStainedGlass; + for (int i = 10107; i <= 10138; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[9626] = Material.BlackTerracotta; + for (int i = 11410; i <= 11413; i++) + materials[i] = Material.BlackWallBanner; + materials[2105] = Material.BlackWool; + materials[19929] = Material.Blackstone; + for (int i = 20334; i <= 20339; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 19930; i <= 20009; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 20010; i <= 20333; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 18897; i <= 18904; i++) + materials[i] = Material.BlastFurnace; + for (int i = 11270; i <= 11285; i++) + materials[i] = Material.BlueBanner; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 21386; i <= 21401; i++) + materials[i] = Material.BlueCandle; + for (int i = 21490; i <= 21491; i++) + materials[i] = Material.BlueCandleCake; + materials[11074] = Material.BlueCarpet; + materials[13208] = Material.BlueConcrete; + materials[13224] = Material.BlueConcretePowder; + for (int i = 13177; i <= 13180; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[13410] = Material.BlueIce; + materials[2121] = Material.BlueOrchid; + for (int i = 13103; i <= 13108; i++) + materials[i] = Material.BlueShulkerBox; + materials[6122] = Material.BlueStainedGlass; + for (int i = 9979; i <= 10010; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[9622] = Material.BlueTerracotta; + for (int i = 11394; i <= 11397; i++) + materials[i] = Material.BlueWallBanner; + materials[2101] = Material.BlueWool; + for (int i = 13015; i <= 13017; i++) + materials[i] = Material.BoneBlock; + materials[2139] = Material.Bookshelf; + for (int i = 13294; i <= 13295; i++) + materials[i] = Material.BrainCoral; + materials[13278] = Material.BrainCoralBlock; + for (int i = 13314; i <= 13315; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 13370; i <= 13377; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 7620; i <= 7627; i++) + materials[i] = Material.BrewingStand; + for (int i = 11599; i <= 11604; i++) + materials[i] = Material.BrickSlab; + for (int i = 7259; i <= 7338; i++) + materials[i] = Material.BrickStairs; + for (int i = 14629; i <= 14952; i++) + materials[i] = Material.BrickWall; + materials[2136] = Material.Bricks; + for (int i = 11286; i <= 11301; i++) + materials[i] = Material.BrownBanner; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 21402; i <= 21417; i++) + materials[i] = Material.BrownCandle; + for (int i = 21492; i <= 21493; i++) + materials[i] = Material.BrownCandleCake; + materials[11075] = Material.BrownCarpet; + materials[13209] = Material.BrownConcrete; + materials[13225] = Material.BrownConcretePowder; + for (int i = 13181; i <= 13184; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2132] = Material.BrownMushroom; + for (int i = 6779; i <= 6842; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 13109; i <= 13114; i++) + materials[i] = Material.BrownShulkerBox; + materials[6123] = Material.BrownStainedGlass; + for (int i = 10011; i <= 10042; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[9623] = Material.BrownTerracotta; + for (int i = 11398; i <= 11401; i++) + materials[i] = Material.BrownWallBanner; + materials[2102] = Material.BrownWool; + for (int i = 13429; i <= 13430; i++) + materials[i] = Material.BubbleColumn; + for (int i = 13296; i <= 13297; i++) + materials[i] = Material.BubbleCoral; + materials[13279] = Material.BubbleCoralBlock; + for (int i = 13316; i <= 13317; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 13378; i <= 13385; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[21501] = Material.BuddingAmethyst; + for (int i = 5948; i <= 5963; i++) + materials[i] = Material.Cactus; + for (int i = 6040; i <= 6046; i++) + materials[i] = Material.Cake; + materials[22785] = Material.Calcite; + for (int i = 22884; i <= 23267; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 18980; i <= 19011; i++) + materials[i] = Material.Campfire; + for (int i = 21194; i <= 21209; i++) + materials[i] = Material.Candle; + for (int i = 21466; i <= 21467; i++) + materials[i] = Material.CandleCake; + for (int i = 8826; i <= 8833; i++) + materials[i] = Material.Carrots; + materials[18905] = Material.CartographyTable; + for (int i = 6032; i <= 6035; i++) + materials[i] = Material.CarvedPumpkin; + materials[7628] = Material.Cauldron; + materials[13428] = Material.CaveAir; + for (int i = 25238; i <= 25289; i++) + materials[i] = Material.CaveVines; + for (int i = 25290; i <= 25291; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 7003; i <= 7008; i++) + materials[i] = Material.Chain; + for (int i = 12996; i <= 13007; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 8962; i <= 8985; i++) + materials[i] = Material.CherryButton; + for (int i = 12483; i <= 12546; i++) + materials[i] = Material.CherryDoor; + for (int i = 12067; i <= 12098; i++) + materials[i] = Material.CherryFence; + for (int i = 11779; i <= 11810; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5182; i <= 5245; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 5890; i <= 5891; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 4482; i <= 4513; i++) + materials[i] = Material.CherrySign; + for (int i = 11527; i <= 11532; i++) + materials[i] = Material.CherrySlab; + for (int i = 10219; i <= 10298; i++) + materials[i] = Material.CherryStairs; + for (int i = 6447; i <= 6510; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 5726; i <= 5733; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 4878; i <= 4885; i++) + materials[i] = Material.CherryWallSign; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 3006; i <= 3029; i++) + materials[i] = Material.Chest; + for (int i = 9366; i <= 9369; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2140; i <= 2395; i++) + materials[i] = Material.ChiseledBookshelf; + materials[23420] = Material.ChiseledCopper; + materials[27020] = Material.ChiseledDeepslate; + materials[21191] = Material.ChiseledNetherBricks; + materials[20343] = Material.ChiseledPolishedBlackstone; + materials[9491] = Material.ChiseledQuartzBlock; + materials[11415] = Material.ChiseledRedSandstone; + materials[579] = Material.ChiseledSandstone; + materials[6770] = Material.ChiseledStoneBricks; + materials[22372] = Material.ChiseledTuff; + materials[22784] = Material.ChiseledTuffBricks; + for (int i = 12873; i <= 12878; i++) + materials[i] = Material.ChorusFlower; + for (int i = 12809; i <= 12872; i++) + materials[i] = Material.ChorusPlant; + materials[5964] = Material.Clay; + materials[11080] = Material.CoalBlock; + materials[133] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[25376] = Material.CobbledDeepslate; + for (int i = 25457; i <= 25462; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 25377; i <= 25456; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 25463; i <= 25786; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 11593; i <= 11598; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 4766; i <= 4845; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 8149; i <= 8472; i++) + materials[i] = Material.CobblestoneWall; + materials[2047] = Material.Cobweb; + for (int i = 7649; i <= 7660; i++) + materials[i] = Material.Cocoa; + for (int i = 8136; i <= 8147; i++) + materials[i] = Material.CommandBlock; + for (int i = 9430; i <= 9445; i++) + materials[i] = Material.Comparator; + for (int i = 19841; i <= 19849; i++) + materials[i] = Material.Composter; + for (int i = 13411; i <= 13412; i++) + materials[i] = Material.Conduit; + materials[23407] = Material.CopperBlock; + for (int i = 25161; i <= 25164; i++) + materials[i] = Material.CopperBulb; + for (int i = 24121; i <= 24184; i++) + materials[i] = Material.CopperDoor; + for (int i = 25145; i <= 25146; i++) + materials[i] = Material.CopperGrate; + materials[23411] = Material.CopperOre; + for (int i = 24633; i <= 24696; i++) + materials[i] = Material.CopperTrapdoor; + materials[2129] = Material.Cornflower; + materials[27021] = Material.CrackedDeepslateBricks; + materials[27022] = Material.CrackedDeepslateTiles; + materials[21192] = Material.CrackedNetherBricks; + materials[20342] = Material.CrackedPolishedBlackstoneBricks; + materials[6769] = Material.CrackedStoneBricks; + for (int i = 27059; i <= 27106; i++) + materials[i] = Material.Crafter; + materials[4329] = Material.CraftingTable; + for (int i = 2917; i <= 2925; i++) + materials[i] = Material.CreakingHeart; + for (int i = 9242; i <= 9273; i++) + materials[i] = Material.CreeperHead; + for (int i = 9274; i <= 9281; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 19569; i <= 19592; i++) + materials[i] = Material.CrimsonButton; + for (int i = 19617; i <= 19680; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 19153; i <= 19184; i++) + materials[i] = Material.CrimsonFence; + for (int i = 19345; i <= 19376; i++) + materials[i] = Material.CrimsonFenceGate; + materials[19078] = Material.CrimsonFungus; + for (int i = 5438; i <= 5501; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 19071; i <= 19073; i++) + materials[i] = Material.CrimsonHyphae; + materials[19077] = Material.CrimsonNylium; + materials[19135] = Material.CrimsonPlanks; + for (int i = 19149; i <= 19150; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[19134] = Material.CrimsonRoots; + for (int i = 19745; i <= 19776; i++) + materials[i] = Material.CrimsonSign; + for (int i = 19137; i <= 19142; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 19409; i <= 19488; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 19065; i <= 19067; i++) + materials[i] = Material.CrimsonStem; + for (int i = 19217; i <= 19280; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 5766; i <= 5773; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 19809; i <= 19816; i++) + materials[i] = Material.CrimsonWallSign; + materials[19918] = Material.CryingObsidian; + materials[23416] = Material.CutCopper; + for (int i = 23763; i <= 23768; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 23665; i <= 23744; i++) + materials[i] = Material.CutCopperStairs; + materials[11416] = Material.CutRedSandstone; + for (int i = 11635; i <= 11640; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[580] = Material.CutSandstone; + for (int i = 11581; i <= 11586; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 11238; i <= 11253; i++) + materials[i] = Material.CyanBanner; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 21354; i <= 21369; i++) + materials[i] = Material.CyanCandle; + for (int i = 21486; i <= 21487; i++) + materials[i] = Material.CyanCandleCake; + materials[11072] = Material.CyanCarpet; + materials[13206] = Material.CyanConcrete; + materials[13222] = Material.CyanConcretePowder; + for (int i = 13169; i <= 13172; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 13091; i <= 13096; i++) + materials[i] = Material.CyanShulkerBox; + materials[6120] = Material.CyanStainedGlass; + for (int i = 9915; i <= 9946; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[9620] = Material.CyanTerracotta; + for (int i = 11386; i <= 11389; i++) + materials[i] = Material.CyanWallBanner; + materials[2099] = Material.CyanWool; + for (int i = 9370; i <= 9373; i++) + materials[i] = Material.DamagedAnvil; + materials[2118] = Material.Dandelion; + for (int i = 8986; i <= 9009; i++) + materials[i] = Material.DarkOakButton; + for (int i = 12547; i <= 12610; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 12099; i <= 12130; i++) + materials[i] = Material.DarkOakFence; + for (int i = 11811; i <= 11842; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 5310; i <= 5373; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 5892; i <= 5893; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 4546; i <= 4577; i++) + materials[i] = Material.DarkOakSign; + for (int i = 11533; i <= 11538; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 10299; i <= 10378; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 6511; i <= 6574; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 5742; i <= 5749; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 4894; i <= 4901; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + materials[10800] = Material.DarkPrismarine; + for (int i = 11053; i <= 11058; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 10961; i <= 11040; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 9446; i <= 9477; i++) + materials[i] = Material.DaylightDetector; + for (int i = 13284; i <= 13285; i++) + materials[i] = Material.DeadBrainCoral; + materials[13273] = Material.DeadBrainCoralBlock; + for (int i = 13304; i <= 13305; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 13330; i <= 13337; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 13286; i <= 13287; i++) + materials[i] = Material.DeadBubbleCoral; + materials[13274] = Material.DeadBubbleCoralBlock; + for (int i = 13306; i <= 13307; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 13338; i <= 13345; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2050] = Material.DeadBush; + for (int i = 13288; i <= 13289; i++) + materials[i] = Material.DeadFireCoral; + materials[13275] = Material.DeadFireCoralBlock; + for (int i = 13308; i <= 13309; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 13346; i <= 13353; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 13290; i <= 13291; i++) + materials[i] = Material.DeadHornCoral; + materials[13276] = Material.DeadHornCoralBlock; + for (int i = 13310; i <= 13311; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 13354; i <= 13361; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 13282; i <= 13283; i++) + materials[i] = Material.DeadTubeCoral; + materials[13272] = Material.DeadTubeCoralBlock; + for (int i = 13302; i <= 13303; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 13322; i <= 13329; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 27043; i <= 27058; i++) + materials[i] = Material.DecoratedPot; + for (int i = 25373; i <= 25375; i++) + materials[i] = Material.Deepslate; + for (int i = 26690; i <= 26695; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 26610; i <= 26689; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 26696; i <= 27019; i++) + materials[i] = Material.DeepslateBrickWall; + materials[26609] = Material.DeepslateBricks; + materials[134] = Material.DeepslateCoalOre; + materials[23412] = Material.DeepslateCopperOre; + materials[4327] = Material.DeepslateDiamondOre; + materials[7742] = Material.DeepslateEmeraldOre; + materials[130] = Material.DeepslateGoldOre; + materials[132] = Material.DeepslateIronOre; + materials[564] = Material.DeepslateLapisOre; + for (int i = 5902; i <= 5903; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 26279; i <= 26284; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 26199; i <= 26278; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 26285; i <= 26608; i++) + materials[i] = Material.DeepslateTileWall; + materials[26198] = Material.DeepslateTiles; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + materials[4328] = Material.DiamondBlock; + materials[4326] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 14623; i <= 14628; i++) + materials[i] = Material.DioriteSlab; + for (int i = 14471; i <= 14550; i++) + materials[i] = Material.DioriteStairs; + for (int i = 18517; i <= 18840; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[12982] = Material.DirtPath; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + materials[7646] = Material.DragonEgg; + for (int i = 9282; i <= 9313; i++) + materials[i] = Material.DragonHead; + for (int i = 9314; i <= 9321; i++) + materials[i] = Material.DragonWallHead; + materials[13256] = Material.DriedKelpBlock; + materials[25237] = Material.DripstoneBlock; + for (int i = 9599; i <= 9610; i++) + materials[i] = Material.Dropper; + materials[7895] = Material.EmeraldBlock; + materials[7741] = Material.EmeraldOre; + materials[7619] = Material.EnchantingTable; + materials[12983] = Material.EndGateway; + materials[7636] = Material.EndPortal; + for (int i = 7637; i <= 7644; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 12803; i <= 12808; i++) + materials[i] = Material.EndRod; + materials[7645] = Material.EndStone; + for (int i = 14581; i <= 14586; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 13831; i <= 13910; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 18193; i <= 18516; i++) + materials[i] = Material.EndStoneBrickWall; + materials[12963] = Material.EndStoneBricks; + for (int i = 7743; i <= 7750; i++) + materials[i] = Material.EnderChest; + materials[23419] = Material.ExposedChiseledCopper; + materials[23408] = Material.ExposedCopper; + for (int i = 25165; i <= 25168; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 24185; i <= 24248; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 25147; i <= 25148; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 24697; i <= 24760; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[23415] = Material.ExposedCutCopper; + for (int i = 23757; i <= 23762; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 23585; i <= 23664; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 4338; i <= 4345; i++) + materials[i] = Material.Farmland; + materials[2049] = Material.Fern; + for (int i = 2403; i <= 2914; i++) + materials[i] = Material.Fire; + for (int i = 13298; i <= 13299; i++) + materials[i] = Material.FireCoral; + materials[13280] = Material.FireCoralBlock; + for (int i = 13318; i <= 13319; i++) + materials[i] = Material.FireCoralFan; + for (int i = 13386; i <= 13393; i++) + materials[i] = Material.FireCoralWallFan; + materials[18906] = Material.FletchingTable; + materials[8797] = Material.FlowerPot; + materials[25294] = Material.FloweringAzalea; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[27041] = Material.Frogspawn; + for (int i = 13008; i <= 13011; i++) + materials[i] = Material.FrostedIce; + for (int i = 4346; i <= 4353; i++) + materials[i] = Material.Furnace; + materials[20754] = Material.GildedBlackstone; + materials[562] = Material.Glass; + for (int i = 7009; i <= 7040; i++) + materials[i] = Material.GlassPane; + for (int i = 7099; i <= 7226; i++) + materials[i] = Material.GlowLichen; + materials[6029] = Material.Glowstone; + materials[2134] = Material.GoldBlock; + materials[129] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 14599; i <= 14604; i++) + materials[i] = Material.GraniteSlab; + for (int i = 14151; i <= 14230; i++) + materials[i] = Material.GraniteStairs; + for (int i = 15925; i <= 16248; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[124] = Material.Gravel; + for (int i = 11206; i <= 11221; i++) + materials[i] = Material.GrayBanner; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 21322; i <= 21337; i++) + materials[i] = Material.GrayCandle; + for (int i = 21482; i <= 21483; i++) + materials[i] = Material.GrayCandleCake; + materials[11070] = Material.GrayCarpet; + materials[13204] = Material.GrayConcrete; + materials[13220] = Material.GrayConcretePowder; + for (int i = 13161; i <= 13164; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 13079; i <= 13084; i++) + materials[i] = Material.GrayShulkerBox; + materials[6118] = Material.GrayStainedGlass; + for (int i = 9851; i <= 9882; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[9618] = Material.GrayTerracotta; + for (int i = 11378; i <= 11381; i++) + materials[i] = Material.GrayWallBanner; + materials[2097] = Material.GrayWool; + for (int i = 11302; i <= 11317; i++) + materials[i] = Material.GreenBanner; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 21418; i <= 21433; i++) + materials[i] = Material.GreenCandle; + for (int i = 21494; i <= 21495; i++) + materials[i] = Material.GreenCandleCake; + materials[11076] = Material.GreenCarpet; + materials[13210] = Material.GreenConcrete; + materials[13226] = Material.GreenConcretePowder; + for (int i = 13185; i <= 13188; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 13115; i <= 13120; i++) + materials[i] = Material.GreenShulkerBox; + materials[6124] = Material.GreenStainedGlass; + for (int i = 10043; i <= 10074; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[9624] = Material.GreenTerracotta; + for (int i = 11402; i <= 11405; i++) + materials[i] = Material.GreenWallBanner; + materials[2103] = Material.GreenWool; + for (int i = 18907; i <= 18918; i++) + materials[i] = Material.Grindstone; + for (int i = 25369; i <= 25370; i++) + materials[i] = Material.HangingRoots; + for (int i = 11060; i <= 11062; i++) + materials[i] = Material.HayBlock; + for (int i = 27151; i <= 27152; i++) + materials[i] = Material.HeavyCore; + for (int i = 9414; i <= 9429; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[19914] = Material.HoneyBlock; + materials[19915] = Material.HoneycombBlock; + for (int i = 9480; i <= 9489; i++) + materials[i] = Material.Hopper; + for (int i = 13300; i <= 13301; i++) + materials[i] = Material.HornCoral; + materials[13281] = Material.HornCoralBlock; + for (int i = 13320; i <= 13321; i++) + materials[i] = Material.HornCoralFan; + for (int i = 13394; i <= 13401; i++) + materials[i] = Material.HornCoralWallFan; + materials[5946] = Material.Ice; + materials[6778] = Material.InfestedChiseledStoneBricks; + materials[6774] = Material.InfestedCobblestone; + materials[6777] = Material.InfestedCrackedStoneBricks; + for (int i = 27023; i <= 27025; i++) + materials[i] = Material.InfestedDeepslate; + materials[6776] = Material.InfestedMossyStoneBricks; + materials[6773] = Material.InfestedStone; + materials[6775] = Material.InfestedStoneBricks; + for (int i = 6971; i <= 7002; i++) + materials[i] = Material.IronBars; + materials[2135] = Material.IronBlock; + for (int i = 5816; i <= 5879; i++) + materials[i] = Material.IronDoor; + materials[131] = Material.IronOre; + for (int i = 10734; i <= 10797; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 6036; i <= 6039; i++) + materials[i] = Material.JackOLantern; + for (int i = 19829; i <= 19840; i++) + materials[i] = Material.Jigsaw; + for (int i = 5981; i <= 5982; i++) + materials[i] = Material.Jukebox; + for (int i = 8914; i <= 8937; i++) + materials[i] = Material.JungleButton; + for (int i = 12355; i <= 12418; i++) + materials[i] = Material.JungleDoor; + for (int i = 12003; i <= 12034; i++) + materials[i] = Material.JungleFence; + for (int i = 11715; i <= 11746; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 5246; i <= 5309; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 5886; i <= 5887; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 4514; i <= 4545; i++) + materials[i] = Material.JungleSign; + for (int i = 11515; i <= 11520; i++) + materials[i] = Material.JungleSlab; + for (int i = 8056; i <= 8135; i++) + materials[i] = Material.JungleStairs; + for (int i = 6319; i <= 6382; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 5734; i <= 5741; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 4886; i <= 4893; i++) + materials[i] = Material.JungleWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 13229; i <= 13254; i++) + materials[i] = Material.Kelp; + materials[13255] = Material.KelpPlant; + for (int i = 4738; i <= 4745; i++) + materials[i] = Material.Ladder; + for (int i = 18972; i <= 18975; i++) + materials[i] = Material.Lantern; + materials[565] = Material.LapisBlock; + materials[563] = Material.LapisOre; + for (int i = 21514; i <= 21525; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 11092; i <= 11093; i++) + materials[i] = Material.LargeFern; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + materials[7632] = Material.LavaCauldron; + for (int i = 18919; i <= 18934; i++) + materials[i] = Material.Lectern; + for (int i = 5790; i <= 5813; i++) + materials[i] = Material.Lever; + for (int i = 10702; i <= 10733; i++) + materials[i] = Material.Light; + for (int i = 11142; i <= 11157; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 21258; i <= 21273; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 21474; i <= 21475; i++) + materials[i] = Material.LightBlueCandleCake; + materials[11066] = Material.LightBlueCarpet; + materials[13200] = Material.LightBlueConcrete; + materials[13216] = Material.LightBlueConcretePowder; + for (int i = 13145; i <= 13148; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 13055; i <= 13060; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[6114] = Material.LightBlueStainedGlass; + for (int i = 9723; i <= 9754; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[9614] = Material.LightBlueTerracotta; + for (int i = 11362; i <= 11365; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2093] = Material.LightBlueWool; + for (int i = 11222; i <= 11237; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 21338; i <= 21353; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 21484; i <= 21485; i++) + materials[i] = Material.LightGrayCandleCake; + materials[11071] = Material.LightGrayCarpet; + materials[13205] = Material.LightGrayConcrete; + materials[13221] = Material.LightGrayConcretePowder; + for (int i = 13165; i <= 13168; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 13085; i <= 13090; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[6119] = Material.LightGrayStainedGlass; + for (int i = 9883; i <= 9914; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[9619] = Material.LightGrayTerracotta; + for (int i = 11382; i <= 11385; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2098] = Material.LightGrayWool; + for (int i = 9398; i <= 9413; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 25193; i <= 25216; i++) + materials[i] = Material.LightningRod; + for (int i = 11084; i <= 11085; i++) + materials[i] = Material.Lilac; + materials[2131] = Material.LilyOfTheValley; + materials[7501] = Material.LilyPad; + for (int i = 11174; i <= 11189; i++) + materials[i] = Material.LimeBanner; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; + for (int i = 21290; i <= 21305; i++) + materials[i] = Material.LimeCandle; + for (int i = 21478; i <= 21479; i++) + materials[i] = Material.LimeCandleCake; + materials[11068] = Material.LimeCarpet; + materials[13202] = Material.LimeConcrete; + materials[13218] = Material.LimeConcretePowder; + for (int i = 13153; i <= 13156; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 13067; i <= 13072; i++) + materials[i] = Material.LimeShulkerBox; + materials[6116] = Material.LimeStainedGlass; + for (int i = 9787; i <= 9818; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[9616] = Material.LimeTerracotta; + for (int i = 11370; i <= 11373; i++) + materials[i] = Material.LimeWallBanner; + materials[2095] = Material.LimeWool; + materials[19928] = Material.Lodestone; + for (int i = 18873; i <= 18876; i++) + materials[i] = Material.Loom; + for (int i = 11126; i <= 11141; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 21242; i <= 21257; i++) + materials[i] = Material.MagentaCandle; + for (int i = 21472; i <= 21473; i++) + materials[i] = Material.MagentaCandleCake; + materials[11065] = Material.MagentaCarpet; + materials[13199] = Material.MagentaConcrete; + materials[13215] = Material.MagentaConcretePowder; + for (int i = 13141; i <= 13144; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 13049; i <= 13054; i++) + materials[i] = Material.MagentaShulkerBox; + materials[6113] = Material.MagentaStainedGlass; + for (int i = 9691; i <= 9722; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[9613] = Material.MagentaTerracotta; + for (int i = 11358; i <= 11361; i++) + materials[i] = Material.MagentaWallBanner; + materials[2092] = Material.MagentaWool; + materials[13012] = Material.MagmaBlock; + for (int i = 9034; i <= 9057; i++) + materials[i] = Material.MangroveButton; + for (int i = 12675; i <= 12738; i++) + materials[i] = Material.MangroveDoor; + for (int i = 12163; i <= 12194; i++) + materials[i] = Material.MangroveFence; + for (int i = 11875; i <= 11906; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 5566; i <= 5629; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + materials[26] = Material.MangrovePlanks; + for (int i = 5896; i <= 5897; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 4610; i <= 4641; i++) + materials[i] = Material.MangroveSign; + for (int i = 11545; i <= 11550; i++) + materials[i] = Material.MangroveSlab; + for (int i = 10459; i <= 10538; i++) + materials[i] = Material.MangroveStairs; + for (int i = 6639; i <= 6702; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 5758; i <= 5765; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 4910; i <= 4917; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 21526; i <= 21537; i++) + materials[i] = Material.MediumAmethystBud; + materials[7042] = Material.Melon; + for (int i = 7059; i <= 7066; i++) + materials[i] = Material.MelonStem; + materials[25312] = Material.MossBlock; + materials[25295] = Material.MossCarpet; + materials[2396] = Material.MossyCobblestone; + for (int i = 14575; i <= 14580; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 13751; i <= 13830; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 8473; i <= 8796; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 14563; i <= 14568; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 13591; i <= 13670; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 15601; i <= 15924; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[6768] = Material.MossyStoneBricks; + for (int i = 2106; i <= 2117; i++) + materials[i] = Material.MovingPiston; + materials[25372] = Material.Mud; + for (int i = 11611; i <= 11616; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 7419; i <= 7498; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 16573; i <= 16896; i++) + materials[i] = Material.MudBrickWall; + materials[6772] = Material.MudBricks; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 6907; i <= 6970; i++) + materials[i] = Material.MushroomStem; + for (int i = 7499; i <= 7500; i++) + materials[i] = Material.Mycelium; + for (int i = 7503; i <= 7534; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 11617; i <= 11622; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 7535; i <= 7614; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 16897; i <= 17220; i++) + materials[i] = Material.NetherBrickWall; + materials[7502] = Material.NetherBricks; + materials[135] = Material.NetherGoldOre; + for (int i = 6030; i <= 6031; i++) + materials[i] = Material.NetherPortal; + materials[9479] = Material.NetherQuartzOre; + materials[19064] = Material.NetherSprouts; + for (int i = 7615; i <= 7618; i++) + materials[i] = Material.NetherWart; + materials[13013] = Material.NetherWartBlock; + materials[19916] = Material.NetheriteBlock; + materials[6015] = Material.Netherrack; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 8842; i <= 8865; i++) + materials[i] = Material.OakButton; + for (int i = 4674; i <= 4737; i++) + materials[i] = Material.OakDoor; + for (int i = 5983; i <= 6014; i++) + materials[i] = Material.OakFence; + for (int i = 7227; i <= 7258; i++) + materials[i] = Material.OakFenceGate; + for (int i = 4926; i <= 4989; i++) + materials[i] = Material.OakHangingSign; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 5880; i <= 5881; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 4354; i <= 4385; i++) + materials[i] = Material.OakSign; + for (int i = 11497; i <= 11502; i++) + materials[i] = Material.OakSlab; + for (int i = 2926; i <= 3005; i++) + materials[i] = Material.OakStairs; + for (int i = 6127; i <= 6190; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 5694; i <= 5701; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 4846; i <= 4853; i++) + materials[i] = Material.OakWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 13019; i <= 13030; i++) + materials[i] = Material.Observer; + materials[2397] = Material.Obsidian; + for (int i = 27032; i <= 27034; i++) + materials[i] = Material.OchreFroglight; + for (int i = 11110; i <= 11125; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 21226; i <= 21241; i++) + materials[i] = Material.OrangeCandle; + for (int i = 21470; i <= 21471; i++) + materials[i] = Material.OrangeCandleCake; + materials[11064] = Material.OrangeCarpet; + materials[13198] = Material.OrangeConcrete; + materials[13214] = Material.OrangeConcretePowder; + for (int i = 13137; i <= 13140; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 13043; i <= 13048; i++) + materials[i] = Material.OrangeShulkerBox; + materials[6112] = Material.OrangeStainedGlass; + for (int i = 9659; i <= 9690; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[9612] = Material.OrangeTerracotta; + materials[2125] = Material.OrangeTulip; + for (int i = 11354; i <= 11357; i++) + materials[i] = Material.OrangeWallBanner; + materials[2091] = Material.OrangeWool; + materials[2128] = Material.OxeyeDaisy; + materials[23417] = Material.OxidizedChiseledCopper; + materials[23410] = Material.OxidizedCopper; + for (int i = 25173; i <= 25176; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 24249; i <= 24312; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 25151; i <= 25152; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 24761; i <= 24824; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[23413] = Material.OxidizedCutCopper; + for (int i = 23745; i <= 23750; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 23425; i <= 23504; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[11081] = Material.PackedIce; + materials[6771] = Material.PackedMud; + for (int i = 27316; i <= 27317; i++) + materials[i] = Material.PaleHangingMoss; + materials[27153] = Material.PaleMossBlock; + for (int i = 27154; i <= 27315; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 9010; i <= 9033; i++) + materials[i] = Material.PaleOakButton; + for (int i = 12611; i <= 12674; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 12131; i <= 12162; i++) + materials[i] = Material.PaleOakFence; + for (int i = 11843; i <= 11874; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 5374; i <= 5437; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + materials[25] = Material.PaleOakPlanks; + for (int i = 5894; i <= 5895; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 4578; i <= 4609; i++) + materials[i] = Material.PaleOakSign; + for (int i = 11539; i <= 11544; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 10379; i <= 10458; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 6575; i <= 6638; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 5750; i <= 5757; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 4902; i <= 4909; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 27038; i <= 27040; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 11088; i <= 11089; i++) + materials[i] = Material.Peony; + for (int i = 11587; i <= 11592; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 9322; i <= 9353; i++) + materials[i] = Material.PiglinHead; + for (int i = 9354; i <= 9361; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 11190; i <= 11205; i++) + materials[i] = Material.PinkBanner; + for (int i = 1827; i <= 1842; i++) + materials[i] = Material.PinkBed; + for (int i = 21306; i <= 21321; i++) + materials[i] = Material.PinkCandle; + for (int i = 21480; i <= 21481; i++) + materials[i] = Material.PinkCandleCake; + materials[11069] = Material.PinkCarpet; + materials[13203] = Material.PinkConcrete; + materials[13219] = Material.PinkConcretePowder; + for (int i = 13157; i <= 13160; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 25296; i <= 25311; i++) + materials[i] = Material.PinkPetals; + for (int i = 13073; i <= 13078; i++) + materials[i] = Material.PinkShulkerBox; + materials[6117] = Material.PinkStainedGlass; + for (int i = 9819; i <= 9850; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[9617] = Material.PinkTerracotta; + materials[2127] = Material.PinkTulip; + for (int i = 11374; i <= 11377; i++) + materials[i] = Material.PinkWallBanner; + materials[2096] = Material.PinkWool; + for (int i = 2054; i <= 2065; i++) + materials[i] = Material.Piston; + for (int i = 2066; i <= 2089; i++) + materials[i] = Material.PistonHead; + for (int i = 12966; i <= 12975; i++) + materials[i] = Material.PitcherCrop; + for (int i = 12976; i <= 12977; i++) + materials[i] = Material.PitcherPlant; + for (int i = 9202; i <= 9233; i++) + materials[i] = Material.PlayerHead; + for (int i = 9234; i <= 9241; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 25217; i <= 25236; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 14617; i <= 14622; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 14391; i <= 14470; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 6021; i <= 6023; i++) + materials[i] = Material.PolishedBasalt; + materials[20340] = Material.PolishedBlackstone; + for (int i = 20344; i <= 20349; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 20350; i <= 20429; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 20430; i <= 20753; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[20341] = Material.PolishedBlackstoneBricks; + for (int i = 20843; i <= 20866; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 20841; i <= 20842; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 20835; i <= 20840; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 20755; i <= 20834; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 20867; i <= 21190; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[25787] = Material.PolishedDeepslate; + for (int i = 25868; i <= 25873; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 25788; i <= 25867; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 25874; i <= 26197; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 14569; i <= 14574; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 13671; i <= 13750; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 14551; i <= 14556; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 13431; i <= 13510; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[21961] = Material.PolishedTuff; + for (int i = 21962; i <= 21967; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 21968; i <= 22047; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 22048; i <= 22371; i++) + materials[i] = Material.PolishedTuffWall; + materials[2120] = Material.Poppy; + for (int i = 8834; i <= 8841; i++) + materials[i] = Material.Potatoes; + materials[8803] = Material.PottedAcaciaSapling; + materials[8812] = Material.PottedAllium; + materials[27030] = Material.PottedAzaleaBush; + materials[8813] = Material.PottedAzureBluet; + materials[13426] = Material.PottedBamboo; + materials[8801] = Material.PottedBirchSapling; + materials[8811] = Material.PottedBlueOrchid; + materials[8823] = Material.PottedBrownMushroom; + materials[8825] = Material.PottedCactus; + materials[8804] = Material.PottedCherrySapling; + materials[8819] = Material.PottedCornflower; + materials[19924] = Material.PottedCrimsonFungus; + materials[19926] = Material.PottedCrimsonRoots; + materials[8809] = Material.PottedDandelion; + materials[8805] = Material.PottedDarkOakSapling; + materials[8824] = Material.PottedDeadBush; + materials[8808] = Material.PottedFern; + materials[27031] = Material.PottedFloweringAzaleaBush; + materials[8802] = Material.PottedJungleSapling; + materials[8820] = Material.PottedLilyOfTheValley; + materials[8807] = Material.PottedMangrovePropagule; + materials[8799] = Material.PottedOakSapling; + materials[8815] = Material.PottedOrangeTulip; + materials[8818] = Material.PottedOxeyeDaisy; + materials[8806] = Material.PottedPaleOakSapling; + materials[8817] = Material.PottedPinkTulip; + materials[8810] = Material.PottedPoppy; + materials[8822] = Material.PottedRedMushroom; + materials[8814] = Material.PottedRedTulip; + materials[8800] = Material.PottedSpruceSapling; + materials[8798] = Material.PottedTorchflower; + materials[19925] = Material.PottedWarpedFungus; + materials[19927] = Material.PottedWarpedRoots; + materials[8816] = Material.PottedWhiteTulip; + materials[8821] = Material.PottedWitherRose; + materials[22787] = Material.PowderSnow; + for (int i = 7633; i <= 7635; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + materials[10798] = Material.Prismarine; + for (int i = 11047; i <= 11052; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 10881; i <= 10960; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[10799] = Material.PrismarineBricks; + for (int i = 11041; i <= 11046; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 10801; i <= 10880; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 14953; i <= 15276; i++) + materials[i] = Material.PrismarineWall; + materials[7041] = Material.Pumpkin; + for (int i = 7051; i <= 7058; i++) + materials[i] = Material.PumpkinStem; + for (int i = 11254; i <= 11269; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 21370; i <= 21385; i++) + materials[i] = Material.PurpleCandle; + for (int i = 21488; i <= 21489; i++) + materials[i] = Material.PurpleCandleCake; + materials[11073] = Material.PurpleCarpet; + materials[13207] = Material.PurpleConcrete; + materials[13223] = Material.PurpleConcretePowder; + for (int i = 13173; i <= 13176; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 13097; i <= 13102; i++) + materials[i] = Material.PurpleShulkerBox; + materials[6121] = Material.PurpleStainedGlass; + for (int i = 9947; i <= 9978; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[9621] = Material.PurpleTerracotta; + for (int i = 11390; i <= 11393; i++) + materials[i] = Material.PurpleWallBanner; + materials[2100] = Material.PurpleWool; + materials[12879] = Material.PurpurBlock; + for (int i = 12880; i <= 12882; i++) + materials[i] = Material.PurpurPillar; + for (int i = 11641; i <= 11646; i++) + materials[i] = Material.PurpurSlab; + for (int i = 12883; i <= 12962; i++) + materials[i] = Material.PurpurStairs; + materials[9490] = Material.QuartzBlock; + materials[21193] = Material.QuartzBricks; + for (int i = 9492; i <= 9494; i++) + materials[i] = Material.QuartzPillar; + for (int i = 11623; i <= 11628; i++) + materials[i] = Material.QuartzSlab; + for (int i = 9495; i <= 9574; i++) + materials[i] = Material.QuartzStairs; + for (int i = 4746; i <= 4765; i++) + materials[i] = Material.Rail; + materials[27028] = Material.RawCopperBlock; + materials[27029] = Material.RawGoldBlock; + materials[27027] = Material.RawIronBlock; + for (int i = 11318; i <= 11333; i++) + materials[i] = Material.RedBanner; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 21434; i <= 21449; i++) + materials[i] = Material.RedCandle; + for (int i = 21496; i <= 21497; i++) + materials[i] = Material.RedCandleCake; + materials[11077] = Material.RedCarpet; + materials[13211] = Material.RedConcrete; + materials[13227] = Material.RedConcretePowder; + for (int i = 13189; i <= 13192; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2133] = Material.RedMushroom; + for (int i = 6843; i <= 6906; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 14611; i <= 14616; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 14311; i <= 14390; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 17545; i <= 17868; i++) + materials[i] = Material.RedNetherBrickWall; + materials[13014] = Material.RedNetherBricks; + materials[123] = Material.RedSand; + materials[11414] = Material.RedSandstone; + for (int i = 11629; i <= 11634; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 11417; i <= 11496; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 15277; i <= 15600; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 13121; i <= 13126; i++) + materials[i] = Material.RedShulkerBox; + materials[6125] = Material.RedStainedGlass; + for (int i = 10075; i <= 10106; i++) + materials[i] = Material.RedStainedGlassPane; + materials[9625] = Material.RedTerracotta; + materials[2124] = Material.RedTulip; + for (int i = 11406; i <= 11409; i++) + materials[i] = Material.RedWallBanner; + materials[2104] = Material.RedWool; + materials[9478] = Material.RedstoneBlock; + for (int i = 7647; i <= 7648; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 5900; i <= 5901; i++) + materials[i] = Material.RedstoneOre; + for (int i = 5904; i <= 5905; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 5906; i <= 5913; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 3030; i <= 4325; i++) + materials[i] = Material.RedstoneWire; + materials[27042] = Material.ReinforcedDeepslate; + for (int i = 6047; i <= 6110; i++) + materials[i] = Material.Repeater; + for (int i = 12984; i <= 12995; i++) + materials[i] = Material.RepeatingCommandBlock; + for (int i = 19919; i <= 19923; i++) + materials[i] = Material.RespawnAnchor; + materials[25371] = Material.RootedDirt; + for (int i = 11086; i <= 11087; i++) + materials[i] = Material.RoseBush; + materials[118] = Material.Sand; + materials[578] = Material.Sandstone; + for (int i = 11575; i <= 11580; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 7661; i <= 7740; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 17869; i <= 18192; i++) + materials[i] = Material.SandstoneWall; + for (int i = 18841; i <= 18872; i++) + materials[i] = Material.Scaffolding; + materials[23268] = Material.Sculk; + for (int i = 23397; i <= 23398; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 22788; i <= 22883; i++) + materials[i] = Material.SculkSensor; + for (int i = 23399; i <= 23406; i++) + materials[i] = Material.SculkShrieker; + for (int i = 23269; i <= 23396; i++) + materials[i] = Material.SculkVein; + materials[11059] = Material.SeaLantern; + for (int i = 13402; i <= 13409; i++) + materials[i] = Material.SeaPickle; + materials[2051] = Material.Seagrass; + materials[2048] = Material.ShortGrass; + materials[19079] = Material.Shroomlight; + for (int i = 13031; i <= 13036; i++) + materials[i] = Material.ShulkerBox; + for (int i = 9082; i <= 9113; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 9114; i <= 9121; i++) + materials[i] = Material.SkeletonWallSkull; + materials[10699] = Material.SlimeBlock; + for (int i = 21538; i <= 21549; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 25353; i <= 25368; i++) + materials[i] = Material.SmallDripleaf; + materials[18935] = Material.SmithingTable; + for (int i = 18889; i <= 18896; i++) + materials[i] = Material.Smoker; + materials[27026] = Material.SmoothBasalt; + materials[11649] = Material.SmoothQuartz; + for (int i = 14593; i <= 14598; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 14071; i <= 14150; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[11650] = Material.SmoothRedSandstone; + for (int i = 14557; i <= 14562; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 13511; i <= 13590; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[11648] = Material.SmoothSandstone; + for (int i = 14587; i <= 14592; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 13991; i <= 14070; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[11647] = Material.SmoothStone; + for (int i = 11569; i <= 11574; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13269; i <= 13271; i++) + materials[i] = Material.SnifferEgg; + for (int i = 5938; i <= 5945; i++) + materials[i] = Material.Snow; + materials[5947] = Material.SnowBlock; + for (int i = 19012; i <= 19043; i++) + materials[i] = Material.SoulCampfire; + materials[2915] = Material.SoulFire; + for (int i = 18976; i <= 18979; i++) + materials[i] = Material.SoulLantern; + materials[6016] = Material.SoulSand; + materials[6017] = Material.SoulSoil; + materials[6024] = Material.SoulTorch; + for (int i = 6025; i <= 6028; i++) + materials[i] = Material.SoulWallTorch; + materials[2916] = Material.Spawner; + materials[560] = Material.Sponge; + materials[25292] = Material.SporeBlossom; + for (int i = 8866; i <= 8889; i++) + materials[i] = Material.SpruceButton; + for (int i = 12227; i <= 12290; i++) + materials[i] = Material.SpruceDoor; + for (int i = 11939; i <= 11970; i++) + materials[i] = Material.SpruceFence; + for (int i = 11651; i <= 11682; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 4990; i <= 5053; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 5882; i <= 5883; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 4386; i <= 4417; i++) + materials[i] = Material.SpruceSign; + for (int i = 11503; i <= 11508; i++) + materials[i] = Material.SpruceSlab; + for (int i = 7896; i <= 7975; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6191; i <= 6254; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 5702; i <= 5709; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 4854; i <= 4861; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 11605; i <= 11610; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 7339; i <= 7418; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 16249; i <= 16572; i++) + materials[i] = Material.StoneBrickWall; + materials[6767] = Material.StoneBricks; + for (int i = 5914; i <= 5937; i++) + materials[i] = Material.StoneButton; + for (int i = 5814; i <= 5815; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 11563; i <= 11568; i++) + materials[i] = Material.StoneSlab; + for (int i = 13911; i <= 13990; i++) + materials[i] = Material.StoneStairs; + for (int i = 18936; i <= 18939; i++) + materials[i] = Material.Stonecutter; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 19074; i <= 19076; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 19068; i <= 19070; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 19057; i <= 19059; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 19051; i <= 19053; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 19825; i <= 19828; i++) + materials[i] = Material.StructureBlock; + materials[13018] = Material.StructureVoid; + for (int i = 5965; i <= 5980; i++) + materials[i] = Material.SugarCane; + for (int i = 11082; i <= 11083; i++) + materials[i] = Material.Sunflower; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 19044; i <= 19047; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 11090; i <= 11091; i++) + materials[i] = Material.TallGrass; + for (int i = 2052; i <= 2053; i++) + materials[i] = Material.TallSeagrass; + for (int i = 19850; i <= 19865; i++) + materials[i] = Material.Target; + materials[11079] = Material.Terracotta; + materials[22786] = Material.TintedGlass; + for (int i = 2137; i <= 2138; i++) + materials[i] = Material.Tnt; + materials[2398] = Material.Torch; + materials[2119] = Material.Torchflower; + for (int i = 12964; i <= 12965; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 9374; i <= 9397; i++) + materials[i] = Material.TrappedChest; + for (int i = 27107; i <= 27118; i++) + materials[i] = Material.TrialSpawner; + for (int i = 7767; i <= 7894; i++) + materials[i] = Material.Tripwire; + for (int i = 7751; i <= 7766; i++) + materials[i] = Material.TripwireHook; + for (int i = 13292; i <= 13293; i++) + materials[i] = Material.TubeCoral; + materials[13277] = Material.TubeCoralBlock; + for (int i = 13312; i <= 13313; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 13362; i <= 13369; i++) + materials[i] = Material.TubeCoralWallFan; + materials[21550] = Material.Tuff; + for (int i = 22374; i <= 22379; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 22380; i <= 22459; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 22460; i <= 22783; i++) + materials[i] = Material.TuffBrickWall; + materials[22373] = Material.TuffBricks; + for (int i = 21551; i <= 21556; i++) + materials[i] = Material.TuffSlab; + for (int i = 21557; i <= 21636; i++) + materials[i] = Material.TuffStairs; + for (int i = 21637; i <= 21960; i++) + materials[i] = Material.TuffWall; + for (int i = 13257; i <= 13268; i++) + materials[i] = Material.TurtleEgg; + for (int i = 19107; i <= 19132; i++) + materials[i] = Material.TwistingVines; + materials[19133] = Material.TwistingVinesPlant; + for (int i = 27119; i <= 27150; i++) + materials[i] = Material.Vault; + for (int i = 27035; i <= 27037; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 7067; i <= 7098; i++) + materials[i] = Material.Vine; + materials[13427] = Material.VoidAir; + for (int i = 2399; i <= 2402; i++) + materials[i] = Material.WallTorch; + for (int i = 19593; i <= 19616; i++) + materials[i] = Material.WarpedButton; + for (int i = 19681; i <= 19744; i++) + materials[i] = Material.WarpedDoor; + for (int i = 19185; i <= 19216; i++) + materials[i] = Material.WarpedFence; + for (int i = 19377; i <= 19408; i++) + materials[i] = Material.WarpedFenceGate; + materials[19061] = Material.WarpedFungus; + for (int i = 5502; i <= 5565; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 19054; i <= 19056; i++) + materials[i] = Material.WarpedHyphae; + materials[19060] = Material.WarpedNylium; + materials[19136] = Material.WarpedPlanks; + for (int i = 19151; i <= 19152; i++) + materials[i] = Material.WarpedPressurePlate; + materials[19063] = Material.WarpedRoots; + for (int i = 19777; i <= 19808; i++) + materials[i] = Material.WarpedSign; + for (int i = 19143; i <= 19148; i++) + materials[i] = Material.WarpedSlab; + for (int i = 19489; i <= 19568; i++) + materials[i] = Material.WarpedStairs; + for (int i = 19048; i <= 19050; i++) + materials[i] = Material.WarpedStem; + for (int i = 19281; i <= 19344; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 5774; i <= 5781; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 19817; i <= 19824; i++) + materials[i] = Material.WarpedWallSign; + materials[19062] = Material.WarpedWartBlock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 7629; i <= 7631; i++) + materials[i] = Material.WaterCauldron; + materials[23424] = Material.WaxedChiseledCopper; + materials[23769] = Material.WaxedCopperBlock; + for (int i = 25177; i <= 25180; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 24377; i <= 24440; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 25153; i <= 25154; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 24889; i <= 24952; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[23776] = Material.WaxedCutCopper; + for (int i = 24115; i <= 24120; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 24017; i <= 24096; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[23423] = Material.WaxedExposedChiseledCopper; + materials[23771] = Material.WaxedExposedCopper; + for (int i = 25181; i <= 25184; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 24441; i <= 24504; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 25155; i <= 25156; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 24953; i <= 25016; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[23775] = Material.WaxedExposedCutCopper; + for (int i = 24109; i <= 24114; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 23937; i <= 24016; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[23421] = Material.WaxedOxidizedChiseledCopper; + materials[23772] = Material.WaxedOxidizedCopper; + for (int i = 25189; i <= 25192; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 24505; i <= 24568; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 25159; i <= 25160; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 25017; i <= 25080; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[23773] = Material.WaxedOxidizedCutCopper; + for (int i = 24097; i <= 24102; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 23777; i <= 23856; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[23422] = Material.WaxedWeatheredChiseledCopper; + materials[23770] = Material.WaxedWeatheredCopper; + for (int i = 25185; i <= 25188; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 24569; i <= 24632; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 25157; i <= 25158; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 25081; i <= 25144; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[23774] = Material.WaxedWeatheredCutCopper; + for (int i = 24103; i <= 24108; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 23857; i <= 23936; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[23418] = Material.WeatheredChiseledCopper; + materials[23409] = Material.WeatheredCopper; + for (int i = 25169; i <= 25172; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 24313; i <= 24376; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 25149; i <= 25150; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 24825; i <= 24888; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[23414] = Material.WeatheredCutCopper; + for (int i = 23751; i <= 23756; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 23505; i <= 23584; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 19080; i <= 19105; i++) + materials[i] = Material.WeepingVines; + materials[19106] = Material.WeepingVinesPlant; + materials[561] = Material.WetSponge; + for (int i = 4330; i <= 4337; i++) + materials[i] = Material.Wheat; + for (int i = 11094; i <= 11109; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 21210; i <= 21225; i++) + materials[i] = Material.WhiteCandle; + for (int i = 21468; i <= 21469; i++) + materials[i] = Material.WhiteCandleCake; + materials[11063] = Material.WhiteCarpet; + materials[13197] = Material.WhiteConcrete; + materials[13213] = Material.WhiteConcretePowder; + for (int i = 13133; i <= 13136; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 13037; i <= 13042; i++) + materials[i] = Material.WhiteShulkerBox; + materials[6111] = Material.WhiteStainedGlass; + for (int i = 9627; i <= 9658; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[9611] = Material.WhiteTerracotta; + materials[2126] = Material.WhiteTulip; + for (int i = 11350; i <= 11353; i++) + materials[i] = Material.WhiteWallBanner; + materials[2090] = Material.WhiteWool; + materials[2130] = Material.WitherRose; + for (int i = 9122; i <= 9153; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 9154; i <= 9161; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 11158; i <= 11173; i++) + materials[i] = Material.YellowBanner; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 21274; i <= 21289; i++) + materials[i] = Material.YellowCandle; + for (int i = 21476; i <= 21477; i++) + materials[i] = Material.YellowCandleCake; + materials[11067] = Material.YellowCarpet; + materials[13201] = Material.YellowConcrete; + materials[13217] = Material.YellowConcretePowder; + for (int i = 13149; i <= 13152; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 13061; i <= 13066; i++) + materials[i] = Material.YellowShulkerBox; + materials[6115] = Material.YellowStainedGlass; + for (int i = 9755; i <= 9786; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[9615] = Material.YellowTerracotta; + for (int i = 11366; i <= 11369; i++) + materials[i] = Material.YellowWallBanner; + materials[2094] = Material.YellowWool; + for (int i = 9162; i <= 9193; i++) + materials[i] = Material.ZombieHead; + for (int i = 9194; i <= 9201; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index e7e5c978..0e86e828 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -23,7 +23,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2 <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 - <= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21 + <= Protocol18Handler.MC_1_21_2_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.2 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1212.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1212.cs new file mode 100644 index 00000000..894738d2 --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1212.cs @@ -0,0 +1,168 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1212 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1212() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.Cat; + mappings[21] = EntityType.CaveSpider; + mappings[22] = EntityType.CherryBoat; + mappings[23] = EntityType.CherryChestBoat; + mappings[24] = EntityType.ChestMinecart; + mappings[25] = EntityType.Chicken; + mappings[26] = EntityType.Cod; + mappings[27] = EntityType.CommandBlockMinecart; + mappings[28] = EntityType.Cow; + mappings[29] = EntityType.Creaking; + mappings[30] = EntityType.CreakingTransient; + mappings[31] = EntityType.Creeper; + mappings[32] = EntityType.DarkOakBoat; + mappings[33] = EntityType.DarkOakChestBoat; + mappings[34] = EntityType.Dolphin; + mappings[35] = EntityType.Donkey; + mappings[36] = EntityType.DragonFireball; + mappings[37] = EntityType.Drowned; + mappings[38] = EntityType.Egg; + mappings[39] = EntityType.ElderGuardian; + mappings[40] = EntityType.Enderman; + mappings[41] = EntityType.Endermite; + mappings[42] = EntityType.EnderDragon; + mappings[43] = EntityType.EnderPearl; + mappings[44] = EntityType.EndCrystal; + mappings[45] = EntityType.Evoker; + mappings[46] = EntityType.EvokerFangs; + mappings[47] = EntityType.ExperienceBottle; + mappings[48] = EntityType.ExperienceOrb; + mappings[49] = EntityType.EyeOfEnder; + mappings[50] = EntityType.FallingBlock; + mappings[51] = EntityType.Fireball; + mappings[52] = EntityType.FireworkRocket; + mappings[53] = EntityType.Fox; + mappings[54] = EntityType.Frog; + mappings[55] = EntityType.FurnaceMinecart; + mappings[56] = EntityType.Ghast; + mappings[57] = EntityType.Giant; + mappings[58] = EntityType.GlowItemFrame; + mappings[59] = EntityType.GlowSquid; + mappings[60] = EntityType.Goat; + mappings[61] = EntityType.Guardian; + mappings[62] = EntityType.Hoglin; + mappings[63] = EntityType.HopperMinecart; + mappings[64] = EntityType.Horse; + mappings[65] = EntityType.Husk; + mappings[66] = EntityType.Illusioner; + mappings[67] = EntityType.Interaction; + mappings[68] = EntityType.IronGolem; + mappings[69] = EntityType.Item; + mappings[70] = EntityType.ItemDisplay; + mappings[71] = EntityType.ItemFrame; + mappings[72] = EntityType.JungleBoat; + mappings[73] = EntityType.JungleChestBoat; + mappings[74] = EntityType.LeashKnot; + mappings[75] = EntityType.LightningBolt; + mappings[76] = EntityType.Llama; + mappings[77] = EntityType.LlamaSpit; + mappings[78] = EntityType.MagmaCube; + mappings[79] = EntityType.MangroveBoat; + mappings[80] = EntityType.MangroveChestBoat; + mappings[81] = EntityType.Marker; + mappings[82] = EntityType.Minecart; + mappings[83] = EntityType.Mooshroom; + mappings[84] = EntityType.Mule; + mappings[85] = EntityType.OakBoat; + mappings[86] = EntityType.OakChestBoat; + mappings[87] = EntityType.Ocelot; + mappings[88] = EntityType.OminousItemSpawner; + mappings[89] = EntityType.Painting; + mappings[90] = EntityType.PaleOakBoat; + mappings[91] = EntityType.PaleOakChestBoat; + mappings[92] = EntityType.Panda; + mappings[93] = EntityType.Parrot; + mappings[94] = EntityType.Phantom; + mappings[95] = EntityType.Pig; + mappings[96] = EntityType.Piglin; + mappings[97] = EntityType.PiglinBrute; + mappings[98] = EntityType.Pillager; + mappings[99] = EntityType.PolarBear; + mappings[100] = EntityType.Potion; + mappings[101] = EntityType.Pufferfish; + mappings[102] = EntityType.Rabbit; + mappings[103] = EntityType.Ravager; + mappings[104] = EntityType.Salmon; + mappings[105] = EntityType.Sheep; + mappings[106] = EntityType.Shulker; + mappings[107] = EntityType.ShulkerBullet; + mappings[108] = EntityType.Silverfish; + mappings[109] = EntityType.Skeleton; + mappings[110] = EntityType.SkeletonHorse; + mappings[111] = EntityType.Slime; + mappings[112] = EntityType.SmallFireball; + mappings[113] = EntityType.Sniffer; + mappings[114] = EntityType.Snowball; + mappings[115] = EntityType.SnowGolem; + mappings[116] = EntityType.SpawnerMinecart; + mappings[117] = EntityType.SpectralArrow; + mappings[118] = EntityType.Spider; + mappings[119] = EntityType.SpruceBoat; + mappings[120] = EntityType.SpruceChestBoat; + mappings[121] = EntityType.Squid; + mappings[122] = EntityType.Stray; + mappings[123] = EntityType.Strider; + mappings[124] = EntityType.Tadpole; + mappings[125] = EntityType.TextDisplay; + mappings[126] = EntityType.Tnt; + mappings[127] = EntityType.TntMinecart; + mappings[128] = EntityType.TraderLlama; + mappings[129] = EntityType.Trident; + mappings[130] = EntityType.TropicalFish; + mappings[131] = EntityType.Turtle; + mappings[132] = EntityType.Vex; + mappings[133] = EntityType.Villager; + mappings[134] = EntityType.Vindicator; + mappings[135] = EntityType.WanderingTrader; + mappings[136] = EntityType.Warden; + mappings[137] = EntityType.WindCharge; + mappings[138] = EntityType.Witch; + mappings[139] = EntityType.Wither; + mappings[140] = EntityType.WitherSkeleton; + mappings[141] = EntityType.WitherSkull; + mappings[142] = EntityType.Wolf; + mappings[143] = EntityType.Zoglin; + mappings[144] = EntityType.Zombie; + mappings[145] = EntityType.ZombieHorse; + mappings[146] = EntityType.ZombieVillager; + mappings[147] = EntityType.ZombifiedPiglin; + mappings[148] = EntityType.Player; + mappings[149] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 1b628729..2aab3358 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Mapping +namespace MinecraftClient.Mapping { /// /// Represents Minecraft Entity Types @@ -14,14 +14,20 @@ /// public enum EntityType { + AcaciaBoat, + AcaciaChestBoat, Allay, AreaEffectCloud, Armadillo, ArmorStand, Arrow, Axolotl, + BambooChestRaft, + BambooRaft, Bat, Bee, + BirchBoat, + BirchChestBoat, Blaze, BlockDisplay, Boat, @@ -31,13 +37,19 @@ Camel, Cat, CaveSpider, + CherryBoat, + CherryChestBoat, ChestBoat, ChestMinecart, Chicken, Cod, CommandBlockMinecart, Cow, + Creaking, + CreakingTransient, Creeper, + DarkOakBoat, + DarkOakChestBoat, Dolphin, Donkey, DragonFireball, @@ -77,18 +89,26 @@ Item, ItemDisplay, ItemFrame, + JungleBoat, + JungleChestBoat, LeashKnot, LightningBolt, Llama, LlamaSpit, MagmaCube, + MangroveBoat, + MangroveChestBoat, Marker, Minecart, Mooshroom, Mule, + OakBoat, + OakChestBoat, Ocelot, OminousItemSpawner, Painting, + PaleOakBoat, + PaleOakChestBoat, Panda, Parrot, Phantom, @@ -117,6 +137,8 @@ SpawnerMinecart, SpectralArrow, Spider, + SpruceBoat, + SpruceChestBoat, Squid, Stray, Strider, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 68300610..6c932397 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Mapping +namespace MinecraftClient.Mapping { /// /// Represents Minecraft Materials @@ -242,6 +242,7 @@ CrackedStoneBricks, Crafter, CraftingTable, + CreakingHeart, CreeperHead, CreeperWallHead, CrimsonButton, @@ -662,6 +663,26 @@ OxidizedCutCopperStairs, PackedIce, PackedMud, + PaleHangingMoss, + PaleMossBlock, + PaleMossCarpet, + PaleOakButton, + PaleOakDoor, + PaleOakFence, + PaleOakFenceGate, + PaleOakHangingSign, + PaleOakLeaves, + PaleOakLog, + PaleOakPlanks, + PaleOakPressurePlate, + PaleOakSapling, + PaleOakSign, + PaleOakSlab, + PaleOakStairs, + PaleOakTrapdoor, + PaleOakWallHangingSign, + PaleOakWallSign, + PaleOakWood, PearlescentFroglight, Peony, PetrifiedOakSlab, @@ -745,6 +766,7 @@ PottedOakSapling, PottedOrangeTulip, PottedOxeyeDaisy, + PottedPaleOakSapling, PottedPinkTulip, PottedPoppy, PottedRedMushroom, @@ -926,6 +948,8 @@ StrippedMangroveWood, StrippedOakLog, StrippedOakWood, + StrippedPaleOakLog, + StrippedPaleOakWood, StrippedSpruceLog, StrippedSpruceWood, StrippedWarpedHyphae, diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index b8a1f788..ee6eda74 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.21"; + public const string MCHighestVersion = "1.21.2"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 3f5590a9..13b86408 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -73,6 +73,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_20_4_Version = 765; internal const int MC_1_20_6_Version = 766; internal const int MC_1_21_Version = 767; + internal const int MC_1_21_2_Version = 768; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -147,8 +148,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_Version when handler.GetTerrainEnabled() => + > MC_1_21_2_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + >= MC_1_21_2_Version => new Palette1212(), >= MC_1_20_6_Version => new Palette1206(), >= MC_1_20_4_Version => new Palette1204(), >= MC_1_20_Version => new Palette120(), @@ -166,8 +168,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_2_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_1_21_2_Version => new EntityPalette1212(), >= MC_1_20_6_Version => new EntityPalette1206(), >= MC_1_20_4_Version => new EntityPalette1204(), >= MC_1_20_Version => new EntityPalette120(), @@ -189,8 +192,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_Version when handler.GetInventoryEnabled() => + > MC_1_21_2_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_2_Version => new ItemPalette1212(), >= MC_1_21_Version => new ItemPalette121(), >= MC_1_20_6_Version => new ItemPalette1206(), >= MC_1_20_4_Version => new ItemPalette1204(), diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index b53354ee..6ac6ca24 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data.Odbc; using System.Globalization; @@ -153,7 +153,7 @@ namespace MinecraftClient.Protocol int[] suppoertedVersionsProtocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, - 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767 + 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -351,6 +351,8 @@ namespace MinecraftClient.Protocol case "1.21": case "1.21.1": return 767; + case "1.21.2": + return 768; default: return 0; } @@ -432,6 +434,7 @@ namespace MinecraftClient.Protocol 765 => "1.20.4", 766 => "1.20.6", 767 => "1.21", + 768 => "1.21.2", _ => "0.0" }; } From 57a0dedb332939c9058a2b7858e5074e924b5809 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 03:25:20 +0800 Subject: [PATCH 054/484] feat: add packet palette, data components, and protocol fixes for MC 1.21.2 Packet Palette (Phase 2.1): - Create PacketPalette1212.cs with complete ID mapping for protocol 768 (131 clientbound + 60 serverbound play packets, plus config packets) - Add new PacketTypesIn enum values: EntityPositionSync, MoveMinecartAlongTrack, PlayerRotation, RecipeBookAdd/Remove/Settings, SetCursorItem, SetHeldSlot, SetPlayerInventory - Add new PacketTypesOut enum values: BundleItemSelected, ClientTickEnd - Update PacketType18Handler routing for 1.21.2 Data Components (Phase 1.4): - Create StructuredComponentsRegistry1212 with 67 components (was 57 in 1.21) reflecting the new 1.21.2 DataComponents ordering - Implement 11 new component parsers: ConsumableComponent, UseRemainderComponent, UseCooldownComponent, DamageResistantComponent, EnchantableComponent, EquippableComponent, RepairableComponent, GliderComponent, TooltipStyleComponent, DeathProtectionComponent, ItemModelComponent - Create FoodComponent1212 (simplified: nutrition/saturation/canAlwaysEat only; eatSeconds/effects/usingConvertsTo moved to consumable/use_remainder) - Create SubComponentRegistry1212 and route in StructuredComponentsHandler Protocol Fixes: - Fix PlayerPositionAndLook packet for 1.21.2 (new format: teleportId first, added deltaMovement Vec3, flags as Int instead of Byte) - Fix login success packet (remove strictErrorHandling read for >= 1.21.2) - Fix ClientSettings/ClientInformation packet (add particleStatus VarInt) - Add SetHeldSlot as alias for HeldItemChange in packet handler Verified: MCC connects to 1.21.2 vanilla server, stays connected, chat works. Made-with: Cursor --- .../PacketPalettes/PacketPalette1212.cs | 243 ++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 7 +- .../Protocol/Handlers/PacketTypesIn.cs | 11 +- .../Protocol/Handlers/PacketTypesOut.cs | 4 +- .../Protocol/Handlers/Protocol18.cs | 69 +++-- .../Components/1_21_2/ConsumableComponent.cs | 129 ++++++++++ .../1_21_2/DamageResistantComponent.cs | 23 ++ .../1_21_2/DeathProtectionComponent.cs | 106 ++++++++ .../Components/1_21_2/EnchantableComponent.cs | 23 ++ .../Components/1_21_2/EquippableComponent.cs | 94 +++++++ .../Components/1_21_2/FoodComponent1212.cs | 29 +++ .../Components/1_21_2/GliderComponent.cs | 8 + .../Components/1_21_2/ItemModelComponent.cs | 23 ++ .../Components/1_21_2/RepairableComponent.cs | 44 ++++ .../1_21_2/TooltipStyleComponent.cs | 23 ++ .../Components/1_21_2/UseCooldownComponent.cs | 31 +++ .../1_21_2/UseRemainderComponent.cs | 24 ++ .../StructuredComponentsRegistry1212.cs | 82 ++++++ .../Subcomponents/SubComponentRegistry1212.cs | 11 + .../StructuredComponentsHandler.cs | 2 + 20 files changed, 953 insertions(+), 33 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1212.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ConsumableComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DamageResistantComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DeathProtectionComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EnchantableComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EquippableComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/FoodComponent1212.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/GliderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ItemModelComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/RepairableComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/TooltipStyleComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseCooldownComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseRemainderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1212.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1212.cs diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1212.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1212.cs new file mode 100644 index 00000000..76deae7e --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1212.cs @@ -0,0 +1,243 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1212 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.SpawnExperienceOrb }, // Add Experience Orb + { 0x03, PacketTypesIn.EntityAnimation }, // Animate + { 0x04, PacketTypesIn.Statistics }, // Award Stats + { 0x05, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x06, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x07, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x08, PacketTypesIn.BlockAction }, // Block Event + { 0x09, PacketTypesIn.BlockChange }, // Block Update + { 0x0A, PacketTypesIn.BossBar }, // Boss Event + { 0x0B, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0C, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0D, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0E, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0F, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x10, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x11, PacketTypesIn.DeclareCommands }, // Commands + { 0x12, PacketTypesIn.CloseWindow }, // Container Close + { 0x13, PacketTypesIn.WindowItems }, // Container Set Content + { 0x14, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x15, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x16, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x17, PacketTypesIn.SetCooldown }, // Cooldown + { 0x18, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x19, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x1A, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1B, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1C, PacketTypesIn.HideMessage }, // Delete Chat + { 0x1D, PacketTypesIn.Disconnect }, // Disconnect + { 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x1F, PacketTypesIn.EntityStatus }, // Entity Event + { 0x20, PacketTypesIn.EntityPositionSync }, // Entity Position Sync (new in 1.21.2) + { 0x21, PacketTypesIn.Explosion }, // Explode + { 0x22, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x23, PacketTypesIn.ChangeGameState }, // Game Event + { 0x24, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open + { 0x25, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x26, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x27, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x28, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x29, PacketTypesIn.Effect }, // Level Event + { 0x2A, PacketTypesIn.Particle }, // Level Particles + { 0x2B, PacketTypesIn.UpdateLight }, // Light Update + { 0x2C, PacketTypesIn.JoinGame }, // Login + { 0x2D, PacketTypesIn.MapData }, // Map Item Data + { 0x2E, PacketTypesIn.TradeList }, // Merchant Offers + { 0x2F, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x30, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x31, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track (new in 1.21.2) + { 0x32, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x33, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x34, PacketTypesIn.OpenBook }, // Open Book + { 0x35, PacketTypesIn.OpenWindow }, // Open Screen + { 0x36, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x37, PacketTypesIn.Ping }, // Ping + { 0x38, PacketTypesIn.PingResponse }, // Pong Response + { 0x39, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x3A, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x3B, PacketTypesIn.ChatMessage }, // Player Chat + { 0x3C, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x3D, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x3E, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x3F, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x40, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x41, PacketTypesIn.FacePlayer }, // Player Look At + { 0x42, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x43, PacketTypesIn.PlayerRotation }, // Player Rotation (new in 1.21.2) + { 0x44, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add (new in 1.21.2, replaces UnlockRecipes) + { 0x45, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove (new in 1.21.2) + { 0x46, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings (new in 1.21.2) + { 0x47, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x48, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x49, PacketTypesIn.ResetScore }, // Reset Score + { 0x4A, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x4B, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x4C, PacketTypesIn.Respawn }, // Respawn + { 0x4D, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x4E, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x4F, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x50, PacketTypesIn.ServerData }, // Server Data + { 0x51, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x52, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x53, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x54, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x55, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x56, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x57, PacketTypesIn.Camera }, // Set Camera + { 0x58, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x59, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x5A, PacketTypesIn.SetCursorItem }, // Set Cursor Item (new in 1.21.2) + { 0x5B, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x5C, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x5D, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x5E, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x5F, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x60, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x61, PacketTypesIn.SetExperience }, // Set Experience + { 0x62, PacketTypesIn.UpdateHealth }, // Set Health + { 0x63, PacketTypesIn.SetHeldSlot }, // Set Held Slot (new in 1.21.2, replaces HeldItemChange) + { 0x64, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x65, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x66, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory (new in 1.21.2) + { 0x67, PacketTypesIn.Teams }, // Set Player Team + { 0x68, PacketTypesIn.UpdateScore }, // Set Score + { 0x69, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x6A, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x6B, PacketTypesIn.TimeUpdate }, // Set Time + { 0x6C, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x6D, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x6E, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x6F, PacketTypesIn.SoundEffect }, // Sound + { 0x70, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x71, PacketTypesIn.StopSound }, // Stop Sound + { 0x72, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x73, PacketTypesIn.SystemChat }, // System Chat + { 0x74, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x75, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x76, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x77, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x78, PacketTypesIn.SetTickingState }, // Ticking State + { 0x79, PacketTypesIn.StepTick }, // Ticking Step + { 0x7A, PacketTypesIn.Transfer }, // Transfer + { 0x7B, PacketTypesIn.Advancements }, // Update Advancements + { 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x7F, PacketTypesIn.Tags }, // Update Tags + { 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x82, PacketTypesIn.ServerLinks } // Server Links + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected (new in 1.21.2) + { 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x05, PacketTypesOut.ChatCommand }, // Chat Command + { 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x07, PacketTypesOut.ChatMessage }, // Chat + { 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0A, PacketTypesOut.ClientStatus }, // Client Command + { 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End (new in 1.21.2) + { 0x0C, PacketTypesOut.ClientSettings }, // Client Information + { 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x10, PacketTypesOut.ClickWindow }, // Container Click + { 0x11, PacketTypesOut.CloseWindow }, // Container Close + { 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x13, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x14, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription + { 0x16, PacketTypesOut.EditBook }, // Edit Book + { 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x18, PacketTypesOut.InteractEntity }, // Interact + { 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x22, PacketTypesOut.PickItem }, // Pick Item + { 0x23, PacketTypesOut.PingRequest }, // Ping Request + { 0x24, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x25, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x26, PacketTypesOut.PlayerDigging }, // Player Action + { 0x27, PacketTypesOut.EntityAction }, // Player Command + { 0x28, PacketTypesOut.SteerVehicle }, // Player Input + { 0x29, PacketTypesOut.Pong }, // Pong + { 0x2A, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2B, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x2C, PacketTypesOut.NameItem }, // Rename Item + { 0x2D, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x2E, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x2F, PacketTypesOut.SelectTrade }, // Select Trade + { 0x30, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x31, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x32, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x33, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x34, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x35, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x36, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x37, PacketTypesOut.UpdateSign }, // Sign Update + { 0x38, PacketTypesOut.Animation }, // Swing + { 0x39, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x3A, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x3B, PacketTypesOut.UseItem }, // Use Item + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks } + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 7d80d4ee..9141627b 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -1,4 +1,4 @@ -using System; +using System; using MinecraftClient.Protocol.Handlers.PacketPalettes; namespace MinecraftClient.Protocol.Handlers @@ -48,7 +48,7 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_2_Version => throw new NotImplementedException(Translations .exception_palette_packet), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), <= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(), @@ -69,7 +69,8 @@ namespace MinecraftClient.Protocol.Handlers <= Protocol18Handler.MC_1_20_2_Version => new PacketPalette1202(), <= Protocol18Handler.MC_1_20_4_Version => new PacketPalette1204(), <= Protocol18Handler.MC_1_20_6_Version => new PacketPalette1206(), - _ => new PacketPalette121() + <= Protocol18Handler.MC_1_21_Version => new PacketPalette121(), + _ => new PacketPalette1212() }; p.SetForgeEnabled(forgeEnabled); diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index d3feabb7..19d72455 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Protocol.Handlers +namespace MinecraftClient.Protocol.Handlers { /// /// Incoming packet types @@ -51,6 +51,7 @@ EntityMovement, // EntityPosition, // EntityPositionAndRotation, // + EntityPositionSync, // Added in 1.21.2 EntityProperties, // EntityRotation, // EntitySoundEffect, // @@ -58,6 +59,7 @@ EntityTeleport, // EntityVelocity, // Explosion, // + MoveMinecartAlongTrack, // Added in 1.21.2 FacePlayer, // FeatureFlags, // Added in 1.19.3 HeldItemChange, // @@ -84,6 +86,7 @@ PlayerListHeaderAndFooter, // PlayerRemove, // Added in 1.19.3 (Not used) PlayerPositionAndLook, // + PlayerRotation, // Added in 1.21.2 PluginMessage, // ProfilelessChatMessage, // Added in 1.19.3 ProjectilePower, // Added in 1.20.6 @@ -92,6 +95,9 @@ ResetScore, // Added in 1.20.3 ResourcePackSend, // Respawn, // + RecipeBookAdd, // Added in 1.21.2 (replaces UnlockRecipes) + RecipeBookRemove, // Added in 1.21.2 + RecipeBookSettings, // Added in 1.21.2 ScoreboardObjective, // SelectAdvancementTab, // ServerData, // Added in 1.19 @@ -99,9 +105,12 @@ ServerLinks, // Added in 1.21 (Not used) SetCompression, // For 1.8 or below SetCooldown, // + SetCursorItem, // Added in 1.21.2 SetDisplayChatPreview, // Added in 1.19 SetExperience, // + SetHeldSlot, // Added in 1.21.2 (replaces HeldItemChange clientbound) SetPassengers, // + SetPlayerInventory, // Added in 1.21.2 SetSlot, // SetTickingState, // Added in 1.20.3 StepTick, // Added in 1.20.3 diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index 1149a71f..9512024a 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Protocol.Handlers +namespace MinecraftClient.Protocol.Handlers { /// /// Outgoing packet types @@ -8,6 +8,7 @@ AcknowledgeConfiguration, // Added in 1.20.2 AdvancementTab, // Animation, // + BundleItemSelected, // Added in 1.21.2 ChangeContainerSlotState, // Added in 1.20.3 ChatCommand, // Added in 1.19 ChatMessage, // @@ -17,6 +18,7 @@ ClickWindowButton, // ClientSettings, // ClientStatus, // + ClientTickEnd, // Added in 1.21.2 CloseWindow, // CraftRecipeRequest, // CreativeInventoryAction, // diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 13b86408..1b1cb1fe 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1411,18 +1411,40 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.PlayerPositionAndLook: { - // These always need to be read, since we need the field after them for teleport confirm - var location = new Location( - dataTypes.ReadNextDouble(packetData), // X - dataTypes.ReadNextDouble(packetData), // Y - dataTypes.ReadNextDouble(packetData) // Z - ); + int teleportId; + Location location; + float yaw, pitch; + int locMask; - var yaw = dataTypes.ReadNextFloat(packetData); - var pitch = dataTypes.ReadNextFloat(packetData); - var locMask = dataTypes.ReadNextByte(packetData); + if (protocolVersion >= MC_1_21_2_Version) + { + teleportId = dataTypes.ReadNextVarInt(packetData); + location = new Location( + dataTypes.ReadNextDouble(packetData), // X + dataTypes.ReadNextDouble(packetData), // Y + dataTypes.ReadNextDouble(packetData) // Z + ); + dataTypes.ReadNextDouble(packetData); // Delta X + dataTypes.ReadNextDouble(packetData); // Delta Y + dataTypes.ReadNextDouble(packetData); // Delta Z + yaw = dataTypes.ReadNextFloat(packetData); + pitch = dataTypes.ReadNextFloat(packetData); + locMask = dataTypes.ReadNextInt(packetData); // Int flags (was Byte before 1.21.2) + } + else + { + location = new Location( + dataTypes.ReadNextDouble(packetData), // X + dataTypes.ReadNextDouble(packetData), // Y + dataTypes.ReadNextDouble(packetData) // Z + ); + yaw = dataTypes.ReadNextFloat(packetData); + pitch = dataTypes.ReadNextFloat(packetData); + locMask = dataTypes.ReadNextByte(packetData); + teleportId = protocolVersion >= MC_1_9_Version + ? dataTypes.ReadNextVarInt(packetData) : -1; + } - // entity handling require player pos for distance calculating if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) { if (protocolVersion >= MC_1_8_Version) @@ -1434,24 +1456,11 @@ namespace MinecraftClient.Protocol.Handlers } } - if (protocolVersion >= MC_1_9_Version) + if (teleportId >= 0) { - var teleportId = dataTypes.ReadNextVarInt(packetData); - - if (teleportId < 0) - { - yaw = LastYaw; - pitch = LastPitch; - } - else - { - LastYaw = yaw; - LastPitch = pitch; - } - + LastYaw = yaw; + LastPitch = pitch; handler.UpdateLocation(location, yaw, pitch); - - // Teleport confirm packet SendPacket(PacketTypesOut.TeleportConfirm, DataTypes.GetVarInt(teleportId)); if (Config.Main.Advanced.TemporaryFixBadpacket) @@ -2723,6 +2732,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); break; case PacketTypesIn.HeldItemChange: + case PacketTypesIn.SetHeldSlot: handler.OnHeldItemChange(dataTypes.ReadNextByte(packetData)); // Slot break; case PacketTypesIn.ScoreboardObjective: @@ -3251,8 +3261,8 @@ namespace MinecraftClient.Protocol.Handlers } } - // Strict Error Handling (Ignored) - if (protocolVersion >= MC_1_20_6_Version) + // Strict Error Handling (removed in 1.21.2) + if (protocolVersion >= MC_1_20_6_Version && protocolVersion < MC_1_21_2_Version) dataTypes.ReadNextBool(packetData); currentState = protocolVersion < MC_1_20_2_Version @@ -3844,6 +3854,9 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_18_1_Version) fields.Add(1); // 1.18 and above - Allow server listings + + if (protocolVersion >= MC_1_21_2_Version) + fields.AddRange(DataTypes.GetVarInt(0)); // 1.21.2+ Particle status: 0=All, 1=Decreased, 2=Minimal SendPacket(PacketTypesOut.ClientSettings, fields); } catch (SocketException) diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ConsumableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ConsumableComponent.cs new file mode 100644 index 00000000..ad931c61 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ConsumableComponent.cs @@ -0,0 +1,129 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class ConsumableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public float ConsumeSeconds { get; set; } + public int Animation { get; set; } + public SoundEventSubComponent? Sound { get; set; } + public bool HasConsumeParticles { get; set; } + public List Effects { get; set; } = new(); + + public override void Parse(Queue data) + { + ConsumeSeconds = dataTypes.ReadNextFloat(data); + Animation = dataTypes.ReadNextVarInt(data); + Sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data); + HasConsumeParticles = dataTypes.ReadNextBool(data); + + var effectCount = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < effectCount; i++) + { + var effectTypeId = dataTypes.ReadNextVarInt(data); + var effectData = ReadConsumeEffectPayload(effectTypeId, data); + Effects.Add(new ConsumeEffectData(effectTypeId, effectData)); + } + } + + private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue data) + { + var payload = new List(); + switch (effectTypeId) + { + case 0: // apply_effects: List + probability(float) + var effectCount = dataTypes.ReadNextVarInt(data); + payload.AddRange(DataTypes.GetVarInt(effectCount)); + for (var i = 0; i < effectCount; i++) + payload.AddRange(ReadMobEffectInstance(data)); + payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data))); + break; + case 1: // remove_effects: HolderSet + payload.AddRange(ReadHolderSet(data)); + break; + case 2: // clear_all_effects: empty + break; + case 3: // teleport_randomly: float diameter + payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data))); + break; + case 4: // play_sound: Holder + var sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data); + payload.AddRange(sound.Serialize()); + break; + } + return payload.ToArray(); + } + + private byte[] ReadMobEffectInstance(Queue data) + { + var result = new List(); + var effectId = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(effectId)); + result.AddRange(ReadMobEffectDetails(data)); + return result.ToArray(); + } + + private byte[] ReadMobEffectDetails(Queue data) + { + var result = new List(); + var amplifier = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(amplifier)); + var duration = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(duration)); + var ambient = dataTypes.ReadNextBool(data); + result.AddRange(DataTypes.GetBool(ambient)); + var showParticles = dataTypes.ReadNextBool(data); + result.AddRange(DataTypes.GetBool(showParticles)); + var showIcon = dataTypes.ReadNextBool(data); + result.AddRange(DataTypes.GetBool(showIcon)); + var hasHiddenEffect = dataTypes.ReadNextBool(data); + result.AddRange(DataTypes.GetBool(hasHiddenEffect)); + if (hasHiddenEffect) + result.AddRange(ReadMobEffectDetails(data)); + return result.ToArray(); + } + + private byte[] ReadHolderSet(Queue data) + { + var result = new List(); + var type = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(type)); + if (type == 0) + { + var tagName = dataTypes.ReadNextString(data); + result.AddRange(DataTypes.GetString(tagName)); + } + else + { + for (var i = 0; i < type - 1; i++) + { + var id = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(id)); + } + } + return result.ToArray(); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetFloat(ConsumeSeconds)); + data.AddRange(DataTypes.GetVarInt(Animation)); + if (Sound != null) data.AddRange(Sound.Serialize()); + data.AddRange(DataTypes.GetBool(HasConsumeParticles)); + data.AddRange(DataTypes.GetVarInt(Effects.Count)); + foreach (var effect in Effects) + { + data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId)); + data.AddRange(effect.Payload); + } + return new Queue(data); + } + + public record ConsumeEffectData(int EffectTypeId, byte[] Payload); +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DamageResistantComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DamageResistantComponent.cs new file mode 100644 index 00000000..25592d2f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DamageResistantComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class DamageResistantComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string Types { get; set; } = null!; + + public override void Parse(Queue data) + { + Types = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(Types)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DeathProtectionComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DeathProtectionComponent.cs new file mode 100644 index 00000000..36c59690 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/DeathProtectionComponent.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class DeathProtectionComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public List DeathEffects { get; set; } = new(); + + public override void Parse(Queue data) + { + var effectCount = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < effectCount; i++) + { + var effectTypeId = dataTypes.ReadNextVarInt(data); + var effectData = ReadConsumeEffectPayload(effectTypeId, data); + DeathEffects.Add(new ConsumeEffectData(effectTypeId, effectData)); + } + } + + private byte[] ReadConsumeEffectPayload(int effectTypeId, Queue data) + { + var payload = new List(); + switch (effectTypeId) + { + case 0: // apply_effects + var effectCount = dataTypes.ReadNextVarInt(data); + payload.AddRange(DataTypes.GetVarInt(effectCount)); + for (var i = 0; i < effectCount; i++) + payload.AddRange(ReadMobEffectInstance(data)); + payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data))); + break; + case 1: // remove_effects + payload.AddRange(ReadHolderSet(data)); + break; + case 2: // clear_all_effects + break; + case 3: // teleport_randomly + payload.AddRange(DataTypes.GetFloat(dataTypes.ReadNextFloat(data))); + break; + case 4: // play_sound + var sound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data); + payload.AddRange(sound.Serialize()); + break; + } + return payload.ToArray(); + } + + private byte[] ReadMobEffectInstance(Queue data) + { + var result = new List(); + result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data))); + result.AddRange(ReadMobEffectDetails(data)); + return result.ToArray(); + } + + private byte[] ReadMobEffectDetails(Queue data) + { + var result = new List(); + result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data))); + result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data))); + result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data))); + result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data))); + result.AddRange(DataTypes.GetBool(dataTypes.ReadNextBool(data))); + var hasHidden = dataTypes.ReadNextBool(data); + result.AddRange(DataTypes.GetBool(hasHidden)); + if (hasHidden) + result.AddRange(ReadMobEffectDetails(data)); + return result.ToArray(); + } + + private byte[] ReadHolderSet(Queue data) + { + var result = new List(); + var type = dataTypes.ReadNextVarInt(data); + result.AddRange(DataTypes.GetVarInt(type)); + if (type == 0) + { + result.AddRange(DataTypes.GetString(dataTypes.ReadNextString(data))); + } + else + { + for (var i = 0; i < type - 1; i++) + result.AddRange(DataTypes.GetVarInt(dataTypes.ReadNextVarInt(data))); + } + return result.ToArray(); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(DeathEffects.Count)); + foreach (var effect in DeathEffects) + { + data.AddRange(DataTypes.GetVarInt(effect.EffectTypeId)); + data.AddRange(effect.Payload); + } + return new Queue(data); + } + + public record ConsumeEffectData(int EffectTypeId, byte[] Payload); +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EnchantableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EnchantableComponent.cs new file mode 100644 index 00000000..4ef63563 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EnchantableComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class EnchantableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Value { get; set; } + + public override void Parse(Queue data) + { + Value = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Value)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EquippableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EquippableComponent.cs new file mode 100644 index 00000000..c63e3f4d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/EquippableComponent.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class EquippableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Slot { get; set; } + public SoundEventSubComponent? EquipSound { get; set; } + public bool HasModel { get; set; } + public string? Model { get; set; } + public bool HasCameraOverlay { get; set; } + public string? CameraOverlay { get; set; } + public bool HasAllowedEntities { get; set; } + public int AllowedEntitiesType { get; set; } + public string? AllowedEntitiesTag { get; set; } + public List? AllowedEntitiesIds { get; set; } + public bool Dispensable { get; set; } + public bool Swappable { get; set; } + public bool DamageOnHurt { get; set; } + + public override void Parse(Queue data) + { + Slot = dataTypes.ReadNextVarInt(data); + EquipSound = (SoundEventSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.SoundEvent, data); + + HasModel = dataTypes.ReadNextBool(data); + if (HasModel) + Model = dataTypes.ReadNextString(data); + + HasCameraOverlay = dataTypes.ReadNextBool(data); + if (HasCameraOverlay) + CameraOverlay = dataTypes.ReadNextString(data); + + HasAllowedEntities = dataTypes.ReadNextBool(data); + if (HasAllowedEntities) + { + AllowedEntitiesType = dataTypes.ReadNextVarInt(data); + if (AllowedEntitiesType == 0) + { + AllowedEntitiesTag = dataTypes.ReadNextString(data); + } + else + { + AllowedEntitiesIds = new List(); + for (var i = 0; i < AllowedEntitiesType - 1; i++) + AllowedEntitiesIds.Add(dataTypes.ReadNextVarInt(data)); + } + } + + Dispensable = dataTypes.ReadNextBool(data); + Swappable = dataTypes.ReadNextBool(data); + DamageOnHurt = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Slot)); + if (EquipSound != null) data.AddRange(EquipSound.Serialize()); + + data.AddRange(DataTypes.GetBool(HasModel)); + if (HasModel && Model != null) + data.AddRange(DataTypes.GetString(Model)); + + data.AddRange(DataTypes.GetBool(HasCameraOverlay)); + if (HasCameraOverlay && CameraOverlay != null) + data.AddRange(DataTypes.GetString(CameraOverlay)); + + data.AddRange(DataTypes.GetBool(HasAllowedEntities)); + if (HasAllowedEntities) + { + data.AddRange(DataTypes.GetVarInt(AllowedEntitiesType)); + if (AllowedEntitiesType == 0 && AllowedEntitiesTag != null) + { + data.AddRange(DataTypes.GetString(AllowedEntitiesTag)); + } + else if (AllowedEntitiesIds != null) + { + foreach (var id in AllowedEntitiesIds) + data.AddRange(DataTypes.GetVarInt(id)); + } + } + + data.AddRange(DataTypes.GetBool(Dispensable)); + data.AddRange(DataTypes.GetBool(Swappable)); + data.AddRange(DataTypes.GetBool(DamageOnHurt)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/FoodComponent1212.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/FoodComponent1212.cs new file mode 100644 index 00000000..1832234d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/FoodComponent1212.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class FoodComponent1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Nutrition { get; set; } + public float Saturation { get; set; } + public bool CanAlwaysEat { get; set; } + + public override void Parse(Queue data) + { + Nutrition = dataTypes.ReadNextVarInt(data); + Saturation = dataTypes.ReadNextFloat(data); + CanAlwaysEat = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Nutrition)); + data.AddRange(DataTypes.GetFloat(Saturation)); + data.AddRange(DataTypes.GetBool(CanAlwaysEat)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/GliderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/GliderComponent.cs new file mode 100644 index 00000000..1aa739d0 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/GliderComponent.cs @@ -0,0 +1,8 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class GliderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EmptyComponent(dataTypes, itemPalette, subComponentRegistry); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ItemModelComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ItemModelComponent.cs new file mode 100644 index 00000000..65cdac8c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/ItemModelComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class ItemModelComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string Identifier { get; set; } = null!; + + public override void Parse(Queue data) + { + Identifier = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(Identifier)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/RepairableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/RepairableComponent.cs new file mode 100644 index 00000000..08dcb91c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/RepairableComponent.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class RepairableComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Type { get; set; } + public string? TagName { get; set; } + public List? ItemIds { get; set; } + + public override void Parse(Queue data) + { + Type = dataTypes.ReadNextVarInt(data); + if (Type == 0) + { + TagName = dataTypes.ReadNextString(data); + } + else + { + ItemIds = new List(); + for (var i = 0; i < Type - 1; i++) + ItemIds.Add(dataTypes.ReadNextVarInt(data)); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Type)); + if (Type == 0 && TagName != null) + { + data.AddRange(DataTypes.GetString(TagName)); + } + else if (ItemIds != null) + { + foreach (var id in ItemIds) + data.AddRange(DataTypes.GetVarInt(id)); + } + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/TooltipStyleComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/TooltipStyleComponent.cs new file mode 100644 index 00000000..aed0af34 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/TooltipStyleComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class TooltipStyleComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string Identifier { get; set; } = null!; + + public override void Parse(Queue data) + { + Identifier = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetString(Identifier)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseCooldownComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseCooldownComponent.cs new file mode 100644 index 00000000..60f175c6 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseCooldownComponent.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class UseCooldownComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public float Seconds { get; set; } + public bool HasCooldownGroup { get; set; } + public string? CooldownGroup { get; set; } + + public override void Parse(Queue data) + { + Seconds = dataTypes.ReadNextFloat(data); + HasCooldownGroup = dataTypes.ReadNextBool(data); + if (HasCooldownGroup) + CooldownGroup = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetFloat(Seconds)); + data.AddRange(DataTypes.GetBool(HasCooldownGroup)); + if (HasCooldownGroup && CooldownGroup != null) + data.AddRange(DataTypes.GetString(CooldownGroup)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseRemainderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseRemainderComponent.cs new file mode 100644 index 00000000..ead551aa --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_2/UseRemainderComponent.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; + +public class UseRemainderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public Item? ConvertInto { get; set; } + + public override void Parse(Queue data) + { + ConvertInto = dataTypes.ReadNextItemSlot(data, ItemPalette); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(dataTypes.GetItemSlot(ConvertInto, ItemPalette)); + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1212.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1212.cs new file mode 100644 index 00000000..361cbfae --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1212.cs @@ -0,0 +1,82 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry1212 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry1212(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) + { + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); + RegisterComponent(5, "minecraft:custom_name"); + RegisterComponent(6, "minecraft:item_name"); + RegisterComponent(7, "minecraft:item_model"); + RegisterComponent(8, "minecraft:lore"); + RegisterComponent(9, "minecraft:rarity"); + RegisterComponent(10, "minecraft:enchantments"); + RegisterComponent(11, "minecraft:can_place_on"); + RegisterComponent(12, "minecraft:can_break"); + RegisterComponent(13, "minecraft:attribute_modifiers"); + RegisterComponent(14, "minecraft:custom_model_data"); + RegisterComponent(15, "minecraft:hide_additional_tooltip"); + RegisterComponent(16, "minecraft:hide_tooltip"); + RegisterComponent(17, "minecraft:repair_cost"); + RegisterComponent(18, "minecraft:creative_slot_lock"); + RegisterComponent(19, "minecraft:enchantment_glint_override"); + RegisterComponent(20, "minecraft:intangible_projectile"); + RegisterComponent(21, "minecraft:food"); + RegisterComponent(22, "minecraft:consumable"); + RegisterComponent(23, "minecraft:use_remainder"); + RegisterComponent(24, "minecraft:use_cooldown"); + RegisterComponent(25, "minecraft:damage_resistant"); + RegisterComponent(26, "minecraft:tool"); + RegisterComponent(27, "minecraft:enchantable"); + RegisterComponent(28, "minecraft:equippable"); + RegisterComponent(29, "minecraft:repairable"); + RegisterComponent(30, "minecraft:glider"); + RegisterComponent(31, "minecraft:tooltip_style"); + RegisterComponent(32, "minecraft:death_protection"); + RegisterComponent(33, "minecraft:stored_enchantments"); + RegisterComponent(34, "minecraft:dyed_color"); + RegisterComponent(35, "minecraft:map_color"); + RegisterComponent(36, "minecraft:map_id"); + RegisterComponent(37, "minecraft:map_decorations"); + RegisterComponent(38, "minecraft:map_post_processing"); + RegisterComponent(39, "minecraft:charged_projectiles"); + RegisterComponent(40, "minecraft:bundle_contents"); + RegisterComponent(41, "minecraft:potion_contents"); + RegisterComponent(42, "minecraft:suspicious_stew_effects"); + RegisterComponent(43, "minecraft:writable_book_content"); + RegisterComponent(44, "minecraft:written_book_content"); + RegisterComponent(45, "minecraft:trim"); + RegisterComponent(46, "minecraft:debug_stick_state"); + RegisterComponent(47, "minecraft:entity_data"); + RegisterComponent(48, "minecraft:bucket_entity_data"); + RegisterComponent(49, "minecraft:block_entity_data"); + RegisterComponent(50, "minecraft:instrument"); + RegisterComponent(51, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(52, "minecraft:jukebox_playable"); + RegisterComponent(53, "minecraft:recipes"); + RegisterComponent(54, "minecraft:lodestone_tracker"); + RegisterComponent(55, "minecraft:firework_explosion"); + RegisterComponent(56, "minecraft:fireworks"); + RegisterComponent(57, "minecraft:profile"); + RegisterComponent(58, "minecraft:note_block_sound"); + RegisterComponent(59, "minecraft:banner_patterns"); + RegisterComponent(60, "minecraft:base_color"); + RegisterComponent(61, "minecraft:pot_decorations"); + RegisterComponent(62, "minecraft:container"); + RegisterComponent(63, "minecraft:block_state"); + RegisterComponent(64, "minecraft:bees"); + RegisterComponent(65, "minecraft:lock"); + RegisterComponent(66, "minecraft:container_loot"); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1212.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1212.cs new file mode 100644 index 00000000..ba5df821 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1212.cs @@ -0,0 +1,11 @@ +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries.Subcomponents; + +public class SubComponentRegistry1212 : SubComponentRegistry121 +{ + public SubComponentRegistry1212(DataTypes dataTypes) : base(dataTypes) + { + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index 2fd0cb82..9729e5f4 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -21,6 +21,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121), + >= Protocol18Handler.MC_1_21_2_Version => typeof(SubComponentRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") }; @@ -32,6 +33,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), + >= Protocol18Handler.MC_1_21_2_Version => typeof(StructuredComponentsRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") }; From a92bf5b071a5f357890f74d539c2c40222c226a2 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 03:45:32 +0800 Subject: [PATCH 055/484] feat: complete 1.21.2 protocol handling for terrain, inventory, and entity support The previous commits added palette files, packet IDs, and structured components for MC 1.21.2 (protocol 768), but terrain/inventory/entity features were still disabled at runtime because the version guards in the constructor checked > MC_1_21_Version (767) instead of > MC_1_21_2_Version (768). This commit completes the 1.21.2 adaptation with the following changes: - Update feature-disable guards from > MC_1_21_Version to > MC_1_21_2_Version so terrain, inventory, and entity handling are enabled for protocol 768 - Update healthField metadata index guard to > MC_1_21_2_Version - Handle container ID encoding change: byte -> VarInt for 1.21.2+ in both clientbound reads (CloseWindow, WindowItems, WindowProperty, SetSlot) and serverbound sends (ClickWindow, CloseWindow) - Handle EntityTeleport format change: 1.21.2 uses PositionMoveRotation (pos + delta + float angles) + relative flags bitmask (int) + onGround - Handle TimeUpdate format change: 1.21.2 appends a tickDayTime boolean - Add handlers for new 1.21.2 packets: EntityPositionSync, PlayerRotation, SetCursorItem, SetPlayerInventory, MoveMinecartAlongTrack, and RecipeBookAdd/Remove/Settings (ignored, MCC doesn't track recipes) Tested: successful connection to 1.21.2 vanilla server with inventory, entity tracking, and chat all working correctly. Made-with: Cursor --- .../Protocol/Handlers/Protocol18.cs | 133 +++++++++++++++--- 1 file changed, 114 insertions(+), 19 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 1b1cb1fe..3ef61f97 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -125,21 +125,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_2_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_2_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_2_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -2261,7 +2261,9 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.CloseWindow: if (handler.GetInventoryEnabled()) { - var windowId = dataTypes.ReadNextByte(packetData); + var windowId = protocolVersion >= MC_1_21_2_Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextByte(packetData); lock (window_actions) { window_actions[windowId] = 0; @@ -2274,7 +2276,9 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.WindowItems: if (handler.GetInventoryEnabled()) { - var windowId = dataTypes.ReadNextByte(packetData); + var windowId = (byte)(protocolVersion >= MC_1_21_2_Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextByte(packetData)); var stateId = -1; int elements; @@ -2306,7 +2310,9 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.WindowProperty: - var containerId = dataTypes.ReadNextByte(packetData); + var containerId = (byte)(protocolVersion >= MC_1_21_2_Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextByte(packetData)); var propertyId = dataTypes.ReadNextShort(packetData); var propertyValue = dataTypes.ReadNextShort(packetData); handler.OnWindowProperties(containerId, propertyId, propertyValue); @@ -2314,7 +2320,9 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.SetSlot: if (handler.GetInventoryEnabled()) { - var windowId = dataTypes.ReadNextByte(packetData); + var windowId = (byte)(protocolVersion >= MC_1_21_2_Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextByte(packetData)); var stateId = -1; if (protocolVersion >= MC_1_17_1_Version) stateId = dataTypes.ReadNextVarInt(packetData); // State ID - 1.17.1 and above @@ -2615,7 +2623,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_Version => throw new NotImplementedException(Translations + > MC_1_21_2_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, @@ -2647,6 +2655,8 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.TimeUpdate: var worldAge = dataTypes.ReadNextLong(packetData); var timeOfDay = dataTypes.ReadNextLong(packetData); + if (protocolVersion >= MC_1_21_2_Version) + dataTypes.ReadNextBool(packetData); // Tick day time handler.OnTimeUpdate(worldAge, timeOfDay); break; case PacketTypesIn.EntityTeleport: @@ -2655,23 +2665,41 @@ namespace MinecraftClient.Protocol.Handlers var entityId = dataTypes.ReadNextVarInt(packetData); double x, y, z; - if (protocolVersion < MC_1_9_Version) + if (protocolVersion >= MC_1_21_2_Version) + { + // 1.21.2+: PositionMoveRotation + relative flags + x = dataTypes.ReadNextDouble(packetData); + y = dataTypes.ReadNextDouble(packetData); + z = dataTypes.ReadNextDouble(packetData); + dataTypes.ReadNextDouble(packetData); // Delta movement X + dataTypes.ReadNextDouble(packetData); // Delta movement Y + dataTypes.ReadNextDouble(packetData); // Delta movement Z + dataTypes.ReadNextFloat(packetData); // Yaw + dataTypes.ReadNextFloat(packetData); // Pitch + dataTypes.ReadNextInt(packetData); // Relative flags bitmask + var isOnGround = dataTypes.ReadNextBool(packetData); + handler.OnEntityTeleport(entityId, x, y, z, isOnGround); + } + else if (protocolVersion < MC_1_9_Version) { x = dataTypes.ReadNextInt(packetData) / 32.0D; y = dataTypes.ReadNextInt(packetData) / 32.0D; z = dataTypes.ReadNextInt(packetData) / 32.0D; + dataTypes.ReadNextByte(packetData); // Yaw + dataTypes.ReadNextByte(packetData); // Pitch + var isOnGround = dataTypes.ReadNextBool(packetData); + handler.OnEntityTeleport(entityId, x, y, z, isOnGround); } else { x = dataTypes.ReadNextDouble(packetData); y = dataTypes.ReadNextDouble(packetData); z = dataTypes.ReadNextDouble(packetData); + dataTypes.ReadNextByte(packetData); // Yaw + dataTypes.ReadNextByte(packetData); // Pitch + var isOnGround = dataTypes.ReadNextBool(packetData); + handler.OnEntityTeleport(entityId, x, y, z, isOnGround); } - - var entityYaw = dataTypes.ReadNextByte(packetData); - var entityPitch = dataTypes.ReadNextByte(packetData); - var isOnGround = dataTypes.ReadNextBool(packetData); - handler.OnEntityTeleport(entityId, x, y, z, isOnGround); } break; @@ -2899,6 +2927,69 @@ namespace MinecraftClient.Protocol.Handlers } break; + // 1.21.2+ new packets + case PacketTypesIn.SetCursorItem: + if (handler.GetInventoryEnabled()) + { + dataTypes.ReadNextItemSlot(packetData, itemPalette); + } + break; + + case PacketTypesIn.SetPlayerInventory: + if (handler.GetInventoryEnabled()) + { + var slotId = dataTypes.ReadNextVarInt(packetData); + var item = dataTypes.ReadNextItemSlot(packetData, itemPalette); + handler.OnSetSlot(0, (short)slotId, item, -1); + } + break; + + case PacketTypesIn.EntityPositionSync: + if (handler.GetEntityHandlingEnabled()) + { + var entityId = dataTypes.ReadNextVarInt(packetData); + var x = dataTypes.ReadNextDouble(packetData); + var y = dataTypes.ReadNextDouble(packetData); + var z = dataTypes.ReadNextDouble(packetData); + dataTypes.ReadNextDouble(packetData); // Delta movement X + dataTypes.ReadNextDouble(packetData); // Delta movement Y + dataTypes.ReadNextDouble(packetData); // Delta movement Z + var yaw = dataTypes.ReadNextFloat(packetData); + var pitch = dataTypes.ReadNextFloat(packetData); + var isOnGround = dataTypes.ReadNextBool(packetData); + handler.OnEntityTeleport(entityId, x, y, z, isOnGround); + } + break; + + case PacketTypesIn.PlayerRotation: + dataTypes.ReadNextFloat(packetData); // Yaw + dataTypes.ReadNextFloat(packetData); // Pitch + break; + + case PacketTypesIn.MoveMinecartAlongTrack: + { + dataTypes.ReadNextVarInt(packetData); // Entity ID + var stepCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < stepCount; i++) + { + dataTypes.ReadNextDouble(packetData); // Pos X + dataTypes.ReadNextDouble(packetData); // Pos Y + dataTypes.ReadNextDouble(packetData); // Pos Z + dataTypes.ReadNextDouble(packetData); // Movement X + dataTypes.ReadNextDouble(packetData); // Movement Y + dataTypes.ReadNextDouble(packetData); // Movement Z + dataTypes.ReadNextByte(packetData); // Yaw + dataTypes.ReadNextByte(packetData); // Pitch + dataTypes.ReadNextFloat(packetData); // Weight + } + } + break; + + case PacketTypesIn.RecipeBookAdd: + case PacketTypesIn.RecipeBookRemove: + case PacketTypesIn.RecipeBookSettings: + break; + default: return false; //Ignored packet } @@ -4383,10 +4474,11 @@ namespace MinecraftClient.Protocol.Handlers break; } - List packet = new() - { - (byte)windowId // Window ID - }; + List packet = new(); + if (protocolVersion >= MC_1_21_2_Version) + packet.AddRange(DataTypes.GetVarInt(windowId)); // Window ID (VarInt in 1.21.2+) + else + packet.Add((byte)windowId); // Window ID (byte before 1.21.2) switch (protocolVersion) { @@ -4589,7 +4681,10 @@ namespace MinecraftClient.Protocol.Handlers window_actions[windowId] = 0; } - SendPacket(PacketTypesOut.CloseWindow, new[] { (byte)windowId }); + SendPacket(PacketTypesOut.CloseWindow, + protocolVersion >= MC_1_21_2_Version + ? DataTypes.GetVarInt(windowId) + : new[] { (byte)windowId }); return true; } catch (SocketException) From 3acfc0aaa472dbabb8822d05cb5a60fc8ce4619a Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 23:05:44 +0800 Subject: [PATCH 056/484] fix: update ConsoleInteractive submodule to .NET 8 Update submodule to commit a045f7e which adds net8.0 target framework, fixing NETSDK1005 build error in CI when publishing with -f net8.0. Made-with: Cursor --- ConsoleInteractive | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ConsoleInteractive b/ConsoleInteractive index db2be2a7..a045f7ed 160000 --- a/ConsoleInteractive +++ b/ConsoleInteractive @@ -1 +1 @@ -Subproject commit db2be2a7f8ea71c734ebeff6314fd2fdec73f4fc +Subproject commit a045f7eddd0e6d914715f358dd7333071e5dd567 From f73148e5ecd16465a756820c41c76e53c372c114 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 23:51:56 +0800 Subject: [PATCH 057/484] feat: add MC 1.21.4 (protocol 769) support Add complete protocol 769 support for Minecraft 1.21.4: - Version constants: Add 769 to supported versions, MC_1_21_4_Version constant, and version string mappings (including 1.21.3 -> 768 compatibility) - Item palette: 10 new items (Resin series + Eyeblossom), generated ItemPalette1214 - Entity palette: Remove CreakingTransient (149 entities, down from 150) - Block palette: 10 new blocks with correct blockstate ID ranges from server data - Packet palette: Serverbound packet ID reshuffling - PickItem split into PickItemFromBlock/PickItemFromEntity, new PlayerLoaded packet inserted after PlayerInput, subsequent IDs shifted accordingly. Clientbound unchanged. - PlayerLoaded: Send empty PlayerLoaded packet after JoinGame processing (>= 1.21.4) - EntityMetadata/DataComponents: Reuse 1.20.6 palettes (unchanged registries) - Update all version guard checks from MC_1_21_2 to MC_1_21_4 Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1214.cs | 1403 +++++++++++++ MinecraftClient/Inventory/ItemType.cs | 10 + .../Mapping/BlockPalettes/Palette1214.cs | 1826 +++++++++++++++++ .../Mapping/EntityMetadataPalette.cs | 2 +- .../EntityPalettes/EntityPalette1214.cs | 168 ++ MinecraftClient/Mapping/Material.cs | 11 + MinecraftClient/Mapping/MaterialExtensions.cs | 11 +- .../PacketPalettes/PacketPalette1214.cs | 245 +++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- .../Protocol/Handlers/PacketTypesOut.cs | 1 + .../Protocol/Handlers/Protocol18.cs | 22 +- MinecraftClient/Protocol/ProtocolHandler.cs | 8 +- 12 files changed, 3699 insertions(+), 11 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1214.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1214.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1214.cs create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1214.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1214.cs new file mode 100644 index 00000000..c0cf85a8 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1214.cs @@ -0,0 +1,1403 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1214 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1214() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Azalea; + mappings[205] = ItemType.FloweringAzalea; + mappings[206] = ItemType.DeadBush; + mappings[207] = ItemType.Seagrass; + mappings[208] = ItemType.SeaPickle; + mappings[209] = ItemType.WhiteWool; + mappings[210] = ItemType.OrangeWool; + mappings[211] = ItemType.MagentaWool; + mappings[212] = ItemType.LightBlueWool; + mappings[213] = ItemType.YellowWool; + mappings[214] = ItemType.LimeWool; + mappings[215] = ItemType.PinkWool; + mappings[216] = ItemType.GrayWool; + mappings[217] = ItemType.LightGrayWool; + mappings[218] = ItemType.CyanWool; + mappings[219] = ItemType.PurpleWool; + mappings[220] = ItemType.BlueWool; + mappings[221] = ItemType.BrownWool; + mappings[222] = ItemType.GreenWool; + mappings[223] = ItemType.RedWool; + mappings[224] = ItemType.BlackWool; + mappings[225] = ItemType.Dandelion; + mappings[226] = ItemType.OpenEyeblossom; + mappings[227] = ItemType.ClosedEyeblossom; + mappings[228] = ItemType.Poppy; + mappings[229] = ItemType.BlueOrchid; + mappings[230] = ItemType.Allium; + mappings[231] = ItemType.AzureBluet; + mappings[232] = ItemType.RedTulip; + mappings[233] = ItemType.OrangeTulip; + mappings[234] = ItemType.WhiteTulip; + mappings[235] = ItemType.PinkTulip; + mappings[236] = ItemType.OxeyeDaisy; + mappings[237] = ItemType.Cornflower; + mappings[238] = ItemType.LilyOfTheValley; + mappings[239] = ItemType.WitherRose; + mappings[240] = ItemType.Torchflower; + mappings[241] = ItemType.PitcherPlant; + mappings[242] = ItemType.SporeBlossom; + mappings[243] = ItemType.BrownMushroom; + mappings[244] = ItemType.RedMushroom; + mappings[245] = ItemType.CrimsonFungus; + mappings[246] = ItemType.WarpedFungus; + mappings[247] = ItemType.CrimsonRoots; + mappings[248] = ItemType.WarpedRoots; + mappings[249] = ItemType.NetherSprouts; + mappings[250] = ItemType.WeepingVines; + mappings[251] = ItemType.TwistingVines; + mappings[252] = ItemType.SugarCane; + mappings[253] = ItemType.Kelp; + mappings[254] = ItemType.PinkPetals; + mappings[255] = ItemType.MossCarpet; + mappings[256] = ItemType.MossBlock; + mappings[257] = ItemType.PaleMossCarpet; + mappings[258] = ItemType.PaleHangingMoss; + mappings[259] = ItemType.PaleMossBlock; + mappings[260] = ItemType.HangingRoots; + mappings[261] = ItemType.BigDripleaf; + mappings[262] = ItemType.SmallDripleaf; + mappings[263] = ItemType.Bamboo; + mappings[264] = ItemType.OakSlab; + mappings[265] = ItemType.SpruceSlab; + mappings[266] = ItemType.BirchSlab; + mappings[267] = ItemType.JungleSlab; + mappings[268] = ItemType.AcaciaSlab; + mappings[269] = ItemType.CherrySlab; + mappings[270] = ItemType.DarkOakSlab; + mappings[271] = ItemType.PaleOakSlab; + mappings[272] = ItemType.MangroveSlab; + mappings[273] = ItemType.BambooSlab; + mappings[274] = ItemType.BambooMosaicSlab; + mappings[275] = ItemType.CrimsonSlab; + mappings[276] = ItemType.WarpedSlab; + mappings[277] = ItemType.StoneSlab; + mappings[278] = ItemType.SmoothStoneSlab; + mappings[279] = ItemType.SandstoneSlab; + mappings[280] = ItemType.CutSandstoneSlab; + mappings[281] = ItemType.PetrifiedOakSlab; + mappings[282] = ItemType.CobblestoneSlab; + mappings[283] = ItemType.BrickSlab; + mappings[284] = ItemType.StoneBrickSlab; + mappings[285] = ItemType.MudBrickSlab; + mappings[286] = ItemType.NetherBrickSlab; + mappings[287] = ItemType.QuartzSlab; + mappings[288] = ItemType.RedSandstoneSlab; + mappings[289] = ItemType.CutRedSandstoneSlab; + mappings[290] = ItemType.PurpurSlab; + mappings[291] = ItemType.PrismarineSlab; + mappings[292] = ItemType.PrismarineBrickSlab; + mappings[293] = ItemType.DarkPrismarineSlab; + mappings[294] = ItemType.SmoothQuartz; + mappings[295] = ItemType.SmoothRedSandstone; + mappings[296] = ItemType.SmoothSandstone; + mappings[297] = ItemType.SmoothStone; + mappings[298] = ItemType.Bricks; + mappings[299] = ItemType.Bookshelf; + mappings[300] = ItemType.ChiseledBookshelf; + mappings[301] = ItemType.DecoratedPot; + mappings[302] = ItemType.MossyCobblestone; + mappings[303] = ItemType.Obsidian; + mappings[304] = ItemType.Torch; + mappings[305] = ItemType.EndRod; + mappings[306] = ItemType.ChorusPlant; + mappings[307] = ItemType.ChorusFlower; + mappings[308] = ItemType.PurpurBlock; + mappings[309] = ItemType.PurpurPillar; + mappings[310] = ItemType.PurpurStairs; + mappings[311] = ItemType.Spawner; + mappings[312] = ItemType.CreakingHeart; + mappings[313] = ItemType.Chest; + mappings[314] = ItemType.CraftingTable; + mappings[315] = ItemType.Farmland; + mappings[316] = ItemType.Furnace; + mappings[317] = ItemType.Ladder; + mappings[318] = ItemType.CobblestoneStairs; + mappings[319] = ItemType.Snow; + mappings[320] = ItemType.Ice; + mappings[321] = ItemType.SnowBlock; + mappings[322] = ItemType.Cactus; + mappings[323] = ItemType.Clay; + mappings[324] = ItemType.Jukebox; + mappings[325] = ItemType.OakFence; + mappings[326] = ItemType.SpruceFence; + mappings[327] = ItemType.BirchFence; + mappings[328] = ItemType.JungleFence; + mappings[329] = ItemType.AcaciaFence; + mappings[330] = ItemType.CherryFence; + mappings[331] = ItemType.DarkOakFence; + mappings[332] = ItemType.PaleOakFence; + mappings[333] = ItemType.MangroveFence; + mappings[334] = ItemType.BambooFence; + mappings[335] = ItemType.CrimsonFence; + mappings[336] = ItemType.WarpedFence; + mappings[337] = ItemType.Pumpkin; + mappings[338] = ItemType.CarvedPumpkin; + mappings[339] = ItemType.JackOLantern; + mappings[340] = ItemType.Netherrack; + mappings[341] = ItemType.SoulSand; + mappings[342] = ItemType.SoulSoil; + mappings[343] = ItemType.Basalt; + mappings[344] = ItemType.PolishedBasalt; + mappings[345] = ItemType.SmoothBasalt; + mappings[346] = ItemType.SoulTorch; + mappings[347] = ItemType.Glowstone; + mappings[348] = ItemType.InfestedStone; + mappings[349] = ItemType.InfestedCobblestone; + mappings[350] = ItemType.InfestedStoneBricks; + mappings[351] = ItemType.InfestedMossyStoneBricks; + mappings[352] = ItemType.InfestedCrackedStoneBricks; + mappings[353] = ItemType.InfestedChiseledStoneBricks; + mappings[354] = ItemType.InfestedDeepslate; + mappings[355] = ItemType.StoneBricks; + mappings[356] = ItemType.MossyStoneBricks; + mappings[357] = ItemType.CrackedStoneBricks; + mappings[358] = ItemType.ChiseledStoneBricks; + mappings[359] = ItemType.PackedMud; + mappings[360] = ItemType.MudBricks; + mappings[361] = ItemType.DeepslateBricks; + mappings[362] = ItemType.CrackedDeepslateBricks; + mappings[363] = ItemType.DeepslateTiles; + mappings[364] = ItemType.CrackedDeepslateTiles; + mappings[365] = ItemType.ChiseledDeepslate; + mappings[366] = ItemType.ReinforcedDeepslate; + mappings[367] = ItemType.BrownMushroomBlock; + mappings[368] = ItemType.RedMushroomBlock; + mappings[369] = ItemType.MushroomStem; + mappings[370] = ItemType.IronBars; + mappings[371] = ItemType.Chain; + mappings[372] = ItemType.GlassPane; + mappings[373] = ItemType.Melon; + mappings[374] = ItemType.Vine; + mappings[375] = ItemType.GlowLichen; + mappings[376] = ItemType.ResinClump; + mappings[377] = ItemType.ResinBlock; + mappings[378] = ItemType.ResinBricks; + mappings[379] = ItemType.ResinBrickStairs; + mappings[380] = ItemType.ResinBrickSlab; + mappings[381] = ItemType.ResinBrickWall; + mappings[382] = ItemType.ChiseledResinBricks; + mappings[383] = ItemType.BrickStairs; + mappings[384] = ItemType.StoneBrickStairs; + mappings[385] = ItemType.MudBrickStairs; + mappings[386] = ItemType.Mycelium; + mappings[387] = ItemType.LilyPad; + mappings[388] = ItemType.NetherBricks; + mappings[389] = ItemType.CrackedNetherBricks; + mappings[390] = ItemType.ChiseledNetherBricks; + mappings[391] = ItemType.NetherBrickFence; + mappings[392] = ItemType.NetherBrickStairs; + mappings[393] = ItemType.Sculk; + mappings[394] = ItemType.SculkVein; + mappings[395] = ItemType.SculkCatalyst; + mappings[396] = ItemType.SculkShrieker; + mappings[397] = ItemType.EnchantingTable; + mappings[398] = ItemType.EndPortalFrame; + mappings[399] = ItemType.EndStone; + mappings[400] = ItemType.EndStoneBricks; + mappings[401] = ItemType.DragonEgg; + mappings[402] = ItemType.SandstoneStairs; + mappings[403] = ItemType.EnderChest; + mappings[404] = ItemType.EmeraldBlock; + mappings[405] = ItemType.OakStairs; + mappings[406] = ItemType.SpruceStairs; + mappings[407] = ItemType.BirchStairs; + mappings[408] = ItemType.JungleStairs; + mappings[409] = ItemType.AcaciaStairs; + mappings[410] = ItemType.CherryStairs; + mappings[411] = ItemType.DarkOakStairs; + mappings[412] = ItemType.PaleOakStairs; + mappings[413] = ItemType.MangroveStairs; + mappings[414] = ItemType.BambooStairs; + mappings[415] = ItemType.BambooMosaicStairs; + mappings[416] = ItemType.CrimsonStairs; + mappings[417] = ItemType.WarpedStairs; + mappings[418] = ItemType.CommandBlock; + mappings[419] = ItemType.Beacon; + mappings[420] = ItemType.CobblestoneWall; + mappings[421] = ItemType.MossyCobblestoneWall; + mappings[422] = ItemType.BrickWall; + mappings[423] = ItemType.PrismarineWall; + mappings[424] = ItemType.RedSandstoneWall; + mappings[425] = ItemType.MossyStoneBrickWall; + mappings[426] = ItemType.GraniteWall; + mappings[427] = ItemType.StoneBrickWall; + mappings[428] = ItemType.MudBrickWall; + mappings[429] = ItemType.NetherBrickWall; + mappings[430] = ItemType.AndesiteWall; + mappings[431] = ItemType.RedNetherBrickWall; + mappings[432] = ItemType.SandstoneWall; + mappings[433] = ItemType.EndStoneBrickWall; + mappings[434] = ItemType.DioriteWall; + mappings[435] = ItemType.BlackstoneWall; + mappings[436] = ItemType.PolishedBlackstoneWall; + mappings[437] = ItemType.PolishedBlackstoneBrickWall; + mappings[438] = ItemType.CobbledDeepslateWall; + mappings[439] = ItemType.PolishedDeepslateWall; + mappings[440] = ItemType.DeepslateBrickWall; + mappings[441] = ItemType.DeepslateTileWall; + mappings[442] = ItemType.Anvil; + mappings[443] = ItemType.ChippedAnvil; + mappings[444] = ItemType.DamagedAnvil; + mappings[445] = ItemType.ChiseledQuartzBlock; + mappings[446] = ItemType.QuartzBlock; + mappings[447] = ItemType.QuartzBricks; + mappings[448] = ItemType.QuartzPillar; + mappings[449] = ItemType.QuartzStairs; + mappings[450] = ItemType.WhiteTerracotta; + mappings[451] = ItemType.OrangeTerracotta; + mappings[452] = ItemType.MagentaTerracotta; + mappings[453] = ItemType.LightBlueTerracotta; + mappings[454] = ItemType.YellowTerracotta; + mappings[455] = ItemType.LimeTerracotta; + mappings[456] = ItemType.PinkTerracotta; + mappings[457] = ItemType.GrayTerracotta; + mappings[458] = ItemType.LightGrayTerracotta; + mappings[459] = ItemType.CyanTerracotta; + mappings[460] = ItemType.PurpleTerracotta; + mappings[461] = ItemType.BlueTerracotta; + mappings[462] = ItemType.BrownTerracotta; + mappings[463] = ItemType.GreenTerracotta; + mappings[464] = ItemType.RedTerracotta; + mappings[465] = ItemType.BlackTerracotta; + mappings[466] = ItemType.Barrier; + mappings[467] = ItemType.Light; + mappings[468] = ItemType.HayBlock; + mappings[469] = ItemType.WhiteCarpet; + mappings[470] = ItemType.OrangeCarpet; + mappings[471] = ItemType.MagentaCarpet; + mappings[472] = ItemType.LightBlueCarpet; + mappings[473] = ItemType.YellowCarpet; + mappings[474] = ItemType.LimeCarpet; + mappings[475] = ItemType.PinkCarpet; + mappings[476] = ItemType.GrayCarpet; + mappings[477] = ItemType.LightGrayCarpet; + mappings[478] = ItemType.CyanCarpet; + mappings[479] = ItemType.PurpleCarpet; + mappings[480] = ItemType.BlueCarpet; + mappings[481] = ItemType.BrownCarpet; + mappings[482] = ItemType.GreenCarpet; + mappings[483] = ItemType.RedCarpet; + mappings[484] = ItemType.BlackCarpet; + mappings[485] = ItemType.Terracotta; + mappings[486] = ItemType.PackedIce; + mappings[487] = ItemType.DirtPath; + mappings[488] = ItemType.Sunflower; + mappings[489] = ItemType.Lilac; + mappings[490] = ItemType.RoseBush; + mappings[491] = ItemType.Peony; + mappings[492] = ItemType.TallGrass; + mappings[493] = ItemType.LargeFern; + mappings[494] = ItemType.WhiteStainedGlass; + mappings[495] = ItemType.OrangeStainedGlass; + mappings[496] = ItemType.MagentaStainedGlass; + mappings[497] = ItemType.LightBlueStainedGlass; + mappings[498] = ItemType.YellowStainedGlass; + mappings[499] = ItemType.LimeStainedGlass; + mappings[500] = ItemType.PinkStainedGlass; + mappings[501] = ItemType.GrayStainedGlass; + mappings[502] = ItemType.LightGrayStainedGlass; + mappings[503] = ItemType.CyanStainedGlass; + mappings[504] = ItemType.PurpleStainedGlass; + mappings[505] = ItemType.BlueStainedGlass; + mappings[506] = ItemType.BrownStainedGlass; + mappings[507] = ItemType.GreenStainedGlass; + mappings[508] = ItemType.RedStainedGlass; + mappings[509] = ItemType.BlackStainedGlass; + mappings[510] = ItemType.WhiteStainedGlassPane; + mappings[511] = ItemType.OrangeStainedGlassPane; + mappings[512] = ItemType.MagentaStainedGlassPane; + mappings[513] = ItemType.LightBlueStainedGlassPane; + mappings[514] = ItemType.YellowStainedGlassPane; + mappings[515] = ItemType.LimeStainedGlassPane; + mappings[516] = ItemType.PinkStainedGlassPane; + mappings[517] = ItemType.GrayStainedGlassPane; + mappings[518] = ItemType.LightGrayStainedGlassPane; + mappings[519] = ItemType.CyanStainedGlassPane; + mappings[520] = ItemType.PurpleStainedGlassPane; + mappings[521] = ItemType.BlueStainedGlassPane; + mappings[522] = ItemType.BrownStainedGlassPane; + mappings[523] = ItemType.GreenStainedGlassPane; + mappings[524] = ItemType.RedStainedGlassPane; + mappings[525] = ItemType.BlackStainedGlassPane; + mappings[526] = ItemType.Prismarine; + mappings[527] = ItemType.PrismarineBricks; + mappings[528] = ItemType.DarkPrismarine; + mappings[529] = ItemType.PrismarineStairs; + mappings[530] = ItemType.PrismarineBrickStairs; + mappings[531] = ItemType.DarkPrismarineStairs; + mappings[532] = ItemType.SeaLantern; + mappings[533] = ItemType.RedSandstone; + mappings[534] = ItemType.ChiseledRedSandstone; + mappings[535] = ItemType.CutRedSandstone; + mappings[536] = ItemType.RedSandstoneStairs; + mappings[537] = ItemType.RepeatingCommandBlock; + mappings[538] = ItemType.ChainCommandBlock; + mappings[539] = ItemType.MagmaBlock; + mappings[540] = ItemType.NetherWartBlock; + mappings[541] = ItemType.WarpedWartBlock; + mappings[542] = ItemType.RedNetherBricks; + mappings[543] = ItemType.BoneBlock; + mappings[544] = ItemType.StructureVoid; + mappings[545] = ItemType.ShulkerBox; + mappings[546] = ItemType.WhiteShulkerBox; + mappings[547] = ItemType.OrangeShulkerBox; + mappings[548] = ItemType.MagentaShulkerBox; + mappings[549] = ItemType.LightBlueShulkerBox; + mappings[550] = ItemType.YellowShulkerBox; + mappings[551] = ItemType.LimeShulkerBox; + mappings[552] = ItemType.PinkShulkerBox; + mappings[553] = ItemType.GrayShulkerBox; + mappings[554] = ItemType.LightGrayShulkerBox; + mappings[555] = ItemType.CyanShulkerBox; + mappings[556] = ItemType.PurpleShulkerBox; + mappings[557] = ItemType.BlueShulkerBox; + mappings[558] = ItemType.BrownShulkerBox; + mappings[559] = ItemType.GreenShulkerBox; + mappings[560] = ItemType.RedShulkerBox; + mappings[561] = ItemType.BlackShulkerBox; + mappings[562] = ItemType.WhiteGlazedTerracotta; + mappings[563] = ItemType.OrangeGlazedTerracotta; + mappings[564] = ItemType.MagentaGlazedTerracotta; + mappings[565] = ItemType.LightBlueGlazedTerracotta; + mappings[566] = ItemType.YellowGlazedTerracotta; + mappings[567] = ItemType.LimeGlazedTerracotta; + mappings[568] = ItemType.PinkGlazedTerracotta; + mappings[569] = ItemType.GrayGlazedTerracotta; + mappings[570] = ItemType.LightGrayGlazedTerracotta; + mappings[571] = ItemType.CyanGlazedTerracotta; + mappings[572] = ItemType.PurpleGlazedTerracotta; + mappings[573] = ItemType.BlueGlazedTerracotta; + mappings[574] = ItemType.BrownGlazedTerracotta; + mappings[575] = ItemType.GreenGlazedTerracotta; + mappings[576] = ItemType.RedGlazedTerracotta; + mappings[577] = ItemType.BlackGlazedTerracotta; + mappings[578] = ItemType.WhiteConcrete; + mappings[579] = ItemType.OrangeConcrete; + mappings[580] = ItemType.MagentaConcrete; + mappings[581] = ItemType.LightBlueConcrete; + mappings[582] = ItemType.YellowConcrete; + mappings[583] = ItemType.LimeConcrete; + mappings[584] = ItemType.PinkConcrete; + mappings[585] = ItemType.GrayConcrete; + mappings[586] = ItemType.LightGrayConcrete; + mappings[587] = ItemType.CyanConcrete; + mappings[588] = ItemType.PurpleConcrete; + mappings[589] = ItemType.BlueConcrete; + mappings[590] = ItemType.BrownConcrete; + mappings[591] = ItemType.GreenConcrete; + mappings[592] = ItemType.RedConcrete; + mappings[593] = ItemType.BlackConcrete; + mappings[594] = ItemType.WhiteConcretePowder; + mappings[595] = ItemType.OrangeConcretePowder; + mappings[596] = ItemType.MagentaConcretePowder; + mappings[597] = ItemType.LightBlueConcretePowder; + mappings[598] = ItemType.YellowConcretePowder; + mappings[599] = ItemType.LimeConcretePowder; + mappings[600] = ItemType.PinkConcretePowder; + mappings[601] = ItemType.GrayConcretePowder; + mappings[602] = ItemType.LightGrayConcretePowder; + mappings[603] = ItemType.CyanConcretePowder; + mappings[604] = ItemType.PurpleConcretePowder; + mappings[605] = ItemType.BlueConcretePowder; + mappings[606] = ItemType.BrownConcretePowder; + mappings[607] = ItemType.GreenConcretePowder; + mappings[608] = ItemType.RedConcretePowder; + mappings[609] = ItemType.BlackConcretePowder; + mappings[610] = ItemType.TurtleEgg; + mappings[611] = ItemType.SnifferEgg; + mappings[612] = ItemType.DeadTubeCoralBlock; + mappings[613] = ItemType.DeadBrainCoralBlock; + mappings[614] = ItemType.DeadBubbleCoralBlock; + mappings[615] = ItemType.DeadFireCoralBlock; + mappings[616] = ItemType.DeadHornCoralBlock; + mappings[617] = ItemType.TubeCoralBlock; + mappings[618] = ItemType.BrainCoralBlock; + mappings[619] = ItemType.BubbleCoralBlock; + mappings[620] = ItemType.FireCoralBlock; + mappings[621] = ItemType.HornCoralBlock; + mappings[622] = ItemType.TubeCoral; + mappings[623] = ItemType.BrainCoral; + mappings[624] = ItemType.BubbleCoral; + mappings[625] = ItemType.FireCoral; + mappings[626] = ItemType.HornCoral; + mappings[627] = ItemType.DeadBrainCoral; + mappings[628] = ItemType.DeadBubbleCoral; + mappings[629] = ItemType.DeadFireCoral; + mappings[630] = ItemType.DeadHornCoral; + mappings[631] = ItemType.DeadTubeCoral; + mappings[632] = ItemType.TubeCoralFan; + mappings[633] = ItemType.BrainCoralFan; + mappings[634] = ItemType.BubbleCoralFan; + mappings[635] = ItemType.FireCoralFan; + mappings[636] = ItemType.HornCoralFan; + mappings[637] = ItemType.DeadTubeCoralFan; + mappings[638] = ItemType.DeadBrainCoralFan; + mappings[639] = ItemType.DeadBubbleCoralFan; + mappings[640] = ItemType.DeadFireCoralFan; + mappings[641] = ItemType.DeadHornCoralFan; + mappings[642] = ItemType.BlueIce; + mappings[643] = ItemType.Conduit; + mappings[644] = ItemType.PolishedGraniteStairs; + mappings[645] = ItemType.SmoothRedSandstoneStairs; + mappings[646] = ItemType.MossyStoneBrickStairs; + mappings[647] = ItemType.PolishedDioriteStairs; + mappings[648] = ItemType.MossyCobblestoneStairs; + mappings[649] = ItemType.EndStoneBrickStairs; + mappings[650] = ItemType.StoneStairs; + mappings[651] = ItemType.SmoothSandstoneStairs; + mappings[652] = ItemType.SmoothQuartzStairs; + mappings[653] = ItemType.GraniteStairs; + mappings[654] = ItemType.AndesiteStairs; + mappings[655] = ItemType.RedNetherBrickStairs; + mappings[656] = ItemType.PolishedAndesiteStairs; + mappings[657] = ItemType.DioriteStairs; + mappings[658] = ItemType.CobbledDeepslateStairs; + mappings[659] = ItemType.PolishedDeepslateStairs; + mappings[660] = ItemType.DeepslateBrickStairs; + mappings[661] = ItemType.DeepslateTileStairs; + mappings[662] = ItemType.PolishedGraniteSlab; + mappings[663] = ItemType.SmoothRedSandstoneSlab; + mappings[664] = ItemType.MossyStoneBrickSlab; + mappings[665] = ItemType.PolishedDioriteSlab; + mappings[666] = ItemType.MossyCobblestoneSlab; + mappings[667] = ItemType.EndStoneBrickSlab; + mappings[668] = ItemType.SmoothSandstoneSlab; + mappings[669] = ItemType.SmoothQuartzSlab; + mappings[670] = ItemType.GraniteSlab; + mappings[671] = ItemType.AndesiteSlab; + mappings[672] = ItemType.RedNetherBrickSlab; + mappings[673] = ItemType.PolishedAndesiteSlab; + mappings[674] = ItemType.DioriteSlab; + mappings[675] = ItemType.CobbledDeepslateSlab; + mappings[676] = ItemType.PolishedDeepslateSlab; + mappings[677] = ItemType.DeepslateBrickSlab; + mappings[678] = ItemType.DeepslateTileSlab; + mappings[679] = ItemType.Scaffolding; + mappings[680] = ItemType.Redstone; + mappings[681] = ItemType.RedstoneTorch; + mappings[682] = ItemType.RedstoneBlock; + mappings[683] = ItemType.Repeater; + mappings[684] = ItemType.Comparator; + mappings[685] = ItemType.Piston; + mappings[686] = ItemType.StickyPiston; + mappings[687] = ItemType.SlimeBlock; + mappings[688] = ItemType.HoneyBlock; + mappings[689] = ItemType.Observer; + mappings[690] = ItemType.Hopper; + mappings[691] = ItemType.Dispenser; + mappings[692] = ItemType.Dropper; + mappings[693] = ItemType.Lectern; + mappings[694] = ItemType.Target; + mappings[695] = ItemType.Lever; + mappings[696] = ItemType.LightningRod; + mappings[697] = ItemType.DaylightDetector; + mappings[698] = ItemType.SculkSensor; + mappings[699] = ItemType.CalibratedSculkSensor; + mappings[700] = ItemType.TripwireHook; + mappings[701] = ItemType.TrappedChest; + mappings[702] = ItemType.Tnt; + mappings[703] = ItemType.RedstoneLamp; + mappings[704] = ItemType.NoteBlock; + mappings[705] = ItemType.StoneButton; + mappings[706] = ItemType.PolishedBlackstoneButton; + mappings[707] = ItemType.OakButton; + mappings[708] = ItemType.SpruceButton; + mappings[709] = ItemType.BirchButton; + mappings[710] = ItemType.JungleButton; + mappings[711] = ItemType.AcaciaButton; + mappings[712] = ItemType.CherryButton; + mappings[713] = ItemType.DarkOakButton; + mappings[714] = ItemType.PaleOakButton; + mappings[715] = ItemType.MangroveButton; + mappings[716] = ItemType.BambooButton; + mappings[717] = ItemType.CrimsonButton; + mappings[718] = ItemType.WarpedButton; + mappings[719] = ItemType.StonePressurePlate; + mappings[720] = ItemType.PolishedBlackstonePressurePlate; + mappings[721] = ItemType.LightWeightedPressurePlate; + mappings[722] = ItemType.HeavyWeightedPressurePlate; + mappings[723] = ItemType.OakPressurePlate; + mappings[724] = ItemType.SprucePressurePlate; + mappings[725] = ItemType.BirchPressurePlate; + mappings[726] = ItemType.JunglePressurePlate; + mappings[727] = ItemType.AcaciaPressurePlate; + mappings[728] = ItemType.CherryPressurePlate; + mappings[729] = ItemType.DarkOakPressurePlate; + mappings[730] = ItemType.PaleOakPressurePlate; + mappings[731] = ItemType.MangrovePressurePlate; + mappings[732] = ItemType.BambooPressurePlate; + mappings[733] = ItemType.CrimsonPressurePlate; + mappings[734] = ItemType.WarpedPressurePlate; + mappings[735] = ItemType.IronDoor; + mappings[736] = ItemType.OakDoor; + mappings[737] = ItemType.SpruceDoor; + mappings[738] = ItemType.BirchDoor; + mappings[739] = ItemType.JungleDoor; + mappings[740] = ItemType.AcaciaDoor; + mappings[741] = ItemType.CherryDoor; + mappings[742] = ItemType.DarkOakDoor; + mappings[743] = ItemType.PaleOakDoor; + mappings[744] = ItemType.MangroveDoor; + mappings[745] = ItemType.BambooDoor; + mappings[746] = ItemType.CrimsonDoor; + mappings[747] = ItemType.WarpedDoor; + mappings[748] = ItemType.CopperDoor; + mappings[749] = ItemType.ExposedCopperDoor; + mappings[750] = ItemType.WeatheredCopperDoor; + mappings[751] = ItemType.OxidizedCopperDoor; + mappings[752] = ItemType.WaxedCopperDoor; + mappings[753] = ItemType.WaxedExposedCopperDoor; + mappings[754] = ItemType.WaxedWeatheredCopperDoor; + mappings[755] = ItemType.WaxedOxidizedCopperDoor; + mappings[756] = ItemType.IronTrapdoor; + mappings[757] = ItemType.OakTrapdoor; + mappings[758] = ItemType.SpruceTrapdoor; + mappings[759] = ItemType.BirchTrapdoor; + mappings[760] = ItemType.JungleTrapdoor; + mappings[761] = ItemType.AcaciaTrapdoor; + mappings[762] = ItemType.CherryTrapdoor; + mappings[763] = ItemType.DarkOakTrapdoor; + mappings[764] = ItemType.PaleOakTrapdoor; + mappings[765] = ItemType.MangroveTrapdoor; + mappings[766] = ItemType.BambooTrapdoor; + mappings[767] = ItemType.CrimsonTrapdoor; + mappings[768] = ItemType.WarpedTrapdoor; + mappings[769] = ItemType.CopperTrapdoor; + mappings[770] = ItemType.ExposedCopperTrapdoor; + mappings[771] = ItemType.WeatheredCopperTrapdoor; + mappings[772] = ItemType.OxidizedCopperTrapdoor; + mappings[773] = ItemType.WaxedCopperTrapdoor; + mappings[774] = ItemType.WaxedExposedCopperTrapdoor; + mappings[775] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[776] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[777] = ItemType.OakFenceGate; + mappings[778] = ItemType.SpruceFenceGate; + mappings[779] = ItemType.BirchFenceGate; + mappings[780] = ItemType.JungleFenceGate; + mappings[781] = ItemType.AcaciaFenceGate; + mappings[782] = ItemType.CherryFenceGate; + mappings[783] = ItemType.DarkOakFenceGate; + mappings[784] = ItemType.PaleOakFenceGate; + mappings[785] = ItemType.MangroveFenceGate; + mappings[786] = ItemType.BambooFenceGate; + mappings[787] = ItemType.CrimsonFenceGate; + mappings[788] = ItemType.WarpedFenceGate; + mappings[789] = ItemType.PoweredRail; + mappings[790] = ItemType.DetectorRail; + mappings[791] = ItemType.Rail; + mappings[792] = ItemType.ActivatorRail; + mappings[793] = ItemType.Saddle; + mappings[794] = ItemType.Minecart; + mappings[795] = ItemType.ChestMinecart; + mappings[796] = ItemType.FurnaceMinecart; + mappings[797] = ItemType.TntMinecart; + mappings[798] = ItemType.HopperMinecart; + mappings[799] = ItemType.CarrotOnAStick; + mappings[800] = ItemType.WarpedFungusOnAStick; + mappings[801] = ItemType.PhantomMembrane; + mappings[802] = ItemType.Elytra; + mappings[803] = ItemType.OakBoat; + mappings[804] = ItemType.OakChestBoat; + mappings[805] = ItemType.SpruceBoat; + mappings[806] = ItemType.SpruceChestBoat; + mappings[807] = ItemType.BirchBoat; + mappings[808] = ItemType.BirchChestBoat; + mappings[809] = ItemType.JungleBoat; + mappings[810] = ItemType.JungleChestBoat; + mappings[811] = ItemType.AcaciaBoat; + mappings[812] = ItemType.AcaciaChestBoat; + mappings[813] = ItemType.CherryBoat; + mappings[814] = ItemType.CherryChestBoat; + mappings[815] = ItemType.DarkOakBoat; + mappings[816] = ItemType.DarkOakChestBoat; + mappings[817] = ItemType.PaleOakBoat; + mappings[818] = ItemType.PaleOakChestBoat; + mappings[819] = ItemType.MangroveBoat; + mappings[820] = ItemType.MangroveChestBoat; + mappings[821] = ItemType.BambooRaft; + mappings[822] = ItemType.BambooChestRaft; + mappings[823] = ItemType.StructureBlock; + mappings[824] = ItemType.Jigsaw; + mappings[825] = ItemType.TurtleHelmet; + mappings[826] = ItemType.TurtleScute; + mappings[827] = ItemType.ArmadilloScute; + mappings[828] = ItemType.WolfArmor; + mappings[829] = ItemType.FlintAndSteel; + mappings[830] = ItemType.Bowl; + mappings[831] = ItemType.Apple; + mappings[832] = ItemType.Bow; + mappings[833] = ItemType.Arrow; + mappings[834] = ItemType.Coal; + mappings[835] = ItemType.Charcoal; + mappings[836] = ItemType.Diamond; + mappings[837] = ItemType.Emerald; + mappings[838] = ItemType.LapisLazuli; + mappings[839] = ItemType.Quartz; + mappings[840] = ItemType.AmethystShard; + mappings[841] = ItemType.RawIron; + mappings[842] = ItemType.IronIngot; + mappings[843] = ItemType.RawCopper; + mappings[844] = ItemType.CopperIngot; + mappings[845] = ItemType.RawGold; + mappings[846] = ItemType.GoldIngot; + mappings[847] = ItemType.NetheriteIngot; + mappings[848] = ItemType.NetheriteScrap; + mappings[849] = ItemType.WoodenSword; + mappings[850] = ItemType.WoodenShovel; + mappings[851] = ItemType.WoodenPickaxe; + mappings[852] = ItemType.WoodenAxe; + mappings[853] = ItemType.WoodenHoe; + mappings[854] = ItemType.StoneSword; + mappings[855] = ItemType.StoneShovel; + mappings[856] = ItemType.StonePickaxe; + mappings[857] = ItemType.StoneAxe; + mappings[858] = ItemType.StoneHoe; + mappings[859] = ItemType.GoldenSword; + mappings[860] = ItemType.GoldenShovel; + mappings[861] = ItemType.GoldenPickaxe; + mappings[862] = ItemType.GoldenAxe; + mappings[863] = ItemType.GoldenHoe; + mappings[864] = ItemType.IronSword; + mappings[865] = ItemType.IronShovel; + mappings[866] = ItemType.IronPickaxe; + mappings[867] = ItemType.IronAxe; + mappings[868] = ItemType.IronHoe; + mappings[869] = ItemType.DiamondSword; + mappings[870] = ItemType.DiamondShovel; + mappings[871] = ItemType.DiamondPickaxe; + mappings[872] = ItemType.DiamondAxe; + mappings[873] = ItemType.DiamondHoe; + mappings[874] = ItemType.NetheriteSword; + mappings[875] = ItemType.NetheriteShovel; + mappings[876] = ItemType.NetheritePickaxe; + mappings[877] = ItemType.NetheriteAxe; + mappings[878] = ItemType.NetheriteHoe; + mappings[879] = ItemType.Stick; + mappings[880] = ItemType.MushroomStew; + mappings[881] = ItemType.String; + mappings[882] = ItemType.Feather; + mappings[883] = ItemType.Gunpowder; + mappings[884] = ItemType.WheatSeeds; + mappings[885] = ItemType.Wheat; + mappings[886] = ItemType.Bread; + mappings[887] = ItemType.LeatherHelmet; + mappings[888] = ItemType.LeatherChestplate; + mappings[889] = ItemType.LeatherLeggings; + mappings[890] = ItemType.LeatherBoots; + mappings[891] = ItemType.ChainmailHelmet; + mappings[892] = ItemType.ChainmailChestplate; + mappings[893] = ItemType.ChainmailLeggings; + mappings[894] = ItemType.ChainmailBoots; + mappings[895] = ItemType.IronHelmet; + mappings[896] = ItemType.IronChestplate; + mappings[897] = ItemType.IronLeggings; + mappings[898] = ItemType.IronBoots; + mappings[899] = ItemType.DiamondHelmet; + mappings[900] = ItemType.DiamondChestplate; + mappings[901] = ItemType.DiamondLeggings; + mappings[902] = ItemType.DiamondBoots; + mappings[903] = ItemType.GoldenHelmet; + mappings[904] = ItemType.GoldenChestplate; + mappings[905] = ItemType.GoldenLeggings; + mappings[906] = ItemType.GoldenBoots; + mappings[907] = ItemType.NetheriteHelmet; + mappings[908] = ItemType.NetheriteChestplate; + mappings[909] = ItemType.NetheriteLeggings; + mappings[910] = ItemType.NetheriteBoots; + mappings[911] = ItemType.Flint; + mappings[912] = ItemType.Porkchop; + mappings[913] = ItemType.CookedPorkchop; + mappings[914] = ItemType.Painting; + mappings[915] = ItemType.GoldenApple; + mappings[916] = ItemType.EnchantedGoldenApple; + mappings[917] = ItemType.OakSign; + mappings[918] = ItemType.SpruceSign; + mappings[919] = ItemType.BirchSign; + mappings[920] = ItemType.JungleSign; + mappings[921] = ItemType.AcaciaSign; + mappings[922] = ItemType.CherrySign; + mappings[923] = ItemType.DarkOakSign; + mappings[924] = ItemType.PaleOakSign; + mappings[925] = ItemType.MangroveSign; + mappings[926] = ItemType.BambooSign; + mappings[927] = ItemType.CrimsonSign; + mappings[928] = ItemType.WarpedSign; + mappings[929] = ItemType.OakHangingSign; + mappings[930] = ItemType.SpruceHangingSign; + mappings[931] = ItemType.BirchHangingSign; + mappings[932] = ItemType.JungleHangingSign; + mappings[933] = ItemType.AcaciaHangingSign; + mappings[934] = ItemType.CherryHangingSign; + mappings[935] = ItemType.DarkOakHangingSign; + mappings[936] = ItemType.PaleOakHangingSign; + mappings[937] = ItemType.MangroveHangingSign; + mappings[938] = ItemType.BambooHangingSign; + mappings[939] = ItemType.CrimsonHangingSign; + mappings[940] = ItemType.WarpedHangingSign; + mappings[941] = ItemType.Bucket; + mappings[942] = ItemType.WaterBucket; + mappings[943] = ItemType.LavaBucket; + mappings[944] = ItemType.PowderSnowBucket; + mappings[945] = ItemType.Snowball; + mappings[946] = ItemType.Leather; + mappings[947] = ItemType.MilkBucket; + mappings[948] = ItemType.PufferfishBucket; + mappings[949] = ItemType.SalmonBucket; + mappings[950] = ItemType.CodBucket; + mappings[951] = ItemType.TropicalFishBucket; + mappings[952] = ItemType.AxolotlBucket; + mappings[953] = ItemType.TadpoleBucket; + mappings[954] = ItemType.Brick; + mappings[955] = ItemType.ClayBall; + mappings[956] = ItemType.DriedKelpBlock; + mappings[957] = ItemType.Paper; + mappings[958] = ItemType.Book; + mappings[959] = ItemType.SlimeBall; + mappings[960] = ItemType.Egg; + mappings[961] = ItemType.Compass; + mappings[962] = ItemType.RecoveryCompass; + mappings[963] = ItemType.Bundle; + mappings[964] = ItemType.WhiteBundle; + mappings[965] = ItemType.OrangeBundle; + mappings[966] = ItemType.MagentaBundle; + mappings[967] = ItemType.LightBlueBundle; + mappings[968] = ItemType.YellowBundle; + mappings[969] = ItemType.LimeBundle; + mappings[970] = ItemType.PinkBundle; + mappings[971] = ItemType.GrayBundle; + mappings[972] = ItemType.LightGrayBundle; + mappings[973] = ItemType.CyanBundle; + mappings[974] = ItemType.PurpleBundle; + mappings[975] = ItemType.BlueBundle; + mappings[976] = ItemType.BrownBundle; + mappings[977] = ItemType.GreenBundle; + mappings[978] = ItemType.RedBundle; + mappings[979] = ItemType.BlackBundle; + mappings[980] = ItemType.FishingRod; + mappings[981] = ItemType.Clock; + mappings[982] = ItemType.Spyglass; + mappings[983] = ItemType.GlowstoneDust; + mappings[984] = ItemType.Cod; + mappings[985] = ItemType.Salmon; + mappings[986] = ItemType.TropicalFish; + mappings[987] = ItemType.Pufferfish; + mappings[988] = ItemType.CookedCod; + mappings[989] = ItemType.CookedSalmon; + mappings[990] = ItemType.InkSac; + mappings[991] = ItemType.GlowInkSac; + mappings[992] = ItemType.CocoaBeans; + mappings[993] = ItemType.WhiteDye; + mappings[994] = ItemType.OrangeDye; + mappings[995] = ItemType.MagentaDye; + mappings[996] = ItemType.LightBlueDye; + mappings[997] = ItemType.YellowDye; + mappings[998] = ItemType.LimeDye; + mappings[999] = ItemType.PinkDye; + mappings[1000] = ItemType.GrayDye; + mappings[1001] = ItemType.LightGrayDye; + mappings[1002] = ItemType.CyanDye; + mappings[1003] = ItemType.PurpleDye; + mappings[1004] = ItemType.BlueDye; + mappings[1005] = ItemType.BrownDye; + mappings[1006] = ItemType.GreenDye; + mappings[1007] = ItemType.RedDye; + mappings[1008] = ItemType.BlackDye; + mappings[1009] = ItemType.BoneMeal; + mappings[1010] = ItemType.Bone; + mappings[1011] = ItemType.Sugar; + mappings[1012] = ItemType.Cake; + mappings[1013] = ItemType.WhiteBed; + mappings[1014] = ItemType.OrangeBed; + mappings[1015] = ItemType.MagentaBed; + mappings[1016] = ItemType.LightBlueBed; + mappings[1017] = ItemType.YellowBed; + mappings[1018] = ItemType.LimeBed; + mappings[1019] = ItemType.PinkBed; + mappings[1020] = ItemType.GrayBed; + mappings[1021] = ItemType.LightGrayBed; + mappings[1022] = ItemType.CyanBed; + mappings[1023] = ItemType.PurpleBed; + mappings[1024] = ItemType.BlueBed; + mappings[1025] = ItemType.BrownBed; + mappings[1026] = ItemType.GreenBed; + mappings[1027] = ItemType.RedBed; + mappings[1028] = ItemType.BlackBed; + mappings[1029] = ItemType.Cookie; + mappings[1030] = ItemType.Crafter; + mappings[1031] = ItemType.FilledMap; + mappings[1032] = ItemType.Shears; + mappings[1033] = ItemType.MelonSlice; + mappings[1034] = ItemType.DriedKelp; + mappings[1035] = ItemType.PumpkinSeeds; + mappings[1036] = ItemType.MelonSeeds; + mappings[1037] = ItemType.Beef; + mappings[1038] = ItemType.CookedBeef; + mappings[1039] = ItemType.Chicken; + mappings[1040] = ItemType.CookedChicken; + mappings[1041] = ItemType.RottenFlesh; + mappings[1042] = ItemType.EnderPearl; + mappings[1043] = ItemType.BlazeRod; + mappings[1044] = ItemType.GhastTear; + mappings[1045] = ItemType.GoldNugget; + mappings[1046] = ItemType.NetherWart; + mappings[1047] = ItemType.GlassBottle; + mappings[1048] = ItemType.Potion; + mappings[1049] = ItemType.SpiderEye; + mappings[1050] = ItemType.FermentedSpiderEye; + mappings[1051] = ItemType.BlazePowder; + mappings[1052] = ItemType.MagmaCream; + mappings[1053] = ItemType.BrewingStand; + mappings[1054] = ItemType.Cauldron; + mappings[1055] = ItemType.EnderEye; + mappings[1056] = ItemType.GlisteringMelonSlice; + mappings[1057] = ItemType.ArmadilloSpawnEgg; + mappings[1058] = ItemType.AllaySpawnEgg; + mappings[1059] = ItemType.AxolotlSpawnEgg; + mappings[1060] = ItemType.BatSpawnEgg; + mappings[1061] = ItemType.BeeSpawnEgg; + mappings[1062] = ItemType.BlazeSpawnEgg; + mappings[1063] = ItemType.BoggedSpawnEgg; + mappings[1064] = ItemType.BreezeSpawnEgg; + mappings[1065] = ItemType.CatSpawnEgg; + mappings[1066] = ItemType.CamelSpawnEgg; + mappings[1067] = ItemType.CaveSpiderSpawnEgg; + mappings[1068] = ItemType.ChickenSpawnEgg; + mappings[1069] = ItemType.CodSpawnEgg; + mappings[1070] = ItemType.CowSpawnEgg; + mappings[1071] = ItemType.CreeperSpawnEgg; + mappings[1072] = ItemType.DolphinSpawnEgg; + mappings[1073] = ItemType.DonkeySpawnEgg; + mappings[1074] = ItemType.DrownedSpawnEgg; + mappings[1075] = ItemType.ElderGuardianSpawnEgg; + mappings[1076] = ItemType.EnderDragonSpawnEgg; + mappings[1077] = ItemType.EndermanSpawnEgg; + mappings[1078] = ItemType.EndermiteSpawnEgg; + mappings[1079] = ItemType.EvokerSpawnEgg; + mappings[1080] = ItemType.FoxSpawnEgg; + mappings[1081] = ItemType.FrogSpawnEgg; + mappings[1082] = ItemType.GhastSpawnEgg; + mappings[1083] = ItemType.GlowSquidSpawnEgg; + mappings[1084] = ItemType.GoatSpawnEgg; + mappings[1085] = ItemType.GuardianSpawnEgg; + mappings[1086] = ItemType.HoglinSpawnEgg; + mappings[1087] = ItemType.HorseSpawnEgg; + mappings[1088] = ItemType.HuskSpawnEgg; + mappings[1089] = ItemType.IronGolemSpawnEgg; + mappings[1090] = ItemType.LlamaSpawnEgg; + mappings[1091] = ItemType.MagmaCubeSpawnEgg; + mappings[1092] = ItemType.MooshroomSpawnEgg; + mappings[1093] = ItemType.MuleSpawnEgg; + mappings[1094] = ItemType.OcelotSpawnEgg; + mappings[1095] = ItemType.PandaSpawnEgg; + mappings[1096] = ItemType.ParrotSpawnEgg; + mappings[1097] = ItemType.PhantomSpawnEgg; + mappings[1098] = ItemType.PigSpawnEgg; + mappings[1099] = ItemType.PiglinSpawnEgg; + mappings[1100] = ItemType.PiglinBruteSpawnEgg; + mappings[1101] = ItemType.PillagerSpawnEgg; + mappings[1102] = ItemType.PolarBearSpawnEgg; + mappings[1103] = ItemType.PufferfishSpawnEgg; + mappings[1104] = ItemType.RabbitSpawnEgg; + mappings[1105] = ItemType.RavagerSpawnEgg; + mappings[1106] = ItemType.SalmonSpawnEgg; + mappings[1107] = ItemType.SheepSpawnEgg; + mappings[1108] = ItemType.ShulkerSpawnEgg; + mappings[1109] = ItemType.SilverfishSpawnEgg; + mappings[1110] = ItemType.SkeletonSpawnEgg; + mappings[1111] = ItemType.SkeletonHorseSpawnEgg; + mappings[1112] = ItemType.SlimeSpawnEgg; + mappings[1113] = ItemType.SnifferSpawnEgg; + mappings[1114] = ItemType.SnowGolemSpawnEgg; + mappings[1115] = ItemType.SpiderSpawnEgg; + mappings[1116] = ItemType.SquidSpawnEgg; + mappings[1117] = ItemType.StraySpawnEgg; + mappings[1118] = ItemType.StriderSpawnEgg; + mappings[1119] = ItemType.TadpoleSpawnEgg; + mappings[1120] = ItemType.TraderLlamaSpawnEgg; + mappings[1121] = ItemType.TropicalFishSpawnEgg; + mappings[1122] = ItemType.TurtleSpawnEgg; + mappings[1123] = ItemType.VexSpawnEgg; + mappings[1124] = ItemType.VillagerSpawnEgg; + mappings[1125] = ItemType.VindicatorSpawnEgg; + mappings[1126] = ItemType.WanderingTraderSpawnEgg; + mappings[1127] = ItemType.WardenSpawnEgg; + mappings[1128] = ItemType.WitchSpawnEgg; + mappings[1129] = ItemType.WitherSpawnEgg; + mappings[1130] = ItemType.WitherSkeletonSpawnEgg; + mappings[1131] = ItemType.WolfSpawnEgg; + mappings[1132] = ItemType.ZoglinSpawnEgg; + mappings[1133] = ItemType.CreakingSpawnEgg; + mappings[1134] = ItemType.ZombieSpawnEgg; + mappings[1135] = ItemType.ZombieHorseSpawnEgg; + mappings[1136] = ItemType.ZombieVillagerSpawnEgg; + mappings[1137] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1138] = ItemType.ExperienceBottle; + mappings[1139] = ItemType.FireCharge; + mappings[1140] = ItemType.WindCharge; + mappings[1141] = ItemType.WritableBook; + mappings[1142] = ItemType.WrittenBook; + mappings[1143] = ItemType.BreezeRod; + mappings[1144] = ItemType.Mace; + mappings[1145] = ItemType.ItemFrame; + mappings[1146] = ItemType.GlowItemFrame; + mappings[1147] = ItemType.FlowerPot; + mappings[1148] = ItemType.Carrot; + mappings[1149] = ItemType.Potato; + mappings[1150] = ItemType.BakedPotato; + mappings[1151] = ItemType.PoisonousPotato; + mappings[1152] = ItemType.Map; + mappings[1153] = ItemType.GoldenCarrot; + mappings[1154] = ItemType.SkeletonSkull; + mappings[1155] = ItemType.WitherSkeletonSkull; + mappings[1156] = ItemType.PlayerHead; + mappings[1157] = ItemType.ZombieHead; + mappings[1158] = ItemType.CreeperHead; + mappings[1159] = ItemType.DragonHead; + mappings[1160] = ItemType.PiglinHead; + mappings[1161] = ItemType.NetherStar; + mappings[1162] = ItemType.PumpkinPie; + mappings[1163] = ItemType.FireworkRocket; + mappings[1164] = ItemType.FireworkStar; + mappings[1165] = ItemType.EnchantedBook; + mappings[1166] = ItemType.NetherBrick; + mappings[1167] = ItemType.ResinBrick; + mappings[1168] = ItemType.PrismarineShard; + mappings[1169] = ItemType.PrismarineCrystals; + mappings[1170] = ItemType.Rabbit; + mappings[1171] = ItemType.CookedRabbit; + mappings[1172] = ItemType.RabbitStew; + mappings[1173] = ItemType.RabbitFoot; + mappings[1174] = ItemType.RabbitHide; + mappings[1175] = ItemType.ArmorStand; + mappings[1176] = ItemType.IronHorseArmor; + mappings[1177] = ItemType.GoldenHorseArmor; + mappings[1178] = ItemType.DiamondHorseArmor; + mappings[1179] = ItemType.LeatherHorseArmor; + mappings[1180] = ItemType.Lead; + mappings[1181] = ItemType.NameTag; + mappings[1182] = ItemType.CommandBlockMinecart; + mappings[1183] = ItemType.Mutton; + mappings[1184] = ItemType.CookedMutton; + mappings[1185] = ItemType.WhiteBanner; + mappings[1186] = ItemType.OrangeBanner; + mappings[1187] = ItemType.MagentaBanner; + mappings[1188] = ItemType.LightBlueBanner; + mappings[1189] = ItemType.YellowBanner; + mappings[1190] = ItemType.LimeBanner; + mappings[1191] = ItemType.PinkBanner; + mappings[1192] = ItemType.GrayBanner; + mappings[1193] = ItemType.LightGrayBanner; + mappings[1194] = ItemType.CyanBanner; + mappings[1195] = ItemType.PurpleBanner; + mappings[1196] = ItemType.BlueBanner; + mappings[1197] = ItemType.BrownBanner; + mappings[1198] = ItemType.GreenBanner; + mappings[1199] = ItemType.RedBanner; + mappings[1200] = ItemType.BlackBanner; + mappings[1201] = ItemType.EndCrystal; + mappings[1202] = ItemType.ChorusFruit; + mappings[1203] = ItemType.PoppedChorusFruit; + mappings[1204] = ItemType.TorchflowerSeeds; + mappings[1205] = ItemType.PitcherPod; + mappings[1206] = ItemType.Beetroot; + mappings[1207] = ItemType.BeetrootSeeds; + mappings[1208] = ItemType.BeetrootSoup; + mappings[1209] = ItemType.DragonBreath; + mappings[1210] = ItemType.SplashPotion; + mappings[1211] = ItemType.SpectralArrow; + mappings[1212] = ItemType.TippedArrow; + mappings[1213] = ItemType.LingeringPotion; + mappings[1214] = ItemType.Shield; + mappings[1215] = ItemType.TotemOfUndying; + mappings[1216] = ItemType.ShulkerShell; + mappings[1217] = ItemType.IronNugget; + mappings[1218] = ItemType.KnowledgeBook; + mappings[1219] = ItemType.DebugStick; + mappings[1220] = ItemType.MusicDisc13; + mappings[1221] = ItemType.MusicDiscCat; + mappings[1222] = ItemType.MusicDiscBlocks; + mappings[1223] = ItemType.MusicDiscChirp; + mappings[1224] = ItemType.MusicDiscCreator; + mappings[1225] = ItemType.MusicDiscCreatorMusicBox; + mappings[1226] = ItemType.MusicDiscFar; + mappings[1227] = ItemType.MusicDiscMall; + mappings[1228] = ItemType.MusicDiscMellohi; + mappings[1229] = ItemType.MusicDiscStal; + mappings[1230] = ItemType.MusicDiscStrad; + mappings[1231] = ItemType.MusicDiscWard; + mappings[1232] = ItemType.MusicDisc11; + mappings[1233] = ItemType.MusicDiscWait; + mappings[1234] = ItemType.MusicDiscOtherside; + mappings[1235] = ItemType.MusicDiscRelic; + mappings[1236] = ItemType.MusicDisc5; + mappings[1237] = ItemType.MusicDiscPigstep; + mappings[1238] = ItemType.MusicDiscPrecipice; + mappings[1239] = ItemType.DiscFragment5; + mappings[1240] = ItemType.Trident; + mappings[1241] = ItemType.NautilusShell; + mappings[1242] = ItemType.HeartOfTheSea; + mappings[1243] = ItemType.Crossbow; + mappings[1244] = ItemType.SuspiciousStew; + mappings[1245] = ItemType.Loom; + mappings[1246] = ItemType.FlowerBannerPattern; + mappings[1247] = ItemType.CreeperBannerPattern; + mappings[1248] = ItemType.SkullBannerPattern; + mappings[1249] = ItemType.MojangBannerPattern; + mappings[1250] = ItemType.GlobeBannerPattern; + mappings[1251] = ItemType.PiglinBannerPattern; + mappings[1252] = ItemType.FlowBannerPattern; + mappings[1253] = ItemType.GusterBannerPattern; + mappings[1254] = ItemType.FieldMasonedBannerPattern; + mappings[1255] = ItemType.BordureIndentedBannerPattern; + mappings[1256] = ItemType.GoatHorn; + mappings[1257] = ItemType.Composter; + mappings[1258] = ItemType.Barrel; + mappings[1259] = ItemType.Smoker; + mappings[1260] = ItemType.BlastFurnace; + mappings[1261] = ItemType.CartographyTable; + mappings[1262] = ItemType.FletchingTable; + mappings[1263] = ItemType.Grindstone; + mappings[1264] = ItemType.SmithingTable; + mappings[1265] = ItemType.Stonecutter; + mappings[1266] = ItemType.Bell; + mappings[1267] = ItemType.Lantern; + mappings[1268] = ItemType.SoulLantern; + mappings[1269] = ItemType.SweetBerries; + mappings[1270] = ItemType.GlowBerries; + mappings[1271] = ItemType.Campfire; + mappings[1272] = ItemType.SoulCampfire; + mappings[1273] = ItemType.Shroomlight; + mappings[1274] = ItemType.Honeycomb; + mappings[1275] = ItemType.BeeNest; + mappings[1276] = ItemType.Beehive; + mappings[1277] = ItemType.HoneyBottle; + mappings[1278] = ItemType.HoneycombBlock; + mappings[1279] = ItemType.Lodestone; + mappings[1280] = ItemType.CryingObsidian; + mappings[1281] = ItemType.Blackstone; + mappings[1282] = ItemType.BlackstoneSlab; + mappings[1283] = ItemType.BlackstoneStairs; + mappings[1284] = ItemType.GildedBlackstone; + mappings[1285] = ItemType.PolishedBlackstone; + mappings[1286] = ItemType.PolishedBlackstoneSlab; + mappings[1287] = ItemType.PolishedBlackstoneStairs; + mappings[1288] = ItemType.ChiseledPolishedBlackstone; + mappings[1289] = ItemType.PolishedBlackstoneBricks; + mappings[1290] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1291] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1292] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1293] = ItemType.RespawnAnchor; + mappings[1294] = ItemType.Candle; + mappings[1295] = ItemType.WhiteCandle; + mappings[1296] = ItemType.OrangeCandle; + mappings[1297] = ItemType.MagentaCandle; + mappings[1298] = ItemType.LightBlueCandle; + mappings[1299] = ItemType.YellowCandle; + mappings[1300] = ItemType.LimeCandle; + mappings[1301] = ItemType.PinkCandle; + mappings[1302] = ItemType.GrayCandle; + mappings[1303] = ItemType.LightGrayCandle; + mappings[1304] = ItemType.CyanCandle; + mappings[1305] = ItemType.PurpleCandle; + mappings[1306] = ItemType.BlueCandle; + mappings[1307] = ItemType.BrownCandle; + mappings[1308] = ItemType.GreenCandle; + mappings[1309] = ItemType.RedCandle; + mappings[1310] = ItemType.BlackCandle; + mappings[1311] = ItemType.SmallAmethystBud; + mappings[1312] = ItemType.MediumAmethystBud; + mappings[1313] = ItemType.LargeAmethystBud; + mappings[1314] = ItemType.AmethystCluster; + mappings[1315] = ItemType.PointedDripstone; + mappings[1316] = ItemType.OchreFroglight; + mappings[1317] = ItemType.VerdantFroglight; + mappings[1318] = ItemType.PearlescentFroglight; + mappings[1319] = ItemType.Frogspawn; + mappings[1320] = ItemType.EchoShard; + mappings[1321] = ItemType.Brush; + mappings[1322] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1323] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1324] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1325] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1326] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1327] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1328] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1329] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1330] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1331] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1332] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1333] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1334] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1335] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1336] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1337] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1338] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1339] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1340] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1341] = ItemType.AnglerPotterySherd; + mappings[1342] = ItemType.ArcherPotterySherd; + mappings[1343] = ItemType.ArmsUpPotterySherd; + mappings[1344] = ItemType.BladePotterySherd; + mappings[1345] = ItemType.BrewerPotterySherd; + mappings[1346] = ItemType.BurnPotterySherd; + mappings[1347] = ItemType.DangerPotterySherd; + mappings[1348] = ItemType.ExplorerPotterySherd; + mappings[1349] = ItemType.FlowPotterySherd; + mappings[1350] = ItemType.FriendPotterySherd; + mappings[1351] = ItemType.GusterPotterySherd; + mappings[1352] = ItemType.HeartPotterySherd; + mappings[1353] = ItemType.HeartbreakPotterySherd; + mappings[1354] = ItemType.HowlPotterySherd; + mappings[1355] = ItemType.MinerPotterySherd; + mappings[1356] = ItemType.MournerPotterySherd; + mappings[1357] = ItemType.PlentyPotterySherd; + mappings[1358] = ItemType.PrizePotterySherd; + mappings[1359] = ItemType.ScrapePotterySherd; + mappings[1360] = ItemType.SheafPotterySherd; + mappings[1361] = ItemType.ShelterPotterySherd; + mappings[1362] = ItemType.SkullPotterySherd; + mappings[1363] = ItemType.SnortPotterySherd; + mappings[1364] = ItemType.CopperGrate; + mappings[1365] = ItemType.ExposedCopperGrate; + mappings[1366] = ItemType.WeatheredCopperGrate; + mappings[1367] = ItemType.OxidizedCopperGrate; + mappings[1368] = ItemType.WaxedCopperGrate; + mappings[1369] = ItemType.WaxedExposedCopperGrate; + mappings[1370] = ItemType.WaxedWeatheredCopperGrate; + mappings[1371] = ItemType.WaxedOxidizedCopperGrate; + mappings[1372] = ItemType.CopperBulb; + mappings[1373] = ItemType.ExposedCopperBulb; + mappings[1374] = ItemType.WeatheredCopperBulb; + mappings[1375] = ItemType.OxidizedCopperBulb; + mappings[1376] = ItemType.WaxedCopperBulb; + mappings[1377] = ItemType.WaxedExposedCopperBulb; + mappings[1378] = ItemType.WaxedWeatheredCopperBulb; + mappings[1379] = ItemType.WaxedOxidizedCopperBulb; + mappings[1380] = ItemType.TrialSpawner; + mappings[1381] = ItemType.TrialKey; + mappings[1382] = ItemType.OminousTrialKey; + mappings[1383] = ItemType.Vault; + mappings[1384] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 318eb1fa..bbe97785 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -244,6 +244,7 @@ namespace MinecraftClient.Inventory ChiseledPolishedBlackstone, ChiseledQuartzBlock, ChiseledRedSandstone, + ChiseledResinBricks, ChiseledSandstone, ChiseledStoneBricks, ChiseledTuff, @@ -254,6 +255,7 @@ namespace MinecraftClient.Inventory Clay, ClayBall, Clock, + ClosedEyeblossom, Coal, CoalBlock, CoalOre, @@ -855,6 +857,7 @@ namespace MinecraftClient.Inventory OchreFroglight, OminousBottle, OminousTrialKey, + OpenEyeblossom, OrangeBanner, OrangeBed, OrangeCandle, @@ -1066,6 +1069,13 @@ namespace MinecraftClient.Inventory ReinforcedDeepslate, Repeater, RepeatingCommandBlock, + ResinBlock, + ResinBrick, + ResinBricks, + ResinBrickSlab, + ResinBrickStairs, + ResinBrickWall, + ResinClump, RespawnAnchor, RibArmorTrimSmithingTemplate, RootedDirt, diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1214.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1214.cs new file mode 100644 index 00000000..fbffcc7f --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1214.cs @@ -0,0 +1,1826 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1214 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1214() + { + for (int i = 9482; i <= 9505; i++) + materials[i] = Material.AcaciaButton; + for (int i = 12963; i <= 13026; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 12579; i <= 12610; i++) + materials[i] = Material.AcaciaFence; + for (int i = 12291; i <= 12322; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5121; i <= 5184; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 5891; i <= 5892; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 4453; i <= 4484; i++) + materials[i] = Material.AcaciaSign; + for (int i = 12065; i <= 12070; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 10683; i <= 10762; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 6386; i <= 6449; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 5721; i <= 5728; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 4873; i <= 4880; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 10119; i <= 10142; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2122] = Material.Allium; + materials[22044] = Material.AmethystBlock; + for (int i = 22046; i <= 22057; i++) + materials[i] = Material.AmethystCluster; + materials[20461] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 15149; i <= 15154; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 14775; i <= 14854; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 17765; i <= 18088; i++) + materials[i] = Material.AndesiteWall; + for (int i = 9906; i <= 9909; i++) + materials[i] = Material.Anvil; + for (int i = 7050; i <= 7053; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 7046; i <= 7049; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[25837] = Material.Azalea; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + materials[2123] = Material.AzureBluet; + for (int i = 13958; i <= 13969; i++) + materials[i] = Material.Bamboo; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 9602; i <= 9625; i++) + materials[i] = Material.BambooButton; + for (int i = 13283; i <= 13346; i++) + materials[i] = Material.BambooDoor; + for (int i = 12739; i <= 12770; i++) + materials[i] = Material.BambooFence; + for (int i = 12451; i <= 12482; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 5633; i <= 5696; i++) + materials[i] = Material.BambooHangingSign; + materials[28] = Material.BambooMosaic; + for (int i = 12101; i <= 12106; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 11163; i <= 11242; i++) + materials[i] = Material.BambooMosaicStairs; + materials[27] = Material.BambooPlanks; + for (int i = 5901; i <= 5902; i++) + materials[i] = Material.BambooPressurePlate; + materials[13957] = Material.BambooSapling; + for (int i = 4645; i <= 4676; i++) + materials[i] = Material.BambooSign; + for (int i = 12095; i <= 12100; i++) + materials[i] = Material.BambooSlab; + for (int i = 11083; i <= 11162; i++) + materials[i] = Material.BambooStairs; + for (int i = 6706; i <= 6769; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 5785; i <= 5792; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 4921; i <= 4928; i++) + materials[i] = Material.BambooWallSign; + for (int i = 19421; i <= 19432; i++) + materials[i] = Material.Barrel; + for (int i = 11244; i <= 11245; i++) + materials[i] = Material.Barrier; + for (int i = 6021; i <= 6023; i++) + materials[i] = Material.Basalt; + materials[8692] = Material.Beacon; + materials[85] = Material.Bedrock; + for (int i = 20410; i <= 20433; i++) + materials[i] = Material.BeeNest; + for (int i = 20434; i <= 20457; i++) + materials[i] = Material.Beehive; + for (int i = 13522; i <= 13525; i++) + materials[i] = Material.Beetroots; + for (int i = 19484; i <= 19515; i++) + materials[i] = Material.Bell; + for (int i = 25857; i <= 25888; i++) + materials[i] = Material.BigDripleaf; + for (int i = 25889; i <= 25896; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 9434; i <= 9457; i++) + materials[i] = Material.BirchButton; + for (int i = 12835; i <= 12898; i++) + materials[i] = Material.BirchDoor; + for (int i = 12515; i <= 12546; i++) + materials[i] = Material.BirchFence; + for (int i = 12227; i <= 12258; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 5057; i <= 5120; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 5887; i <= 5888; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 4421; i <= 4452; i++) + materials[i] = Material.BirchSign; + for (int i = 12053; i <= 12058; i++) + materials[i] = Material.BirchSlab; + for (int i = 8520; i <= 8599; i++) + materials[i] = Material.BirchStairs; + for (int i = 6258; i <= 6321; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 5713; i <= 5720; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 4865; i <= 4872; i++) + materials[i] = Material.BirchWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 11878; i <= 11893; i++) + materials[i] = Material.BlackBanner; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 21994; i <= 22009; i++) + materials[i] = Material.BlackCandle; + for (int i = 22042; i <= 22043; i++) + materials[i] = Material.BlackCandleCake; + materials[11622] = Material.BlackCarpet; + materials[13756] = Material.BlackConcrete; + materials[13772] = Material.BlackConcretePowder; + for (int i = 13737; i <= 13740; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 13671; i <= 13676; i++) + materials[i] = Material.BlackShulkerBox; + materials[6129] = Material.BlackStainedGlass; + for (int i = 10651; i <= 10682; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[10170] = Material.BlackTerracotta; + for (int i = 11954; i <= 11957; i++) + materials[i] = Material.BlackWallBanner; + materials[2105] = Material.BlackWool; + materials[20473] = Material.Blackstone; + for (int i = 20878; i <= 20883; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 20474; i <= 20553; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 20554; i <= 20877; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 19441; i <= 19448; i++) + materials[i] = Material.BlastFurnace; + for (int i = 11814; i <= 11829; i++) + materials[i] = Material.BlueBanner; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 21930; i <= 21945; i++) + materials[i] = Material.BlueCandle; + for (int i = 22034; i <= 22035; i++) + materials[i] = Material.BlueCandleCake; + materials[11618] = Material.BlueCarpet; + materials[13752] = Material.BlueConcrete; + materials[13768] = Material.BlueConcretePowder; + for (int i = 13721; i <= 13724; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[13954] = Material.BlueIce; + materials[2121] = Material.BlueOrchid; + for (int i = 13647; i <= 13652; i++) + materials[i] = Material.BlueShulkerBox; + materials[6125] = Material.BlueStainedGlass; + for (int i = 10523; i <= 10554; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[10166] = Material.BlueTerracotta; + for (int i = 11938; i <= 11941; i++) + materials[i] = Material.BlueWallBanner; + materials[2101] = Material.BlueWool; + for (int i = 13559; i <= 13561; i++) + materials[i] = Material.BoneBlock; + materials[2139] = Material.Bookshelf; + for (int i = 13838; i <= 13839; i++) + materials[i] = Material.BrainCoral; + materials[13822] = Material.BrainCoralBlock; + for (int i = 13858; i <= 13859; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 13914; i <= 13921; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 8164; i <= 8171; i++) + materials[i] = Material.BrewingStand; + for (int i = 12143; i <= 12148; i++) + materials[i] = Material.BrickSlab; + for (int i = 7390; i <= 7469; i++) + materials[i] = Material.BrickStairs; + for (int i = 15173; i <= 15496; i++) + materials[i] = Material.BrickWall; + materials[2136] = Material.Bricks; + for (int i = 11830; i <= 11845; i++) + materials[i] = Material.BrownBanner; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 21946; i <= 21961; i++) + materials[i] = Material.BrownCandle; + for (int i = 22036; i <= 22037; i++) + materials[i] = Material.BrownCandleCake; + materials[11619] = Material.BrownCarpet; + materials[13753] = Material.BrownConcrete; + materials[13769] = Material.BrownConcretePowder; + for (int i = 13725; i <= 13728; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2132] = Material.BrownMushroom; + for (int i = 6782; i <= 6845; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 13653; i <= 13658; i++) + materials[i] = Material.BrownShulkerBox; + materials[6126] = Material.BrownStainedGlass; + for (int i = 10555; i <= 10586; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[10167] = Material.BrownTerracotta; + for (int i = 11942; i <= 11945; i++) + materials[i] = Material.BrownWallBanner; + materials[2102] = Material.BrownWool; + for (int i = 13973; i <= 13974; i++) + materials[i] = Material.BubbleColumn; + for (int i = 13840; i <= 13841; i++) + materials[i] = Material.BubbleCoral; + materials[13823] = Material.BubbleCoralBlock; + for (int i = 13860; i <= 13861; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 13922; i <= 13929; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[22045] = Material.BuddingAmethyst; + for (int i = 5951; i <= 5966; i++) + materials[i] = Material.Cactus; + for (int i = 6043; i <= 6049; i++) + materials[i] = Material.Cake; + materials[23329] = Material.Calcite; + for (int i = 23428; i <= 23811; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 19524; i <= 19555; i++) + materials[i] = Material.Campfire; + for (int i = 21738; i <= 21753; i++) + materials[i] = Material.Candle; + for (int i = 22010; i <= 22011; i++) + materials[i] = Material.CandleCake; + for (int i = 9370; i <= 9377; i++) + materials[i] = Material.Carrots; + materials[19449] = Material.CartographyTable; + for (int i = 6035; i <= 6038; i++) + materials[i] = Material.CarvedPumpkin; + materials[8172] = Material.Cauldron; + materials[13972] = Material.CaveAir; + for (int i = 25782; i <= 25833; i++) + materials[i] = Material.CaveVines; + for (int i = 25834; i <= 25835; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 7006; i <= 7011; i++) + materials[i] = Material.Chain; + for (int i = 13540; i <= 13551; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 9506; i <= 9529; i++) + materials[i] = Material.CherryButton; + for (int i = 13027; i <= 13090; i++) + materials[i] = Material.CherryDoor; + for (int i = 12611; i <= 12642; i++) + materials[i] = Material.CherryFence; + for (int i = 12323; i <= 12354; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5185; i <= 5248; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 5893; i <= 5894; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 4485; i <= 4516; i++) + materials[i] = Material.CherrySign; + for (int i = 12071; i <= 12076; i++) + materials[i] = Material.CherrySlab; + for (int i = 10763; i <= 10842; i++) + materials[i] = Material.CherryStairs; + for (int i = 6450; i <= 6513; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 5729; i <= 5736; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 4881; i <= 4888; i++) + materials[i] = Material.CherryWallSign; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 3009; i <= 3032; i++) + materials[i] = Material.Chest; + for (int i = 9910; i <= 9913; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2140; i <= 2395; i++) + materials[i] = Material.ChiseledBookshelf; + materials[23964] = Material.ChiseledCopper; + materials[27564] = Material.ChiseledDeepslate; + materials[21735] = Material.ChiseledNetherBricks; + materials[20887] = Material.ChiseledPolishedBlackstone; + materials[10035] = Material.ChiseledQuartzBlock; + materials[11959] = Material.ChiseledRedSandstone; + materials[8045] = Material.ChiseledResinBricks; + materials[579] = Material.ChiseledSandstone; + materials[6773] = Material.ChiseledStoneBricks; + materials[22916] = Material.ChiseledTuff; + materials[23328] = Material.ChiseledTuffBricks; + for (int i = 13417; i <= 13422; i++) + materials[i] = Material.ChorusFlower; + for (int i = 13353; i <= 13416; i++) + materials[i] = Material.ChorusPlant; + materials[5967] = Material.Clay; + materials[27863] = Material.ClosedEyeblossom; + materials[11624] = Material.CoalBlock; + materials[133] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[25920] = Material.CobbledDeepslate; + for (int i = 26001; i <= 26006; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 25921; i <= 26000; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 26007; i <= 26330; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 12137; i <= 12142; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 4769; i <= 4848; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 8693; i <= 9016; i++) + materials[i] = Material.CobblestoneWall; + materials[2047] = Material.Cobweb; + for (int i = 8193; i <= 8204; i++) + materials[i] = Material.Cocoa; + for (int i = 8680; i <= 8691; i++) + materials[i] = Material.CommandBlock; + for (int i = 9974; i <= 9989; i++) + materials[i] = Material.Comparator; + for (int i = 20385; i <= 20393; i++) + materials[i] = Material.Composter; + for (int i = 13955; i <= 13956; i++) + materials[i] = Material.Conduit; + materials[23951] = Material.CopperBlock; + for (int i = 25705; i <= 25708; i++) + materials[i] = Material.CopperBulb; + for (int i = 24665; i <= 24728; i++) + materials[i] = Material.CopperDoor; + for (int i = 25689; i <= 25690; i++) + materials[i] = Material.CopperGrate; + materials[23955] = Material.CopperOre; + for (int i = 25177; i <= 25240; i++) + materials[i] = Material.CopperTrapdoor; + materials[2129] = Material.Cornflower; + materials[27565] = Material.CrackedDeepslateBricks; + materials[27566] = Material.CrackedDeepslateTiles; + materials[21736] = Material.CrackedNetherBricks; + materials[20886] = Material.CrackedPolishedBlackstoneBricks; + materials[6772] = Material.CrackedStoneBricks; + for (int i = 27603; i <= 27650; i++) + materials[i] = Material.Crafter; + materials[4332] = Material.CraftingTable; + for (int i = 2917; i <= 2928; i++) + materials[i] = Material.CreakingHeart; + for (int i = 9786; i <= 9817; i++) + materials[i] = Material.CreeperHead; + for (int i = 9818; i <= 9825; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 20113; i <= 20136; i++) + materials[i] = Material.CrimsonButton; + for (int i = 20161; i <= 20224; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 19697; i <= 19728; i++) + materials[i] = Material.CrimsonFence; + for (int i = 19889; i <= 19920; i++) + materials[i] = Material.CrimsonFenceGate; + materials[19622] = Material.CrimsonFungus; + for (int i = 5441; i <= 5504; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 19615; i <= 19617; i++) + materials[i] = Material.CrimsonHyphae; + materials[19621] = Material.CrimsonNylium; + materials[19679] = Material.CrimsonPlanks; + for (int i = 19693; i <= 19694; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[19678] = Material.CrimsonRoots; + for (int i = 20289; i <= 20320; i++) + materials[i] = Material.CrimsonSign; + for (int i = 19681; i <= 19686; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 19953; i <= 20032; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 19609; i <= 19611; i++) + materials[i] = Material.CrimsonStem; + for (int i = 19761; i <= 19824; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 5769; i <= 5776; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 20353; i <= 20360; i++) + materials[i] = Material.CrimsonWallSign; + materials[20462] = Material.CryingObsidian; + materials[23960] = Material.CutCopper; + for (int i = 24307; i <= 24312; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 24209; i <= 24288; i++) + materials[i] = Material.CutCopperStairs; + materials[11960] = Material.CutRedSandstone; + for (int i = 12179; i <= 12184; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[580] = Material.CutSandstone; + for (int i = 12125; i <= 12130; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 11782; i <= 11797; i++) + materials[i] = Material.CyanBanner; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 21898; i <= 21913; i++) + materials[i] = Material.CyanCandle; + for (int i = 22030; i <= 22031; i++) + materials[i] = Material.CyanCandleCake; + materials[11616] = Material.CyanCarpet; + materials[13750] = Material.CyanConcrete; + materials[13766] = Material.CyanConcretePowder; + for (int i = 13713; i <= 13716; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 13635; i <= 13640; i++) + materials[i] = Material.CyanShulkerBox; + materials[6123] = Material.CyanStainedGlass; + for (int i = 10459; i <= 10490; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[10164] = Material.CyanTerracotta; + for (int i = 11930; i <= 11933; i++) + materials[i] = Material.CyanWallBanner; + materials[2099] = Material.CyanWool; + for (int i = 9914; i <= 9917; i++) + materials[i] = Material.DamagedAnvil; + materials[2118] = Material.Dandelion; + for (int i = 9530; i <= 9553; i++) + materials[i] = Material.DarkOakButton; + for (int i = 13091; i <= 13154; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 12643; i <= 12674; i++) + materials[i] = Material.DarkOakFence; + for (int i = 12355; i <= 12386; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 5313; i <= 5376; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 5895; i <= 5896; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 4549; i <= 4580; i++) + materials[i] = Material.DarkOakSign; + for (int i = 12077; i <= 12082; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 10843; i <= 10922; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 6514; i <= 6577; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 5745; i <= 5752; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 4897; i <= 4904; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + materials[11344] = Material.DarkPrismarine; + for (int i = 11597; i <= 11602; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 11505; i <= 11584; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 9990; i <= 10021; i++) + materials[i] = Material.DaylightDetector; + for (int i = 13828; i <= 13829; i++) + materials[i] = Material.DeadBrainCoral; + materials[13817] = Material.DeadBrainCoralBlock; + for (int i = 13848; i <= 13849; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 13874; i <= 13881; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 13830; i <= 13831; i++) + materials[i] = Material.DeadBubbleCoral; + materials[13818] = Material.DeadBubbleCoralBlock; + for (int i = 13850; i <= 13851; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 13882; i <= 13889; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2050] = Material.DeadBush; + for (int i = 13832; i <= 13833; i++) + materials[i] = Material.DeadFireCoral; + materials[13819] = Material.DeadFireCoralBlock; + for (int i = 13852; i <= 13853; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 13890; i <= 13897; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 13834; i <= 13835; i++) + materials[i] = Material.DeadHornCoral; + materials[13820] = Material.DeadHornCoralBlock; + for (int i = 13854; i <= 13855; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 13898; i <= 13905; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 13826; i <= 13827; i++) + materials[i] = Material.DeadTubeCoral; + materials[13816] = Material.DeadTubeCoralBlock; + for (int i = 13846; i <= 13847; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 13866; i <= 13873; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 27587; i <= 27602; i++) + materials[i] = Material.DecoratedPot; + for (int i = 25917; i <= 25919; i++) + materials[i] = Material.Deepslate; + for (int i = 27234; i <= 27239; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 27154; i <= 27233; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 27240; i <= 27563; i++) + materials[i] = Material.DeepslateBrickWall; + materials[27153] = Material.DeepslateBricks; + materials[134] = Material.DeepslateCoalOre; + materials[23956] = Material.DeepslateCopperOre; + materials[4330] = Material.DeepslateDiamondOre; + materials[8286] = Material.DeepslateEmeraldOre; + materials[130] = Material.DeepslateGoldOre; + materials[132] = Material.DeepslateIronOre; + materials[564] = Material.DeepslateLapisOre; + for (int i = 5905; i <= 5906; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 26823; i <= 26828; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 26743; i <= 26822; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 26829; i <= 27152; i++) + materials[i] = Material.DeepslateTileWall; + materials[26742] = Material.DeepslateTiles; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + materials[4331] = Material.DiamondBlock; + materials[4329] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 15167; i <= 15172; i++) + materials[i] = Material.DioriteSlab; + for (int i = 15015; i <= 15094; i++) + materials[i] = Material.DioriteStairs; + for (int i = 19061; i <= 19384; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[13526] = Material.DirtPath; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + materials[8190] = Material.DragonEgg; + for (int i = 9826; i <= 9857; i++) + materials[i] = Material.DragonHead; + for (int i = 9858; i <= 9865; i++) + materials[i] = Material.DragonWallHead; + materials[13800] = Material.DriedKelpBlock; + materials[25781] = Material.DripstoneBlock; + for (int i = 10143; i <= 10154; i++) + materials[i] = Material.Dropper; + materials[8439] = Material.EmeraldBlock; + materials[8285] = Material.EmeraldOre; + materials[8163] = Material.EnchantingTable; + materials[13527] = Material.EndGateway; + materials[8180] = Material.EndPortal; + for (int i = 8181; i <= 8188; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 13347; i <= 13352; i++) + materials[i] = Material.EndRod; + materials[8189] = Material.EndStone; + for (int i = 15125; i <= 15130; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 14375; i <= 14454; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 18737; i <= 19060; i++) + materials[i] = Material.EndStoneBrickWall; + materials[13507] = Material.EndStoneBricks; + for (int i = 8287; i <= 8294; i++) + materials[i] = Material.EnderChest; + materials[23963] = Material.ExposedChiseledCopper; + materials[23952] = Material.ExposedCopper; + for (int i = 25709; i <= 25712; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 24729; i <= 24792; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 25691; i <= 25692; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 25241; i <= 25304; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[23959] = Material.ExposedCutCopper; + for (int i = 24301; i <= 24306; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 24129; i <= 24208; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 4341; i <= 4348; i++) + materials[i] = Material.Farmland; + materials[2049] = Material.Fern; + for (int i = 2403; i <= 2914; i++) + materials[i] = Material.Fire; + for (int i = 13842; i <= 13843; i++) + materials[i] = Material.FireCoral; + materials[13824] = Material.FireCoralBlock; + for (int i = 13862; i <= 13863; i++) + materials[i] = Material.FireCoralFan; + for (int i = 13930; i <= 13937; i++) + materials[i] = Material.FireCoralWallFan; + materials[19450] = Material.FletchingTable; + materials[9341] = Material.FlowerPot; + materials[25838] = Material.FloweringAzalea; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[27585] = Material.Frogspawn; + for (int i = 13552; i <= 13555; i++) + materials[i] = Material.FrostedIce; + for (int i = 4349; i <= 4356; i++) + materials[i] = Material.Furnace; + materials[21298] = Material.GildedBlackstone; + materials[562] = Material.Glass; + for (int i = 7012; i <= 7043; i++) + materials[i] = Material.GlassPane; + for (int i = 7102; i <= 7229; i++) + materials[i] = Material.GlowLichen; + materials[6032] = Material.Glowstone; + materials[2134] = Material.GoldBlock; + materials[129] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 15143; i <= 15148; i++) + materials[i] = Material.GraniteSlab; + for (int i = 14695; i <= 14774; i++) + materials[i] = Material.GraniteStairs; + for (int i = 16469; i <= 16792; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[124] = Material.Gravel; + for (int i = 11750; i <= 11765; i++) + materials[i] = Material.GrayBanner; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 21866; i <= 21881; i++) + materials[i] = Material.GrayCandle; + for (int i = 22026; i <= 22027; i++) + materials[i] = Material.GrayCandleCake; + materials[11614] = Material.GrayCarpet; + materials[13748] = Material.GrayConcrete; + materials[13764] = Material.GrayConcretePowder; + for (int i = 13705; i <= 13708; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 13623; i <= 13628; i++) + materials[i] = Material.GrayShulkerBox; + materials[6121] = Material.GrayStainedGlass; + for (int i = 10395; i <= 10426; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[10162] = Material.GrayTerracotta; + for (int i = 11922; i <= 11925; i++) + materials[i] = Material.GrayWallBanner; + materials[2097] = Material.GrayWool; + for (int i = 11846; i <= 11861; i++) + materials[i] = Material.GreenBanner; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 21962; i <= 21977; i++) + materials[i] = Material.GreenCandle; + for (int i = 22038; i <= 22039; i++) + materials[i] = Material.GreenCandleCake; + materials[11620] = Material.GreenCarpet; + materials[13754] = Material.GreenConcrete; + materials[13770] = Material.GreenConcretePowder; + for (int i = 13729; i <= 13732; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 13659; i <= 13664; i++) + materials[i] = Material.GreenShulkerBox; + materials[6127] = Material.GreenStainedGlass; + for (int i = 10587; i <= 10618; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[10168] = Material.GreenTerracotta; + for (int i = 11946; i <= 11949; i++) + materials[i] = Material.GreenWallBanner; + materials[2103] = Material.GreenWool; + for (int i = 19451; i <= 19462; i++) + materials[i] = Material.Grindstone; + for (int i = 25913; i <= 25914; i++) + materials[i] = Material.HangingRoots; + for (int i = 11604; i <= 11606; i++) + materials[i] = Material.HayBlock; + for (int i = 27695; i <= 27696; i++) + materials[i] = Material.HeavyCore; + for (int i = 9958; i <= 9973; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[20458] = Material.HoneyBlock; + materials[20459] = Material.HoneycombBlock; + for (int i = 10024; i <= 10033; i++) + materials[i] = Material.Hopper; + for (int i = 13844; i <= 13845; i++) + materials[i] = Material.HornCoral; + materials[13825] = Material.HornCoralBlock; + for (int i = 13864; i <= 13865; i++) + materials[i] = Material.HornCoralFan; + for (int i = 13938; i <= 13945; i++) + materials[i] = Material.HornCoralWallFan; + materials[5949] = Material.Ice; + materials[6781] = Material.InfestedChiseledStoneBricks; + materials[6777] = Material.InfestedCobblestone; + materials[6780] = Material.InfestedCrackedStoneBricks; + for (int i = 27567; i <= 27569; i++) + materials[i] = Material.InfestedDeepslate; + materials[6779] = Material.InfestedMossyStoneBricks; + materials[6776] = Material.InfestedStone; + materials[6778] = Material.InfestedStoneBricks; + for (int i = 6974; i <= 7005; i++) + materials[i] = Material.IronBars; + materials[2135] = Material.IronBlock; + for (int i = 5819; i <= 5882; i++) + materials[i] = Material.IronDoor; + materials[131] = Material.IronOre; + for (int i = 11278; i <= 11341; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 6039; i <= 6042; i++) + materials[i] = Material.JackOLantern; + for (int i = 20373; i <= 20384; i++) + materials[i] = Material.Jigsaw; + for (int i = 5984; i <= 5985; i++) + materials[i] = Material.Jukebox; + for (int i = 9458; i <= 9481; i++) + materials[i] = Material.JungleButton; + for (int i = 12899; i <= 12962; i++) + materials[i] = Material.JungleDoor; + for (int i = 12547; i <= 12578; i++) + materials[i] = Material.JungleFence; + for (int i = 12259; i <= 12290; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 5249; i <= 5312; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 5889; i <= 5890; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 4517; i <= 4548; i++) + materials[i] = Material.JungleSign; + for (int i = 12059; i <= 12064; i++) + materials[i] = Material.JungleSlab; + for (int i = 8600; i <= 8679; i++) + materials[i] = Material.JungleStairs; + for (int i = 6322; i <= 6385; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 5737; i <= 5744; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 4889; i <= 4896; i++) + materials[i] = Material.JungleWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 13773; i <= 13798; i++) + materials[i] = Material.Kelp; + materials[13799] = Material.KelpPlant; + for (int i = 4741; i <= 4748; i++) + materials[i] = Material.Ladder; + for (int i = 19516; i <= 19519; i++) + materials[i] = Material.Lantern; + materials[565] = Material.LapisBlock; + materials[563] = Material.LapisOre; + for (int i = 22058; i <= 22069; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 11636; i <= 11637; i++) + materials[i] = Material.LargeFern; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + materials[8176] = Material.LavaCauldron; + for (int i = 19463; i <= 19478; i++) + materials[i] = Material.Lectern; + for (int i = 5793; i <= 5816; i++) + materials[i] = Material.Lever; + for (int i = 11246; i <= 11277; i++) + materials[i] = Material.Light; + for (int i = 11686; i <= 11701; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 21802; i <= 21817; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 22018; i <= 22019; i++) + materials[i] = Material.LightBlueCandleCake; + materials[11610] = Material.LightBlueCarpet; + materials[13744] = Material.LightBlueConcrete; + materials[13760] = Material.LightBlueConcretePowder; + for (int i = 13689; i <= 13692; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 13599; i <= 13604; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[6117] = Material.LightBlueStainedGlass; + for (int i = 10267; i <= 10298; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[10158] = Material.LightBlueTerracotta; + for (int i = 11906; i <= 11909; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2093] = Material.LightBlueWool; + for (int i = 11766; i <= 11781; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 21882; i <= 21897; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 22028; i <= 22029; i++) + materials[i] = Material.LightGrayCandleCake; + materials[11615] = Material.LightGrayCarpet; + materials[13749] = Material.LightGrayConcrete; + materials[13765] = Material.LightGrayConcretePowder; + for (int i = 13709; i <= 13712; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 13629; i <= 13634; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[6122] = Material.LightGrayStainedGlass; + for (int i = 10427; i <= 10458; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[10163] = Material.LightGrayTerracotta; + for (int i = 11926; i <= 11929; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2098] = Material.LightGrayWool; + for (int i = 9942; i <= 9957; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 25737; i <= 25760; i++) + materials[i] = Material.LightningRod; + for (int i = 11628; i <= 11629; i++) + materials[i] = Material.Lilac; + materials[2131] = Material.LilyOfTheValley; + materials[7632] = Material.LilyPad; + for (int i = 11718; i <= 11733; i++) + materials[i] = Material.LimeBanner; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; + for (int i = 21834; i <= 21849; i++) + materials[i] = Material.LimeCandle; + for (int i = 22022; i <= 22023; i++) + materials[i] = Material.LimeCandleCake; + materials[11612] = Material.LimeCarpet; + materials[13746] = Material.LimeConcrete; + materials[13762] = Material.LimeConcretePowder; + for (int i = 13697; i <= 13700; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 13611; i <= 13616; i++) + materials[i] = Material.LimeShulkerBox; + materials[6119] = Material.LimeStainedGlass; + for (int i = 10331; i <= 10362; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[10160] = Material.LimeTerracotta; + for (int i = 11914; i <= 11917; i++) + materials[i] = Material.LimeWallBanner; + materials[2095] = Material.LimeWool; + materials[20472] = Material.Lodestone; + for (int i = 19417; i <= 19420; i++) + materials[i] = Material.Loom; + for (int i = 11670; i <= 11685; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 21786; i <= 21801; i++) + materials[i] = Material.MagentaCandle; + for (int i = 22016; i <= 22017; i++) + materials[i] = Material.MagentaCandleCake; + materials[11609] = Material.MagentaCarpet; + materials[13743] = Material.MagentaConcrete; + materials[13759] = Material.MagentaConcretePowder; + for (int i = 13685; i <= 13688; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 13593; i <= 13598; i++) + materials[i] = Material.MagentaShulkerBox; + materials[6116] = Material.MagentaStainedGlass; + for (int i = 10235; i <= 10266; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[10157] = Material.MagentaTerracotta; + for (int i = 11902; i <= 11905; i++) + materials[i] = Material.MagentaWallBanner; + materials[2092] = Material.MagentaWool; + materials[13556] = Material.MagmaBlock; + for (int i = 9578; i <= 9601; i++) + materials[i] = Material.MangroveButton; + for (int i = 13219; i <= 13282; i++) + materials[i] = Material.MangroveDoor; + for (int i = 12707; i <= 12738; i++) + materials[i] = Material.MangroveFence; + for (int i = 12419; i <= 12450; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 5569; i <= 5632; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + materials[26] = Material.MangrovePlanks; + for (int i = 5899; i <= 5900; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 4613; i <= 4644; i++) + materials[i] = Material.MangroveSign; + for (int i = 12089; i <= 12094; i++) + materials[i] = Material.MangroveSlab; + for (int i = 11003; i <= 11082; i++) + materials[i] = Material.MangroveStairs; + for (int i = 6642; i <= 6705; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 5761; i <= 5768; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 4913; i <= 4920; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 22070; i <= 22081; i++) + materials[i] = Material.MediumAmethystBud; + materials[7045] = Material.Melon; + for (int i = 7062; i <= 7069; i++) + materials[i] = Material.MelonStem; + materials[25856] = Material.MossBlock; + materials[25839] = Material.MossCarpet; + materials[2396] = Material.MossyCobblestone; + for (int i = 15119; i <= 15124; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 14295; i <= 14374; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 9017; i <= 9340; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 15107; i <= 15112; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 14135; i <= 14214; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 16145; i <= 16468; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[6771] = Material.MossyStoneBricks; + for (int i = 2106; i <= 2117; i++) + materials[i] = Material.MovingPiston; + materials[25916] = Material.Mud; + for (int i = 12155; i <= 12160; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 7550; i <= 7629; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 17117; i <= 17440; i++) + materials[i] = Material.MudBrickWall; + materials[6775] = Material.MudBricks; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 6910; i <= 6973; i++) + materials[i] = Material.MushroomStem; + for (int i = 7630; i <= 7631; i++) + materials[i] = Material.Mycelium; + for (int i = 8047; i <= 8078; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 12161; i <= 12166; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 8079; i <= 8158; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 17441; i <= 17764; i++) + materials[i] = Material.NetherBrickWall; + materials[8046] = Material.NetherBricks; + materials[135] = Material.NetherGoldOre; + for (int i = 6033; i <= 6034; i++) + materials[i] = Material.NetherPortal; + materials[10023] = Material.NetherQuartzOre; + materials[19608] = Material.NetherSprouts; + for (int i = 8159; i <= 8162; i++) + materials[i] = Material.NetherWart; + materials[13557] = Material.NetherWartBlock; + materials[20460] = Material.NetheriteBlock; + materials[6018] = Material.Netherrack; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 9386; i <= 9409; i++) + materials[i] = Material.OakButton; + for (int i = 4677; i <= 4740; i++) + materials[i] = Material.OakDoor; + for (int i = 5986; i <= 6017; i++) + materials[i] = Material.OakFence; + for (int i = 7358; i <= 7389; i++) + materials[i] = Material.OakFenceGate; + for (int i = 4929; i <= 4992; i++) + materials[i] = Material.OakHangingSign; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 5883; i <= 5884; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 4357; i <= 4388; i++) + materials[i] = Material.OakSign; + for (int i = 12041; i <= 12046; i++) + materials[i] = Material.OakSlab; + for (int i = 2929; i <= 3008; i++) + materials[i] = Material.OakStairs; + for (int i = 6130; i <= 6193; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 5697; i <= 5704; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 4849; i <= 4856; i++) + materials[i] = Material.OakWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 13563; i <= 13574; i++) + materials[i] = Material.Observer; + materials[2397] = Material.Obsidian; + for (int i = 27576; i <= 27578; i++) + materials[i] = Material.OchreFroglight; + materials[27862] = Material.OpenEyeblossom; + for (int i = 11654; i <= 11669; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 21770; i <= 21785; i++) + materials[i] = Material.OrangeCandle; + for (int i = 22014; i <= 22015; i++) + materials[i] = Material.OrangeCandleCake; + materials[11608] = Material.OrangeCarpet; + materials[13742] = Material.OrangeConcrete; + materials[13758] = Material.OrangeConcretePowder; + for (int i = 13681; i <= 13684; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 13587; i <= 13592; i++) + materials[i] = Material.OrangeShulkerBox; + materials[6115] = Material.OrangeStainedGlass; + for (int i = 10203; i <= 10234; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[10156] = Material.OrangeTerracotta; + materials[2125] = Material.OrangeTulip; + for (int i = 11898; i <= 11901; i++) + materials[i] = Material.OrangeWallBanner; + materials[2091] = Material.OrangeWool; + materials[2128] = Material.OxeyeDaisy; + materials[23961] = Material.OxidizedChiseledCopper; + materials[23954] = Material.OxidizedCopper; + for (int i = 25717; i <= 25720; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 24793; i <= 24856; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 25695; i <= 25696; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 25305; i <= 25368; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[23957] = Material.OxidizedCutCopper; + for (int i = 24289; i <= 24294; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 23969; i <= 24048; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[11625] = Material.PackedIce; + materials[6774] = Material.PackedMud; + for (int i = 27860; i <= 27861; i++) + materials[i] = Material.PaleHangingMoss; + materials[27697] = Material.PaleMossBlock; + for (int i = 27698; i <= 27859; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 9554; i <= 9577; i++) + materials[i] = Material.PaleOakButton; + for (int i = 13155; i <= 13218; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 12675; i <= 12706; i++) + materials[i] = Material.PaleOakFence; + for (int i = 12387; i <= 12418; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 5377; i <= 5440; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + materials[25] = Material.PaleOakPlanks; + for (int i = 5897; i <= 5898; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 4581; i <= 4612; i++) + materials[i] = Material.PaleOakSign; + for (int i = 12083; i <= 12088; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 10923; i <= 11002; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 6578; i <= 6641; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 5753; i <= 5760; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 4905; i <= 4912; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 27582; i <= 27584; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 11632; i <= 11633; i++) + materials[i] = Material.Peony; + for (int i = 12131; i <= 12136; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 9866; i <= 9897; i++) + materials[i] = Material.PiglinHead; + for (int i = 9898; i <= 9905; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 11734; i <= 11749; i++) + materials[i] = Material.PinkBanner; + for (int i = 1827; i <= 1842; i++) + materials[i] = Material.PinkBed; + for (int i = 21850; i <= 21865; i++) + materials[i] = Material.PinkCandle; + for (int i = 22024; i <= 22025; i++) + materials[i] = Material.PinkCandleCake; + materials[11613] = Material.PinkCarpet; + materials[13747] = Material.PinkConcrete; + materials[13763] = Material.PinkConcretePowder; + for (int i = 13701; i <= 13704; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 25840; i <= 25855; i++) + materials[i] = Material.PinkPetals; + for (int i = 13617; i <= 13622; i++) + materials[i] = Material.PinkShulkerBox; + materials[6120] = Material.PinkStainedGlass; + for (int i = 10363; i <= 10394; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[10161] = Material.PinkTerracotta; + materials[2127] = Material.PinkTulip; + for (int i = 11918; i <= 11921; i++) + materials[i] = Material.PinkWallBanner; + materials[2096] = Material.PinkWool; + for (int i = 2054; i <= 2065; i++) + materials[i] = Material.Piston; + for (int i = 2066; i <= 2089; i++) + materials[i] = Material.PistonHead; + for (int i = 13510; i <= 13519; i++) + materials[i] = Material.PitcherCrop; + for (int i = 13520; i <= 13521; i++) + materials[i] = Material.PitcherPlant; + for (int i = 9746; i <= 9777; i++) + materials[i] = Material.PlayerHead; + for (int i = 9778; i <= 9785; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 25761; i <= 25780; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 15161; i <= 15166; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 14935; i <= 15014; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 6024; i <= 6026; i++) + materials[i] = Material.PolishedBasalt; + materials[20884] = Material.PolishedBlackstone; + for (int i = 20888; i <= 20893; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 20894; i <= 20973; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 20974; i <= 21297; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[20885] = Material.PolishedBlackstoneBricks; + for (int i = 21387; i <= 21410; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 21385; i <= 21386; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 21379; i <= 21384; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 21299; i <= 21378; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 21411; i <= 21734; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[26331] = Material.PolishedDeepslate; + for (int i = 26412; i <= 26417; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 26332; i <= 26411; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 26418; i <= 26741; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 15113; i <= 15118; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 14215; i <= 14294; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 15095; i <= 15100; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 13975; i <= 14054; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[22505] = Material.PolishedTuff; + for (int i = 22506; i <= 22511; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 22512; i <= 22591; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 22592; i <= 22915; i++) + materials[i] = Material.PolishedTuffWall; + materials[2120] = Material.Poppy; + for (int i = 9378; i <= 9385; i++) + materials[i] = Material.Potatoes; + materials[9347] = Material.PottedAcaciaSapling; + materials[9356] = Material.PottedAllium; + materials[27574] = Material.PottedAzaleaBush; + materials[9357] = Material.PottedAzureBluet; + materials[13970] = Material.PottedBamboo; + materials[9345] = Material.PottedBirchSapling; + materials[9355] = Material.PottedBlueOrchid; + materials[9367] = Material.PottedBrownMushroom; + materials[9369] = Material.PottedCactus; + materials[9348] = Material.PottedCherrySapling; + materials[27865] = Material.PottedClosedEyeblossom; + materials[9363] = Material.PottedCornflower; + materials[20468] = Material.PottedCrimsonFungus; + materials[20470] = Material.PottedCrimsonRoots; + materials[9353] = Material.PottedDandelion; + materials[9349] = Material.PottedDarkOakSapling; + materials[9368] = Material.PottedDeadBush; + materials[9352] = Material.PottedFern; + materials[27575] = Material.PottedFloweringAzaleaBush; + materials[9346] = Material.PottedJungleSapling; + materials[9364] = Material.PottedLilyOfTheValley; + materials[9351] = Material.PottedMangrovePropagule; + materials[9343] = Material.PottedOakSapling; + materials[27864] = Material.PottedOpenEyeblossom; + materials[9359] = Material.PottedOrangeTulip; + materials[9362] = Material.PottedOxeyeDaisy; + materials[9350] = Material.PottedPaleOakSapling; + materials[9361] = Material.PottedPinkTulip; + materials[9354] = Material.PottedPoppy; + materials[9366] = Material.PottedRedMushroom; + materials[9358] = Material.PottedRedTulip; + materials[9344] = Material.PottedSpruceSapling; + materials[9342] = Material.PottedTorchflower; + materials[20469] = Material.PottedWarpedFungus; + materials[20471] = Material.PottedWarpedRoots; + materials[9360] = Material.PottedWhiteTulip; + materials[9365] = Material.PottedWitherRose; + materials[23331] = Material.PowderSnow; + for (int i = 8177; i <= 8179; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + materials[11342] = Material.Prismarine; + for (int i = 11591; i <= 11596; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 11425; i <= 11504; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[11343] = Material.PrismarineBricks; + for (int i = 11585; i <= 11590; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 11345; i <= 11424; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 15497; i <= 15820; i++) + materials[i] = Material.PrismarineWall; + materials[7044] = Material.Pumpkin; + for (int i = 7054; i <= 7061; i++) + materials[i] = Material.PumpkinStem; + for (int i = 11798; i <= 11813; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 21914; i <= 21929; i++) + materials[i] = Material.PurpleCandle; + for (int i = 22032; i <= 22033; i++) + materials[i] = Material.PurpleCandleCake; + materials[11617] = Material.PurpleCarpet; + materials[13751] = Material.PurpleConcrete; + materials[13767] = Material.PurpleConcretePowder; + for (int i = 13717; i <= 13720; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 13641; i <= 13646; i++) + materials[i] = Material.PurpleShulkerBox; + materials[6124] = Material.PurpleStainedGlass; + for (int i = 10491; i <= 10522; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[10165] = Material.PurpleTerracotta; + for (int i = 11934; i <= 11937; i++) + materials[i] = Material.PurpleWallBanner; + materials[2100] = Material.PurpleWool; + materials[13423] = Material.PurpurBlock; + for (int i = 13424; i <= 13426; i++) + materials[i] = Material.PurpurPillar; + for (int i = 12185; i <= 12190; i++) + materials[i] = Material.PurpurSlab; + for (int i = 13427; i <= 13506; i++) + materials[i] = Material.PurpurStairs; + materials[10034] = Material.QuartzBlock; + materials[21737] = Material.QuartzBricks; + for (int i = 10036; i <= 10038; i++) + materials[i] = Material.QuartzPillar; + for (int i = 12167; i <= 12172; i++) + materials[i] = Material.QuartzSlab; + for (int i = 10039; i <= 10118; i++) + materials[i] = Material.QuartzStairs; + for (int i = 4749; i <= 4768; i++) + materials[i] = Material.Rail; + materials[27572] = Material.RawCopperBlock; + materials[27573] = Material.RawGoldBlock; + materials[27571] = Material.RawIronBlock; + for (int i = 11862; i <= 11877; i++) + materials[i] = Material.RedBanner; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 21978; i <= 21993; i++) + materials[i] = Material.RedCandle; + for (int i = 22040; i <= 22041; i++) + materials[i] = Material.RedCandleCake; + materials[11621] = Material.RedCarpet; + materials[13755] = Material.RedConcrete; + materials[13771] = Material.RedConcretePowder; + for (int i = 13733; i <= 13736; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2133] = Material.RedMushroom; + for (int i = 6846; i <= 6909; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 15155; i <= 15160; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 14855; i <= 14934; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 18089; i <= 18412; i++) + materials[i] = Material.RedNetherBrickWall; + materials[13558] = Material.RedNetherBricks; + materials[123] = Material.RedSand; + materials[11958] = Material.RedSandstone; + for (int i = 12173; i <= 12178; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 11961; i <= 12040; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 15821; i <= 16144; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 13665; i <= 13670; i++) + materials[i] = Material.RedShulkerBox; + materials[6128] = Material.RedStainedGlass; + for (int i = 10619; i <= 10650; i++) + materials[i] = Material.RedStainedGlassPane; + materials[10169] = Material.RedTerracotta; + materials[2124] = Material.RedTulip; + for (int i = 11950; i <= 11953; i++) + materials[i] = Material.RedWallBanner; + materials[2104] = Material.RedWool; + materials[10022] = Material.RedstoneBlock; + for (int i = 8191; i <= 8192; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 5903; i <= 5904; i++) + materials[i] = Material.RedstoneOre; + for (int i = 5907; i <= 5908; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 5909; i <= 5916; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 3033; i <= 4328; i++) + materials[i] = Material.RedstoneWire; + materials[27586] = Material.ReinforcedDeepslate; + for (int i = 6050; i <= 6113; i++) + materials[i] = Material.Repeater; + for (int i = 13528; i <= 13539; i++) + materials[i] = Material.RepeatingCommandBlock; + materials[7633] = Material.ResinBlock; + for (int i = 7715; i <= 7720; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 7635; i <= 7714; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 7721; i <= 8044; i++) + materials[i] = Material.ResinBrickWall; + materials[7634] = Material.ResinBricks; + for (int i = 7230; i <= 7357; i++) + materials[i] = Material.ResinClump; + for (int i = 20463; i <= 20467; i++) + materials[i] = Material.RespawnAnchor; + materials[25915] = Material.RootedDirt; + for (int i = 11630; i <= 11631; i++) + materials[i] = Material.RoseBush; + materials[118] = Material.Sand; + materials[578] = Material.Sandstone; + for (int i = 12119; i <= 12124; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 8205; i <= 8284; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 18413; i <= 18736; i++) + materials[i] = Material.SandstoneWall; + for (int i = 19385; i <= 19416; i++) + materials[i] = Material.Scaffolding; + materials[23812] = Material.Sculk; + for (int i = 23941; i <= 23942; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 23332; i <= 23427; i++) + materials[i] = Material.SculkSensor; + for (int i = 23943; i <= 23950; i++) + materials[i] = Material.SculkShrieker; + for (int i = 23813; i <= 23940; i++) + materials[i] = Material.SculkVein; + materials[11603] = Material.SeaLantern; + for (int i = 13946; i <= 13953; i++) + materials[i] = Material.SeaPickle; + materials[2051] = Material.Seagrass; + materials[2048] = Material.ShortGrass; + materials[19623] = Material.Shroomlight; + for (int i = 13575; i <= 13580; i++) + materials[i] = Material.ShulkerBox; + for (int i = 9626; i <= 9657; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 9658; i <= 9665; i++) + materials[i] = Material.SkeletonWallSkull; + materials[11243] = Material.SlimeBlock; + for (int i = 22082; i <= 22093; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 25897; i <= 25912; i++) + materials[i] = Material.SmallDripleaf; + materials[19479] = Material.SmithingTable; + for (int i = 19433; i <= 19440; i++) + materials[i] = Material.Smoker; + materials[27570] = Material.SmoothBasalt; + materials[12193] = Material.SmoothQuartz; + for (int i = 15137; i <= 15142; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 14615; i <= 14694; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[12194] = Material.SmoothRedSandstone; + for (int i = 15101; i <= 15106; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 14055; i <= 14134; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[12192] = Material.SmoothSandstone; + for (int i = 15131; i <= 15136; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 14535; i <= 14614; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[12191] = Material.SmoothStone; + for (int i = 12113; i <= 12118; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13813; i <= 13815; i++) + materials[i] = Material.SnifferEgg; + for (int i = 5941; i <= 5948; i++) + materials[i] = Material.Snow; + materials[5950] = Material.SnowBlock; + for (int i = 19556; i <= 19587; i++) + materials[i] = Material.SoulCampfire; + materials[2915] = Material.SoulFire; + for (int i = 19520; i <= 19523; i++) + materials[i] = Material.SoulLantern; + materials[6019] = Material.SoulSand; + materials[6020] = Material.SoulSoil; + materials[6027] = Material.SoulTorch; + for (int i = 6028; i <= 6031; i++) + materials[i] = Material.SoulWallTorch; + materials[2916] = Material.Spawner; + materials[560] = Material.Sponge; + materials[25836] = Material.SporeBlossom; + for (int i = 9410; i <= 9433; i++) + materials[i] = Material.SpruceButton; + for (int i = 12771; i <= 12834; i++) + materials[i] = Material.SpruceDoor; + for (int i = 12483; i <= 12514; i++) + materials[i] = Material.SpruceFence; + for (int i = 12195; i <= 12226; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 4993; i <= 5056; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 5885; i <= 5886; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 4389; i <= 4420; i++) + materials[i] = Material.SpruceSign; + for (int i = 12047; i <= 12052; i++) + materials[i] = Material.SpruceSlab; + for (int i = 8440; i <= 8519; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6194; i <= 6257; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 5705; i <= 5712; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 4857; i <= 4864; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 12149; i <= 12154; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 7470; i <= 7549; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 16793; i <= 17116; i++) + materials[i] = Material.StoneBrickWall; + materials[6770] = Material.StoneBricks; + for (int i = 5917; i <= 5940; i++) + materials[i] = Material.StoneButton; + for (int i = 5817; i <= 5818; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 12107; i <= 12112; i++) + materials[i] = Material.StoneSlab; + for (int i = 14455; i <= 14534; i++) + materials[i] = Material.StoneStairs; + for (int i = 19480; i <= 19483; i++) + materials[i] = Material.Stonecutter; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 19618; i <= 19620; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 19612; i <= 19614; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 19601; i <= 19603; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 19595; i <= 19597; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 20369; i <= 20372; i++) + materials[i] = Material.StructureBlock; + materials[13562] = Material.StructureVoid; + for (int i = 5968; i <= 5983; i++) + materials[i] = Material.SugarCane; + for (int i = 11626; i <= 11627; i++) + materials[i] = Material.Sunflower; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 19588; i <= 19591; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 11634; i <= 11635; i++) + materials[i] = Material.TallGrass; + for (int i = 2052; i <= 2053; i++) + materials[i] = Material.TallSeagrass; + for (int i = 20394; i <= 20409; i++) + materials[i] = Material.Target; + materials[11623] = Material.Terracotta; + materials[23330] = Material.TintedGlass; + for (int i = 2137; i <= 2138; i++) + materials[i] = Material.Tnt; + materials[2398] = Material.Torch; + materials[2119] = Material.Torchflower; + for (int i = 13508; i <= 13509; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 9918; i <= 9941; i++) + materials[i] = Material.TrappedChest; + for (int i = 27651; i <= 27662; i++) + materials[i] = Material.TrialSpawner; + for (int i = 8311; i <= 8438; i++) + materials[i] = Material.Tripwire; + for (int i = 8295; i <= 8310; i++) + materials[i] = Material.TripwireHook; + for (int i = 13836; i <= 13837; i++) + materials[i] = Material.TubeCoral; + materials[13821] = Material.TubeCoralBlock; + for (int i = 13856; i <= 13857; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 13906; i <= 13913; i++) + materials[i] = Material.TubeCoralWallFan; + materials[22094] = Material.Tuff; + for (int i = 22918; i <= 22923; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 22924; i <= 23003; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 23004; i <= 23327; i++) + materials[i] = Material.TuffBrickWall; + materials[22917] = Material.TuffBricks; + for (int i = 22095; i <= 22100; i++) + materials[i] = Material.TuffSlab; + for (int i = 22101; i <= 22180; i++) + materials[i] = Material.TuffStairs; + for (int i = 22181; i <= 22504; i++) + materials[i] = Material.TuffWall; + for (int i = 13801; i <= 13812; i++) + materials[i] = Material.TurtleEgg; + for (int i = 19651; i <= 19676; i++) + materials[i] = Material.TwistingVines; + materials[19677] = Material.TwistingVinesPlant; + for (int i = 27663; i <= 27694; i++) + materials[i] = Material.Vault; + for (int i = 27579; i <= 27581; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 7070; i <= 7101; i++) + materials[i] = Material.Vine; + materials[13971] = Material.VoidAir; + for (int i = 2399; i <= 2402; i++) + materials[i] = Material.WallTorch; + for (int i = 20137; i <= 20160; i++) + materials[i] = Material.WarpedButton; + for (int i = 20225; i <= 20288; i++) + materials[i] = Material.WarpedDoor; + for (int i = 19729; i <= 19760; i++) + materials[i] = Material.WarpedFence; + for (int i = 19921; i <= 19952; i++) + materials[i] = Material.WarpedFenceGate; + materials[19605] = Material.WarpedFungus; + for (int i = 5505; i <= 5568; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 19598; i <= 19600; i++) + materials[i] = Material.WarpedHyphae; + materials[19604] = Material.WarpedNylium; + materials[19680] = Material.WarpedPlanks; + for (int i = 19695; i <= 19696; i++) + materials[i] = Material.WarpedPressurePlate; + materials[19607] = Material.WarpedRoots; + for (int i = 20321; i <= 20352; i++) + materials[i] = Material.WarpedSign; + for (int i = 19687; i <= 19692; i++) + materials[i] = Material.WarpedSlab; + for (int i = 20033; i <= 20112; i++) + materials[i] = Material.WarpedStairs; + for (int i = 19592; i <= 19594; i++) + materials[i] = Material.WarpedStem; + for (int i = 19825; i <= 19888; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 5777; i <= 5784; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 20361; i <= 20368; i++) + materials[i] = Material.WarpedWallSign; + materials[19606] = Material.WarpedWartBlock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 8173; i <= 8175; i++) + materials[i] = Material.WaterCauldron; + materials[23968] = Material.WaxedChiseledCopper; + materials[24313] = Material.WaxedCopperBlock; + for (int i = 25721; i <= 25724; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 24921; i <= 24984; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 25697; i <= 25698; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 25433; i <= 25496; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[24320] = Material.WaxedCutCopper; + for (int i = 24659; i <= 24664; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 24561; i <= 24640; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[23967] = Material.WaxedExposedChiseledCopper; + materials[24315] = Material.WaxedExposedCopper; + for (int i = 25725; i <= 25728; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 24985; i <= 25048; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 25699; i <= 25700; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 25497; i <= 25560; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[24319] = Material.WaxedExposedCutCopper; + for (int i = 24653; i <= 24658; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 24481; i <= 24560; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[23965] = Material.WaxedOxidizedChiseledCopper; + materials[24316] = Material.WaxedOxidizedCopper; + for (int i = 25733; i <= 25736; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 25049; i <= 25112; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 25703; i <= 25704; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 25561; i <= 25624; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[24317] = Material.WaxedOxidizedCutCopper; + for (int i = 24641; i <= 24646; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 24321; i <= 24400; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[23966] = Material.WaxedWeatheredChiseledCopper; + materials[24314] = Material.WaxedWeatheredCopper; + for (int i = 25729; i <= 25732; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 25113; i <= 25176; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 25701; i <= 25702; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 25625; i <= 25688; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[24318] = Material.WaxedWeatheredCutCopper; + for (int i = 24647; i <= 24652; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 24401; i <= 24480; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[23962] = Material.WeatheredChiseledCopper; + materials[23953] = Material.WeatheredCopper; + for (int i = 25713; i <= 25716; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 24857; i <= 24920; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 25693; i <= 25694; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 25369; i <= 25432; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[23958] = Material.WeatheredCutCopper; + for (int i = 24295; i <= 24300; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 24049; i <= 24128; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 19624; i <= 19649; i++) + materials[i] = Material.WeepingVines; + materials[19650] = Material.WeepingVinesPlant; + materials[561] = Material.WetSponge; + for (int i = 4333; i <= 4340; i++) + materials[i] = Material.Wheat; + for (int i = 11638; i <= 11653; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 21754; i <= 21769; i++) + materials[i] = Material.WhiteCandle; + for (int i = 22012; i <= 22013; i++) + materials[i] = Material.WhiteCandleCake; + materials[11607] = Material.WhiteCarpet; + materials[13741] = Material.WhiteConcrete; + materials[13757] = Material.WhiteConcretePowder; + for (int i = 13677; i <= 13680; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 13581; i <= 13586; i++) + materials[i] = Material.WhiteShulkerBox; + materials[6114] = Material.WhiteStainedGlass; + for (int i = 10171; i <= 10202; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[10155] = Material.WhiteTerracotta; + materials[2126] = Material.WhiteTulip; + for (int i = 11894; i <= 11897; i++) + materials[i] = Material.WhiteWallBanner; + materials[2090] = Material.WhiteWool; + materials[2130] = Material.WitherRose; + for (int i = 9666; i <= 9697; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 9698; i <= 9705; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 11702; i <= 11717; i++) + materials[i] = Material.YellowBanner; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 21818; i <= 21833; i++) + materials[i] = Material.YellowCandle; + for (int i = 22020; i <= 22021; i++) + materials[i] = Material.YellowCandleCake; + materials[11611] = Material.YellowCarpet; + materials[13745] = Material.YellowConcrete; + materials[13761] = Material.YellowConcretePowder; + for (int i = 13693; i <= 13696; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 13605; i <= 13610; i++) + materials[i] = Material.YellowShulkerBox; + materials[6118] = Material.YellowStainedGlass; + for (int i = 10299; i <= 10330; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[10159] = Material.YellowTerracotta; + for (int i = 11910; i <= 11913; i++) + materials[i] = Material.YellowWallBanner; + materials[2094] = Material.YellowWool; + for (int i = 9706; i <= 9737; i++) + materials[i] = Material.ZombieHead; + for (int i = 9738; i <= 9745; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 0e86e828..369672de 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -23,7 +23,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_2_Version => new EntityMetadataPalette1191(), // 1.13 - 1.19.2 <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 - <= Protocol18Handler.MC_1_21_2_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.2 + <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1214.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1214.cs new file mode 100644 index 00000000..dd047d1d --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1214.cs @@ -0,0 +1,168 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1214 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1214() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.Cat; + mappings[21] = EntityType.CaveSpider; + mappings[22] = EntityType.CherryBoat; + mappings[23] = EntityType.CherryChestBoat; + mappings[24] = EntityType.ChestMinecart; + mappings[25] = EntityType.Chicken; + mappings[26] = EntityType.Cod; + mappings[27] = EntityType.CommandBlockMinecart; + mappings[28] = EntityType.Cow; + mappings[29] = EntityType.Creaking; + // CreakingTransient removed in 1.21.4 + mappings[30] = EntityType.Creeper; + mappings[31] = EntityType.DarkOakBoat; + mappings[32] = EntityType.DarkOakChestBoat; + mappings[33] = EntityType.Dolphin; + mappings[34] = EntityType.Donkey; + mappings[35] = EntityType.DragonFireball; + mappings[36] = EntityType.Drowned; + mappings[37] = EntityType.Egg; + mappings[38] = EntityType.ElderGuardian; + mappings[39] = EntityType.Enderman; + mappings[40] = EntityType.Endermite; + mappings[41] = EntityType.EnderDragon; + mappings[42] = EntityType.EnderPearl; + mappings[43] = EntityType.EndCrystal; + mappings[44] = EntityType.Evoker; + mappings[45] = EntityType.EvokerFangs; + mappings[46] = EntityType.ExperienceBottle; + mappings[47] = EntityType.ExperienceOrb; + mappings[48] = EntityType.EyeOfEnder; + mappings[49] = EntityType.FallingBlock; + mappings[50] = EntityType.Fireball; + mappings[51] = EntityType.FireworkRocket; + mappings[52] = EntityType.Fox; + mappings[53] = EntityType.Frog; + mappings[54] = EntityType.FurnaceMinecart; + mappings[55] = EntityType.Ghast; + mappings[56] = EntityType.Giant; + mappings[57] = EntityType.GlowItemFrame; + mappings[58] = EntityType.GlowSquid; + mappings[59] = EntityType.Goat; + mappings[60] = EntityType.Guardian; + mappings[61] = EntityType.Hoglin; + mappings[62] = EntityType.HopperMinecart; + mappings[63] = EntityType.Horse; + mappings[64] = EntityType.Husk; + mappings[65] = EntityType.Illusioner; + mappings[66] = EntityType.Interaction; + mappings[67] = EntityType.IronGolem; + mappings[68] = EntityType.Item; + mappings[69] = EntityType.ItemDisplay; + mappings[70] = EntityType.ItemFrame; + mappings[71] = EntityType.JungleBoat; + mappings[72] = EntityType.JungleChestBoat; + mappings[73] = EntityType.LeashKnot; + mappings[74] = EntityType.LightningBolt; + mappings[75] = EntityType.Llama; + mappings[76] = EntityType.LlamaSpit; + mappings[77] = EntityType.MagmaCube; + mappings[78] = EntityType.MangroveBoat; + mappings[79] = EntityType.MangroveChestBoat; + mappings[80] = EntityType.Marker; + mappings[81] = EntityType.Minecart; + mappings[82] = EntityType.Mooshroom; + mappings[83] = EntityType.Mule; + mappings[84] = EntityType.OakBoat; + mappings[85] = EntityType.OakChestBoat; + mappings[86] = EntityType.Ocelot; + mappings[87] = EntityType.OminousItemSpawner; + mappings[88] = EntityType.Painting; + mappings[89] = EntityType.PaleOakBoat; + mappings[90] = EntityType.PaleOakChestBoat; + mappings[91] = EntityType.Panda; + mappings[92] = EntityType.Parrot; + mappings[93] = EntityType.Phantom; + mappings[94] = EntityType.Pig; + mappings[95] = EntityType.Piglin; + mappings[96] = EntityType.PiglinBrute; + mappings[97] = EntityType.Pillager; + mappings[98] = EntityType.PolarBear; + mappings[99] = EntityType.Potion; + mappings[100] = EntityType.Pufferfish; + mappings[101] = EntityType.Rabbit; + mappings[102] = EntityType.Ravager; + mappings[103] = EntityType.Salmon; + mappings[104] = EntityType.Sheep; + mappings[105] = EntityType.Shulker; + mappings[106] = EntityType.ShulkerBullet; + mappings[107] = EntityType.Silverfish; + mappings[108] = EntityType.Skeleton; + mappings[109] = EntityType.SkeletonHorse; + mappings[110] = EntityType.Slime; + mappings[111] = EntityType.SmallFireball; + mappings[112] = EntityType.Sniffer; + mappings[113] = EntityType.Snowball; + mappings[114] = EntityType.SnowGolem; + mappings[115] = EntityType.SpawnerMinecart; + mappings[116] = EntityType.SpectralArrow; + mappings[117] = EntityType.Spider; + mappings[118] = EntityType.SpruceBoat; + mappings[119] = EntityType.SpruceChestBoat; + mappings[120] = EntityType.Squid; + mappings[121] = EntityType.Stray; + mappings[122] = EntityType.Strider; + mappings[123] = EntityType.Tadpole; + mappings[124] = EntityType.TextDisplay; + mappings[125] = EntityType.Tnt; + mappings[126] = EntityType.TntMinecart; + mappings[127] = EntityType.TraderLlama; + mappings[128] = EntityType.Trident; + mappings[129] = EntityType.TropicalFish; + mappings[130] = EntityType.Turtle; + mappings[131] = EntityType.Vex; + mappings[132] = EntityType.Villager; + mappings[133] = EntityType.Vindicator; + mappings[134] = EntityType.WanderingTrader; + mappings[135] = EntityType.Warden; + mappings[136] = EntityType.WindCharge; + mappings[137] = EntityType.Witch; + mappings[138] = EntityType.Wither; + mappings[139] = EntityType.WitherSkeleton; + mappings[140] = EntityType.WitherSkull; + mappings[141] = EntityType.Wolf; + mappings[142] = EntityType.Zoglin; + mappings[143] = EntityType.Zombie; + mappings[144] = EntityType.ZombieHorse; + mappings[145] = EntityType.ZombieVillager; + mappings[146] = EntityType.ZombifiedPiglin; + mappings[147] = EntityType.Player; + mappings[148] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 6c932397..0f43af41 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -204,6 +204,7 @@ namespace MinecraftClient.Mapping ChiseledPolishedBlackstone, ChiseledQuartzBlock, ChiseledRedSandstone, + ChiseledResinBricks, ChiseledSandstone, ChiseledStoneBricks, ChiseledTuff, @@ -211,6 +212,7 @@ namespace MinecraftClient.Mapping ChorusFlower, ChorusPlant, Clay, + ClosedEyeblossom, CoalBlock, CoalOre, CoarseDirt, @@ -636,6 +638,7 @@ namespace MinecraftClient.Mapping Observer, Obsidian, OchreFroglight, + OpenEyeblossom, OrangeBanner, OrangeBed, OrangeCandle, @@ -752,6 +755,7 @@ namespace MinecraftClient.Mapping PottedBrownMushroom, PottedCactus, PottedCherrySapling, + PottedClosedEyeblossom, PottedCornflower, PottedCrimsonFungus, PottedCrimsonRoots, @@ -764,6 +768,7 @@ namespace MinecraftClient.Mapping PottedLilyOfTheValley, PottedMangrovePropagule, PottedOakSapling, + PottedOpenEyeblossom, PottedOrangeTulip, PottedOxeyeDaisy, PottedPaleOakSapling, @@ -851,6 +856,12 @@ namespace MinecraftClient.Mapping ReinforcedDeepslate, Repeater, RepeatingCommandBlock, + ResinBlock, + ResinBrickSlab, + ResinBrickStairs, + ResinBrickWall, + ResinBricks, + ResinClump, RespawnAnchor, RootedDirt, RoseBush, diff --git a/MinecraftClient/Mapping/MaterialExtensions.cs b/MinecraftClient/Mapping/MaterialExtensions.cs index 2e62d695..5d2fe06d 100644 --- a/MinecraftClient/Mapping/MaterialExtensions.cs +++ b/MinecraftClient/Mapping/MaterialExtensions.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Mapping +namespace MinecraftClient.Mapping { /// /// Defines extension methods for the Material enumeration @@ -122,6 +122,7 @@ case Material.ChiseledPolishedBlackstone: case Material.ChiseledQuartzBlock: case Material.ChiseledRedSandstone: + case Material.ChiseledResinBricks: case Material.ChiseledSandstone: case Material.ChiseledStoneBricks: case Material.ChorusFlower: @@ -500,6 +501,8 @@ case Material.PottedBlueOrchid: case Material.PottedBrownMushroom: case Material.PottedCactus: + case Material.PottedCherrySapling: + case Material.PottedClosedEyeblossom: case Material.PottedCornflower: case Material.PottedDandelion: case Material.PottedDarkOakSapling: @@ -509,6 +512,7 @@ case Material.PottedJungleSapling: case Material.PottedLilyOfTheValley: case Material.PottedOakSapling: + case Material.PottedOpenEyeblossom: case Material.PottedOrangeTulip: case Material.PottedOxeyeDaisy: case Material.PottedPinkTulip: @@ -576,6 +580,10 @@ case Material.RedWool: case Material.ReinforcedDeepslate: case Material.RepeatingCommandBlock: + case Material.ResinBlock: + case Material.ResinBrickStairs: + case Material.ResinBrickWall: + case Material.ResinBricks: case Material.RespawnAnchor: case Material.RootedDirt: case Material.Sand: @@ -868,6 +876,7 @@ case Material.QuartzSlab: case Material.RedNetherBrickSlab: case Material.RedSandstoneSlab: + case Material.ResinBrickSlab: case Material.SandstoneSlab: case Material.SmoothQuartzSlab: case Material.SmoothRedSandstoneSlab: diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs new file mode 100644 index 00000000..810b3479 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs @@ -0,0 +1,245 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1214 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.SpawnExperienceOrb }, // Add Experience Orb + { 0x03, PacketTypesIn.EntityAnimation }, // Animate + { 0x04, PacketTypesIn.Statistics }, // Award Stats + { 0x05, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x06, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x07, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x08, PacketTypesIn.BlockAction }, // Block Event + { 0x09, PacketTypesIn.BlockChange }, // Block Update + { 0x0A, PacketTypesIn.BossBar }, // Boss Event + { 0x0B, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0C, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0D, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0E, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0F, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x10, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x11, PacketTypesIn.DeclareCommands }, // Commands + { 0x12, PacketTypesIn.CloseWindow }, // Container Close + { 0x13, PacketTypesIn.WindowItems }, // Container Set Content + { 0x14, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x15, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x16, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x17, PacketTypesIn.SetCooldown }, // Cooldown + { 0x18, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x19, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x1A, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1B, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1C, PacketTypesIn.HideMessage }, // Delete Chat + { 0x1D, PacketTypesIn.Disconnect }, // Disconnect + { 0x1E, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x1F, PacketTypesIn.EntityStatus }, // Entity Event + { 0x20, PacketTypesIn.EntityPositionSync }, // Entity Position Sync (new in 1.21.2) + { 0x21, PacketTypesIn.Explosion }, // Explode + { 0x22, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x23, PacketTypesIn.ChangeGameState }, // Game Event + { 0x24, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open + { 0x25, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x26, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x27, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x28, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x29, PacketTypesIn.Effect }, // Level Event + { 0x2A, PacketTypesIn.Particle }, // Level Particles + { 0x2B, PacketTypesIn.UpdateLight }, // Light Update + { 0x2C, PacketTypesIn.JoinGame }, // Login + { 0x2D, PacketTypesIn.MapData }, // Map Item Data + { 0x2E, PacketTypesIn.TradeList }, // Merchant Offers + { 0x2F, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x30, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x31, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track (new in 1.21.2) + { 0x32, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x33, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x34, PacketTypesIn.OpenBook }, // Open Book + { 0x35, PacketTypesIn.OpenWindow }, // Open Screen + { 0x36, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x37, PacketTypesIn.Ping }, // Ping + { 0x38, PacketTypesIn.PingResponse }, // Pong Response + { 0x39, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x3A, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x3B, PacketTypesIn.ChatMessage }, // Player Chat + { 0x3C, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x3D, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x3E, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x3F, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x40, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x41, PacketTypesIn.FacePlayer }, // Player Look At + { 0x42, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x43, PacketTypesIn.PlayerRotation }, // Player Rotation (new in 1.21.2) + { 0x44, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add (new in 1.21.2, replaces UnlockRecipes) + { 0x45, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove (new in 1.21.2) + { 0x46, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings (new in 1.21.2) + { 0x47, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x48, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x49, PacketTypesIn.ResetScore }, // Reset Score + { 0x4A, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x4B, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x4C, PacketTypesIn.Respawn }, // Respawn + { 0x4D, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x4E, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x4F, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x50, PacketTypesIn.ServerData }, // Server Data + { 0x51, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x52, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x53, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x54, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x55, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x56, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x57, PacketTypesIn.Camera }, // Set Camera + { 0x58, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x59, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x5A, PacketTypesIn.SetCursorItem }, // Set Cursor Item (new in 1.21.2) + { 0x5B, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x5C, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x5D, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x5E, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x5F, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x60, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x61, PacketTypesIn.SetExperience }, // Set Experience + { 0x62, PacketTypesIn.UpdateHealth }, // Set Health + { 0x63, PacketTypesIn.SetHeldSlot }, // Set Held Slot (new in 1.21.2, replaces HeldItemChange) + { 0x64, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x65, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x66, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory (new in 1.21.2) + { 0x67, PacketTypesIn.Teams }, // Set Player Team + { 0x68, PacketTypesIn.UpdateScore }, // Set Score + { 0x69, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x6A, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x6B, PacketTypesIn.TimeUpdate }, // Set Time + { 0x6C, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x6D, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x6E, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x6F, PacketTypesIn.SoundEffect }, // Sound + { 0x70, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x71, PacketTypesIn.StopSound }, // Stop Sound + { 0x72, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x73, PacketTypesIn.SystemChat }, // System Chat + { 0x74, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x75, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x76, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x77, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x78, PacketTypesIn.SetTickingState }, // Ticking State + { 0x79, PacketTypesIn.StepTick }, // Ticking Step + { 0x7A, PacketTypesIn.Transfer }, // Transfer + { 0x7B, PacketTypesIn.Advancements }, // Update Advancements + { 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x7F, PacketTypesIn.Tags }, // Update Tags + { 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x82, PacketTypesIn.ServerLinks } // Server Links + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected + { 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x05, PacketTypesOut.ChatCommand }, // Chat Command + { 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x07, PacketTypesOut.ChatMessage }, // Chat + { 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0A, PacketTypesOut.ClientStatus }, // Client Command + { 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End + { 0x0C, PacketTypesOut.ClientSettings }, // Client Information + { 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x10, PacketTypesOut.ClickWindow }, // Container Click + { 0x11, PacketTypesOut.CloseWindow }, // Container Close + { 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x13, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x14, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription + { 0x16, PacketTypesOut.EditBook }, // Edit Book + { 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x18, PacketTypesOut.InteractEntity }, // Interact + { 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x22, PacketTypesOut.PickItem }, // Pick Item From Block (split in 1.21.4) + { 0x23, PacketTypesOut.PickItem }, // Pick Item From Entity (split in 1.21.4) + { 0x24, PacketTypesOut.PingRequest }, // Ping Request + { 0x25, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x26, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x27, PacketTypesOut.PlayerDigging }, // Player Action + { 0x28, PacketTypesOut.EntityAction }, // Player Command + { 0x29, PacketTypesOut.SteerVehicle }, // Player Input + { 0x2A, PacketTypesOut.PlayerLoaded }, // Player Loaded (new in 1.21.4) + { 0x2B, PacketTypesOut.Pong }, // Pong + { 0x2C, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2D, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x2E, PacketTypesOut.NameItem }, // Rename Item + { 0x2F, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x30, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x31, PacketTypesOut.SelectTrade }, // Select Trade + { 0x32, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x33, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x34, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x35, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x36, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x37, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x38, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x39, PacketTypesOut.UpdateSign }, // Sign Update + { 0x3A, PacketTypesOut.Animation }, // Swing + { 0x3B, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x3C, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x3D, PacketTypesOut.UseItem }, // Use Item + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks } + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 9141627b..c03ade1b 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_2_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_4_Version => throw new NotImplementedException(Translations .exception_palette_packet), + <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), <= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(), <= Protocol18Handler.MC_1_12_Version => new PacketPalette112(), diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index 9512024a..bba5910f 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -41,6 +41,7 @@ namespace MinecraftClient.Protocol.Handlers PlayerAbilities, // PlayerBlockPlacement, // PlayerDigging, // + PlayerLoaded, // Added in 1.21.4 PlayerMovement, // PlayerPosition, // PlayerPositionAndRotation, // diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 3ef61f97..b2393fa9 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -74,6 +74,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_20_6_Version = 766; internal const int MC_1_21_Version = 767; internal const int MC_1_21_2_Version = 768; + internal const int MC_1_21_4_Version = 769; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -125,21 +126,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_2_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_4_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_2_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_4_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_2_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_4_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -148,8 +149,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_2_Version when handler.GetTerrainEnabled() => + > MC_1_21_4_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + >= MC_1_21_4_Version => new Palette1214(), >= MC_1_21_2_Version => new Palette1212(), >= MC_1_20_6_Version => new Palette1206(), >= MC_1_20_4_Version => new Palette1204(), @@ -168,8 +170,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_2_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_4_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_1_21_4_Version => new EntityPalette1214(), >= MC_1_21_2_Version => new EntityPalette1212(), >= MC_1_20_6_Version => new EntityPalette1206(), >= MC_1_20_4_Version => new EntityPalette1204(), @@ -192,8 +195,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_2_Version when handler.GetInventoryEnabled() => + > MC_1_21_4_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_4_Version => new ItemPalette1214(), >= MC_1_21_2_Version => new ItemPalette1212(), >= MC_1_21_Version => new ItemPalette121(), >= MC_1_20_6_Version => new ItemPalette1206(), @@ -877,6 +881,10 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_20_6_Version) dataTypes.ReadNextBool(packetData); // Enforoces Secure Chat } + + if (protocolVersion >= MC_1_21_4_Version) + SendPacket(PacketTypesOut.PlayerLoaded, new List()); + break; case PacketTypesIn.SpawnPainting: // Just skip, no need for this return true; @@ -2623,7 +2631,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_2_Version => throw new NotImplementedException(Translations + > MC_1_21_4_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 6ac6ca24..aba121fa 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -153,7 +153,8 @@ namespace MinecraftClient.Protocol int[] suppoertedVersionsProtocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, - 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768 + 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, + 769 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -353,6 +354,10 @@ namespace MinecraftClient.Protocol return 767; case "1.21.2": return 768; + case "1.21.3": + return 768; + case "1.21.4": + return 769; default: return 0; } @@ -435,6 +440,7 @@ namespace MinecraftClient.Protocol 766 => "1.20.6", 767 => "1.21", 768 => "1.21.2", + 769 => "1.21.4", _ => "0.0" }; } From 067bd8faffcb1864aaf348c41ff56e827e4b8449 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 23:55:27 +0800 Subject: [PATCH 058/484] fix: resolve PickItem duplicate key in PacketPalette1214 The PickItem packet was split into PickItemFromBlock (0x22) and PickItemFromEntity (0x23) in 1.21.4. Mapping both to the same PacketTypesOut.PickItem enum caused a duplicate key error in the reverse mapping. Added PickItemFromEntity enum to resolve this. Made-with: Cursor --- .../Protocol/Handlers/PacketPalettes/PacketPalette1214.cs | 2 +- MinecraftClient/Protocol/Handlers/PacketTypesOut.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs index 810b3479..8ab00e22 100644 --- a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1214.cs @@ -176,7 +176,7 @@ public class PacketPalette1214 : PacketTypePalette { 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle { 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat { 0x22, PacketTypesOut.PickItem }, // Pick Item From Block (split in 1.21.4) - { 0x23, PacketTypesOut.PickItem }, // Pick Item From Entity (split in 1.21.4) + { 0x23, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity (new in 1.21.4) { 0x24, PacketTypesOut.PingRequest }, // Ping Request { 0x25, PacketTypesOut.CraftRecipeRequest }, // Place Recipe { 0x26, PacketTypesOut.PlayerAbilities }, // Player Abilities diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index bba5910f..a93ea13b 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -37,6 +37,7 @@ namespace MinecraftClient.Protocol.Handlers MessageAcknowledgment, // Added in 1.19.1 (1.19.2) NameItem, // PickItem, // + PickItemFromEntity, // Added in 1.21.4 (split from PickItem) PingRequest, // Added in 1.20.2 PlayerAbilities, // PlayerBlockPlacement, // From c31739ddd1c266de0fa5d3c00dfbab2232bd0379 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 20 Mar 2026 23:59:06 +0800 Subject: [PATCH 059/484] chore: update .gitignore to include Minecraft official source code directory Added a new entry to the .gitignore file to exclude the directory for decompiled Minecraft official source code. Also ensured that the .vscode/launch.json file is not ignored. Made-with: Cursor --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2ebfd2d8..1c8d8eb1 100644 --- a/.gitignore +++ b/.gitignore @@ -383,7 +383,7 @@ FodyWeavers.xsd .vscode/* !.vscode/settings.json !.vscode/tasks.json -!.vscode/launch.json +!.vscode/launch.json`` !.vscode/extensions.json *.code-workspace @@ -419,3 +419,6 @@ FodyWeavers.xsd /docs/l10n/ /docs/.vuepress/public/MCC-README/ + +# Floder to store the decompiled Minecraft official source code +MinecraftOfficial/ From 9c1502600a4eaba3d898490651e72ec3962b3004 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 00:09:58 +0800 Subject: [PATCH 060/484] chore: update .gitignore to include additional debug files Added entries to the .gitignore file to exclude possible debug files related to Minecraft, including language files, input configurations, and backup files. Made-with: Cursor --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 1c8d8eb1..6a75425a 100644 --- a/.gitignore +++ b/.gitignore @@ -422,3 +422,9 @@ FodyWeavers.xsd # Floder to store the decompiled Minecraft official source code MinecraftOfficial/ + +# Possible debug files +/lang/* +/mcc_input.txt +/MinecraftClient.ini +/MinecraftClient.backup.ini From 8df39ba74a801a181a9c519099fc051acb0405a8 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 00:48:27 +0800 Subject: [PATCH 061/484] feat: add MC 1.21.5 (protocol 770) support Full protocol adaptation for Minecraft 1.21.5: - Protocol version mapping: 770 -> 1.21.5 - Packet palette: AddExperienceOrb removed (S2C), TestInstanceBlockStatus added (S2C), SetTestBlock and TestInstanceBlockAction added (C2S) - Entity metadata palette: 5 new serializer types (OptionalLivingEntityReference, CowVariant, WolfSoundVariant, PigVariant, ChickenVariant), OPTIONAL_UUID replaced by OPTIONAL_LIVING_ENTITY_REFERENCE - Item palette: 11 new items (Bush, FireflyBush, DryShortGrass, DryTallGrass, Wildflowers, LeafLitter, CactusFlower, TestBlock, TestInstanceBlock, BlueEgg, BrownEgg) - Entity palette: Potion split into SplashPotion and LingeringPotion - Block palette: 9 new blocks (bush, cactus_flower, firefly_bush, leaf_litter, short_dry_grass, tall_dry_grass, test_block, test_instance_block, wildflowers) - Structured components: 31 new components including tooltip_display, weapon, blocks_attacks, potion_duration_scale, provides_trim_material, provides_banner_patterns, break_sound, and 25 entity variant components; unbreakable changed from Bool to Unit; instrument changed to EitherHolder Made-with: Cursor --- MinecraftClient/Commands/Entitycmd.cs | 6 +- .../Inventory/ItemPalettes/ItemPalette1215.cs | 1414 +++++++++++++ MinecraftClient/Inventory/ItemType.cs | 11 + .../Mapping/BlockPalettes/Palette1215.cs | 1838 +++++++++++++++++ MinecraftClient/Mapping/EntityMetaDataType.cs | 20 + .../Mapping/EntityMetadataPalette.cs | 1 + .../EntityMetadataPalette1215.cs | 50 + .../EntityPalettes/EntityPalette1215.cs | 168 ++ MinecraftClient/Mapping/EntityType.cs | 2 + .../Mapping/EntityTypeExtensions.cs | 4 +- MinecraftClient/Mapping/Material.cs | 9 + .../Protocol/Handlers/DataTypes.cs | 5 + .../PacketPalettes/PacketPalette1215.cs | 247 +++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- .../Protocol/Handlers/PacketTypesIn.cs | 1 + .../Protocol/Handlers/PacketTypesOut.cs | 2 + .../Protocol/Handlers/Protocol18.cs | 18 +- .../1_21_5/BlocksAttacksComponent.cs | 83 + .../1_21_5/EitherHolderComponent.cs | 51 + .../1_21_5/InstrumentComponent1215.cs | 43 + .../1_21_5/PaintingVariantHolderComponent.cs | 35 + .../1_21_5/PotionDurationScaleComponent.cs | 23 + .../1_21_5/ProvidesBannerPatternsComponent.cs | 23 + .../1_21_5/ProvidesTrimMaterialComponent.cs | 42 + .../1_21_5/SoundEventHolderComponent.cs | 40 + .../1_21_5/TooltipDisplayComponent.cs | 30 + .../Components/1_21_5/VarIntComponent.cs | 23 + .../Components/1_21_5/WeaponComponent.cs | 26 + .../StructuredComponentsRegistry1215.cs | 116 ++ .../StructuredComponentsHandler.cs | 2 + MinecraftClient/Protocol/ProtocolHandler.cs | 5 +- scripts/gen_palette_1214.py | 112 + tools/gen_entity_metadata_palette.py | 5 + 33 files changed, 4445 insertions(+), 13 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1215.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1215.cs create mode 100644 MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1215.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1215.cs create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1215.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/BlocksAttacksComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EitherHolderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/InstrumentComponent1215.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PaintingVariantHolderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PotionDurationScaleComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesBannerPatternsComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesTrimMaterialComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/SoundEventHolderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/TooltipDisplayComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/VarIntComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/WeaponComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs create mode 100644 scripts/gen_palette_1214.py diff --git a/MinecraftClient/Commands/Entitycmd.cs b/MinecraftClient/Commands/Entitycmd.cs index 258227cd..e9935a80 100644 --- a/MinecraftClient/Commands/Entitycmd.cs +++ b/MinecraftClient/Commands/Entitycmd.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -210,7 +210,7 @@ namespace MinecraftClient.Commands Item item = entity.Item; string location = $"X:{Math.Round(entity.Location.X, 2)}, Y:{Math.Round(entity.Location.Y, 2)}, Z:{Math.Round(entity.Location.Z, 2)}"; - if (type == EntityType.Item || type == EntityType.ItemFrame || type == EntityType.EyeOfEnder || type == EntityType.Egg || type == EntityType.EnderPearl || type == EntityType.Potion || type == EntityType.Fireball || type == EntityType.FireworkRocket) + if (type == EntityType.Item || type == EntityType.ItemFrame || type == EntityType.EyeOfEnder || type == EntityType.Egg || type == EntityType.EnderPearl || type == EntityType.Potion || type == EntityType.SplashPotion || type == EntityType.LingeringPotion || type == EntityType.Fireball || type == EntityType.FireworkRocket) return $" #{id}: {Translations.cmd_entityCmd_type}: {entity.GetTypeString()}, {Translations.cmd_entityCmd_item}: {item.GetTypeString()}, {Translations.cmd_entityCmd_location}: {location}"; else if (type == EntityType.Player && !string.IsNullOrEmpty(nickname)) return $" #{id}: {Translations.cmd_entityCmd_type}: {entity.GetTypeString()}, {Translations.cmd_entityCmd_nickname}: §8{nickname}§8, {Translations.cmd_entityCmd_latency}: {latency}, {Translations.cmd_entityCmd_health}: {health}, {Translations.cmd_entityCmd_pose}: {pose}, {Translations.cmd_entityCmd_location}: {location}"; @@ -251,7 +251,7 @@ namespace MinecraftClient.Commands { sb.Append($"\n [MCC] {Translations.cmd_entityCmd_latency}: {latency}"); } - else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket) + else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.SplashPotion || type == Mapping.EntityType.LingeringPotion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket) { string? displayName = item.DisplayName; if (string.IsNullOrEmpty(displayName)) diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1215.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1215.cs new file mode 100644 index 00000000..19795e50 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1215.cs @@ -0,0 +1,1414 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1215 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1215() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.DryShortGrass; + mappings[210] = ItemType.DryTallGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.OpenEyeblossom; + mappings[231] = ItemType.ClosedEyeblossom; + mappings[232] = ItemType.Poppy; + mappings[233] = ItemType.BlueOrchid; + mappings[234] = ItemType.Allium; + mappings[235] = ItemType.AzureBluet; + mappings[236] = ItemType.RedTulip; + mappings[237] = ItemType.OrangeTulip; + mappings[238] = ItemType.WhiteTulip; + mappings[239] = ItemType.PinkTulip; + mappings[240] = ItemType.OxeyeDaisy; + mappings[241] = ItemType.Cornflower; + mappings[242] = ItemType.LilyOfTheValley; + mappings[243] = ItemType.WitherRose; + mappings[244] = ItemType.Torchflower; + mappings[245] = ItemType.PitcherPlant; + mappings[246] = ItemType.SporeBlossom; + mappings[247] = ItemType.BrownMushroom; + mappings[248] = ItemType.RedMushroom; + mappings[249] = ItemType.CrimsonFungus; + mappings[250] = ItemType.WarpedFungus; + mappings[251] = ItemType.CrimsonRoots; + mappings[252] = ItemType.WarpedRoots; + mappings[253] = ItemType.NetherSprouts; + mappings[254] = ItemType.WeepingVines; + mappings[255] = ItemType.TwistingVines; + mappings[256] = ItemType.SugarCane; + mappings[257] = ItemType.Kelp; + mappings[258] = ItemType.PinkPetals; + mappings[259] = ItemType.Wildflowers; + mappings[260] = ItemType.LeafLitter; + mappings[261] = ItemType.MossCarpet; + mappings[262] = ItemType.MossBlock; + mappings[263] = ItemType.PaleMossCarpet; + mappings[264] = ItemType.PaleHangingMoss; + mappings[265] = ItemType.PaleMossBlock; + mappings[266] = ItemType.HangingRoots; + mappings[267] = ItemType.BigDripleaf; + mappings[268] = ItemType.SmallDripleaf; + mappings[269] = ItemType.Bamboo; + mappings[270] = ItemType.OakSlab; + mappings[271] = ItemType.SpruceSlab; + mappings[272] = ItemType.BirchSlab; + mappings[273] = ItemType.JungleSlab; + mappings[274] = ItemType.AcaciaSlab; + mappings[275] = ItemType.CherrySlab; + mappings[276] = ItemType.DarkOakSlab; + mappings[277] = ItemType.PaleOakSlab; + mappings[278] = ItemType.MangroveSlab; + mappings[279] = ItemType.BambooSlab; + mappings[280] = ItemType.BambooMosaicSlab; + mappings[281] = ItemType.CrimsonSlab; + mappings[282] = ItemType.WarpedSlab; + mappings[283] = ItemType.StoneSlab; + mappings[284] = ItemType.SmoothStoneSlab; + mappings[285] = ItemType.SandstoneSlab; + mappings[286] = ItemType.CutSandstoneSlab; + mappings[287] = ItemType.PetrifiedOakSlab; + mappings[288] = ItemType.CobblestoneSlab; + mappings[289] = ItemType.BrickSlab; + mappings[290] = ItemType.StoneBrickSlab; + mappings[291] = ItemType.MudBrickSlab; + mappings[292] = ItemType.NetherBrickSlab; + mappings[293] = ItemType.QuartzSlab; + mappings[294] = ItemType.RedSandstoneSlab; + mappings[295] = ItemType.CutRedSandstoneSlab; + mappings[296] = ItemType.PurpurSlab; + mappings[297] = ItemType.PrismarineSlab; + mappings[298] = ItemType.PrismarineBrickSlab; + mappings[299] = ItemType.DarkPrismarineSlab; + mappings[300] = ItemType.SmoothQuartz; + mappings[301] = ItemType.SmoothRedSandstone; + mappings[302] = ItemType.SmoothSandstone; + mappings[303] = ItemType.SmoothStone; + mappings[304] = ItemType.Bricks; + mappings[305] = ItemType.Bookshelf; + mappings[306] = ItemType.ChiseledBookshelf; + mappings[307] = ItemType.DecoratedPot; + mappings[308] = ItemType.MossyCobblestone; + mappings[309] = ItemType.Obsidian; + mappings[310] = ItemType.Torch; + mappings[311] = ItemType.EndRod; + mappings[312] = ItemType.ChorusPlant; + mappings[313] = ItemType.ChorusFlower; + mappings[314] = ItemType.PurpurBlock; + mappings[315] = ItemType.PurpurPillar; + mappings[316] = ItemType.PurpurStairs; + mappings[317] = ItemType.Spawner; + mappings[318] = ItemType.CreakingHeart; + mappings[319] = ItemType.Chest; + mappings[320] = ItemType.CraftingTable; + mappings[321] = ItemType.Farmland; + mappings[322] = ItemType.Furnace; + mappings[323] = ItemType.Ladder; + mappings[324] = ItemType.CobblestoneStairs; + mappings[325] = ItemType.Snow; + mappings[326] = ItemType.Ice; + mappings[327] = ItemType.SnowBlock; + mappings[328] = ItemType.Cactus; + mappings[329] = ItemType.CactusFlower; + mappings[330] = ItemType.Clay; + mappings[331] = ItemType.Jukebox; + mappings[332] = ItemType.OakFence; + mappings[333] = ItemType.SpruceFence; + mappings[334] = ItemType.BirchFence; + mappings[335] = ItemType.JungleFence; + mappings[336] = ItemType.AcaciaFence; + mappings[337] = ItemType.CherryFence; + mappings[338] = ItemType.DarkOakFence; + mappings[339] = ItemType.PaleOakFence; + mappings[340] = ItemType.MangroveFence; + mappings[341] = ItemType.BambooFence; + mappings[342] = ItemType.CrimsonFence; + mappings[343] = ItemType.WarpedFence; + mappings[344] = ItemType.Pumpkin; + mappings[345] = ItemType.CarvedPumpkin; + mappings[346] = ItemType.JackOLantern; + mappings[347] = ItemType.Netherrack; + mappings[348] = ItemType.SoulSand; + mappings[349] = ItemType.SoulSoil; + mappings[350] = ItemType.Basalt; + mappings[351] = ItemType.PolishedBasalt; + mappings[352] = ItemType.SmoothBasalt; + mappings[353] = ItemType.SoulTorch; + mappings[354] = ItemType.Glowstone; + mappings[355] = ItemType.InfestedStone; + mappings[356] = ItemType.InfestedCobblestone; + mappings[357] = ItemType.InfestedStoneBricks; + mappings[358] = ItemType.InfestedMossyStoneBricks; + mappings[359] = ItemType.InfestedCrackedStoneBricks; + mappings[360] = ItemType.InfestedChiseledStoneBricks; + mappings[361] = ItemType.InfestedDeepslate; + mappings[362] = ItemType.StoneBricks; + mappings[363] = ItemType.MossyStoneBricks; + mappings[364] = ItemType.CrackedStoneBricks; + mappings[365] = ItemType.ChiseledStoneBricks; + mappings[366] = ItemType.PackedMud; + mappings[367] = ItemType.MudBricks; + mappings[368] = ItemType.DeepslateBricks; + mappings[369] = ItemType.CrackedDeepslateBricks; + mappings[370] = ItemType.DeepslateTiles; + mappings[371] = ItemType.CrackedDeepslateTiles; + mappings[372] = ItemType.ChiseledDeepslate; + mappings[373] = ItemType.ReinforcedDeepslate; + mappings[374] = ItemType.BrownMushroomBlock; + mappings[375] = ItemType.RedMushroomBlock; + mappings[376] = ItemType.MushroomStem; + mappings[377] = ItemType.IronBars; + mappings[378] = ItemType.Chain; + mappings[379] = ItemType.GlassPane; + mappings[380] = ItemType.Melon; + mappings[381] = ItemType.Vine; + mappings[382] = ItemType.GlowLichen; + mappings[383] = ItemType.ResinClump; + mappings[384] = ItemType.ResinBlock; + mappings[385] = ItemType.ResinBricks; + mappings[386] = ItemType.ResinBrickStairs; + mappings[387] = ItemType.ResinBrickSlab; + mappings[388] = ItemType.ResinBrickWall; + mappings[389] = ItemType.ChiseledResinBricks; + mappings[390] = ItemType.BrickStairs; + mappings[391] = ItemType.StoneBrickStairs; + mappings[392] = ItemType.MudBrickStairs; + mappings[393] = ItemType.Mycelium; + mappings[394] = ItemType.LilyPad; + mappings[395] = ItemType.NetherBricks; + mappings[396] = ItemType.CrackedNetherBricks; + mappings[397] = ItemType.ChiseledNetherBricks; + mappings[398] = ItemType.NetherBrickFence; + mappings[399] = ItemType.NetherBrickStairs; + mappings[400] = ItemType.Sculk; + mappings[401] = ItemType.SculkVein; + mappings[402] = ItemType.SculkCatalyst; + mappings[403] = ItemType.SculkShrieker; + mappings[404] = ItemType.EnchantingTable; + mappings[405] = ItemType.EndPortalFrame; + mappings[406] = ItemType.EndStone; + mappings[407] = ItemType.EndStoneBricks; + mappings[408] = ItemType.DragonEgg; + mappings[409] = ItemType.SandstoneStairs; + mappings[410] = ItemType.EnderChest; + mappings[411] = ItemType.EmeraldBlock; + mappings[412] = ItemType.OakStairs; + mappings[413] = ItemType.SpruceStairs; + mappings[414] = ItemType.BirchStairs; + mappings[415] = ItemType.JungleStairs; + mappings[416] = ItemType.AcaciaStairs; + mappings[417] = ItemType.CherryStairs; + mappings[418] = ItemType.DarkOakStairs; + mappings[419] = ItemType.PaleOakStairs; + mappings[420] = ItemType.MangroveStairs; + mappings[421] = ItemType.BambooStairs; + mappings[422] = ItemType.BambooMosaicStairs; + mappings[423] = ItemType.CrimsonStairs; + mappings[424] = ItemType.WarpedStairs; + mappings[425] = ItemType.CommandBlock; + mappings[426] = ItemType.Beacon; + mappings[427] = ItemType.CobblestoneWall; + mappings[428] = ItemType.MossyCobblestoneWall; + mappings[429] = ItemType.BrickWall; + mappings[430] = ItemType.PrismarineWall; + mappings[431] = ItemType.RedSandstoneWall; + mappings[432] = ItemType.MossyStoneBrickWall; + mappings[433] = ItemType.GraniteWall; + mappings[434] = ItemType.StoneBrickWall; + mappings[435] = ItemType.MudBrickWall; + mappings[436] = ItemType.NetherBrickWall; + mappings[437] = ItemType.AndesiteWall; + mappings[438] = ItemType.RedNetherBrickWall; + mappings[439] = ItemType.SandstoneWall; + mappings[440] = ItemType.EndStoneBrickWall; + mappings[441] = ItemType.DioriteWall; + mappings[442] = ItemType.BlackstoneWall; + mappings[443] = ItemType.PolishedBlackstoneWall; + mappings[444] = ItemType.PolishedBlackstoneBrickWall; + mappings[445] = ItemType.CobbledDeepslateWall; + mappings[446] = ItemType.PolishedDeepslateWall; + mappings[447] = ItemType.DeepslateBrickWall; + mappings[448] = ItemType.DeepslateTileWall; + mappings[449] = ItemType.Anvil; + mappings[450] = ItemType.ChippedAnvil; + mappings[451] = ItemType.DamagedAnvil; + mappings[452] = ItemType.ChiseledQuartzBlock; + mappings[453] = ItemType.QuartzBlock; + mappings[454] = ItemType.QuartzBricks; + mappings[455] = ItemType.QuartzPillar; + mappings[456] = ItemType.QuartzStairs; + mappings[457] = ItemType.WhiteTerracotta; + mappings[458] = ItemType.OrangeTerracotta; + mappings[459] = ItemType.MagentaTerracotta; + mappings[460] = ItemType.LightBlueTerracotta; + mappings[461] = ItemType.YellowTerracotta; + mappings[462] = ItemType.LimeTerracotta; + mappings[463] = ItemType.PinkTerracotta; + mappings[464] = ItemType.GrayTerracotta; + mappings[465] = ItemType.LightGrayTerracotta; + mappings[466] = ItemType.CyanTerracotta; + mappings[467] = ItemType.PurpleTerracotta; + mappings[468] = ItemType.BlueTerracotta; + mappings[469] = ItemType.BrownTerracotta; + mappings[470] = ItemType.GreenTerracotta; + mappings[471] = ItemType.RedTerracotta; + mappings[472] = ItemType.BlackTerracotta; + mappings[473] = ItemType.Barrier; + mappings[474] = ItemType.Light; + mappings[475] = ItemType.HayBlock; + mappings[476] = ItemType.WhiteCarpet; + mappings[477] = ItemType.OrangeCarpet; + mappings[478] = ItemType.MagentaCarpet; + mappings[479] = ItemType.LightBlueCarpet; + mappings[480] = ItemType.YellowCarpet; + mappings[481] = ItemType.LimeCarpet; + mappings[482] = ItemType.PinkCarpet; + mappings[483] = ItemType.GrayCarpet; + mappings[484] = ItemType.LightGrayCarpet; + mappings[485] = ItemType.CyanCarpet; + mappings[486] = ItemType.PurpleCarpet; + mappings[487] = ItemType.BlueCarpet; + mappings[488] = ItemType.BrownCarpet; + mappings[489] = ItemType.GreenCarpet; + mappings[490] = ItemType.RedCarpet; + mappings[491] = ItemType.BlackCarpet; + mappings[492] = ItemType.Terracotta; + mappings[493] = ItemType.PackedIce; + mappings[494] = ItemType.DirtPath; + mappings[495] = ItemType.Sunflower; + mappings[496] = ItemType.Lilac; + mappings[497] = ItemType.RoseBush; + mappings[498] = ItemType.Peony; + mappings[499] = ItemType.TallGrass; + mappings[500] = ItemType.LargeFern; + mappings[501] = ItemType.WhiteStainedGlass; + mappings[502] = ItemType.OrangeStainedGlass; + mappings[503] = ItemType.MagentaStainedGlass; + mappings[504] = ItemType.LightBlueStainedGlass; + mappings[505] = ItemType.YellowStainedGlass; + mappings[506] = ItemType.LimeStainedGlass; + mappings[507] = ItemType.PinkStainedGlass; + mappings[508] = ItemType.GrayStainedGlass; + mappings[509] = ItemType.LightGrayStainedGlass; + mappings[510] = ItemType.CyanStainedGlass; + mappings[511] = ItemType.PurpleStainedGlass; + mappings[512] = ItemType.BlueStainedGlass; + mappings[513] = ItemType.BrownStainedGlass; + mappings[514] = ItemType.GreenStainedGlass; + mappings[515] = ItemType.RedStainedGlass; + mappings[516] = ItemType.BlackStainedGlass; + mappings[517] = ItemType.WhiteStainedGlassPane; + mappings[518] = ItemType.OrangeStainedGlassPane; + mappings[519] = ItemType.MagentaStainedGlassPane; + mappings[520] = ItemType.LightBlueStainedGlassPane; + mappings[521] = ItemType.YellowStainedGlassPane; + mappings[522] = ItemType.LimeStainedGlassPane; + mappings[523] = ItemType.PinkStainedGlassPane; + mappings[524] = ItemType.GrayStainedGlassPane; + mappings[525] = ItemType.LightGrayStainedGlassPane; + mappings[526] = ItemType.CyanStainedGlassPane; + mappings[527] = ItemType.PurpleStainedGlassPane; + mappings[528] = ItemType.BlueStainedGlassPane; + mappings[529] = ItemType.BrownStainedGlassPane; + mappings[530] = ItemType.GreenStainedGlassPane; + mappings[531] = ItemType.RedStainedGlassPane; + mappings[532] = ItemType.BlackStainedGlassPane; + mappings[533] = ItemType.Prismarine; + mappings[534] = ItemType.PrismarineBricks; + mappings[535] = ItemType.DarkPrismarine; + mappings[536] = ItemType.PrismarineStairs; + mappings[537] = ItemType.PrismarineBrickStairs; + mappings[538] = ItemType.DarkPrismarineStairs; + mappings[539] = ItemType.SeaLantern; + mappings[540] = ItemType.RedSandstone; + mappings[541] = ItemType.ChiseledRedSandstone; + mappings[542] = ItemType.CutRedSandstone; + mappings[543] = ItemType.RedSandstoneStairs; + mappings[544] = ItemType.RepeatingCommandBlock; + mappings[545] = ItemType.ChainCommandBlock; + mappings[546] = ItemType.MagmaBlock; + mappings[547] = ItemType.NetherWartBlock; + mappings[548] = ItemType.WarpedWartBlock; + mappings[549] = ItemType.RedNetherBricks; + mappings[550] = ItemType.BoneBlock; + mappings[551] = ItemType.StructureVoid; + mappings[552] = ItemType.ShulkerBox; + mappings[553] = ItemType.WhiteShulkerBox; + mappings[554] = ItemType.OrangeShulkerBox; + mappings[555] = ItemType.MagentaShulkerBox; + mappings[556] = ItemType.LightBlueShulkerBox; + mappings[557] = ItemType.YellowShulkerBox; + mappings[558] = ItemType.LimeShulkerBox; + mappings[559] = ItemType.PinkShulkerBox; + mappings[560] = ItemType.GrayShulkerBox; + mappings[561] = ItemType.LightGrayShulkerBox; + mappings[562] = ItemType.CyanShulkerBox; + mappings[563] = ItemType.PurpleShulkerBox; + mappings[564] = ItemType.BlueShulkerBox; + mappings[565] = ItemType.BrownShulkerBox; + mappings[566] = ItemType.GreenShulkerBox; + mappings[567] = ItemType.RedShulkerBox; + mappings[568] = ItemType.BlackShulkerBox; + mappings[569] = ItemType.WhiteGlazedTerracotta; + mappings[570] = ItemType.OrangeGlazedTerracotta; + mappings[571] = ItemType.MagentaGlazedTerracotta; + mappings[572] = ItemType.LightBlueGlazedTerracotta; + mappings[573] = ItemType.YellowGlazedTerracotta; + mappings[574] = ItemType.LimeGlazedTerracotta; + mappings[575] = ItemType.PinkGlazedTerracotta; + mappings[576] = ItemType.GrayGlazedTerracotta; + mappings[577] = ItemType.LightGrayGlazedTerracotta; + mappings[578] = ItemType.CyanGlazedTerracotta; + mappings[579] = ItemType.PurpleGlazedTerracotta; + mappings[580] = ItemType.BlueGlazedTerracotta; + mappings[581] = ItemType.BrownGlazedTerracotta; + mappings[582] = ItemType.GreenGlazedTerracotta; + mappings[583] = ItemType.RedGlazedTerracotta; + mappings[584] = ItemType.BlackGlazedTerracotta; + mappings[585] = ItemType.WhiteConcrete; + mappings[586] = ItemType.OrangeConcrete; + mappings[587] = ItemType.MagentaConcrete; + mappings[588] = ItemType.LightBlueConcrete; + mappings[589] = ItemType.YellowConcrete; + mappings[590] = ItemType.LimeConcrete; + mappings[591] = ItemType.PinkConcrete; + mappings[592] = ItemType.GrayConcrete; + mappings[593] = ItemType.LightGrayConcrete; + mappings[594] = ItemType.CyanConcrete; + mappings[595] = ItemType.PurpleConcrete; + mappings[596] = ItemType.BlueConcrete; + mappings[597] = ItemType.BrownConcrete; + mappings[598] = ItemType.GreenConcrete; + mappings[599] = ItemType.RedConcrete; + mappings[600] = ItemType.BlackConcrete; + mappings[601] = ItemType.WhiteConcretePowder; + mappings[602] = ItemType.OrangeConcretePowder; + mappings[603] = ItemType.MagentaConcretePowder; + mappings[604] = ItemType.LightBlueConcretePowder; + mappings[605] = ItemType.YellowConcretePowder; + mappings[606] = ItemType.LimeConcretePowder; + mappings[607] = ItemType.PinkConcretePowder; + mappings[608] = ItemType.GrayConcretePowder; + mappings[609] = ItemType.LightGrayConcretePowder; + mappings[610] = ItemType.CyanConcretePowder; + mappings[611] = ItemType.PurpleConcretePowder; + mappings[612] = ItemType.BlueConcretePowder; + mappings[613] = ItemType.BrownConcretePowder; + mappings[614] = ItemType.GreenConcretePowder; + mappings[615] = ItemType.RedConcretePowder; + mappings[616] = ItemType.BlackConcretePowder; + mappings[617] = ItemType.TurtleEgg; + mappings[618] = ItemType.SnifferEgg; + mappings[619] = ItemType.DeadTubeCoralBlock; + mappings[620] = ItemType.DeadBrainCoralBlock; + mappings[621] = ItemType.DeadBubbleCoralBlock; + mappings[622] = ItemType.DeadFireCoralBlock; + mappings[623] = ItemType.DeadHornCoralBlock; + mappings[624] = ItemType.TubeCoralBlock; + mappings[625] = ItemType.BrainCoralBlock; + mappings[626] = ItemType.BubbleCoralBlock; + mappings[627] = ItemType.FireCoralBlock; + mappings[628] = ItemType.HornCoralBlock; + mappings[629] = ItemType.TubeCoral; + mappings[630] = ItemType.BrainCoral; + mappings[631] = ItemType.BubbleCoral; + mappings[632] = ItemType.FireCoral; + mappings[633] = ItemType.HornCoral; + mappings[634] = ItemType.DeadBrainCoral; + mappings[635] = ItemType.DeadBubbleCoral; + mappings[636] = ItemType.DeadFireCoral; + mappings[637] = ItemType.DeadHornCoral; + mappings[638] = ItemType.DeadTubeCoral; + mappings[639] = ItemType.TubeCoralFan; + mappings[640] = ItemType.BrainCoralFan; + mappings[641] = ItemType.BubbleCoralFan; + mappings[642] = ItemType.FireCoralFan; + mappings[643] = ItemType.HornCoralFan; + mappings[644] = ItemType.DeadTubeCoralFan; + mappings[645] = ItemType.DeadBrainCoralFan; + mappings[646] = ItemType.DeadBubbleCoralFan; + mappings[647] = ItemType.DeadFireCoralFan; + mappings[648] = ItemType.DeadHornCoralFan; + mappings[649] = ItemType.BlueIce; + mappings[650] = ItemType.Conduit; + mappings[651] = ItemType.PolishedGraniteStairs; + mappings[652] = ItemType.SmoothRedSandstoneStairs; + mappings[653] = ItemType.MossyStoneBrickStairs; + mappings[654] = ItemType.PolishedDioriteStairs; + mappings[655] = ItemType.MossyCobblestoneStairs; + mappings[656] = ItemType.EndStoneBrickStairs; + mappings[657] = ItemType.StoneStairs; + mappings[658] = ItemType.SmoothSandstoneStairs; + mappings[659] = ItemType.SmoothQuartzStairs; + mappings[660] = ItemType.GraniteStairs; + mappings[661] = ItemType.AndesiteStairs; + mappings[662] = ItemType.RedNetherBrickStairs; + mappings[663] = ItemType.PolishedAndesiteStairs; + mappings[664] = ItemType.DioriteStairs; + mappings[665] = ItemType.CobbledDeepslateStairs; + mappings[666] = ItemType.PolishedDeepslateStairs; + mappings[667] = ItemType.DeepslateBrickStairs; + mappings[668] = ItemType.DeepslateTileStairs; + mappings[669] = ItemType.PolishedGraniteSlab; + mappings[670] = ItemType.SmoothRedSandstoneSlab; + mappings[671] = ItemType.MossyStoneBrickSlab; + mappings[672] = ItemType.PolishedDioriteSlab; + mappings[673] = ItemType.MossyCobblestoneSlab; + mappings[674] = ItemType.EndStoneBrickSlab; + mappings[675] = ItemType.SmoothSandstoneSlab; + mappings[676] = ItemType.SmoothQuartzSlab; + mappings[677] = ItemType.GraniteSlab; + mappings[678] = ItemType.AndesiteSlab; + mappings[679] = ItemType.RedNetherBrickSlab; + mappings[680] = ItemType.PolishedAndesiteSlab; + mappings[681] = ItemType.DioriteSlab; + mappings[682] = ItemType.CobbledDeepslateSlab; + mappings[683] = ItemType.PolishedDeepslateSlab; + mappings[684] = ItemType.DeepslateBrickSlab; + mappings[685] = ItemType.DeepslateTileSlab; + mappings[686] = ItemType.Scaffolding; + mappings[687] = ItemType.Redstone; + mappings[688] = ItemType.RedstoneTorch; + mappings[689] = ItemType.RedstoneBlock; + mappings[690] = ItemType.Repeater; + mappings[691] = ItemType.Comparator; + mappings[692] = ItemType.Piston; + mappings[693] = ItemType.StickyPiston; + mappings[694] = ItemType.SlimeBlock; + mappings[695] = ItemType.HoneyBlock; + mappings[696] = ItemType.Observer; + mappings[697] = ItemType.Hopper; + mappings[698] = ItemType.Dispenser; + mappings[699] = ItemType.Dropper; + mappings[700] = ItemType.Lectern; + mappings[701] = ItemType.Target; + mappings[702] = ItemType.Lever; + mappings[703] = ItemType.LightningRod; + mappings[704] = ItemType.DaylightDetector; + mappings[705] = ItemType.SculkSensor; + mappings[706] = ItemType.CalibratedSculkSensor; + mappings[707] = ItemType.TripwireHook; + mappings[708] = ItemType.TrappedChest; + mappings[709] = ItemType.Tnt; + mappings[710] = ItemType.RedstoneLamp; + mappings[711] = ItemType.NoteBlock; + mappings[712] = ItemType.StoneButton; + mappings[713] = ItemType.PolishedBlackstoneButton; + mappings[714] = ItemType.OakButton; + mappings[715] = ItemType.SpruceButton; + mappings[716] = ItemType.BirchButton; + mappings[717] = ItemType.JungleButton; + mappings[718] = ItemType.AcaciaButton; + mappings[719] = ItemType.CherryButton; + mappings[720] = ItemType.DarkOakButton; + mappings[721] = ItemType.PaleOakButton; + mappings[722] = ItemType.MangroveButton; + mappings[723] = ItemType.BambooButton; + mappings[724] = ItemType.CrimsonButton; + mappings[725] = ItemType.WarpedButton; + mappings[726] = ItemType.StonePressurePlate; + mappings[727] = ItemType.PolishedBlackstonePressurePlate; + mappings[728] = ItemType.LightWeightedPressurePlate; + mappings[729] = ItemType.HeavyWeightedPressurePlate; + mappings[730] = ItemType.OakPressurePlate; + mappings[731] = ItemType.SprucePressurePlate; + mappings[732] = ItemType.BirchPressurePlate; + mappings[733] = ItemType.JunglePressurePlate; + mappings[734] = ItemType.AcaciaPressurePlate; + mappings[735] = ItemType.CherryPressurePlate; + mappings[736] = ItemType.DarkOakPressurePlate; + mappings[737] = ItemType.PaleOakPressurePlate; + mappings[738] = ItemType.MangrovePressurePlate; + mappings[739] = ItemType.BambooPressurePlate; + mappings[740] = ItemType.CrimsonPressurePlate; + mappings[741] = ItemType.WarpedPressurePlate; + mappings[742] = ItemType.IronDoor; + mappings[743] = ItemType.OakDoor; + mappings[744] = ItemType.SpruceDoor; + mappings[745] = ItemType.BirchDoor; + mappings[746] = ItemType.JungleDoor; + mappings[747] = ItemType.AcaciaDoor; + mappings[748] = ItemType.CherryDoor; + mappings[749] = ItemType.DarkOakDoor; + mappings[750] = ItemType.PaleOakDoor; + mappings[751] = ItemType.MangroveDoor; + mappings[752] = ItemType.BambooDoor; + mappings[753] = ItemType.CrimsonDoor; + mappings[754] = ItemType.WarpedDoor; + mappings[755] = ItemType.CopperDoor; + mappings[756] = ItemType.ExposedCopperDoor; + mappings[757] = ItemType.WeatheredCopperDoor; + mappings[758] = ItemType.OxidizedCopperDoor; + mappings[759] = ItemType.WaxedCopperDoor; + mappings[760] = ItemType.WaxedExposedCopperDoor; + mappings[761] = ItemType.WaxedWeatheredCopperDoor; + mappings[762] = ItemType.WaxedOxidizedCopperDoor; + mappings[763] = ItemType.IronTrapdoor; + mappings[764] = ItemType.OakTrapdoor; + mappings[765] = ItemType.SpruceTrapdoor; + mappings[766] = ItemType.BirchTrapdoor; + mappings[767] = ItemType.JungleTrapdoor; + mappings[768] = ItemType.AcaciaTrapdoor; + mappings[769] = ItemType.CherryTrapdoor; + mappings[770] = ItemType.DarkOakTrapdoor; + mappings[771] = ItemType.PaleOakTrapdoor; + mappings[772] = ItemType.MangroveTrapdoor; + mappings[773] = ItemType.BambooTrapdoor; + mappings[774] = ItemType.CrimsonTrapdoor; + mappings[775] = ItemType.WarpedTrapdoor; + mappings[776] = ItemType.CopperTrapdoor; + mappings[777] = ItemType.ExposedCopperTrapdoor; + mappings[778] = ItemType.WeatheredCopperTrapdoor; + mappings[779] = ItemType.OxidizedCopperTrapdoor; + mappings[780] = ItemType.WaxedCopperTrapdoor; + mappings[781] = ItemType.WaxedExposedCopperTrapdoor; + mappings[782] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[783] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[784] = ItemType.OakFenceGate; + mappings[785] = ItemType.SpruceFenceGate; + mappings[786] = ItemType.BirchFenceGate; + mappings[787] = ItemType.JungleFenceGate; + mappings[788] = ItemType.AcaciaFenceGate; + mappings[789] = ItemType.CherryFenceGate; + mappings[790] = ItemType.DarkOakFenceGate; + mappings[791] = ItemType.PaleOakFenceGate; + mappings[792] = ItemType.MangroveFenceGate; + mappings[793] = ItemType.BambooFenceGate; + mappings[794] = ItemType.CrimsonFenceGate; + mappings[795] = ItemType.WarpedFenceGate; + mappings[796] = ItemType.PoweredRail; + mappings[797] = ItemType.DetectorRail; + mappings[798] = ItemType.Rail; + mappings[799] = ItemType.ActivatorRail; + mappings[800] = ItemType.Saddle; + mappings[801] = ItemType.Minecart; + mappings[802] = ItemType.ChestMinecart; + mappings[803] = ItemType.FurnaceMinecart; + mappings[804] = ItemType.TntMinecart; + mappings[805] = ItemType.HopperMinecart; + mappings[806] = ItemType.CarrotOnAStick; + mappings[807] = ItemType.WarpedFungusOnAStick; + mappings[808] = ItemType.PhantomMembrane; + mappings[809] = ItemType.Elytra; + mappings[810] = ItemType.OakBoat; + mappings[811] = ItemType.OakChestBoat; + mappings[812] = ItemType.SpruceBoat; + mappings[813] = ItemType.SpruceChestBoat; + mappings[814] = ItemType.BirchBoat; + mappings[815] = ItemType.BirchChestBoat; + mappings[816] = ItemType.JungleBoat; + mappings[817] = ItemType.JungleChestBoat; + mappings[818] = ItemType.AcaciaBoat; + mappings[819] = ItemType.AcaciaChestBoat; + mappings[820] = ItemType.CherryBoat; + mappings[821] = ItemType.CherryChestBoat; + mappings[822] = ItemType.DarkOakBoat; + mappings[823] = ItemType.DarkOakChestBoat; + mappings[824] = ItemType.PaleOakBoat; + mappings[825] = ItemType.PaleOakChestBoat; + mappings[826] = ItemType.MangroveBoat; + mappings[827] = ItemType.MangroveChestBoat; + mappings[828] = ItemType.BambooRaft; + mappings[829] = ItemType.BambooChestRaft; + mappings[830] = ItemType.StructureBlock; + mappings[831] = ItemType.Jigsaw; + mappings[832] = ItemType.TestBlock; + mappings[833] = ItemType.TestInstanceBlock; + mappings[834] = ItemType.TurtleHelmet; + mappings[835] = ItemType.TurtleScute; + mappings[836] = ItemType.ArmadilloScute; + mappings[837] = ItemType.WolfArmor; + mappings[838] = ItemType.FlintAndSteel; + mappings[839] = ItemType.Bowl; + mappings[840] = ItemType.Apple; + mappings[841] = ItemType.Bow; + mappings[842] = ItemType.Arrow; + mappings[843] = ItemType.Coal; + mappings[844] = ItemType.Charcoal; + mappings[845] = ItemType.Diamond; + mappings[846] = ItemType.Emerald; + mappings[847] = ItemType.LapisLazuli; + mappings[848] = ItemType.Quartz; + mappings[849] = ItemType.AmethystShard; + mappings[850] = ItemType.RawIron; + mappings[851] = ItemType.IronIngot; + mappings[852] = ItemType.RawCopper; + mappings[853] = ItemType.CopperIngot; + mappings[854] = ItemType.RawGold; + mappings[855] = ItemType.GoldIngot; + mappings[856] = ItemType.NetheriteIngot; + mappings[857] = ItemType.NetheriteScrap; + mappings[858] = ItemType.WoodenSword; + mappings[859] = ItemType.WoodenShovel; + mappings[860] = ItemType.WoodenPickaxe; + mappings[861] = ItemType.WoodenAxe; + mappings[862] = ItemType.WoodenHoe; + mappings[863] = ItemType.StoneSword; + mappings[864] = ItemType.StoneShovel; + mappings[865] = ItemType.StonePickaxe; + mappings[866] = ItemType.StoneAxe; + mappings[867] = ItemType.StoneHoe; + mappings[868] = ItemType.GoldenSword; + mappings[869] = ItemType.GoldenShovel; + mappings[870] = ItemType.GoldenPickaxe; + mappings[871] = ItemType.GoldenAxe; + mappings[872] = ItemType.GoldenHoe; + mappings[873] = ItemType.IronSword; + mappings[874] = ItemType.IronShovel; + mappings[875] = ItemType.IronPickaxe; + mappings[876] = ItemType.IronAxe; + mappings[877] = ItemType.IronHoe; + mappings[878] = ItemType.DiamondSword; + mappings[879] = ItemType.DiamondShovel; + mappings[880] = ItemType.DiamondPickaxe; + mappings[881] = ItemType.DiamondAxe; + mappings[882] = ItemType.DiamondHoe; + mappings[883] = ItemType.NetheriteSword; + mappings[884] = ItemType.NetheriteShovel; + mappings[885] = ItemType.NetheritePickaxe; + mappings[886] = ItemType.NetheriteAxe; + mappings[887] = ItemType.NetheriteHoe; + mappings[888] = ItemType.Stick; + mappings[889] = ItemType.MushroomStew; + mappings[890] = ItemType.String; + mappings[891] = ItemType.Feather; + mappings[892] = ItemType.Gunpowder; + mappings[893] = ItemType.WheatSeeds; + mappings[894] = ItemType.Wheat; + mappings[895] = ItemType.Bread; + mappings[896] = ItemType.LeatherHelmet; + mappings[897] = ItemType.LeatherChestplate; + mappings[898] = ItemType.LeatherLeggings; + mappings[899] = ItemType.LeatherBoots; + mappings[900] = ItemType.ChainmailHelmet; + mappings[901] = ItemType.ChainmailChestplate; + mappings[902] = ItemType.ChainmailLeggings; + mappings[903] = ItemType.ChainmailBoots; + mappings[904] = ItemType.IronHelmet; + mappings[905] = ItemType.IronChestplate; + mappings[906] = ItemType.IronLeggings; + mappings[907] = ItemType.IronBoots; + mappings[908] = ItemType.DiamondHelmet; + mappings[909] = ItemType.DiamondChestplate; + mappings[910] = ItemType.DiamondLeggings; + mappings[911] = ItemType.DiamondBoots; + mappings[912] = ItemType.GoldenHelmet; + mappings[913] = ItemType.GoldenChestplate; + mappings[914] = ItemType.GoldenLeggings; + mappings[915] = ItemType.GoldenBoots; + mappings[916] = ItemType.NetheriteHelmet; + mappings[917] = ItemType.NetheriteChestplate; + mappings[918] = ItemType.NetheriteLeggings; + mappings[919] = ItemType.NetheriteBoots; + mappings[920] = ItemType.Flint; + mappings[921] = ItemType.Porkchop; + mappings[922] = ItemType.CookedPorkchop; + mappings[923] = ItemType.Painting; + mappings[924] = ItemType.GoldenApple; + mappings[925] = ItemType.EnchantedGoldenApple; + mappings[926] = ItemType.OakSign; + mappings[927] = ItemType.SpruceSign; + mappings[928] = ItemType.BirchSign; + mappings[929] = ItemType.JungleSign; + mappings[930] = ItemType.AcaciaSign; + mappings[931] = ItemType.CherrySign; + mappings[932] = ItemType.DarkOakSign; + mappings[933] = ItemType.PaleOakSign; + mappings[934] = ItemType.MangroveSign; + mappings[935] = ItemType.BambooSign; + mappings[936] = ItemType.CrimsonSign; + mappings[937] = ItemType.WarpedSign; + mappings[938] = ItemType.OakHangingSign; + mappings[939] = ItemType.SpruceHangingSign; + mappings[940] = ItemType.BirchHangingSign; + mappings[941] = ItemType.JungleHangingSign; + mappings[942] = ItemType.AcaciaHangingSign; + mappings[943] = ItemType.CherryHangingSign; + mappings[944] = ItemType.DarkOakHangingSign; + mappings[945] = ItemType.PaleOakHangingSign; + mappings[946] = ItemType.MangroveHangingSign; + mappings[947] = ItemType.BambooHangingSign; + mappings[948] = ItemType.CrimsonHangingSign; + mappings[949] = ItemType.WarpedHangingSign; + mappings[950] = ItemType.Bucket; + mappings[951] = ItemType.WaterBucket; + mappings[952] = ItemType.LavaBucket; + mappings[953] = ItemType.PowderSnowBucket; + mappings[954] = ItemType.Snowball; + mappings[955] = ItemType.Leather; + mappings[956] = ItemType.MilkBucket; + mappings[957] = ItemType.PufferfishBucket; + mappings[958] = ItemType.SalmonBucket; + mappings[959] = ItemType.CodBucket; + mappings[960] = ItemType.TropicalFishBucket; + mappings[961] = ItemType.AxolotlBucket; + mappings[962] = ItemType.TadpoleBucket; + mappings[963] = ItemType.Brick; + mappings[964] = ItemType.ClayBall; + mappings[965] = ItemType.DriedKelpBlock; + mappings[966] = ItemType.Paper; + mappings[967] = ItemType.Book; + mappings[968] = ItemType.SlimeBall; + mappings[969] = ItemType.Egg; + mappings[970] = ItemType.BlueEgg; + mappings[971] = ItemType.BrownEgg; + mappings[972] = ItemType.Compass; + mappings[973] = ItemType.RecoveryCompass; + mappings[974] = ItemType.Bundle; + mappings[975] = ItemType.WhiteBundle; + mappings[976] = ItemType.OrangeBundle; + mappings[977] = ItemType.MagentaBundle; + mappings[978] = ItemType.LightBlueBundle; + mappings[979] = ItemType.YellowBundle; + mappings[980] = ItemType.LimeBundle; + mappings[981] = ItemType.PinkBundle; + mappings[982] = ItemType.GrayBundle; + mappings[983] = ItemType.LightGrayBundle; + mappings[984] = ItemType.CyanBundle; + mappings[985] = ItemType.PurpleBundle; + mappings[986] = ItemType.BlueBundle; + mappings[987] = ItemType.BrownBundle; + mappings[988] = ItemType.GreenBundle; + mappings[989] = ItemType.RedBundle; + mappings[990] = ItemType.BlackBundle; + mappings[991] = ItemType.FishingRod; + mappings[992] = ItemType.Clock; + mappings[993] = ItemType.Spyglass; + mappings[994] = ItemType.GlowstoneDust; + mappings[995] = ItemType.Cod; + mappings[996] = ItemType.Salmon; + mappings[997] = ItemType.TropicalFish; + mappings[998] = ItemType.Pufferfish; + mappings[999] = ItemType.CookedCod; + mappings[1000] = ItemType.CookedSalmon; + mappings[1001] = ItemType.InkSac; + mappings[1002] = ItemType.GlowInkSac; + mappings[1003] = ItemType.CocoaBeans; + mappings[1004] = ItemType.WhiteDye; + mappings[1005] = ItemType.OrangeDye; + mappings[1006] = ItemType.MagentaDye; + mappings[1007] = ItemType.LightBlueDye; + mappings[1008] = ItemType.YellowDye; + mappings[1009] = ItemType.LimeDye; + mappings[1010] = ItemType.PinkDye; + mappings[1011] = ItemType.GrayDye; + mappings[1012] = ItemType.LightGrayDye; + mappings[1013] = ItemType.CyanDye; + mappings[1014] = ItemType.PurpleDye; + mappings[1015] = ItemType.BlueDye; + mappings[1016] = ItemType.BrownDye; + mappings[1017] = ItemType.GreenDye; + mappings[1018] = ItemType.RedDye; + mappings[1019] = ItemType.BlackDye; + mappings[1020] = ItemType.BoneMeal; + mappings[1021] = ItemType.Bone; + mappings[1022] = ItemType.Sugar; + mappings[1023] = ItemType.Cake; + mappings[1024] = ItemType.WhiteBed; + mappings[1025] = ItemType.OrangeBed; + mappings[1026] = ItemType.MagentaBed; + mappings[1027] = ItemType.LightBlueBed; + mappings[1028] = ItemType.YellowBed; + mappings[1029] = ItemType.LimeBed; + mappings[1030] = ItemType.PinkBed; + mappings[1031] = ItemType.GrayBed; + mappings[1032] = ItemType.LightGrayBed; + mappings[1033] = ItemType.CyanBed; + mappings[1034] = ItemType.PurpleBed; + mappings[1035] = ItemType.BlueBed; + mappings[1036] = ItemType.BrownBed; + mappings[1037] = ItemType.GreenBed; + mappings[1038] = ItemType.RedBed; + mappings[1039] = ItemType.BlackBed; + mappings[1040] = ItemType.Cookie; + mappings[1041] = ItemType.Crafter; + mappings[1042] = ItemType.FilledMap; + mappings[1043] = ItemType.Shears; + mappings[1044] = ItemType.MelonSlice; + mappings[1045] = ItemType.DriedKelp; + mappings[1046] = ItemType.PumpkinSeeds; + mappings[1047] = ItemType.MelonSeeds; + mappings[1048] = ItemType.Beef; + mappings[1049] = ItemType.CookedBeef; + mappings[1050] = ItemType.Chicken; + mappings[1051] = ItemType.CookedChicken; + mappings[1052] = ItemType.RottenFlesh; + mappings[1053] = ItemType.EnderPearl; + mappings[1054] = ItemType.BlazeRod; + mappings[1055] = ItemType.GhastTear; + mappings[1056] = ItemType.GoldNugget; + mappings[1057] = ItemType.NetherWart; + mappings[1058] = ItemType.GlassBottle; + mappings[1059] = ItemType.Potion; + mappings[1060] = ItemType.SpiderEye; + mappings[1061] = ItemType.FermentedSpiderEye; + mappings[1062] = ItemType.BlazePowder; + mappings[1063] = ItemType.MagmaCream; + mappings[1064] = ItemType.BrewingStand; + mappings[1065] = ItemType.Cauldron; + mappings[1066] = ItemType.EnderEye; + mappings[1067] = ItemType.GlisteringMelonSlice; + mappings[1068] = ItemType.ArmadilloSpawnEgg; + mappings[1069] = ItemType.AllaySpawnEgg; + mappings[1070] = ItemType.AxolotlSpawnEgg; + mappings[1071] = ItemType.BatSpawnEgg; + mappings[1072] = ItemType.BeeSpawnEgg; + mappings[1073] = ItemType.BlazeSpawnEgg; + mappings[1074] = ItemType.BoggedSpawnEgg; + mappings[1075] = ItemType.BreezeSpawnEgg; + mappings[1076] = ItemType.CatSpawnEgg; + mappings[1077] = ItemType.CamelSpawnEgg; + mappings[1078] = ItemType.CaveSpiderSpawnEgg; + mappings[1079] = ItemType.ChickenSpawnEgg; + mappings[1080] = ItemType.CodSpawnEgg; + mappings[1081] = ItemType.CowSpawnEgg; + mappings[1082] = ItemType.CreeperSpawnEgg; + mappings[1083] = ItemType.DolphinSpawnEgg; + mappings[1084] = ItemType.DonkeySpawnEgg; + mappings[1085] = ItemType.DrownedSpawnEgg; + mappings[1086] = ItemType.ElderGuardianSpawnEgg; + mappings[1087] = ItemType.EnderDragonSpawnEgg; + mappings[1088] = ItemType.EndermanSpawnEgg; + mappings[1089] = ItemType.EndermiteSpawnEgg; + mappings[1090] = ItemType.EvokerSpawnEgg; + mappings[1091] = ItemType.FoxSpawnEgg; + mappings[1092] = ItemType.FrogSpawnEgg; + mappings[1093] = ItemType.GhastSpawnEgg; + mappings[1094] = ItemType.GlowSquidSpawnEgg; + mappings[1095] = ItemType.GoatSpawnEgg; + mappings[1096] = ItemType.GuardianSpawnEgg; + mappings[1097] = ItemType.HoglinSpawnEgg; + mappings[1098] = ItemType.HorseSpawnEgg; + mappings[1099] = ItemType.HuskSpawnEgg; + mappings[1100] = ItemType.IronGolemSpawnEgg; + mappings[1101] = ItemType.LlamaSpawnEgg; + mappings[1102] = ItemType.MagmaCubeSpawnEgg; + mappings[1103] = ItemType.MooshroomSpawnEgg; + mappings[1104] = ItemType.MuleSpawnEgg; + mappings[1105] = ItemType.OcelotSpawnEgg; + mappings[1106] = ItemType.PandaSpawnEgg; + mappings[1107] = ItemType.ParrotSpawnEgg; + mappings[1108] = ItemType.PhantomSpawnEgg; + mappings[1109] = ItemType.PigSpawnEgg; + mappings[1110] = ItemType.PiglinSpawnEgg; + mappings[1111] = ItemType.PiglinBruteSpawnEgg; + mappings[1112] = ItemType.PillagerSpawnEgg; + mappings[1113] = ItemType.PolarBearSpawnEgg; + mappings[1114] = ItemType.PufferfishSpawnEgg; + mappings[1115] = ItemType.RabbitSpawnEgg; + mappings[1116] = ItemType.RavagerSpawnEgg; + mappings[1117] = ItemType.SalmonSpawnEgg; + mappings[1118] = ItemType.SheepSpawnEgg; + mappings[1119] = ItemType.ShulkerSpawnEgg; + mappings[1120] = ItemType.SilverfishSpawnEgg; + mappings[1121] = ItemType.SkeletonSpawnEgg; + mappings[1122] = ItemType.SkeletonHorseSpawnEgg; + mappings[1123] = ItemType.SlimeSpawnEgg; + mappings[1124] = ItemType.SnifferSpawnEgg; + mappings[1125] = ItemType.SnowGolemSpawnEgg; + mappings[1126] = ItemType.SpiderSpawnEgg; + mappings[1127] = ItemType.SquidSpawnEgg; + mappings[1128] = ItemType.StraySpawnEgg; + mappings[1129] = ItemType.StriderSpawnEgg; + mappings[1130] = ItemType.TadpoleSpawnEgg; + mappings[1131] = ItemType.TraderLlamaSpawnEgg; + mappings[1132] = ItemType.TropicalFishSpawnEgg; + mappings[1133] = ItemType.TurtleSpawnEgg; + mappings[1134] = ItemType.VexSpawnEgg; + mappings[1135] = ItemType.VillagerSpawnEgg; + mappings[1136] = ItemType.VindicatorSpawnEgg; + mappings[1137] = ItemType.WanderingTraderSpawnEgg; + mappings[1138] = ItemType.WardenSpawnEgg; + mappings[1139] = ItemType.WitchSpawnEgg; + mappings[1140] = ItemType.WitherSpawnEgg; + mappings[1141] = ItemType.WitherSkeletonSpawnEgg; + mappings[1142] = ItemType.WolfSpawnEgg; + mappings[1143] = ItemType.ZoglinSpawnEgg; + mappings[1144] = ItemType.CreakingSpawnEgg; + mappings[1145] = ItemType.ZombieSpawnEgg; + mappings[1146] = ItemType.ZombieHorseSpawnEgg; + mappings[1147] = ItemType.ZombieVillagerSpawnEgg; + mappings[1148] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1149] = ItemType.ExperienceBottle; + mappings[1150] = ItemType.FireCharge; + mappings[1151] = ItemType.WindCharge; + mappings[1152] = ItemType.WritableBook; + mappings[1153] = ItemType.WrittenBook; + mappings[1154] = ItemType.BreezeRod; + mappings[1155] = ItemType.Mace; + mappings[1156] = ItemType.ItemFrame; + mappings[1157] = ItemType.GlowItemFrame; + mappings[1158] = ItemType.FlowerPot; + mappings[1159] = ItemType.Carrot; + mappings[1160] = ItemType.Potato; + mappings[1161] = ItemType.BakedPotato; + mappings[1162] = ItemType.PoisonousPotato; + mappings[1163] = ItemType.Map; + mappings[1164] = ItemType.GoldenCarrot; + mappings[1165] = ItemType.SkeletonSkull; + mappings[1166] = ItemType.WitherSkeletonSkull; + mappings[1167] = ItemType.PlayerHead; + mappings[1168] = ItemType.ZombieHead; + mappings[1169] = ItemType.CreeperHead; + mappings[1170] = ItemType.DragonHead; + mappings[1171] = ItemType.PiglinHead; + mappings[1172] = ItemType.NetherStar; + mappings[1173] = ItemType.PumpkinPie; + mappings[1174] = ItemType.FireworkRocket; + mappings[1175] = ItemType.FireworkStar; + mappings[1176] = ItemType.EnchantedBook; + mappings[1177] = ItemType.NetherBrick; + mappings[1178] = ItemType.ResinBrick; + mappings[1179] = ItemType.PrismarineShard; + mappings[1180] = ItemType.PrismarineCrystals; + mappings[1181] = ItemType.Rabbit; + mappings[1182] = ItemType.CookedRabbit; + mappings[1183] = ItemType.RabbitStew; + mappings[1184] = ItemType.RabbitFoot; + mappings[1185] = ItemType.RabbitHide; + mappings[1186] = ItemType.ArmorStand; + mappings[1187] = ItemType.IronHorseArmor; + mappings[1188] = ItemType.GoldenHorseArmor; + mappings[1189] = ItemType.DiamondHorseArmor; + mappings[1190] = ItemType.LeatherHorseArmor; + mappings[1191] = ItemType.Lead; + mappings[1192] = ItemType.NameTag; + mappings[1193] = ItemType.CommandBlockMinecart; + mappings[1194] = ItemType.Mutton; + mappings[1195] = ItemType.CookedMutton; + mappings[1196] = ItemType.WhiteBanner; + mappings[1197] = ItemType.OrangeBanner; + mappings[1198] = ItemType.MagentaBanner; + mappings[1199] = ItemType.LightBlueBanner; + mappings[1200] = ItemType.YellowBanner; + mappings[1201] = ItemType.LimeBanner; + mappings[1202] = ItemType.PinkBanner; + mappings[1203] = ItemType.GrayBanner; + mappings[1204] = ItemType.LightGrayBanner; + mappings[1205] = ItemType.CyanBanner; + mappings[1206] = ItemType.PurpleBanner; + mappings[1207] = ItemType.BlueBanner; + mappings[1208] = ItemType.BrownBanner; + mappings[1209] = ItemType.GreenBanner; + mappings[1210] = ItemType.RedBanner; + mappings[1211] = ItemType.BlackBanner; + mappings[1212] = ItemType.EndCrystal; + mappings[1213] = ItemType.ChorusFruit; + mappings[1214] = ItemType.PoppedChorusFruit; + mappings[1215] = ItemType.TorchflowerSeeds; + mappings[1216] = ItemType.PitcherPod; + mappings[1217] = ItemType.Beetroot; + mappings[1218] = ItemType.BeetrootSeeds; + mappings[1219] = ItemType.BeetrootSoup; + mappings[1220] = ItemType.DragonBreath; + mappings[1221] = ItemType.SplashPotion; + mappings[1222] = ItemType.SpectralArrow; + mappings[1223] = ItemType.TippedArrow; + mappings[1224] = ItemType.LingeringPotion; + mappings[1225] = ItemType.Shield; + mappings[1226] = ItemType.TotemOfUndying; + mappings[1227] = ItemType.ShulkerShell; + mappings[1228] = ItemType.IronNugget; + mappings[1229] = ItemType.KnowledgeBook; + mappings[1230] = ItemType.DebugStick; + mappings[1231] = ItemType.MusicDisc13; + mappings[1232] = ItemType.MusicDiscCat; + mappings[1233] = ItemType.MusicDiscBlocks; + mappings[1234] = ItemType.MusicDiscChirp; + mappings[1235] = ItemType.MusicDiscCreator; + mappings[1236] = ItemType.MusicDiscCreatorMusicBox; + mappings[1237] = ItemType.MusicDiscFar; + mappings[1238] = ItemType.MusicDiscMall; + mappings[1239] = ItemType.MusicDiscMellohi; + mappings[1240] = ItemType.MusicDiscStal; + mappings[1241] = ItemType.MusicDiscStrad; + mappings[1242] = ItemType.MusicDiscWard; + mappings[1243] = ItemType.MusicDisc11; + mappings[1244] = ItemType.MusicDiscWait; + mappings[1245] = ItemType.MusicDiscOtherside; + mappings[1246] = ItemType.MusicDiscRelic; + mappings[1247] = ItemType.MusicDisc5; + mappings[1248] = ItemType.MusicDiscPigstep; + mappings[1249] = ItemType.MusicDiscPrecipice; + mappings[1250] = ItemType.DiscFragment5; + mappings[1251] = ItemType.Trident; + mappings[1252] = ItemType.NautilusShell; + mappings[1253] = ItemType.HeartOfTheSea; + mappings[1254] = ItemType.Crossbow; + mappings[1255] = ItemType.SuspiciousStew; + mappings[1256] = ItemType.Loom; + mappings[1257] = ItemType.FlowerBannerPattern; + mappings[1258] = ItemType.CreeperBannerPattern; + mappings[1259] = ItemType.SkullBannerPattern; + mappings[1260] = ItemType.MojangBannerPattern; + mappings[1261] = ItemType.GlobeBannerPattern; + mappings[1262] = ItemType.PiglinBannerPattern; + mappings[1263] = ItemType.FlowBannerPattern; + mappings[1264] = ItemType.GusterBannerPattern; + mappings[1265] = ItemType.FieldMasonedBannerPattern; + mappings[1266] = ItemType.BordureIndentedBannerPattern; + mappings[1267] = ItemType.GoatHorn; + mappings[1268] = ItemType.Composter; + mappings[1269] = ItemType.Barrel; + mappings[1270] = ItemType.Smoker; + mappings[1271] = ItemType.BlastFurnace; + mappings[1272] = ItemType.CartographyTable; + mappings[1273] = ItemType.FletchingTable; + mappings[1274] = ItemType.Grindstone; + mappings[1275] = ItemType.SmithingTable; + mappings[1276] = ItemType.Stonecutter; + mappings[1277] = ItemType.Bell; + mappings[1278] = ItemType.Lantern; + mappings[1279] = ItemType.SoulLantern; + mappings[1280] = ItemType.SweetBerries; + mappings[1281] = ItemType.GlowBerries; + mappings[1282] = ItemType.Campfire; + mappings[1283] = ItemType.SoulCampfire; + mappings[1284] = ItemType.Shroomlight; + mappings[1285] = ItemType.Honeycomb; + mappings[1286] = ItemType.BeeNest; + mappings[1287] = ItemType.Beehive; + mappings[1288] = ItemType.HoneyBottle; + mappings[1289] = ItemType.HoneycombBlock; + mappings[1290] = ItemType.Lodestone; + mappings[1291] = ItemType.CryingObsidian; + mappings[1292] = ItemType.Blackstone; + mappings[1293] = ItemType.BlackstoneSlab; + mappings[1294] = ItemType.BlackstoneStairs; + mappings[1295] = ItemType.GildedBlackstone; + mappings[1296] = ItemType.PolishedBlackstone; + mappings[1297] = ItemType.PolishedBlackstoneSlab; + mappings[1298] = ItemType.PolishedBlackstoneStairs; + mappings[1299] = ItemType.ChiseledPolishedBlackstone; + mappings[1300] = ItemType.PolishedBlackstoneBricks; + mappings[1301] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1302] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1303] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1304] = ItemType.RespawnAnchor; + mappings[1305] = ItemType.Candle; + mappings[1306] = ItemType.WhiteCandle; + mappings[1307] = ItemType.OrangeCandle; + mappings[1308] = ItemType.MagentaCandle; + mappings[1309] = ItemType.LightBlueCandle; + mappings[1310] = ItemType.YellowCandle; + mappings[1311] = ItemType.LimeCandle; + mappings[1312] = ItemType.PinkCandle; + mappings[1313] = ItemType.GrayCandle; + mappings[1314] = ItemType.LightGrayCandle; + mappings[1315] = ItemType.CyanCandle; + mappings[1316] = ItemType.PurpleCandle; + mappings[1317] = ItemType.BlueCandle; + mappings[1318] = ItemType.BrownCandle; + mappings[1319] = ItemType.GreenCandle; + mappings[1320] = ItemType.RedCandle; + mappings[1321] = ItemType.BlackCandle; + mappings[1322] = ItemType.SmallAmethystBud; + mappings[1323] = ItemType.MediumAmethystBud; + mappings[1324] = ItemType.LargeAmethystBud; + mappings[1325] = ItemType.AmethystCluster; + mappings[1326] = ItemType.PointedDripstone; + mappings[1327] = ItemType.OchreFroglight; + mappings[1328] = ItemType.VerdantFroglight; + mappings[1329] = ItemType.PearlescentFroglight; + mappings[1330] = ItemType.Frogspawn; + mappings[1331] = ItemType.EchoShard; + mappings[1332] = ItemType.Brush; + mappings[1333] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1334] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1335] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1336] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1337] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1338] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1339] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1340] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1341] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1342] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1343] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1344] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1345] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1346] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1347] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1348] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1349] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1350] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1351] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1352] = ItemType.AnglerPotterySherd; + mappings[1353] = ItemType.ArcherPotterySherd; + mappings[1354] = ItemType.ArmsUpPotterySherd; + mappings[1355] = ItemType.BladePotterySherd; + mappings[1356] = ItemType.BrewerPotterySherd; + mappings[1357] = ItemType.BurnPotterySherd; + mappings[1358] = ItemType.DangerPotterySherd; + mappings[1359] = ItemType.ExplorerPotterySherd; + mappings[1360] = ItemType.FlowPotterySherd; + mappings[1361] = ItemType.FriendPotterySherd; + mappings[1362] = ItemType.GusterPotterySherd; + mappings[1363] = ItemType.HeartPotterySherd; + mappings[1364] = ItemType.HeartbreakPotterySherd; + mappings[1365] = ItemType.HowlPotterySherd; + mappings[1366] = ItemType.MinerPotterySherd; + mappings[1367] = ItemType.MournerPotterySherd; + mappings[1368] = ItemType.PlentyPotterySherd; + mappings[1369] = ItemType.PrizePotterySherd; + mappings[1370] = ItemType.ScrapePotterySherd; + mappings[1371] = ItemType.SheafPotterySherd; + mappings[1372] = ItemType.ShelterPotterySherd; + mappings[1373] = ItemType.SkullPotterySherd; + mappings[1374] = ItemType.SnortPotterySherd; + mappings[1375] = ItemType.CopperGrate; + mappings[1376] = ItemType.ExposedCopperGrate; + mappings[1377] = ItemType.WeatheredCopperGrate; + mappings[1378] = ItemType.OxidizedCopperGrate; + mappings[1379] = ItemType.WaxedCopperGrate; + mappings[1380] = ItemType.WaxedExposedCopperGrate; + mappings[1381] = ItemType.WaxedWeatheredCopperGrate; + mappings[1382] = ItemType.WaxedOxidizedCopperGrate; + mappings[1383] = ItemType.CopperBulb; + mappings[1384] = ItemType.ExposedCopperBulb; + mappings[1385] = ItemType.WeatheredCopperBulb; + mappings[1386] = ItemType.OxidizedCopperBulb; + mappings[1387] = ItemType.WaxedCopperBulb; + mappings[1388] = ItemType.WaxedExposedCopperBulb; + mappings[1389] = ItemType.WaxedWeatheredCopperBulb; + mappings[1390] = ItemType.WaxedOxidizedCopperBulb; + mappings[1391] = ItemType.TrialSpawner; + mappings[1392] = ItemType.TrialKey; + mappings[1393] = ItemType.OminousTrialKey; + mappings[1394] = ItemType.Vault; + mappings[1395] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index bbe97785..1809b7ab 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -138,6 +138,7 @@ namespace MinecraftClient.Inventory BlueConcrete, BlueConcretePowder, BlueDye, + BlueEgg, // blue egg BlueGlazedTerracotta, BlueIce, BlueOrchid, @@ -177,6 +178,7 @@ namespace MinecraftClient.Inventory BrownConcrete, BrownConcretePowder, BrownDye, + BrownEgg, // brown egg BrownGlazedTerracotta, BrownMushroom, BrownMushroomBlock, @@ -194,7 +196,9 @@ namespace MinecraftClient.Inventory BuddingAmethyst, Bundle, BurnPotterySherd, + Bush, // bush Cactus, + CactusFlower, // cactus flower Cake, Calcite, CalibratedSculkSensor, @@ -439,6 +443,8 @@ namespace MinecraftClient.Inventory DripstoneBlock, Dropper, DrownedSpawnEgg, + DryShortGrass, // dry short grass + DryTallGrass, // dry tall grass DuneArmorTrimSmithingTemplate, EchoShard, Egg, @@ -487,6 +493,7 @@ namespace MinecraftClient.Inventory FireCoral, FireCoralBlock, FireCoralFan, + FireflyBush, // firefly bush FireworkRocket, FireworkStar, FishingRod, @@ -658,6 +665,7 @@ namespace MinecraftClient.Inventory LargeFern, LavaBucket, Lead, + LeafLitter, // leaf litter Leather, LeatherBoots, LeatherChestplate, @@ -1235,6 +1243,8 @@ namespace MinecraftClient.Inventory TallGrass, Target, Terracotta, + TestBlock, // test block + TestInstanceBlock, // test instance block TideArmorTrimSmithingTemplate, TintedGlass, TippedArrow, @@ -1364,6 +1374,7 @@ namespace MinecraftClient.Inventory WhiteWool, WhiteBundle, WildArmorTrimSmithingTemplate, + Wildflowers, // wildflowers WindCharge, WitchSpawnEgg, WitherRose, diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1215.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1215.cs new file mode 100644 index 00000000..c01f5d00 --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1215.cs @@ -0,0 +1,1838 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1215 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1215() + { + for (int i = 9492; i <= 9515; i++) + materials[i] = Material.AcaciaButton; + for (int i = 12973; i <= 13036; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 12589; i <= 12620; i++) + materials[i] = Material.AcaciaFence; + for (int i = 12301; i <= 12332; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5130; i <= 5193; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 5900; i <= 5901; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 4462; i <= 4493; i++) + materials[i] = Material.AcaciaSign; + for (int i = 12075; i <= 12080; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 10693; i <= 10772; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 6396; i <= 6459; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 5730; i <= 5737; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 4882; i <= 4889; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 10129; i <= 10152; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2125] = Material.Allium; + materials[22059] = Material.AmethystBlock; + for (int i = 22061; i <= 22072; i++) + materials[i] = Material.AmethystCluster; + materials[20476] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 15159; i <= 15164; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 14785; i <= 14864; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 17775; i <= 18098; i++) + materials[i] = Material.AndesiteWall; + for (int i = 9916; i <= 9919; i++) + materials[i] = Material.Anvil; + for (int i = 7060; i <= 7063; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 7056; i <= 7059; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[25852] = Material.Azalea; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + materials[2126] = Material.AzureBluet; + for (int i = 13968; i <= 13979; i++) + materials[i] = Material.Bamboo; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 9612; i <= 9635; i++) + materials[i] = Material.BambooButton; + for (int i = 13293; i <= 13356; i++) + materials[i] = Material.BambooDoor; + for (int i = 12749; i <= 12780; i++) + materials[i] = Material.BambooFence; + for (int i = 12461; i <= 12492; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 5642; i <= 5705; i++) + materials[i] = Material.BambooHangingSign; + materials[28] = Material.BambooMosaic; + for (int i = 12111; i <= 12116; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 11173; i <= 11252; i++) + materials[i] = Material.BambooMosaicStairs; + materials[27] = Material.BambooPlanks; + for (int i = 5910; i <= 5911; i++) + materials[i] = Material.BambooPressurePlate; + materials[13967] = Material.BambooSapling; + for (int i = 4654; i <= 4685; i++) + materials[i] = Material.BambooSign; + for (int i = 12105; i <= 12110; i++) + materials[i] = Material.BambooSlab; + for (int i = 11093; i <= 11172; i++) + materials[i] = Material.BambooStairs; + for (int i = 6716; i <= 6779; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 5794; i <= 5801; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 4930; i <= 4937; i++) + materials[i] = Material.BambooWallSign; + for (int i = 19431; i <= 19442; i++) + materials[i] = Material.Barrel; + for (int i = 11254; i <= 11255; i++) + materials[i] = Material.Barrier; + for (int i = 6031; i <= 6033; i++) + materials[i] = Material.Basalt; + materials[8702] = Material.Beacon; + materials[85] = Material.Bedrock; + for (int i = 20425; i <= 20448; i++) + materials[i] = Material.BeeNest; + for (int i = 20449; i <= 20472; i++) + materials[i] = Material.Beehive; + for (int i = 13532; i <= 13535; i++) + materials[i] = Material.Beetroots; + for (int i = 19494; i <= 19525; i++) + materials[i] = Material.Bell; + for (int i = 25904; i <= 25935; i++) + materials[i] = Material.BigDripleaf; + for (int i = 25936; i <= 25943; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 9444; i <= 9467; i++) + materials[i] = Material.BirchButton; + for (int i = 12845; i <= 12908; i++) + materials[i] = Material.BirchDoor; + for (int i = 12525; i <= 12556; i++) + materials[i] = Material.BirchFence; + for (int i = 12237; i <= 12268; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 5066; i <= 5129; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 5896; i <= 5897; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 4430; i <= 4461; i++) + materials[i] = Material.BirchSign; + for (int i = 12063; i <= 12068; i++) + materials[i] = Material.BirchSlab; + for (int i = 8530; i <= 8609; i++) + materials[i] = Material.BirchStairs; + for (int i = 6268; i <= 6331; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 5722; i <= 5729; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 4874; i <= 4881; i++) + materials[i] = Material.BirchWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 11888; i <= 11903; i++) + materials[i] = Material.BlackBanner; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 22009; i <= 22024; i++) + materials[i] = Material.BlackCandle; + for (int i = 22057; i <= 22058; i++) + materials[i] = Material.BlackCandleCake; + materials[11632] = Material.BlackCarpet; + materials[13766] = Material.BlackConcrete; + materials[13782] = Material.BlackConcretePowder; + for (int i = 13747; i <= 13750; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 13681; i <= 13686; i++) + materials[i] = Material.BlackShulkerBox; + materials[6139] = Material.BlackStainedGlass; + for (int i = 10661; i <= 10692; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[10180] = Material.BlackTerracotta; + for (int i = 11964; i <= 11967; i++) + materials[i] = Material.BlackWallBanner; + materials[2108] = Material.BlackWool; + materials[20488] = Material.Blackstone; + for (int i = 20893; i <= 20898; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 20489; i <= 20568; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 20569; i <= 20892; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 19451; i <= 19458; i++) + materials[i] = Material.BlastFurnace; + for (int i = 11824; i <= 11839; i++) + materials[i] = Material.BlueBanner; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 21945; i <= 21960; i++) + materials[i] = Material.BlueCandle; + for (int i = 22049; i <= 22050; i++) + materials[i] = Material.BlueCandleCake; + materials[11628] = Material.BlueCarpet; + materials[13762] = Material.BlueConcrete; + materials[13778] = Material.BlueConcretePowder; + for (int i = 13731; i <= 13734; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[13964] = Material.BlueIce; + materials[2124] = Material.BlueOrchid; + for (int i = 13657; i <= 13662; i++) + materials[i] = Material.BlueShulkerBox; + materials[6135] = Material.BlueStainedGlass; + for (int i = 10533; i <= 10564; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[10176] = Material.BlueTerracotta; + for (int i = 11948; i <= 11951; i++) + materials[i] = Material.BlueWallBanner; + materials[2104] = Material.BlueWool; + for (int i = 13569; i <= 13571; i++) + materials[i] = Material.BoneBlock; + materials[2142] = Material.Bookshelf; + for (int i = 13848; i <= 13849; i++) + materials[i] = Material.BrainCoral; + materials[13832] = Material.BrainCoralBlock; + for (int i = 13868; i <= 13869; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 13924; i <= 13931; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 8174; i <= 8181; i++) + materials[i] = Material.BrewingStand; + for (int i = 12153; i <= 12158; i++) + materials[i] = Material.BrickSlab; + for (int i = 7400; i <= 7479; i++) + materials[i] = Material.BrickStairs; + for (int i = 15183; i <= 15506; i++) + materials[i] = Material.BrickWall; + materials[2139] = Material.Bricks; + for (int i = 11840; i <= 11855; i++) + materials[i] = Material.BrownBanner; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 21961; i <= 21976; i++) + materials[i] = Material.BrownCandle; + for (int i = 22051; i <= 22052; i++) + materials[i] = Material.BrownCandleCake; + materials[11629] = Material.BrownCarpet; + materials[13763] = Material.BrownConcrete; + materials[13779] = Material.BrownConcretePowder; + for (int i = 13735; i <= 13738; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2135] = Material.BrownMushroom; + for (int i = 6792; i <= 6855; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 13663; i <= 13668; i++) + materials[i] = Material.BrownShulkerBox; + materials[6136] = Material.BrownStainedGlass; + for (int i = 10565; i <= 10596; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[10177] = Material.BrownTerracotta; + for (int i = 11952; i <= 11955; i++) + materials[i] = Material.BrownWallBanner; + materials[2105] = Material.BrownWool; + for (int i = 13983; i <= 13984; i++) + materials[i] = Material.BubbleColumn; + for (int i = 13850; i <= 13851; i++) + materials[i] = Material.BubbleCoral; + materials[13833] = Material.BubbleCoralBlock; + for (int i = 13870; i <= 13871; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 13932; i <= 13939; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[22060] = Material.BuddingAmethyst; + materials[2051] = Material.Bush; + for (int i = 5960; i <= 5975; i++) + materials[i] = Material.Cactus; + materials[5976] = Material.CactusFlower; + for (int i = 6053; i <= 6059; i++) + materials[i] = Material.Cake; + materials[23344] = Material.Calcite; + for (int i = 23443; i <= 23826; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 19534; i <= 19565; i++) + materials[i] = Material.Campfire; + for (int i = 21753; i <= 21768; i++) + materials[i] = Material.Candle; + for (int i = 22025; i <= 22026; i++) + materials[i] = Material.CandleCake; + for (int i = 9380; i <= 9387; i++) + materials[i] = Material.Carrots; + materials[19459] = Material.CartographyTable; + for (int i = 6045; i <= 6048; i++) + materials[i] = Material.CarvedPumpkin; + materials[8182] = Material.Cauldron; + materials[13982] = Material.CaveAir; + for (int i = 25797; i <= 25848; i++) + materials[i] = Material.CaveVines; + for (int i = 25849; i <= 25850; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 7016; i <= 7021; i++) + materials[i] = Material.Chain; + for (int i = 13550; i <= 13561; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 9516; i <= 9539; i++) + materials[i] = Material.CherryButton; + for (int i = 13037; i <= 13100; i++) + materials[i] = Material.CherryDoor; + for (int i = 12621; i <= 12652; i++) + materials[i] = Material.CherryFence; + for (int i = 12333; i <= 12364; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5194; i <= 5257; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 5902; i <= 5903; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 4494; i <= 4525; i++) + materials[i] = Material.CherrySign; + for (int i = 12081; i <= 12086; i++) + materials[i] = Material.CherrySlab; + for (int i = 10773; i <= 10852; i++) + materials[i] = Material.CherryStairs; + for (int i = 6460; i <= 6523; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 5738; i <= 5745; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 4890; i <= 4897; i++) + materials[i] = Material.CherryWallSign; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 3018; i <= 3041; i++) + materials[i] = Material.Chest; + for (int i = 9920; i <= 9923; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2143; i <= 2398; i++) + materials[i] = Material.ChiseledBookshelf; + materials[23979] = Material.ChiseledCopper; + materials[27611] = Material.ChiseledDeepslate; + materials[21750] = Material.ChiseledNetherBricks; + materials[20902] = Material.ChiseledPolishedBlackstone; + materials[10045] = Material.ChiseledQuartzBlock; + materials[11969] = Material.ChiseledRedSandstone; + materials[8055] = Material.ChiseledResinBricks; + materials[579] = Material.ChiseledSandstone; + materials[6783] = Material.ChiseledStoneBricks; + materials[22931] = Material.ChiseledTuff; + materials[23343] = Material.ChiseledTuffBricks; + for (int i = 13427; i <= 13432; i++) + materials[i] = Material.ChorusFlower; + for (int i = 13363; i <= 13426; i++) + materials[i] = Material.ChorusPlant; + materials[5977] = Material.Clay; + materials[27910] = Material.ClosedEyeblossom; + materials[11634] = Material.CoalBlock; + materials[133] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[25967] = Material.CobbledDeepslate; + for (int i = 26048; i <= 26053; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 25968; i <= 26047; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 26054; i <= 26377; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 12147; i <= 12152; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 4778; i <= 4857; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 8703; i <= 9026; i++) + materials[i] = Material.CobblestoneWall; + materials[2047] = Material.Cobweb; + for (int i = 8203; i <= 8214; i++) + materials[i] = Material.Cocoa; + for (int i = 8690; i <= 8701; i++) + materials[i] = Material.CommandBlock; + for (int i = 9984; i <= 9999; i++) + materials[i] = Material.Comparator; + for (int i = 20400; i <= 20408; i++) + materials[i] = Material.Composter; + for (int i = 13965; i <= 13966; i++) + materials[i] = Material.Conduit; + materials[23966] = Material.CopperBlock; + for (int i = 25720; i <= 25723; i++) + materials[i] = Material.CopperBulb; + for (int i = 24680; i <= 24743; i++) + materials[i] = Material.CopperDoor; + for (int i = 25704; i <= 25705; i++) + materials[i] = Material.CopperGrate; + materials[23970] = Material.CopperOre; + for (int i = 25192; i <= 25255; i++) + materials[i] = Material.CopperTrapdoor; + materials[2132] = Material.Cornflower; + materials[27612] = Material.CrackedDeepslateBricks; + materials[27613] = Material.CrackedDeepslateTiles; + materials[21751] = Material.CrackedNetherBricks; + materials[20901] = Material.CrackedPolishedBlackstoneBricks; + materials[6782] = Material.CrackedStoneBricks; + for (int i = 27650; i <= 27697; i++) + materials[i] = Material.Crafter; + materials[4341] = Material.CraftingTable; + for (int i = 2920; i <= 2937; i++) + materials[i] = Material.CreakingHeart; + for (int i = 9796; i <= 9827; i++) + materials[i] = Material.CreeperHead; + for (int i = 9828; i <= 9835; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 20123; i <= 20146; i++) + materials[i] = Material.CrimsonButton; + for (int i = 20171; i <= 20234; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 19707; i <= 19738; i++) + materials[i] = Material.CrimsonFence; + for (int i = 19899; i <= 19930; i++) + materials[i] = Material.CrimsonFenceGate; + materials[19632] = Material.CrimsonFungus; + for (int i = 5450; i <= 5513; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 19625; i <= 19627; i++) + materials[i] = Material.CrimsonHyphae; + materials[19631] = Material.CrimsonNylium; + materials[19689] = Material.CrimsonPlanks; + for (int i = 19703; i <= 19704; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[19688] = Material.CrimsonRoots; + for (int i = 20299; i <= 20330; i++) + materials[i] = Material.CrimsonSign; + for (int i = 19691; i <= 19696; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 19963; i <= 20042; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 19619; i <= 19621; i++) + materials[i] = Material.CrimsonStem; + for (int i = 19771; i <= 19834; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 5778; i <= 5785; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 20363; i <= 20370; i++) + materials[i] = Material.CrimsonWallSign; + materials[20477] = Material.CryingObsidian; + materials[23975] = Material.CutCopper; + for (int i = 24322; i <= 24327; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 24224; i <= 24303; i++) + materials[i] = Material.CutCopperStairs; + materials[11970] = Material.CutRedSandstone; + for (int i = 12189; i <= 12194; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[580] = Material.CutSandstone; + for (int i = 12135; i <= 12140; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 11792; i <= 11807; i++) + materials[i] = Material.CyanBanner; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 21913; i <= 21928; i++) + materials[i] = Material.CyanCandle; + for (int i = 22045; i <= 22046; i++) + materials[i] = Material.CyanCandleCake; + materials[11626] = Material.CyanCarpet; + materials[13760] = Material.CyanConcrete; + materials[13776] = Material.CyanConcretePowder; + for (int i = 13723; i <= 13726; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 13645; i <= 13650; i++) + materials[i] = Material.CyanShulkerBox; + materials[6133] = Material.CyanStainedGlass; + for (int i = 10469; i <= 10500; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[10174] = Material.CyanTerracotta; + for (int i = 11940; i <= 11943; i++) + materials[i] = Material.CyanWallBanner; + materials[2102] = Material.CyanWool; + for (int i = 9924; i <= 9927; i++) + materials[i] = Material.DamagedAnvil; + materials[2121] = Material.Dandelion; + for (int i = 9540; i <= 9563; i++) + materials[i] = Material.DarkOakButton; + for (int i = 13101; i <= 13164; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 12653; i <= 12684; i++) + materials[i] = Material.DarkOakFence; + for (int i = 12365; i <= 12396; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 5322; i <= 5385; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 5904; i <= 5905; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 4558; i <= 4589; i++) + materials[i] = Material.DarkOakSign; + for (int i = 12087; i <= 12092; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 10853; i <= 10932; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 6524; i <= 6587; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 5754; i <= 5761; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 4906; i <= 4913; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + materials[11354] = Material.DarkPrismarine; + for (int i = 11607; i <= 11612; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 11515; i <= 11594; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 10000; i <= 10031; i++) + materials[i] = Material.DaylightDetector; + for (int i = 13838; i <= 13839; i++) + materials[i] = Material.DeadBrainCoral; + materials[13827] = Material.DeadBrainCoralBlock; + for (int i = 13858; i <= 13859; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 13884; i <= 13891; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 13840; i <= 13841; i++) + materials[i] = Material.DeadBubbleCoral; + materials[13828] = Material.DeadBubbleCoralBlock; + for (int i = 13860; i <= 13861; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 13892; i <= 13899; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2050] = Material.DeadBush; + for (int i = 13842; i <= 13843; i++) + materials[i] = Material.DeadFireCoral; + materials[13829] = Material.DeadFireCoralBlock; + for (int i = 13862; i <= 13863; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 13900; i <= 13907; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 13844; i <= 13845; i++) + materials[i] = Material.DeadHornCoral; + materials[13830] = Material.DeadHornCoralBlock; + for (int i = 13864; i <= 13865; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 13908; i <= 13915; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 13836; i <= 13837; i++) + materials[i] = Material.DeadTubeCoral; + materials[13826] = Material.DeadTubeCoralBlock; + for (int i = 13856; i <= 13857; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 13876; i <= 13883; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 27634; i <= 27649; i++) + materials[i] = Material.DecoratedPot; + for (int i = 25964; i <= 25966; i++) + materials[i] = Material.Deepslate; + for (int i = 27281; i <= 27286; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 27201; i <= 27280; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 27287; i <= 27610; i++) + materials[i] = Material.DeepslateBrickWall; + materials[27200] = Material.DeepslateBricks; + materials[134] = Material.DeepslateCoalOre; + materials[23971] = Material.DeepslateCopperOre; + materials[4339] = Material.DeepslateDiamondOre; + materials[8296] = Material.DeepslateEmeraldOre; + materials[130] = Material.DeepslateGoldOre; + materials[132] = Material.DeepslateIronOre; + materials[564] = Material.DeepslateLapisOre; + for (int i = 5914; i <= 5915; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 26870; i <= 26875; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 26790; i <= 26869; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 26876; i <= 27199; i++) + materials[i] = Material.DeepslateTileWall; + materials[26789] = Material.DeepslateTiles; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + materials[4340] = Material.DiamondBlock; + materials[4338] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 15177; i <= 15182; i++) + materials[i] = Material.DioriteSlab; + for (int i = 15025; i <= 15104; i++) + materials[i] = Material.DioriteStairs; + for (int i = 19071; i <= 19394; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[13536] = Material.DirtPath; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + materials[8200] = Material.DragonEgg; + for (int i = 9836; i <= 9867; i++) + materials[i] = Material.DragonHead; + for (int i = 9868; i <= 9875; i++) + materials[i] = Material.DragonWallHead; + materials[13810] = Material.DriedKelpBlock; + materials[25796] = Material.DripstoneBlock; + for (int i = 10153; i <= 10164; i++) + materials[i] = Material.Dropper; + materials[8449] = Material.EmeraldBlock; + materials[8295] = Material.EmeraldOre; + materials[8173] = Material.EnchantingTable; + materials[13537] = Material.EndGateway; + materials[8190] = Material.EndPortal; + for (int i = 8191; i <= 8198; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 13357; i <= 13362; i++) + materials[i] = Material.EndRod; + materials[8199] = Material.EndStone; + for (int i = 15135; i <= 15140; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 14385; i <= 14464; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 18747; i <= 19070; i++) + materials[i] = Material.EndStoneBrickWall; + materials[13517] = Material.EndStoneBricks; + for (int i = 8297; i <= 8304; i++) + materials[i] = Material.EnderChest; + materials[23978] = Material.ExposedChiseledCopper; + materials[23967] = Material.ExposedCopper; + for (int i = 25724; i <= 25727; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 24744; i <= 24807; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 25706; i <= 25707; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 25256; i <= 25319; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[23974] = Material.ExposedCutCopper; + for (int i = 24316; i <= 24321; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 24144; i <= 24223; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 4350; i <= 4357; i++) + materials[i] = Material.Farmland; + materials[2049] = Material.Fern; + for (int i = 2406; i <= 2917; i++) + materials[i] = Material.Fire; + for (int i = 13852; i <= 13853; i++) + materials[i] = Material.FireCoral; + materials[13834] = Material.FireCoralBlock; + for (int i = 13872; i <= 13873; i++) + materials[i] = Material.FireCoralFan; + for (int i = 13940; i <= 13947; i++) + materials[i] = Material.FireCoralWallFan; + materials[27913] = Material.FireflyBush; + materials[19460] = Material.FletchingTable; + materials[9351] = Material.FlowerPot; + materials[25853] = Material.FloweringAzalea; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[27632] = Material.Frogspawn; + for (int i = 13562; i <= 13565; i++) + materials[i] = Material.FrostedIce; + for (int i = 4358; i <= 4365; i++) + materials[i] = Material.Furnace; + materials[21313] = Material.GildedBlackstone; + materials[562] = Material.Glass; + for (int i = 7022; i <= 7053; i++) + materials[i] = Material.GlassPane; + for (int i = 7112; i <= 7239; i++) + materials[i] = Material.GlowLichen; + materials[6042] = Material.Glowstone; + materials[2137] = Material.GoldBlock; + materials[129] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 15153; i <= 15158; i++) + materials[i] = Material.GraniteSlab; + for (int i = 14705; i <= 14784; i++) + materials[i] = Material.GraniteStairs; + for (int i = 16479; i <= 16802; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[124] = Material.Gravel; + for (int i = 11760; i <= 11775; i++) + materials[i] = Material.GrayBanner; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 21881; i <= 21896; i++) + materials[i] = Material.GrayCandle; + for (int i = 22041; i <= 22042; i++) + materials[i] = Material.GrayCandleCake; + materials[11624] = Material.GrayCarpet; + materials[13758] = Material.GrayConcrete; + materials[13774] = Material.GrayConcretePowder; + for (int i = 13715; i <= 13718; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 13633; i <= 13638; i++) + materials[i] = Material.GrayShulkerBox; + materials[6131] = Material.GrayStainedGlass; + for (int i = 10405; i <= 10436; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[10172] = Material.GrayTerracotta; + for (int i = 11932; i <= 11935; i++) + materials[i] = Material.GrayWallBanner; + materials[2100] = Material.GrayWool; + for (int i = 11856; i <= 11871; i++) + materials[i] = Material.GreenBanner; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 21977; i <= 21992; i++) + materials[i] = Material.GreenCandle; + for (int i = 22053; i <= 22054; i++) + materials[i] = Material.GreenCandleCake; + materials[11630] = Material.GreenCarpet; + materials[13764] = Material.GreenConcrete; + materials[13780] = Material.GreenConcretePowder; + for (int i = 13739; i <= 13742; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 13669; i <= 13674; i++) + materials[i] = Material.GreenShulkerBox; + materials[6137] = Material.GreenStainedGlass; + for (int i = 10597; i <= 10628; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[10178] = Material.GreenTerracotta; + for (int i = 11956; i <= 11959; i++) + materials[i] = Material.GreenWallBanner; + materials[2106] = Material.GreenWool; + for (int i = 19461; i <= 19472; i++) + materials[i] = Material.Grindstone; + for (int i = 25960; i <= 25961; i++) + materials[i] = Material.HangingRoots; + for (int i = 11614; i <= 11616; i++) + materials[i] = Material.HayBlock; + for (int i = 27742; i <= 27743; i++) + materials[i] = Material.HeavyCore; + for (int i = 9968; i <= 9983; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[20473] = Material.HoneyBlock; + materials[20474] = Material.HoneycombBlock; + for (int i = 10034; i <= 10043; i++) + materials[i] = Material.Hopper; + for (int i = 13854; i <= 13855; i++) + materials[i] = Material.HornCoral; + materials[13835] = Material.HornCoralBlock; + for (int i = 13874; i <= 13875; i++) + materials[i] = Material.HornCoralFan; + for (int i = 13948; i <= 13955; i++) + materials[i] = Material.HornCoralWallFan; + materials[5958] = Material.Ice; + materials[6791] = Material.InfestedChiseledStoneBricks; + materials[6787] = Material.InfestedCobblestone; + materials[6790] = Material.InfestedCrackedStoneBricks; + for (int i = 27614; i <= 27616; i++) + materials[i] = Material.InfestedDeepslate; + materials[6789] = Material.InfestedMossyStoneBricks; + materials[6786] = Material.InfestedStone; + materials[6788] = Material.InfestedStoneBricks; + for (int i = 6984; i <= 7015; i++) + materials[i] = Material.IronBars; + materials[2138] = Material.IronBlock; + for (int i = 5828; i <= 5891; i++) + materials[i] = Material.IronDoor; + materials[131] = Material.IronOre; + for (int i = 11288; i <= 11351; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 6049; i <= 6052; i++) + materials[i] = Material.JackOLantern; + for (int i = 20383; i <= 20394; i++) + materials[i] = Material.Jigsaw; + for (int i = 5994; i <= 5995; i++) + materials[i] = Material.Jukebox; + for (int i = 9468; i <= 9491; i++) + materials[i] = Material.JungleButton; + for (int i = 12909; i <= 12972; i++) + materials[i] = Material.JungleDoor; + for (int i = 12557; i <= 12588; i++) + materials[i] = Material.JungleFence; + for (int i = 12269; i <= 12300; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 5258; i <= 5321; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 5898; i <= 5899; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 4526; i <= 4557; i++) + materials[i] = Material.JungleSign; + for (int i = 12069; i <= 12074; i++) + materials[i] = Material.JungleSlab; + for (int i = 8610; i <= 8689; i++) + materials[i] = Material.JungleStairs; + for (int i = 6332; i <= 6395; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 5746; i <= 5753; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 4898; i <= 4905; i++) + materials[i] = Material.JungleWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 13783; i <= 13808; i++) + materials[i] = Material.Kelp; + materials[13809] = Material.KelpPlant; + for (int i = 4750; i <= 4757; i++) + materials[i] = Material.Ladder; + for (int i = 19526; i <= 19529; i++) + materials[i] = Material.Lantern; + materials[565] = Material.LapisBlock; + materials[563] = Material.LapisOre; + for (int i = 22073; i <= 22084; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 11646; i <= 11647; i++) + materials[i] = Material.LargeFern; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + materials[8186] = Material.LavaCauldron; + for (int i = 25887; i <= 25902; i++) + materials[i] = Material.LeafLitter; + for (int i = 19473; i <= 19488; i++) + materials[i] = Material.Lectern; + for (int i = 5802; i <= 5825; i++) + materials[i] = Material.Lever; + for (int i = 11256; i <= 11287; i++) + materials[i] = Material.Light; + for (int i = 11696; i <= 11711; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 21817; i <= 21832; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 22033; i <= 22034; i++) + materials[i] = Material.LightBlueCandleCake; + materials[11620] = Material.LightBlueCarpet; + materials[13754] = Material.LightBlueConcrete; + materials[13770] = Material.LightBlueConcretePowder; + for (int i = 13699; i <= 13702; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 13609; i <= 13614; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[6127] = Material.LightBlueStainedGlass; + for (int i = 10277; i <= 10308; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[10168] = Material.LightBlueTerracotta; + for (int i = 11916; i <= 11919; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2096] = Material.LightBlueWool; + for (int i = 11776; i <= 11791; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 21897; i <= 21912; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 22043; i <= 22044; i++) + materials[i] = Material.LightGrayCandleCake; + materials[11625] = Material.LightGrayCarpet; + materials[13759] = Material.LightGrayConcrete; + materials[13775] = Material.LightGrayConcretePowder; + for (int i = 13719; i <= 13722; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 13639; i <= 13644; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[6132] = Material.LightGrayStainedGlass; + for (int i = 10437; i <= 10468; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[10173] = Material.LightGrayTerracotta; + for (int i = 11936; i <= 11939; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2101] = Material.LightGrayWool; + for (int i = 9952; i <= 9967; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 25752; i <= 25775; i++) + materials[i] = Material.LightningRod; + for (int i = 11638; i <= 11639; i++) + materials[i] = Material.Lilac; + materials[2134] = Material.LilyOfTheValley; + materials[7642] = Material.LilyPad; + for (int i = 11728; i <= 11743; i++) + materials[i] = Material.LimeBanner; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; + for (int i = 21849; i <= 21864; i++) + materials[i] = Material.LimeCandle; + for (int i = 22037; i <= 22038; i++) + materials[i] = Material.LimeCandleCake; + materials[11622] = Material.LimeCarpet; + materials[13756] = Material.LimeConcrete; + materials[13772] = Material.LimeConcretePowder; + for (int i = 13707; i <= 13710; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 13621; i <= 13626; i++) + materials[i] = Material.LimeShulkerBox; + materials[6129] = Material.LimeStainedGlass; + for (int i = 10341; i <= 10372; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[10170] = Material.LimeTerracotta; + for (int i = 11924; i <= 11927; i++) + materials[i] = Material.LimeWallBanner; + materials[2098] = Material.LimeWool; + materials[20487] = Material.Lodestone; + for (int i = 19427; i <= 19430; i++) + materials[i] = Material.Loom; + for (int i = 11680; i <= 11695; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 21801; i <= 21816; i++) + materials[i] = Material.MagentaCandle; + for (int i = 22031; i <= 22032; i++) + materials[i] = Material.MagentaCandleCake; + materials[11619] = Material.MagentaCarpet; + materials[13753] = Material.MagentaConcrete; + materials[13769] = Material.MagentaConcretePowder; + for (int i = 13695; i <= 13698; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 13603; i <= 13608; i++) + materials[i] = Material.MagentaShulkerBox; + materials[6126] = Material.MagentaStainedGlass; + for (int i = 10245; i <= 10276; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[10167] = Material.MagentaTerracotta; + for (int i = 11912; i <= 11915; i++) + materials[i] = Material.MagentaWallBanner; + materials[2095] = Material.MagentaWool; + materials[13566] = Material.MagmaBlock; + for (int i = 9588; i <= 9611; i++) + materials[i] = Material.MangroveButton; + for (int i = 13229; i <= 13292; i++) + materials[i] = Material.MangroveDoor; + for (int i = 12717; i <= 12748; i++) + materials[i] = Material.MangroveFence; + for (int i = 12429; i <= 12460; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 5578; i <= 5641; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + materials[26] = Material.MangrovePlanks; + for (int i = 5908; i <= 5909; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 4622; i <= 4653; i++) + materials[i] = Material.MangroveSign; + for (int i = 12099; i <= 12104; i++) + materials[i] = Material.MangroveSlab; + for (int i = 11013; i <= 11092; i++) + materials[i] = Material.MangroveStairs; + for (int i = 6652; i <= 6715; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 5770; i <= 5777; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 4922; i <= 4929; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 22085; i <= 22096; i++) + materials[i] = Material.MediumAmethystBud; + materials[7055] = Material.Melon; + for (int i = 7072; i <= 7079; i++) + materials[i] = Material.MelonStem; + materials[25903] = Material.MossBlock; + materials[25854] = Material.MossCarpet; + materials[2399] = Material.MossyCobblestone; + for (int i = 15129; i <= 15134; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 14305; i <= 14384; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 9027; i <= 9350; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 15117; i <= 15122; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 14145; i <= 14224; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 16155; i <= 16478; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[6781] = Material.MossyStoneBricks; + for (int i = 2109; i <= 2120; i++) + materials[i] = Material.MovingPiston; + materials[25963] = Material.Mud; + for (int i = 12165; i <= 12170; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 7560; i <= 7639; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 17127; i <= 17450; i++) + materials[i] = Material.MudBrickWall; + materials[6785] = Material.MudBricks; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 6920; i <= 6983; i++) + materials[i] = Material.MushroomStem; + for (int i = 7640; i <= 7641; i++) + materials[i] = Material.Mycelium; + for (int i = 8057; i <= 8088; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 12171; i <= 12176; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 8089; i <= 8168; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 17451; i <= 17774; i++) + materials[i] = Material.NetherBrickWall; + materials[8056] = Material.NetherBricks; + materials[135] = Material.NetherGoldOre; + for (int i = 6043; i <= 6044; i++) + materials[i] = Material.NetherPortal; + materials[10033] = Material.NetherQuartzOre; + materials[19618] = Material.NetherSprouts; + for (int i = 8169; i <= 8172; i++) + materials[i] = Material.NetherWart; + materials[13567] = Material.NetherWartBlock; + materials[20475] = Material.NetheriteBlock; + materials[6028] = Material.Netherrack; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 9396; i <= 9419; i++) + materials[i] = Material.OakButton; + for (int i = 4686; i <= 4749; i++) + materials[i] = Material.OakDoor; + for (int i = 5996; i <= 6027; i++) + materials[i] = Material.OakFence; + for (int i = 7368; i <= 7399; i++) + materials[i] = Material.OakFenceGate; + for (int i = 4938; i <= 5001; i++) + materials[i] = Material.OakHangingSign; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 5892; i <= 5893; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 4366; i <= 4397; i++) + materials[i] = Material.OakSign; + for (int i = 12051; i <= 12056; i++) + materials[i] = Material.OakSlab; + for (int i = 2938; i <= 3017; i++) + materials[i] = Material.OakStairs; + for (int i = 6140; i <= 6203; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 5706; i <= 5713; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 4858; i <= 4865; i++) + materials[i] = Material.OakWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 13573; i <= 13584; i++) + materials[i] = Material.Observer; + materials[2400] = Material.Obsidian; + for (int i = 27623; i <= 27625; i++) + materials[i] = Material.OchreFroglight; + materials[27909] = Material.OpenEyeblossom; + for (int i = 11664; i <= 11679; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 21785; i <= 21800; i++) + materials[i] = Material.OrangeCandle; + for (int i = 22029; i <= 22030; i++) + materials[i] = Material.OrangeCandleCake; + materials[11618] = Material.OrangeCarpet; + materials[13752] = Material.OrangeConcrete; + materials[13768] = Material.OrangeConcretePowder; + for (int i = 13691; i <= 13694; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 13597; i <= 13602; i++) + materials[i] = Material.OrangeShulkerBox; + materials[6125] = Material.OrangeStainedGlass; + for (int i = 10213; i <= 10244; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[10166] = Material.OrangeTerracotta; + materials[2128] = Material.OrangeTulip; + for (int i = 11908; i <= 11911; i++) + materials[i] = Material.OrangeWallBanner; + materials[2094] = Material.OrangeWool; + materials[2131] = Material.OxeyeDaisy; + materials[23976] = Material.OxidizedChiseledCopper; + materials[23969] = Material.OxidizedCopper; + for (int i = 25732; i <= 25735; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 24808; i <= 24871; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 25710; i <= 25711; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 25320; i <= 25383; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[23972] = Material.OxidizedCutCopper; + for (int i = 24304; i <= 24309; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 23984; i <= 24063; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[11635] = Material.PackedIce; + materials[6784] = Material.PackedMud; + for (int i = 27907; i <= 27908; i++) + materials[i] = Material.PaleHangingMoss; + materials[27744] = Material.PaleMossBlock; + for (int i = 27745; i <= 27906; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 9564; i <= 9587; i++) + materials[i] = Material.PaleOakButton; + for (int i = 13165; i <= 13228; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 12685; i <= 12716; i++) + materials[i] = Material.PaleOakFence; + for (int i = 12397; i <= 12428; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 5386; i <= 5449; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + materials[25] = Material.PaleOakPlanks; + for (int i = 5906; i <= 5907; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 4590; i <= 4621; i++) + materials[i] = Material.PaleOakSign; + for (int i = 12093; i <= 12098; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 10933; i <= 11012; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 6588; i <= 6651; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 5762; i <= 5769; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 4914; i <= 4921; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 27629; i <= 27631; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 11642; i <= 11643; i++) + materials[i] = Material.Peony; + for (int i = 12141; i <= 12146; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 9876; i <= 9907; i++) + materials[i] = Material.PiglinHead; + for (int i = 9908; i <= 9915; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 11744; i <= 11759; i++) + materials[i] = Material.PinkBanner; + for (int i = 1827; i <= 1842; i++) + materials[i] = Material.PinkBed; + for (int i = 21865; i <= 21880; i++) + materials[i] = Material.PinkCandle; + for (int i = 22039; i <= 22040; i++) + materials[i] = Material.PinkCandleCake; + materials[11623] = Material.PinkCarpet; + materials[13757] = Material.PinkConcrete; + materials[13773] = Material.PinkConcretePowder; + for (int i = 13711; i <= 13714; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 25855; i <= 25870; i++) + materials[i] = Material.PinkPetals; + for (int i = 13627; i <= 13632; i++) + materials[i] = Material.PinkShulkerBox; + materials[6130] = Material.PinkStainedGlass; + for (int i = 10373; i <= 10404; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[10171] = Material.PinkTerracotta; + materials[2130] = Material.PinkTulip; + for (int i = 11928; i <= 11931; i++) + materials[i] = Material.PinkWallBanner; + materials[2099] = Material.PinkWool; + for (int i = 2057; i <= 2068; i++) + materials[i] = Material.Piston; + for (int i = 2069; i <= 2092; i++) + materials[i] = Material.PistonHead; + for (int i = 13520; i <= 13529; i++) + materials[i] = Material.PitcherCrop; + for (int i = 13530; i <= 13531; i++) + materials[i] = Material.PitcherPlant; + for (int i = 9756; i <= 9787; i++) + materials[i] = Material.PlayerHead; + for (int i = 9788; i <= 9795; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 25776; i <= 25795; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 15171; i <= 15176; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 14945; i <= 15024; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 6034; i <= 6036; i++) + materials[i] = Material.PolishedBasalt; + materials[20899] = Material.PolishedBlackstone; + for (int i = 20903; i <= 20908; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 20909; i <= 20988; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 20989; i <= 21312; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[20900] = Material.PolishedBlackstoneBricks; + for (int i = 21402; i <= 21425; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 21400; i <= 21401; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 21394; i <= 21399; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 21314; i <= 21393; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 21426; i <= 21749; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[26378] = Material.PolishedDeepslate; + for (int i = 26459; i <= 26464; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 26379; i <= 26458; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 26465; i <= 26788; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 15123; i <= 15128; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 14225; i <= 14304; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 15105; i <= 15110; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 13985; i <= 14064; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[22520] = Material.PolishedTuff; + for (int i = 22521; i <= 22526; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 22527; i <= 22606; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 22607; i <= 22930; i++) + materials[i] = Material.PolishedTuffWall; + materials[2123] = Material.Poppy; + for (int i = 9388; i <= 9395; i++) + materials[i] = Material.Potatoes; + materials[9357] = Material.PottedAcaciaSapling; + materials[9366] = Material.PottedAllium; + materials[27621] = Material.PottedAzaleaBush; + materials[9367] = Material.PottedAzureBluet; + materials[13980] = Material.PottedBamboo; + materials[9355] = Material.PottedBirchSapling; + materials[9365] = Material.PottedBlueOrchid; + materials[9377] = Material.PottedBrownMushroom; + materials[9379] = Material.PottedCactus; + materials[9358] = Material.PottedCherrySapling; + materials[27912] = Material.PottedClosedEyeblossom; + materials[9373] = Material.PottedCornflower; + materials[20483] = Material.PottedCrimsonFungus; + materials[20485] = Material.PottedCrimsonRoots; + materials[9363] = Material.PottedDandelion; + materials[9359] = Material.PottedDarkOakSapling; + materials[9378] = Material.PottedDeadBush; + materials[9362] = Material.PottedFern; + materials[27622] = Material.PottedFloweringAzaleaBush; + materials[9356] = Material.PottedJungleSapling; + materials[9374] = Material.PottedLilyOfTheValley; + materials[9361] = Material.PottedMangrovePropagule; + materials[9353] = Material.PottedOakSapling; + materials[27911] = Material.PottedOpenEyeblossom; + materials[9369] = Material.PottedOrangeTulip; + materials[9372] = Material.PottedOxeyeDaisy; + materials[9360] = Material.PottedPaleOakSapling; + materials[9371] = Material.PottedPinkTulip; + materials[9364] = Material.PottedPoppy; + materials[9376] = Material.PottedRedMushroom; + materials[9368] = Material.PottedRedTulip; + materials[9354] = Material.PottedSpruceSapling; + materials[9352] = Material.PottedTorchflower; + materials[20484] = Material.PottedWarpedFungus; + materials[20486] = Material.PottedWarpedRoots; + materials[9370] = Material.PottedWhiteTulip; + materials[9375] = Material.PottedWitherRose; + materials[23346] = Material.PowderSnow; + for (int i = 8187; i <= 8189; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + materials[11352] = Material.Prismarine; + for (int i = 11601; i <= 11606; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 11435; i <= 11514; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[11353] = Material.PrismarineBricks; + for (int i = 11595; i <= 11600; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 11355; i <= 11434; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 15507; i <= 15830; i++) + materials[i] = Material.PrismarineWall; + materials[7054] = Material.Pumpkin; + for (int i = 7064; i <= 7071; i++) + materials[i] = Material.PumpkinStem; + for (int i = 11808; i <= 11823; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 21929; i <= 21944; i++) + materials[i] = Material.PurpleCandle; + for (int i = 22047; i <= 22048; i++) + materials[i] = Material.PurpleCandleCake; + materials[11627] = Material.PurpleCarpet; + materials[13761] = Material.PurpleConcrete; + materials[13777] = Material.PurpleConcretePowder; + for (int i = 13727; i <= 13730; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 13651; i <= 13656; i++) + materials[i] = Material.PurpleShulkerBox; + materials[6134] = Material.PurpleStainedGlass; + for (int i = 10501; i <= 10532; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[10175] = Material.PurpleTerracotta; + for (int i = 11944; i <= 11947; i++) + materials[i] = Material.PurpleWallBanner; + materials[2103] = Material.PurpleWool; + materials[13433] = Material.PurpurBlock; + for (int i = 13434; i <= 13436; i++) + materials[i] = Material.PurpurPillar; + for (int i = 12195; i <= 12200; i++) + materials[i] = Material.PurpurSlab; + for (int i = 13437; i <= 13516; i++) + materials[i] = Material.PurpurStairs; + materials[10044] = Material.QuartzBlock; + materials[21752] = Material.QuartzBricks; + for (int i = 10046; i <= 10048; i++) + materials[i] = Material.QuartzPillar; + for (int i = 12177; i <= 12182; i++) + materials[i] = Material.QuartzSlab; + for (int i = 10049; i <= 10128; i++) + materials[i] = Material.QuartzStairs; + for (int i = 4758; i <= 4777; i++) + materials[i] = Material.Rail; + materials[27619] = Material.RawCopperBlock; + materials[27620] = Material.RawGoldBlock; + materials[27618] = Material.RawIronBlock; + for (int i = 11872; i <= 11887; i++) + materials[i] = Material.RedBanner; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 21993; i <= 22008; i++) + materials[i] = Material.RedCandle; + for (int i = 22055; i <= 22056; i++) + materials[i] = Material.RedCandleCake; + materials[11631] = Material.RedCarpet; + materials[13765] = Material.RedConcrete; + materials[13781] = Material.RedConcretePowder; + for (int i = 13743; i <= 13746; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2136] = Material.RedMushroom; + for (int i = 6856; i <= 6919; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 15165; i <= 15170; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 14865; i <= 14944; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 18099; i <= 18422; i++) + materials[i] = Material.RedNetherBrickWall; + materials[13568] = Material.RedNetherBricks; + materials[123] = Material.RedSand; + materials[11968] = Material.RedSandstone; + for (int i = 12183; i <= 12188; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 11971; i <= 12050; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 15831; i <= 16154; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 13675; i <= 13680; i++) + materials[i] = Material.RedShulkerBox; + materials[6138] = Material.RedStainedGlass; + for (int i = 10629; i <= 10660; i++) + materials[i] = Material.RedStainedGlassPane; + materials[10179] = Material.RedTerracotta; + materials[2127] = Material.RedTulip; + for (int i = 11960; i <= 11963; i++) + materials[i] = Material.RedWallBanner; + materials[2107] = Material.RedWool; + materials[10032] = Material.RedstoneBlock; + for (int i = 8201; i <= 8202; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 5912; i <= 5913; i++) + materials[i] = Material.RedstoneOre; + for (int i = 5916; i <= 5917; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 5918; i <= 5925; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 3042; i <= 4337; i++) + materials[i] = Material.RedstoneWire; + materials[27633] = Material.ReinforcedDeepslate; + for (int i = 6060; i <= 6123; i++) + materials[i] = Material.Repeater; + for (int i = 13538; i <= 13549; i++) + materials[i] = Material.RepeatingCommandBlock; + materials[7643] = Material.ResinBlock; + for (int i = 7725; i <= 7730; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 7645; i <= 7724; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 7731; i <= 8054; i++) + materials[i] = Material.ResinBrickWall; + materials[7644] = Material.ResinBricks; + for (int i = 7240; i <= 7367; i++) + materials[i] = Material.ResinClump; + for (int i = 20478; i <= 20482; i++) + materials[i] = Material.RespawnAnchor; + materials[25962] = Material.RootedDirt; + for (int i = 11640; i <= 11641; i++) + materials[i] = Material.RoseBush; + materials[118] = Material.Sand; + materials[578] = Material.Sandstone; + for (int i = 12129; i <= 12134; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 8215; i <= 8294; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 18423; i <= 18746; i++) + materials[i] = Material.SandstoneWall; + for (int i = 19395; i <= 19426; i++) + materials[i] = Material.Scaffolding; + materials[23827] = Material.Sculk; + for (int i = 23956; i <= 23957; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 23347; i <= 23442; i++) + materials[i] = Material.SculkSensor; + for (int i = 23958; i <= 23965; i++) + materials[i] = Material.SculkShrieker; + for (int i = 23828; i <= 23955; i++) + materials[i] = Material.SculkVein; + materials[11613] = Material.SeaLantern; + for (int i = 13956; i <= 13963; i++) + materials[i] = Material.SeaPickle; + materials[2054] = Material.Seagrass; + materials[2052] = Material.ShortDryGrass; + materials[2048] = Material.ShortGrass; + materials[19633] = Material.Shroomlight; + for (int i = 13585; i <= 13590; i++) + materials[i] = Material.ShulkerBox; + for (int i = 9636; i <= 9667; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 9668; i <= 9675; i++) + materials[i] = Material.SkeletonWallSkull; + materials[11253] = Material.SlimeBlock; + for (int i = 22097; i <= 22108; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 25944; i <= 25959; i++) + materials[i] = Material.SmallDripleaf; + materials[19489] = Material.SmithingTable; + for (int i = 19443; i <= 19450; i++) + materials[i] = Material.Smoker; + materials[27617] = Material.SmoothBasalt; + materials[12203] = Material.SmoothQuartz; + for (int i = 15147; i <= 15152; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 14625; i <= 14704; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[12204] = Material.SmoothRedSandstone; + for (int i = 15111; i <= 15116; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 14065; i <= 14144; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[12202] = Material.SmoothSandstone; + for (int i = 15141; i <= 15146; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 14545; i <= 14624; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[12201] = Material.SmoothStone; + for (int i = 12123; i <= 12128; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13823; i <= 13825; i++) + materials[i] = Material.SnifferEgg; + for (int i = 5950; i <= 5957; i++) + materials[i] = Material.Snow; + materials[5959] = Material.SnowBlock; + for (int i = 19566; i <= 19597; i++) + materials[i] = Material.SoulCampfire; + materials[2918] = Material.SoulFire; + for (int i = 19530; i <= 19533; i++) + materials[i] = Material.SoulLantern; + materials[6029] = Material.SoulSand; + materials[6030] = Material.SoulSoil; + materials[6037] = Material.SoulTorch; + for (int i = 6038; i <= 6041; i++) + materials[i] = Material.SoulWallTorch; + materials[2919] = Material.Spawner; + materials[560] = Material.Sponge; + materials[25851] = Material.SporeBlossom; + for (int i = 9420; i <= 9443; i++) + materials[i] = Material.SpruceButton; + for (int i = 12781; i <= 12844; i++) + materials[i] = Material.SpruceDoor; + for (int i = 12493; i <= 12524; i++) + materials[i] = Material.SpruceFence; + for (int i = 12205; i <= 12236; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 5002; i <= 5065; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 5894; i <= 5895; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 4398; i <= 4429; i++) + materials[i] = Material.SpruceSign; + for (int i = 12057; i <= 12062; i++) + materials[i] = Material.SpruceSlab; + for (int i = 8450; i <= 8529; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6204; i <= 6267; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 5714; i <= 5721; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 4866; i <= 4873; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 12159; i <= 12164; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 7480; i <= 7559; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 16803; i <= 17126; i++) + materials[i] = Material.StoneBrickWall; + materials[6780] = Material.StoneBricks; + for (int i = 5926; i <= 5949; i++) + materials[i] = Material.StoneButton; + for (int i = 5826; i <= 5827; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 12117; i <= 12122; i++) + materials[i] = Material.StoneSlab; + for (int i = 14465; i <= 14544; i++) + materials[i] = Material.StoneStairs; + for (int i = 19490; i <= 19493; i++) + materials[i] = Material.Stonecutter; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 19628; i <= 19630; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 19622; i <= 19624; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 19611; i <= 19613; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 19605; i <= 19607; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 20379; i <= 20382; i++) + materials[i] = Material.StructureBlock; + materials[13572] = Material.StructureVoid; + for (int i = 5978; i <= 5993; i++) + materials[i] = Material.SugarCane; + for (int i = 11636; i <= 11637; i++) + materials[i] = Material.Sunflower; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 19598; i <= 19601; i++) + materials[i] = Material.SweetBerryBush; + materials[2053] = Material.TallDryGrass; + for (int i = 11644; i <= 11645; i++) + materials[i] = Material.TallGrass; + for (int i = 2055; i <= 2056; i++) + materials[i] = Material.TallSeagrass; + for (int i = 20409; i <= 20424; i++) + materials[i] = Material.Target; + materials[11633] = Material.Terracotta; + for (int i = 20395; i <= 20398; i++) + materials[i] = Material.TestBlock; + materials[20399] = Material.TestInstanceBlock; + materials[23345] = Material.TintedGlass; + for (int i = 2140; i <= 2141; i++) + materials[i] = Material.Tnt; + materials[2401] = Material.Torch; + materials[2122] = Material.Torchflower; + for (int i = 13518; i <= 13519; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 9928; i <= 9951; i++) + materials[i] = Material.TrappedChest; + for (int i = 27698; i <= 27709; i++) + materials[i] = Material.TrialSpawner; + for (int i = 8321; i <= 8448; i++) + materials[i] = Material.Tripwire; + for (int i = 8305; i <= 8320; i++) + materials[i] = Material.TripwireHook; + for (int i = 13846; i <= 13847; i++) + materials[i] = Material.TubeCoral; + materials[13831] = Material.TubeCoralBlock; + for (int i = 13866; i <= 13867; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 13916; i <= 13923; i++) + materials[i] = Material.TubeCoralWallFan; + materials[22109] = Material.Tuff; + for (int i = 22933; i <= 22938; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 22939; i <= 23018; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 23019; i <= 23342; i++) + materials[i] = Material.TuffBrickWall; + materials[22932] = Material.TuffBricks; + for (int i = 22110; i <= 22115; i++) + materials[i] = Material.TuffSlab; + for (int i = 22116; i <= 22195; i++) + materials[i] = Material.TuffStairs; + for (int i = 22196; i <= 22519; i++) + materials[i] = Material.TuffWall; + for (int i = 13811; i <= 13822; i++) + materials[i] = Material.TurtleEgg; + for (int i = 19661; i <= 19686; i++) + materials[i] = Material.TwistingVines; + materials[19687] = Material.TwistingVinesPlant; + for (int i = 27710; i <= 27741; i++) + materials[i] = Material.Vault; + for (int i = 27626; i <= 27628; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 7080; i <= 7111; i++) + materials[i] = Material.Vine; + materials[13981] = Material.VoidAir; + for (int i = 2402; i <= 2405; i++) + materials[i] = Material.WallTorch; + for (int i = 20147; i <= 20170; i++) + materials[i] = Material.WarpedButton; + for (int i = 20235; i <= 20298; i++) + materials[i] = Material.WarpedDoor; + for (int i = 19739; i <= 19770; i++) + materials[i] = Material.WarpedFence; + for (int i = 19931; i <= 19962; i++) + materials[i] = Material.WarpedFenceGate; + materials[19615] = Material.WarpedFungus; + for (int i = 5514; i <= 5577; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 19608; i <= 19610; i++) + materials[i] = Material.WarpedHyphae; + materials[19614] = Material.WarpedNylium; + materials[19690] = Material.WarpedPlanks; + for (int i = 19705; i <= 19706; i++) + materials[i] = Material.WarpedPressurePlate; + materials[19617] = Material.WarpedRoots; + for (int i = 20331; i <= 20362; i++) + materials[i] = Material.WarpedSign; + for (int i = 19697; i <= 19702; i++) + materials[i] = Material.WarpedSlab; + for (int i = 20043; i <= 20122; i++) + materials[i] = Material.WarpedStairs; + for (int i = 19602; i <= 19604; i++) + materials[i] = Material.WarpedStem; + for (int i = 19835; i <= 19898; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 5786; i <= 5793; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 20371; i <= 20378; i++) + materials[i] = Material.WarpedWallSign; + materials[19616] = Material.WarpedWartBlock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 8183; i <= 8185; i++) + materials[i] = Material.WaterCauldron; + materials[23983] = Material.WaxedChiseledCopper; + materials[24328] = Material.WaxedCopperBlock; + for (int i = 25736; i <= 25739; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 24936; i <= 24999; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 25712; i <= 25713; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 25448; i <= 25511; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[24335] = Material.WaxedCutCopper; + for (int i = 24674; i <= 24679; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 24576; i <= 24655; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[23982] = Material.WaxedExposedChiseledCopper; + materials[24330] = Material.WaxedExposedCopper; + for (int i = 25740; i <= 25743; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 25000; i <= 25063; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 25714; i <= 25715; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 25512; i <= 25575; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[24334] = Material.WaxedExposedCutCopper; + for (int i = 24668; i <= 24673; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 24496; i <= 24575; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[23980] = Material.WaxedOxidizedChiseledCopper; + materials[24331] = Material.WaxedOxidizedCopper; + for (int i = 25748; i <= 25751; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 25064; i <= 25127; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 25718; i <= 25719; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 25576; i <= 25639; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[24332] = Material.WaxedOxidizedCutCopper; + for (int i = 24656; i <= 24661; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 24336; i <= 24415; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[23981] = Material.WaxedWeatheredChiseledCopper; + materials[24329] = Material.WaxedWeatheredCopper; + for (int i = 25744; i <= 25747; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 25128; i <= 25191; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 25716; i <= 25717; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 25640; i <= 25703; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[24333] = Material.WaxedWeatheredCutCopper; + for (int i = 24662; i <= 24667; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 24416; i <= 24495; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[23977] = Material.WeatheredChiseledCopper; + materials[23968] = Material.WeatheredCopper; + for (int i = 25728; i <= 25731; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 24872; i <= 24935; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 25708; i <= 25709; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 25384; i <= 25447; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[23973] = Material.WeatheredCutCopper; + for (int i = 24310; i <= 24315; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 24064; i <= 24143; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 19634; i <= 19659; i++) + materials[i] = Material.WeepingVines; + materials[19660] = Material.WeepingVinesPlant; + materials[561] = Material.WetSponge; + for (int i = 4342; i <= 4349; i++) + materials[i] = Material.Wheat; + for (int i = 11648; i <= 11663; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 21769; i <= 21784; i++) + materials[i] = Material.WhiteCandle; + for (int i = 22027; i <= 22028; i++) + materials[i] = Material.WhiteCandleCake; + materials[11617] = Material.WhiteCarpet; + materials[13751] = Material.WhiteConcrete; + materials[13767] = Material.WhiteConcretePowder; + for (int i = 13687; i <= 13690; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 13591; i <= 13596; i++) + materials[i] = Material.WhiteShulkerBox; + materials[6124] = Material.WhiteStainedGlass; + for (int i = 10181; i <= 10212; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[10165] = Material.WhiteTerracotta; + materials[2129] = Material.WhiteTulip; + for (int i = 11904; i <= 11907; i++) + materials[i] = Material.WhiteWallBanner; + materials[2093] = Material.WhiteWool; + for (int i = 25871; i <= 25886; i++) + materials[i] = Material.Wildflowers; + materials[2133] = Material.WitherRose; + for (int i = 9676; i <= 9707; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 9708; i <= 9715; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 11712; i <= 11727; i++) + materials[i] = Material.YellowBanner; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 21833; i <= 21848; i++) + materials[i] = Material.YellowCandle; + for (int i = 22035; i <= 22036; i++) + materials[i] = Material.YellowCandleCake; + materials[11621] = Material.YellowCarpet; + materials[13755] = Material.YellowConcrete; + materials[13771] = Material.YellowConcretePowder; + for (int i = 13703; i <= 13706; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 13615; i <= 13620; i++) + materials[i] = Material.YellowShulkerBox; + materials[6128] = Material.YellowStainedGlass; + for (int i = 10309; i <= 10340; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[10169] = Material.YellowTerracotta; + for (int i = 11920; i <= 11923; i++) + materials[i] = Material.YellowWallBanner; + materials[2097] = Material.YellowWool; + for (int i = 9716; i <= 9747; i++) + materials[i] = Material.ZombieHead; + for (int i = 9748; i <= 9755; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetaDataType.cs b/MinecraftClient/Mapping/EntityMetaDataType.cs index 53afecfa..075bb52d 100644 --- a/MinecraftClient/Mapping/EntityMetaDataType.cs +++ b/MinecraftClient/Mapping/EntityMetaDataType.cs @@ -26,6 +26,10 @@ public enum EntityMetaDataType Direction, OptionalUuid, /// + /// Boolean + UUID (1.21.5+, replaces OptionalUuid) + /// + OptionalLivingEntityReference, + /// /// VarInt /// BlockId, @@ -55,9 +59,25 @@ public enum EntityMetaDataType /// /// VarInt (1.20.6+) /// + CowVariant, + /// + /// VarInt (1.20.6+) + /// WolfVariant, + /// + /// VarInt (1.21.5+) + /// + WolfSoundVariant, FrogVariant, /// + /// VarInt (1.21.5+) + /// + PigVariant, + /// + /// VarInt (1.21.5+) + /// + ChickenVariant, + /// /// String + Position /// GlobalPosition, diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 369672de..e9496d8b 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -24,6 +24,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 + <= Protocol18Handler.MC_1_21_5_Version => new EntityMetadataPalette1215(), // 1.21.5 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1215.cs b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1215.cs new file mode 100644 index 00000000..71653f03 --- /dev/null +++ b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1215.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityMetadataPalettes; + +public class EntityMetadataPalette1215 : EntityMetadataPalette +{ + private readonly Dictionary entityMetadataMappings = new() + { + { 0, EntityMetaDataType.Byte }, + { 1, EntityMetaDataType.VarInt }, + { 2, EntityMetaDataType.VarLong }, + { 3, EntityMetaDataType.Float }, + { 4, EntityMetaDataType.String }, + { 5, EntityMetaDataType.Chat }, + { 6, EntityMetaDataType.OptionalChat }, + { 7, EntityMetaDataType.Slot }, + { 8, EntityMetaDataType.Boolean }, + { 9, EntityMetaDataType.Rotation }, + { 10, EntityMetaDataType.Position }, + { 11, EntityMetaDataType.OptionalPosition }, + { 12, EntityMetaDataType.Direction }, + { 13, EntityMetaDataType.OptionalLivingEntityReference }, + { 14, EntityMetaDataType.BlockId }, + { 15, EntityMetaDataType.OptionalBlockId }, + { 16, EntityMetaDataType.Nbt }, + { 17, EntityMetaDataType.Particle }, + { 18, EntityMetaDataType.Particles }, + { 19, EntityMetaDataType.VillagerData }, + { 20, EntityMetaDataType.OptionalVarInt }, + { 21, EntityMetaDataType.Pose }, + { 22, EntityMetaDataType.CatVariant }, + { 23, EntityMetaDataType.CowVariant }, + { 24, EntityMetaDataType.WolfVariant }, + { 25, EntityMetaDataType.WolfSoundVariant }, + { 26, EntityMetaDataType.FrogVariant }, + { 27, EntityMetaDataType.PigVariant }, + { 28, EntityMetaDataType.ChickenVariant }, + { 29, EntityMetaDataType.OptionalGlobalPosition }, + { 30, EntityMetaDataType.PaintingVariant }, + { 31, EntityMetaDataType.SnifferState }, + { 32, EntityMetaDataType.ArmadilloState }, + { 33, EntityMetaDataType.Vector3 }, + { 34, EntityMetaDataType.Quaternion }, + }; + + public override Dictionary GetEntityMetadataMappingsList() + { + return entityMetadataMappings; + } +} diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1215.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1215.cs new file mode 100644 index 00000000..ebfe6ab3 --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1215.cs @@ -0,0 +1,168 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1215 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1215() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.Cat; + mappings[21] = EntityType.CaveSpider; + mappings[22] = EntityType.CherryBoat; + mappings[23] = EntityType.CherryChestBoat; + mappings[24] = EntityType.ChestMinecart; + mappings[25] = EntityType.Chicken; + mappings[26] = EntityType.Cod; + mappings[27] = EntityType.CommandBlockMinecart; + mappings[28] = EntityType.Cow; + mappings[29] = EntityType.Creaking; + mappings[30] = EntityType.Creeper; + mappings[31] = EntityType.DarkOakBoat; + mappings[32] = EntityType.DarkOakChestBoat; + mappings[33] = EntityType.Dolphin; + mappings[34] = EntityType.Donkey; + mappings[35] = EntityType.DragonFireball; + mappings[36] = EntityType.Drowned; + mappings[37] = EntityType.Egg; + mappings[38] = EntityType.ElderGuardian; + mappings[39] = EntityType.Enderman; + mappings[40] = EntityType.Endermite; + mappings[41] = EntityType.EnderDragon; + mappings[42] = EntityType.EnderPearl; + mappings[43] = EntityType.EndCrystal; + mappings[44] = EntityType.Evoker; + mappings[45] = EntityType.EvokerFangs; + mappings[46] = EntityType.ExperienceBottle; + mappings[47] = EntityType.ExperienceOrb; + mappings[48] = EntityType.EyeOfEnder; + mappings[49] = EntityType.FallingBlock; + mappings[50] = EntityType.Fireball; + mappings[51] = EntityType.FireworkRocket; + mappings[52] = EntityType.Fox; + mappings[53] = EntityType.Frog; + mappings[54] = EntityType.FurnaceMinecart; + mappings[55] = EntityType.Ghast; + mappings[56] = EntityType.Giant; + mappings[57] = EntityType.GlowItemFrame; + mappings[58] = EntityType.GlowSquid; + mappings[59] = EntityType.Goat; + mappings[60] = EntityType.Guardian; + mappings[61] = EntityType.Hoglin; + mappings[62] = EntityType.HopperMinecart; + mappings[63] = EntityType.Horse; + mappings[64] = EntityType.Husk; + mappings[65] = EntityType.Illusioner; + mappings[66] = EntityType.Interaction; + mappings[67] = EntityType.IronGolem; + mappings[68] = EntityType.Item; + mappings[69] = EntityType.ItemDisplay; + mappings[70] = EntityType.ItemFrame; + mappings[71] = EntityType.JungleBoat; + mappings[72] = EntityType.JungleChestBoat; + mappings[73] = EntityType.LeashKnot; + mappings[74] = EntityType.LightningBolt; + mappings[75] = EntityType.Llama; + mappings[76] = EntityType.LlamaSpit; + mappings[77] = EntityType.MagmaCube; + mappings[78] = EntityType.MangroveBoat; + mappings[79] = EntityType.MangroveChestBoat; + mappings[80] = EntityType.Marker; + mappings[81] = EntityType.Minecart; + mappings[82] = EntityType.Mooshroom; + mappings[83] = EntityType.Mule; + mappings[84] = EntityType.OakBoat; + mappings[85] = EntityType.OakChestBoat; + mappings[86] = EntityType.Ocelot; + mappings[87] = EntityType.OminousItemSpawner; + mappings[88] = EntityType.Painting; + mappings[89] = EntityType.PaleOakBoat; + mappings[90] = EntityType.PaleOakChestBoat; + mappings[91] = EntityType.Panda; + mappings[92] = EntityType.Parrot; + mappings[93] = EntityType.Phantom; + mappings[94] = EntityType.Pig; + mappings[95] = EntityType.Piglin; + mappings[96] = EntityType.PiglinBrute; + mappings[97] = EntityType.Pillager; + mappings[98] = EntityType.PolarBear; + mappings[99] = EntityType.SplashPotion; + mappings[100] = EntityType.LingeringPotion; + mappings[101] = EntityType.Pufferfish; + mappings[102] = EntityType.Rabbit; + mappings[103] = EntityType.Ravager; + mappings[104] = EntityType.Salmon; + mappings[105] = EntityType.Sheep; + mappings[106] = EntityType.Shulker; + mappings[107] = EntityType.ShulkerBullet; + mappings[108] = EntityType.Silverfish; + mappings[109] = EntityType.Skeleton; + mappings[110] = EntityType.SkeletonHorse; + mappings[111] = EntityType.Slime; + mappings[112] = EntityType.SmallFireball; + mappings[113] = EntityType.Sniffer; + mappings[114] = EntityType.Snowball; + mappings[115] = EntityType.SnowGolem; + mappings[116] = EntityType.SpawnerMinecart; + mappings[117] = EntityType.SpectralArrow; + mappings[118] = EntityType.Spider; + mappings[119] = EntityType.SpruceBoat; + mappings[120] = EntityType.SpruceChestBoat; + mappings[121] = EntityType.Squid; + mappings[122] = EntityType.Stray; + mappings[123] = EntityType.Strider; + mappings[124] = EntityType.Tadpole; + mappings[125] = EntityType.TextDisplay; + mappings[126] = EntityType.Tnt; + mappings[127] = EntityType.TntMinecart; + mappings[128] = EntityType.TraderLlama; + mappings[129] = EntityType.Trident; + mappings[130] = EntityType.TropicalFish; + mappings[131] = EntityType.Turtle; + mappings[132] = EntityType.Vex; + mappings[133] = EntityType.Villager; + mappings[134] = EntityType.Vindicator; + mappings[135] = EntityType.WanderingTrader; + mappings[136] = EntityType.Warden; + mappings[137] = EntityType.WindCharge; + mappings[138] = EntityType.Witch; + mappings[139] = EntityType.Wither; + mappings[140] = EntityType.WitherSkeleton; + mappings[141] = EntityType.WitherSkull; + mappings[142] = EntityType.Wolf; + mappings[143] = EntityType.Zoglin; + mappings[144] = EntityType.Zombie; + mappings[145] = EntityType.ZombieHorse; + mappings[146] = EntityType.ZombieVillager; + mappings[147] = EntityType.ZombifiedPiglin; + mappings[148] = EntityType.Player; + mappings[149] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 2aab3358..2dc813c8 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -118,6 +118,8 @@ namespace MinecraftClient.Mapping Pillager, Player, PolarBear, + SplashPotion, + LingeringPotion, Potion, Pufferfish, Rabbit, diff --git a/MinecraftClient/Mapping/EntityTypeExtensions.cs b/MinecraftClient/Mapping/EntityTypeExtensions.cs index e6546d22..8609a2c2 100644 --- a/MinecraftClient/Mapping/EntityTypeExtensions.cs +++ b/MinecraftClient/Mapping/EntityTypeExtensions.cs @@ -1,4 +1,4 @@ -namespace MinecraftClient.Mapping +namespace MinecraftClient.Mapping { public static class EntityTypeExtensions { @@ -110,6 +110,8 @@ case EntityType.Egg: case EntityType.EnderPearl: case EntityType.Potion: + case EntityType.SplashPotion: + case EntityType.LingeringPotion: case EntityType.Fireball: case EntityType.FireworkRocket: return true; diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 0f43af41..9485e760 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -162,7 +162,9 @@ namespace MinecraftClient.Mapping BubbleCoralFan, BubbleCoralWallFan, BuddingAmethyst, + Bush, // bush Cactus, + CactusFlower, // cactus_flower Cake, Calcite, CalibratedSculkSensor, @@ -394,6 +396,7 @@ namespace MinecraftClient.Mapping FireCoralBlock, FireCoralFan, FireCoralWallFan, + FireflyBush, // firefly_bush FletchingTable, FlowerPot, FloweringAzalea, @@ -497,6 +500,7 @@ namespace MinecraftClient.Mapping LargeFern, Lava, LavaCauldron, + LeafLitter, // leaf_litter Lectern, Lever, Light, @@ -879,6 +883,7 @@ namespace MinecraftClient.Mapping SeaLantern, SeaPickle, Seagrass, + ShortDryGrass, // short_dry_grass ShortGrass, Shroomlight, ShulkerBox, @@ -972,10 +977,13 @@ namespace MinecraftClient.Mapping SuspiciousGravel, SuspiciousSand, SweetBerryBush, + TallDryGrass, // tall_dry_grass TallGrass, TallSeagrass, Target, Terracotta, + TestBlock, // test_block + TestInstanceBlock, // test_instance_block TintedGlass, Tnt, Torch, @@ -1090,6 +1098,7 @@ namespace MinecraftClient.Mapping WhiteTulip, WhiteWallBanner, WhiteWool, + Wildflowers, // wildflowers WitherRose, WitherSkeletonSkull, WitherSkeletonWallSkull, diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 271d98f8..ab46dca7 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -826,6 +826,7 @@ namespace MinecraftClient.Protocol.Handlers value = ReadNextVarInt(cache); break; case EntityMetaDataType.OptionalUuid: // Optional UUID + case EntityMetaDataType.OptionalLivingEntityReference: // Optional Living Entity Reference (1.21.5+, same wire format) if (ReadNextBool(cache)) { value = ReadNextUUID(cache); @@ -873,10 +874,14 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.CatVariant: // Cat Variant value = ReadNextVarInt(cache); break; + case EntityMetaDataType.CowVariant: // Cow Variant (1.21.5+) case EntityMetaDataType.WolfVariant: // Wolf Variant (1.20.6+) + case EntityMetaDataType.WolfSoundVariant: // Wolf Sound Variant (1.21.5+) value = ReadNextVarInt(cache); break; case EntityMetaDataType.FrogVariant: // Frog Variant + case EntityMetaDataType.PigVariant: // Pig Variant (1.21.5+) + case EntityMetaDataType.ChickenVariant: // Chicken Variant (1.21.5+) value = ReadNextVarInt(cache); break; case EntityMetaDataType.GlobalPosition: // GlobalPos diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1215.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1215.cs new file mode 100644 index 00000000..4ecc5079 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1215.cs @@ -0,0 +1,247 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1215 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.EntityAnimation }, // Animate (was 0x03 in 1.21.4; AddExperienceOrb removed) + { 0x03, PacketTypesIn.Statistics }, // Award Stats + { 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x07, PacketTypesIn.BlockAction }, // Block Event + { 0x08, PacketTypesIn.BlockChange }, // Block Update + { 0x09, PacketTypesIn.BossBar }, // Boss Event + { 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x10, PacketTypesIn.DeclareCommands }, // Commands + { 0x11, PacketTypesIn.CloseWindow }, // Container Close + { 0x12, PacketTypesIn.WindowItems }, // Container Set Content + { 0x13, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x14, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x15, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x16, PacketTypesIn.SetCooldown }, // Cooldown + { 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x18, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x19, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1A, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1B, PacketTypesIn.HideMessage }, // Delete Chat + { 0x1C, PacketTypesIn.Disconnect }, // Disconnect + { 0x1D, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x1E, PacketTypesIn.EntityStatus }, // Entity Event + { 0x1F, PacketTypesIn.EntityPositionSync }, // Entity Position Sync + { 0x20, PacketTypesIn.Explosion }, // Explode + { 0x21, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x22, PacketTypesIn.ChangeGameState }, // Game Event + { 0x23, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open + { 0x24, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x25, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x26, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x27, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x28, PacketTypesIn.Effect }, // Level Event + { 0x29, PacketTypesIn.Particle }, // Level Particles + { 0x2A, PacketTypesIn.UpdateLight }, // Light Update + { 0x2B, PacketTypesIn.JoinGame }, // Login + { 0x2C, PacketTypesIn.MapData }, // Map Item Data + { 0x2D, PacketTypesIn.TradeList }, // Merchant Offers + { 0x2E, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x2F, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x30, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track + { 0x31, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x32, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x33, PacketTypesIn.OpenBook }, // Open Book + { 0x34, PacketTypesIn.OpenWindow }, // Open Screen + { 0x35, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x36, PacketTypesIn.Ping }, // Ping + { 0x37, PacketTypesIn.PingResponse }, // Pong Response + { 0x38, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x39, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x3A, PacketTypesIn.ChatMessage }, // Player Chat + { 0x3B, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x3C, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x3D, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x3E, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x3F, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x40, PacketTypesIn.FacePlayer }, // Player Look At + { 0x41, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x42, PacketTypesIn.PlayerRotation }, // Player Rotation + { 0x43, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add + { 0x44, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove + { 0x45, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings + { 0x46, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x47, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x48, PacketTypesIn.ResetScore }, // Reset Score + { 0x49, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x4A, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x4B, PacketTypesIn.Respawn }, // Respawn + { 0x4C, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x4D, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x4E, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x4F, PacketTypesIn.ServerData }, // Server Data + { 0x50, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x51, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x52, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x53, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x54, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x55, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x56, PacketTypesIn.Camera }, // Set Camera + { 0x57, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x58, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x59, PacketTypesIn.SetCursorItem }, // Set Cursor Item + { 0x5A, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x5B, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x5C, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x5D, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x5E, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x5F, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x60, PacketTypesIn.SetExperience }, // Set Experience + { 0x61, PacketTypesIn.UpdateHealth }, // Set Health + { 0x62, PacketTypesIn.SetHeldSlot }, // Set Held Slot + { 0x63, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x64, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x65, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory + { 0x66, PacketTypesIn.Teams }, // Set Player Team + { 0x67, PacketTypesIn.UpdateScore }, // Set Score + { 0x68, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x69, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x6A, PacketTypesIn.TimeUpdate }, // Set Time + { 0x6B, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x6C, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x6D, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x6E, PacketTypesIn.SoundEffect }, // Sound + { 0x6F, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x70, PacketTypesIn.StopSound }, // Stop Sound + { 0x71, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x72, PacketTypesIn.SystemChat }, // System Chat + { 0x73, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x74, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x75, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x76, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x77, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status (new in 1.21.5) + { 0x78, PacketTypesIn.SetTickingState }, // Ticking State + { 0x79, PacketTypesIn.StepTick }, // Ticking Step + { 0x7A, PacketTypesIn.Transfer }, // Transfer + { 0x7B, PacketTypesIn.Advancements }, // Update Advancements + { 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x7F, PacketTypesIn.Tags }, // Update Tags + { 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x82, PacketTypesIn.ServerLinks } // Server Links + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected + { 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x04, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x05, PacketTypesOut.ChatCommand }, // Chat Command + { 0x06, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x07, PacketTypesOut.ChatMessage }, // Chat + { 0x08, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x09, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0A, PacketTypesOut.ClientStatus }, // Client Command + { 0x0B, PacketTypesOut.ClientTickEnd }, // Client Tick End + { 0x0C, PacketTypesOut.ClientSettings }, // Client Information + { 0x0D, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x0E, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x0F, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x10, PacketTypesOut.ClickWindow }, // Container Click + { 0x11, PacketTypesOut.CloseWindow }, // Container Close + { 0x12, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x13, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x14, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x15, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription + { 0x16, PacketTypesOut.EditBook }, // Edit Book + { 0x17, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x18, PacketTypesOut.InteractEntity }, // Interact + { 0x19, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1A, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1B, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1C, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1D, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x1E, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x1F, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x20, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x21, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x22, PacketTypesOut.PickItem }, // Pick Item From Block + { 0x23, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity + { 0x24, PacketTypesOut.PingRequest }, // Ping Request + { 0x25, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x26, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x27, PacketTypesOut.PlayerDigging }, // Player Action + { 0x28, PacketTypesOut.EntityAction }, // Player Command + { 0x29, PacketTypesOut.SteerVehicle }, // Player Input + { 0x2A, PacketTypesOut.PlayerLoaded }, // Player Loaded + { 0x2B, PacketTypesOut.Pong }, // Pong + { 0x2C, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2D, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x2E, PacketTypesOut.NameItem }, // Rename Item + { 0x2F, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x30, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x31, PacketTypesOut.SelectTrade }, // Select Trade + { 0x32, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x33, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x34, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x35, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x36, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x37, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x38, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x39, PacketTypesOut.SetTestBlock }, // Set Test Block (new in 1.21.5) + { 0x3A, PacketTypesOut.UpdateSign }, // Sign Update + { 0x3B, PacketTypesOut.Animation }, // Swing + { 0x3C, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x3D, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action (new in 1.21.5) + { 0x3E, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x3F, PacketTypesOut.UseItem }, // Use Item + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks } + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index c03ade1b..ab800bb6 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_4_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_5_Version => throw new NotImplementedException(Translations .exception_palette_packet), + <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), <= Protocol18Handler.MC_1_11_2_Version => new PacketPalette110(), diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 19d72455..7defe5e7 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -134,6 +134,7 @@ namespace MinecraftClient.Protocol.Handlers TabComplete, // Tags, // Teams, // + TestInstanceBlockStatus, // Added in 1.21.5 TimeUpdate, // Title, // TradeList, // diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index a93ea13b..3b1523eb 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -71,6 +71,8 @@ namespace MinecraftClient.Protocol.Handlers UpdateJigsawBlock, // UpdateSign, // UpdateStructureBlock, // + SetTestBlock, // Added in 1.21.5 + TestInstanceBlockAction, // Added in 1.21.5 UseItem, // VehicleMove, // WindowConfirmation, // diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index b2393fa9..e9019316 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -75,6 +75,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_Version = 767; internal const int MC_1_21_2_Version = 768; internal const int MC_1_21_4_Version = 769; + internal const int MC_1_21_5_Version = 770; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -126,21 +127,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_4_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_5_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_4_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_5_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_4_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_5_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -149,8 +150,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_4_Version when handler.GetTerrainEnabled() => + > MC_1_21_5_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + >= MC_1_21_5_Version => new Palette1215(), >= MC_1_21_4_Version => new Palette1214(), >= MC_1_21_2_Version => new Palette1212(), >= MC_1_20_6_Version => new Palette1206(), @@ -170,8 +172,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_4_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_5_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_1_21_5_Version => new EntityPalette1215(), >= MC_1_21_4_Version => new EntityPalette1214(), >= MC_1_21_2_Version => new EntityPalette1212(), >= MC_1_20_6_Version => new EntityPalette1206(), @@ -195,8 +198,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_4_Version when handler.GetInventoryEnabled() => + > MC_1_21_5_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_5_Version => new ItemPalette1215(), >= MC_1_21_4_Version => new ItemPalette1214(), >= MC_1_21_2_Version => new ItemPalette1212(), >= MC_1_21_Version => new ItemPalette121(), @@ -2631,7 +2635,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_4_Version => throw new NotImplementedException(Translations + > MC_1_21_5_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/BlocksAttacksComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/BlocksAttacksComponent.cs new file mode 100644 index 00000000..f756e9a2 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/BlocksAttacksComponent.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class BlocksAttacksComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public float BlockDelaySeconds { get; set; } + public float DisableCooldownScale { get; set; } + public List RawDamageReductions { get; set; } = []; + public float ItemDamageThreshold { get; set; } + public float ItemDamageBase { get; set; } + public float ItemDamageFactor { get; set; } + + public override void Parse(Queue data) + { + BlockDelaySeconds = dataTypes.ReadNextFloat(data); + DisableCooldownScale = dataTypes.ReadNextFloat(data); + + var reductionCount = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < reductionCount; i++) + { + var horizontalBlockingAngle = dataTypes.ReadNextFloat(data); + + var hasTypeFilter = dataTypes.ReadNextBool(data); + if (hasTypeFilter) + ReadHolderSet(data); + + var baseDmg = dataTypes.ReadNextFloat(data); + var factor = dataTypes.ReadNextFloat(data); + } + + ItemDamageThreshold = dataTypes.ReadNextFloat(data); + ItemDamageBase = dataTypes.ReadNextFloat(data); + ItemDamageFactor = dataTypes.ReadNextFloat(data); + + var hasBypassedBy = dataTypes.ReadNextBool(data); + if (hasBypassedBy) + dataTypes.ReadNextString(data); // TagKey as ResourceLocation + + var hasBlockSound = dataTypes.ReadNextBool(data); + if (hasBlockSound) + ReadSoundEventHolder(data); + + var hasDisableSound = dataTypes.ReadNextBool(data); + if (hasDisableSound) + ReadSoundEventHolder(data); + } + + private void ReadHolderSet(Queue data) + { + var sizeOrTag = dataTypes.ReadNextVarInt(data); + if (sizeOrTag == 0) + { + dataTypes.ReadNextString(data); // Tag ResourceLocation + } + else + { + var count = sizeOrTag - 1; + for (var i = 0; i < count; i++) + dataTypes.ReadNextVarInt(data); // Holder registry ids + } + } + + private void ReadSoundEventHolder(Queue data) + { + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + dataTypes.ReadNextString(data); // ResourceLocation + var hasFixedRange = dataTypes.ReadNextBool(data); + if (hasFixedRange) + dataTypes.ReadNextFloat(data); + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EitherHolderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EitherHolderComponent.cs new file mode 100644 index 00000000..4319693f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EitherHolderComponent.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class EitherHolderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool IsHolder { get; set; } + public int HolderId { get; set; } + public string? ResourceKey { get; set; } + + public override void Parse(Queue data) + { + IsHolder = dataTypes.ReadNextBool(data); + if (IsHolder) + { + HolderId = dataTypes.ReadNextVarInt(data); + // For simple entity variants, holderId > 0 means registry ref (id = holderId - 1) + // holderId == 0 means inline data; for most variants the inline is just the variant fields + // We skip inline data since MCC doesn't use variant details + if (HolderId == 0) + { + // Read inline variant data - varies by type, but most are simple + // For chicken/variant specifically this might have additional fields + // We'll consume what we can based on the pattern + // TODO: If needed, specialize per variant type + } + } + else + { + ResourceKey = dataTypes.ReadNextString(data); + } + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetBool(IsHolder)); + if (IsHolder) + { + bytes.AddRange(DataTypes.GetVarInt(HolderId)); + } + else + { + bytes.AddRange(DataTypes.GetString(ResourceKey ?? "")); + } + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/InstrumentComponent1215.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/InstrumentComponent1215.cs new file mode 100644 index 00000000..bedbde20 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/InstrumentComponent1215.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class InstrumentComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + // EitherHolder: Bool + (Holder OR ResourceLocation) + var isHolder = dataTypes.ReadNextBool(data); + if (isHolder) + { + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + // Inline Instrument: SoundEvent holder + VarInt useDuration + Float range + Component description + var soundHolderId = dataTypes.ReadNextVarInt(data); + if (soundHolderId == 0) + { + dataTypes.ReadNextString(data); // ResourceLocation + var hasFixedRange = dataTypes.ReadNextBool(data); + if (hasFixedRange) + dataTypes.ReadNextFloat(data); + } + dataTypes.ReadNextVarInt(data); // useDuration + dataTypes.ReadNextFloat(data); // range + dataTypes.ReadNextString(data); // description (Component as JSON string) + } + } + else + { + dataTypes.ReadNextString(data); // ResourceLocation key + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PaintingVariantHolderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PaintingVariantHolderComponent.cs new file mode 100644 index 00000000..a67bef25 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PaintingVariantHolderComponent.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class PaintingVariantHolderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + // Holder: VarInt discriminator + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + // Inline PaintingVariant: VarInt width + VarInt height + ResourceLocation assetId + dataTypes.ReadNextVarInt(data); // width + dataTypes.ReadNextVarInt(data); // height + dataTypes.ReadNextString(data); // assetId + + // Optional title + if (dataTypes.ReadNextBool(data)) + dataTypes.ReadNextString(data); + + // Optional author + if (dataTypes.ReadNextBool(data)) + dataTypes.ReadNextString(data); + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PotionDurationScaleComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PotionDurationScaleComponent.cs new file mode 100644 index 00000000..d0fac894 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/PotionDurationScaleComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class PotionDurationScaleComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public float Scale { get; set; } + + public override void Parse(Queue data) + { + Scale = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetFloat(Scale)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesBannerPatternsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesBannerPatternsComponent.cs new file mode 100644 index 00000000..0b0db7f7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesBannerPatternsComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class ProvidesBannerPatternsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public string TagKey { get; set; } = string.Empty; + + public override void Parse(Queue data) + { + TagKey = dataTypes.ReadNextString(data); // ResourceLocation + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetString(TagKey)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesTrimMaterialComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesTrimMaterialComponent.cs new file mode 100644 index 00000000..fde8db41 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/ProvidesTrimMaterialComponent.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class ProvidesTrimMaterialComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + // EitherHolder: Bool + (Holder OR ResourceLocation) + var isHolder = dataTypes.ReadNextBool(data); + if (isHolder) + { + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + // Inline TrimMaterial: MaterialAssetGroup + Component description + // MaterialAssetGroup: string + map + dataTypes.ReadNextString(data); // base asset suffix + var overrideCount = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < overrideCount; i++) + { + dataTypes.ReadNextString(data); // ResourceKey + dataTypes.ReadNextString(data); // override suffix + } + // description Component + dataTypes.ReadNextString(data); + } + } + else + { + dataTypes.ReadNextString(data); // ResourceLocation key + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/SoundEventHolderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/SoundEventHolderComponent.cs new file mode 100644 index 00000000..849f3018 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/SoundEventHolderComponent.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class SoundEventHolderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int HolderId { get; set; } + public string? SoundLocation { get; set; } + public bool HasFixedRange { get; set; } + public float FixedRange { get; set; } + + public override void Parse(Queue data) + { + HolderId = dataTypes.ReadNextVarInt(data); + if (HolderId == 0) + { + SoundLocation = dataTypes.ReadNextString(data); + HasFixedRange = dataTypes.ReadNextBool(data); + if (HasFixedRange) + FixedRange = dataTypes.ReadNextFloat(data); + } + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetVarInt(HolderId)); + if (HolderId == 0) + { + bytes.AddRange(DataTypes.GetString(SoundLocation ?? "")); + bytes.AddRange(DataTypes.GetBool(HasFixedRange)); + if (HasFixedRange) + bytes.AddRange(DataTypes.GetFloat(FixedRange)); + } + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/TooltipDisplayComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/TooltipDisplayComponent.cs new file mode 100644 index 00000000..9611e3d5 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/TooltipDisplayComponent.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class TooltipDisplayComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool HideTooltip { get; set; } + public List HiddenComponentIds { get; set; } = []; + + public override void Parse(Queue data) + { + HideTooltip = dataTypes.ReadNextBool(data); + var count = dataTypes.ReadNextVarInt(data); + for (var i = 0; i < count; i++) + HiddenComponentIds.Add(dataTypes.ReadNextVarInt(data)); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetBool(HideTooltip)); + bytes.AddRange(DataTypes.GetVarInt(HiddenComponentIds.Count)); + foreach (var id in HiddenComponentIds) + bytes.AddRange(DataTypes.GetVarInt(id)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/VarIntComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/VarIntComponent.cs new file mode 100644 index 00000000..086b14cd --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/VarIntComponent.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class VarIntComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int Value { get; set; } + + public override void Parse(Queue data) + { + Value = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetVarInt(Value)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/WeaponComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/WeaponComponent.cs new file mode 100644 index 00000000..64c513eb --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/WeaponComponent.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class WeaponComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int ItemDamagePerAttack { get; set; } + public float DisableBlockingForSeconds { get; set; } + + public override void Parse(Queue data) + { + ItemDamagePerAttack = dataTypes.ReadNextVarInt(data); + DisableBlockingForSeconds = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetVarInt(ItemDamagePerAttack)); + bytes.AddRange(DataTypes.GetFloat(DisableBlockingForSeconds)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs new file mode 100644 index 00000000..26b3b27e --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs @@ -0,0 +1,116 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry1215 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) + { + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); // Changed from Unbreakable (Bool) to Unit (empty) in 1.21.5 + RegisterComponent(5, "minecraft:custom_name"); + RegisterComponent(6, "minecraft:item_name"); + RegisterComponent(7, "minecraft:item_model"); + RegisterComponent(8, "minecraft:lore"); + RegisterComponent(9, "minecraft:rarity"); + RegisterComponent(10, "minecraft:enchantments"); + RegisterComponent(11, "minecraft:can_place_on"); + RegisterComponent(12, "minecraft:can_break"); + RegisterComponent(13, "minecraft:attribute_modifiers"); + RegisterComponent(14, "minecraft:custom_model_data"); + // 15: tooltip_display (NEW, replaces hide_additional_tooltip + hide_tooltip) + RegisterComponent(15, "minecraft:tooltip_display"); + RegisterComponent(16, "minecraft:repair_cost"); + RegisterComponent(17, "minecraft:creative_slot_lock"); + RegisterComponent(18, "minecraft:enchantment_glint_override"); + RegisterComponent(19, "minecraft:intangible_projectile"); + RegisterComponent(20, "minecraft:food"); + RegisterComponent(21, "minecraft:consumable"); + RegisterComponent(22, "minecraft:use_remainder"); + RegisterComponent(23, "minecraft:use_cooldown"); + RegisterComponent(24, "minecraft:damage_resistant"); + RegisterComponent(25, "minecraft:tool"); + RegisterComponent(26, "minecraft:weapon"); // NEW + RegisterComponent(27, "minecraft:enchantable"); + RegisterComponent(28, "minecraft:equippable"); + RegisterComponent(29, "minecraft:repairable"); + RegisterComponent(30, "minecraft:glider"); + RegisterComponent(31, "minecraft:tooltip_style"); + RegisterComponent(32, "minecraft:death_protection"); + RegisterComponent(33, "minecraft:blocks_attacks"); // NEW + RegisterComponent(34, "minecraft:stored_enchantments"); + RegisterComponent(35, "minecraft:dyed_color"); + RegisterComponent(36, "minecraft:map_color"); + RegisterComponent(37, "minecraft:map_id"); + RegisterComponent(38, "minecraft:map_decorations"); + RegisterComponent(39, "minecraft:map_post_processing"); + RegisterComponent(40, "minecraft:charged_projectiles"); + RegisterComponent(41, "minecraft:bundle_contents"); + RegisterComponent(42, "minecraft:potion_contents"); + RegisterComponent(43, "minecraft:potion_duration_scale"); // NEW + RegisterComponent(44, "minecraft:suspicious_stew_effects"); + RegisterComponent(45, "minecraft:writable_book_content"); + RegisterComponent(46, "minecraft:written_book_content"); + RegisterComponent(47, "minecraft:trim"); + RegisterComponent(48, "minecraft:debug_stick_state"); + RegisterComponent(49, "minecraft:entity_data"); + RegisterComponent(50, "minecraft:bucket_entity_data"); + RegisterComponent(51, "minecraft:block_entity_data"); + RegisterComponent(52, "minecraft:instrument"); // Changed to EitherHolder in 1.21.5 + RegisterComponent(53, "minecraft:provides_trim_material"); // NEW + RegisterComponent(54, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(55, "minecraft:jukebox_playable"); + RegisterComponent(56, "minecraft:provides_banner_patterns"); // NEW + RegisterComponent(57, "minecraft:recipes"); + RegisterComponent(58, "minecraft:lodestone_tracker"); + RegisterComponent(59, "minecraft:firework_explosion"); + RegisterComponent(60, "minecraft:fireworks"); + RegisterComponent(61, "minecraft:profile"); + RegisterComponent(62, "minecraft:note_block_sound"); + RegisterComponent(63, "minecraft:banner_patterns"); + RegisterComponent(64, "minecraft:base_color"); + RegisterComponent(65, "minecraft:pot_decorations"); + RegisterComponent(66, "minecraft:container"); + RegisterComponent(67, "minecraft:block_state"); + RegisterComponent(68, "minecraft:bees"); // Wire format unchanged in 1.21.5 + RegisterComponent(69, "minecraft:lock"); + RegisterComponent(70, "minecraft:container_loot"); + + // Entity variant components (NEW in 1.21.5) + RegisterComponent(71, "minecraft:break_sound"); + RegisterComponent(72, "minecraft:villager/variant"); + RegisterComponent(73, "minecraft:wolf/variant"); + RegisterComponent(74, "minecraft:wolf/sound_variant"); + RegisterComponent(75, "minecraft:wolf/collar"); // DyeColor as VarInt + RegisterComponent(76, "minecraft:fox/variant"); + RegisterComponent(77, "minecraft:salmon/size"); + RegisterComponent(78, "minecraft:parrot/variant"); + RegisterComponent(79, "minecraft:tropical_fish/pattern"); + RegisterComponent(80, "minecraft:tropical_fish/base_color"); // DyeColor + RegisterComponent(81, "minecraft:tropical_fish/pattern_color"); // DyeColor + RegisterComponent(82, "minecraft:mooshroom/variant"); + RegisterComponent(83, "minecraft:rabbit/variant"); + RegisterComponent(84, "minecraft:pig/variant"); + RegisterComponent(85, "minecraft:cow/variant"); + RegisterComponent(86, "minecraft:chicken/variant"); // EitherHolder + RegisterComponent(87, "minecraft:frog/variant"); + RegisterComponent(88, "minecraft:horse/variant"); + RegisterComponent(89, "minecraft:painting/variant"); // Holder + RegisterComponent(90, "minecraft:llama/variant"); + RegisterComponent(91, "minecraft:axolotl/variant"); + RegisterComponent(92, "minecraft:cat/variant"); + RegisterComponent(93, "minecraft:cat/collar"); // DyeColor + RegisterComponent(94, "minecraft:sheep/color"); // DyeColor + RegisterComponent(95, "minecraft:shulker/color"); // DyeColor + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index 9729e5f4..7274c319 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -21,6 +21,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121), + >= Protocol18Handler.MC_1_21_5_Version => typeof(SubComponentRegistry1212), >= Protocol18Handler.MC_1_21_2_Version => typeof(SubComponentRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") }; @@ -33,6 +34,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), + >= Protocol18Handler.MC_1_21_5_Version => typeof(StructuredComponentsRegistry1215), >= Protocol18Handler.MC_1_21_2_Version => typeof(StructuredComponentsRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") }; diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index aba121fa..684e351b 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -154,7 +154,7 @@ namespace MinecraftClient.Protocol { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769 + 769, 770 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -358,6 +358,8 @@ namespace MinecraftClient.Protocol return 768; case "1.21.4": return 769; + case "1.21.5": + return 770; default: return 0; } @@ -441,6 +443,7 @@ namespace MinecraftClient.Protocol 767 => "1.21", 768 => "1.21.2", 769 => "1.21.4", + 770 => "1.21.5", _ => "0.0" }; } diff --git a/scripts/gen_palette_1214.py b/scripts/gen_palette_1214.py new file mode 100644 index 00000000..cf3ce31c --- /dev/null +++ b/scripts/gen_palette_1214.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +""" +Generate Palette1214.cs from vanilla reports/blocks.json (1.21.4). + +Obtain blocks.json: + java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports --output + -> /reports/blocks.json + +Default input: /tmp/mc1214_reports/reports/blocks.json (run this script after generating reports). +""" +from __future__ import annotations + +import json +import re +import sys +from collections import defaultdict +from pathlib import Path + +ROOT = Path("/home/ryan/Minecraft/Minecraft-Console-Client-milutinke") +DEFAULT_JSON = Path("/tmp/mc1214_reports/reports/blocks.json") +OUT = ROOT / "MinecraftClient/Mapping/BlockPalettes/Palette1214.cs" + + +def snake_to_material_pascal(snake: str) -> str: + return "".join(part.capitalize() for part in snake.split("_")) + + +def merge_ranges(sorted_ids: list[int]) -> list[tuple[int, int]]: + if not sorted_ids: + return [] + ids = sorted(sorted_ids) + out: list[tuple[int, int]] = [] + s = e = ids[0] + for x in ids[1:]: + if x == e + 1: + e = x + else: + out.append((s, e)) + s = e = x + out.append((s, e)) + return out + + +def emit_palette(assignments: list[tuple[str, list[tuple[int, int]]]]) -> str: + lines = [ + "using System.Collections.Generic;", + "", + "namespace MinecraftClient.Mapping.BlockPalettes", + "{", + " public class Palette1214 : BlockPalette", + " {", + " private static readonly Dictionary materials = new();", + "", + " static Palette1214()", + " {", + ] + for mat, ranges in sorted(assignments, key=lambda x: x[0]): + for start, end in ranges: + if start == end: + lines.append(f" materials[{start}] = Material.{mat};") + else: + lines.append(f" for (int i = {start}; i <= {end}; i++)") + lines.append(f" materials[i] = Material.{mat};") + lines.extend( + [ + " }", + "", + " protected override Dictionary GetDict()", + " {", + " return materials;", + " }", + " }", + "}", + ] + ) + return "\n".join(lines) + "\n" + + +def main() -> None: + json_path = Path(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_JSON + if not json_path.is_file(): + raise SystemExit(f"Missing {json_path} — generate with server.jar --reports") + + data = json.loads(json_path.read_text(encoding="utf-8")) + ids_by_material: dict[str, list[int]] = defaultdict(list) + known: set[int] = set() + max_id = -1 + + for key, val in data.items(): + if not key.startswith("minecraft:"): + raise SystemExit(f"Unexpected block key: {key}") + name = key.split(":", 1)[1] + mat = snake_to_material_pascal(name) + for st in val["states"]: + sid = int(st["id"]) + if sid in known: + raise SystemExit(f"Duplicate state id {sid}") + known.add(sid) + max_id = max(max_id, sid) + ids_by_material[mat].append(sid) + + expected = max_id + 1 + if len(known) != expected: + raise SystemExit(f"Non-contiguous state IDs: have {len(known)}, expected 0..{max_id}") + + assignments = [(m, merge_ranges(ids)) for m, ids in ids_by_material.items()] + OUT.write_text(emit_palette(assignments), encoding="utf-8") + print(f"Wrote {OUT} ({expected} states, {len(data)} block types)") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_entity_metadata_palette.py b/tools/gen_entity_metadata_palette.py index ab914cf8..260fe722 100644 --- a/tools/gen_entity_metadata_palette.py +++ b/tools/gen_entity_metadata_palette.py @@ -37,6 +37,7 @@ FIELD_TO_ENUM = { "OPTIONAL_BLOCK_POS": "OptionalPosition", "DIRECTION": "Direction", "OPTIONAL_UUID": "OptionalUuid", + "OPTIONAL_LIVING_ENTITY_REFERENCE": "OptionalLivingEntityReference", "BLOCK_STATE": "BlockId", "OPTIONAL_BLOCK_STATE": "OptionalBlockId", "COMPOUND_TAG": "Nbt", @@ -46,8 +47,12 @@ FIELD_TO_ENUM = { "OPTIONAL_UNSIGNED_INT": "OptionalVarInt", "POSE": "Pose", "CAT_VARIANT": "CatVariant", + "COW_VARIANT": "CowVariant", "WOLF_VARIANT": "WolfVariant", + "WOLF_SOUND_VARIANT": "WolfSoundVariant", "FROG_VARIANT": "FrogVariant", + "PIG_VARIANT": "PigVariant", + "CHICKEN_VARIANT": "ChickenVariant", "OPTIONAL_GLOBAL_POS": "OptionalGlobalPosition", "PAINTING_VARIANT": "PaintingVariant", "SNIFFER_STATE": "SnifferState", From 9af6c643e3f146cacf3992ca8e7a543030f52c5d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 00:54:27 +0800 Subject: [PATCH 062/484] fix: handle 1.21.5 chunk data format changes In 1.21.5, two wire format changes in level chunk packets: 1. Heightmaps changed from NBT CompoundTag to map encoding 2. PalettedContainer data arrays no longer have VarInt length prefix (uses writeFixedSizeLongArray instead of writeLongArray) Both changes affect ChunkData (level_chunk_with_light) packet parsing. Without this fix, MCC crashes with "Queue empty" when processing chunks. Made-with: Cursor --- .../Protocol/Handlers/Protocol18.cs | 17 +++++++++++- .../Protocol/Handlers/Protocol18Terrain.cs | 26 ++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e9019316..743fd3e9 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1511,7 +1511,22 @@ namespace MinecraftClient.Protocol.Handlers dataTypes.ReadNextULongArray( packetData); // Bit Mask Length and Primary Bit Mask - dataTypes.ReadNextNbt(packetData); // Heightmaps + if (protocolVersion >= MC_1_21_5_Version) + { + // 1.21.5: Heightmaps encoded as map instead of NBT + var hmCount = dataTypes.ReadNextVarInt(packetData); + for (var hm = 0; hm < hmCount; hm++) + { + dataTypes.ReadNextVarInt(packetData); // Heightmap type id + var longCount = dataTypes.ReadNextVarInt(packetData); + for (var l = 0; l < longCount; l++) + dataTypes.ReadNextLong(packetData); + } + } + else + { + dataTypes.ReadNextNbt(packetData); // Heightmaps (NBT format) + } if (protocolVersion is MC_1_17_Version or MC_1_17_1_Version) { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs index fc66edd0..75bf7b34 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Numerics; using System.Runtime.CompilerServices; @@ -47,7 +47,8 @@ namespace MinecraftClient.Protocol.Handlers ushort blockId = (ushort)dataTypes.ReadNextVarInt(cache); Block block = new(blockId); - dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero + if (protocolversion < Protocol18Handler.MC_1_21_5_Version) + dataTypes.SkipNextVarInt(cache); // Data Array Length will be zero (removed in 1.21.5) // Empty chunks will not be stored if (block.Type == Material.Air) @@ -80,7 +81,8 @@ namespace MinecraftClient.Protocol.Handlers palette[i] = (uint)dataTypes.ReadNextVarInt(cache); //// Block IDs are packed in the array of 64-bits integers - dataTypes.SkipNextVarInt(cache); // Entry length + if (protocolversion < Protocol18Handler.MC_1_21_5_Version) + dataTypes.SkipNextVarInt(cache); // Entry length (removed in 1.21.5) Span entryDataByte = stackalloc byte[8]; Span entryDataLong = MemoryMarshal.Cast(entryDataByte); // Faster than MemoryMarshal.Read @@ -196,8 +198,8 @@ namespace MinecraftClient.Protocol.Handlers if (bitsPerEntryBiome == 0) { dataTypes.SkipNextVarInt(cache); // Value - dataTypes.SkipNextVarInt(cache); // Data Array Length - // Data Array must be empty + if (protocolversion < Protocol18Handler.MC_1_21_5_Version) + dataTypes.SkipNextVarInt(cache); // Data Array Length (removed in 1.21.5) } else { @@ -207,8 +209,18 @@ namespace MinecraftClient.Protocol.Handlers for (int i = 0; i < paletteLength; i++) dataTypes.SkipNextVarInt(cache); // Palette } - int dataArrayLength = dataTypes.ReadNextVarInt(cache); // Data Array Length - dataTypes.DropData(dataArrayLength * 8, cache); // Data Array + if (protocolversion >= Protocol18Handler.MC_1_21_5_Version) + { + // 1.21.5: No VarInt length prefix; calculate from bits per entry + // Biome container has 64 entries (4x4x4) + int dataArrayLength = (64 * bitsPerEntryBiome + 63) / 64; + dataTypes.DropData(dataArrayLength * 8, cache); + } + else + { + int dataArrayLength = dataTypes.ReadNextVarInt(cache); // Data Array Length + dataTypes.DropData(dataArrayLength * 8, cache); // Data Array + } } } } From 26e8a2f2e6e57bb0aca3bab2c3fc965f45da1c25 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 01:08:08 +0800 Subject: [PATCH 063/484] fix: adapt chat packet format for MC 1.21.5 (protocol 770) 1.21.5 changed LastSeenMessages.Update to include a trailing checksum byte (0 = skip verification). This affects serverbound chat and signed chat command packets. Additionally, the clientbound PlayerChat packet now has a globalIndex VarInt prepended before the sender UUID. Without these fixes: - Sending plain chat messages causes DecoderException on the server - Receiving player chat messages causes Queue empty crash in MCC Made-with: Cursor --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 743fd3e9..9beae52e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1069,6 +1069,11 @@ namespace MinecraftClient.Protocol.Handlers // 1.19.3+ // Header section // net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket#write + + // 1.21.5+: globalIndex prepended before sender UUID + if (protocolVersion >= MC_1_21_5_Version) + dataTypes.ReadNextVarInt(packetData); + var senderUuid = dataTypes.ReadNextUUID(packetData); var index = dataTypes.ReadNextVarInt(packetData); // Signature is fixed size of 256 bytes @@ -3732,6 +3737,10 @@ namespace MinecraftClient.Protocol.Handlers case >= MC_1_19_3_Version: fields.AddRange(DataTypes.GetVarInt(messageCount1193)); fields.AddRange(bitset1193); + + // Checksum: Byte (1.21.5+, 0 = skip verification) + if (protocolVersion >= MC_1_21_5_Version) + fields.Add(0); break; } @@ -3835,6 +3844,10 @@ namespace MinecraftClient.Protocol.Handlers // Acknowledged: BitSet fields.AddRange(bitset1193); + + // Checksum: Byte (1.21.5+, 0 = skip verification) + if (protocolVersion >= MC_1_21_5_Version) + fields.Add(0); break; case MC_1_19_2_Version: // Message Acknowledgment From 066a1d1238c045c9a4ecc2850cf1757894bef63d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 01:15:39 +0800 Subject: [PATCH 064/484] Remove unused script --- scripts/gen_palette_1214.py | 112 ------------------------------------ 1 file changed, 112 deletions(-) delete mode 100644 scripts/gen_palette_1214.py diff --git a/scripts/gen_palette_1214.py b/scripts/gen_palette_1214.py deleted file mode 100644 index cf3ce31c..00000000 --- a/scripts/gen_palette_1214.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python3 -""" -Generate Palette1214.cs from vanilla reports/blocks.json (1.21.4). - -Obtain blocks.json: - java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports --output - -> /reports/blocks.json - -Default input: /tmp/mc1214_reports/reports/blocks.json (run this script after generating reports). -""" -from __future__ import annotations - -import json -import re -import sys -from collections import defaultdict -from pathlib import Path - -ROOT = Path("/home/ryan/Minecraft/Minecraft-Console-Client-milutinke") -DEFAULT_JSON = Path("/tmp/mc1214_reports/reports/blocks.json") -OUT = ROOT / "MinecraftClient/Mapping/BlockPalettes/Palette1214.cs" - - -def snake_to_material_pascal(snake: str) -> str: - return "".join(part.capitalize() for part in snake.split("_")) - - -def merge_ranges(sorted_ids: list[int]) -> list[tuple[int, int]]: - if not sorted_ids: - return [] - ids = sorted(sorted_ids) - out: list[tuple[int, int]] = [] - s = e = ids[0] - for x in ids[1:]: - if x == e + 1: - e = x - else: - out.append((s, e)) - s = e = x - out.append((s, e)) - return out - - -def emit_palette(assignments: list[tuple[str, list[tuple[int, int]]]]) -> str: - lines = [ - "using System.Collections.Generic;", - "", - "namespace MinecraftClient.Mapping.BlockPalettes", - "{", - " public class Palette1214 : BlockPalette", - " {", - " private static readonly Dictionary materials = new();", - "", - " static Palette1214()", - " {", - ] - for mat, ranges in sorted(assignments, key=lambda x: x[0]): - for start, end in ranges: - if start == end: - lines.append(f" materials[{start}] = Material.{mat};") - else: - lines.append(f" for (int i = {start}; i <= {end}; i++)") - lines.append(f" materials[i] = Material.{mat};") - lines.extend( - [ - " }", - "", - " protected override Dictionary GetDict()", - " {", - " return materials;", - " }", - " }", - "}", - ] - ) - return "\n".join(lines) + "\n" - - -def main() -> None: - json_path = Path(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_JSON - if not json_path.is_file(): - raise SystemExit(f"Missing {json_path} — generate with server.jar --reports") - - data = json.loads(json_path.read_text(encoding="utf-8")) - ids_by_material: dict[str, list[int]] = defaultdict(list) - known: set[int] = set() - max_id = -1 - - for key, val in data.items(): - if not key.startswith("minecraft:"): - raise SystemExit(f"Unexpected block key: {key}") - name = key.split(":", 1)[1] - mat = snake_to_material_pascal(name) - for st in val["states"]: - sid = int(st["id"]) - if sid in known: - raise SystemExit(f"Duplicate state id {sid}") - known.add(sid) - max_id = max(max_id, sid) - ids_by_material[mat].append(sid) - - expected = max_id + 1 - if len(known) != expected: - raise SystemExit(f"Non-contiguous state IDs: have {len(known)}, expected 0..{max_id}") - - assignments = [(m, merge_ranges(ids)) for m, ids in ids_by_material.items()] - OUT.write_text(emit_palette(assignments), encoding="utf-8") - print(f"Wrote {OUT} ({expected} states, {len(data)} block types)") - - -if __name__ == "__main__": - main() From 779de6c996f7111df08f2351bd64ee45f028e0ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:47:21 +0000 Subject: [PATCH 065/484] Initial plan From 4efe75174ec81e8183941d9e31a54e1ba0da0818 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:51:53 +0000 Subject: [PATCH 066/484] Fix skipci CI/CD skip feature in GitHub Actions workflow Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/e765016c-a3e8-4423-b21c-b05ec19cb97a --- .github/workflows/build-and-release.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index fefa6400..144e9819 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -14,7 +14,7 @@ env: jobs: build: runs-on: ubuntu-latest - if: ${{ always() && needs.fetch-translations.result != 'failure' }} + if: ${{ always() && needs.fetch-translations.result != 'failure' && needs.determine-build.result != 'skipped' }} needs: [determine-build, fetch-translations] timeout-minutes: 15 strategy: @@ -148,7 +148,15 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: true - if: ${{ !contains(github.event.head_commit.message, 'skip') || !contains(github.event.head_commit.message, 'skipci')}} + if: >- + ${{ + !contains(github.event.head_commit.message, 'skipci') && + !contains(github.event.head_commit.message, '[skipci]') && + !contains(github.event.head_commit.message, 'skipci | ') && + !contains(github.event.pull_request.title, 'skipci') && + !contains(github.event.pull_request.title, '[skipci]') && + !contains(github.event.pull_request.title, 'skipci | ') + }} steps: - name: dummy action run: "echo 'dummy action that checks if the build is to be skipped, if it is, this action does not run to break the entire build action'" From 96a7e4a659f817c099293f0d491a1054075e4c63 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 11:34:20 +0800 Subject: [PATCH 067/484] feat: add MC 1.21.6 (protocol 771) version constants and enum values - Add protocol 771 constant MC_1_21_6_Version in Protocol18.cs - Register 1.21.6 in ProtocolHandler (version map, supported list) - Extend upper-bound checks from MC_1_21_5 to MC_1_21_6 - Add 19 new ItemType entries (16 colored Harnesses, DriedGhast, HappyGhastSpawnEgg, MusicDiscTears) - Add HappyGhast to EntityType enum - Add DriedGhast to Material enum - Add new packet types: Waypoint, ClearDialog, ShowDialog (clientbound), ChangeGameMode, CustomClickAction (serverbound), ClearDialog, ShowDialog (config clientbound), CustomClickAction (config serverbound) Made-with: Cursor --- MinecraftClient/Inventory/ItemType.cs | 19 +++++++++++++++++++ MinecraftClient/Mapping/EntityType.cs | 1 + MinecraftClient/Mapping/Material.cs | 1 + .../Handlers/ConfigurationPacketTypesIn.cs | 2 ++ .../Handlers/ConfigurationPacketTypesOut.cs | 1 + .../Protocol/Handlers/PacketTypesIn.cs | 3 +++ .../Protocol/Handlers/PacketTypesOut.cs | 2 ++ .../Protocol/Handlers/Protocol18.cs | 15 ++++++++------- MinecraftClient/Protocol/ProtocolHandler.cs | 5 ++++- 9 files changed, 41 insertions(+), 8 deletions(-) diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 1809b7ab..a51d9d0f 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -122,6 +122,7 @@ namespace MinecraftClient.Inventory BlackTerracotta, BlackWool, BlackBundle, + BlackHarness, Blackstone, BlackstoneSlab, BlackstoneStairs, @@ -148,6 +149,7 @@ namespace MinecraftClient.Inventory BlueTerracotta, BlueWool, BlueBundle, + BlueHarness, BoggedSpawnEgg, BoltArmorTrimSmithingTemplate, Bone, @@ -188,6 +190,7 @@ namespace MinecraftClient.Inventory BrownTerracotta, BrownWool, BrownBundle, + BrownHarness, Brush, BubbleCoral, BubbleCoralBlock, @@ -352,6 +355,7 @@ namespace MinecraftClient.Inventory CyanTerracotta, CyanWool, CyanBundle, + CyanHarness, DamagedAnvil, Dandelion, DangerPotterySherd, @@ -438,6 +442,7 @@ namespace MinecraftClient.Inventory DragonBreath, DragonEgg, DragonHead, + DriedGhast, DriedKelp, DriedKelpBlock, DripstoneBlock, @@ -566,6 +571,7 @@ namespace MinecraftClient.Inventory GrayTerracotta, GrayWool, GrayBundle, + GrayHarness, GreenBanner, GreenBed, GreenCandle, @@ -580,12 +586,14 @@ namespace MinecraftClient.Inventory GreenTerracotta, GreenWool, GreenBundle, + GreenHarness, Grindstone, GuardianSpawnEgg, Gunpowder, GusterBannerPattern, GusterPotterySherd, HangingRoots, + HappyGhastSpawnEgg, HayBlock, HeartOfTheSea, HeartPotterySherd, @@ -689,6 +697,7 @@ namespace MinecraftClient.Inventory LightBlueTerracotta, LightBlueWool, LightBlueBundle, + LightBlueHarness, LightGrayBanner, LightGrayBed, LightGrayCandle, @@ -703,6 +712,7 @@ namespace MinecraftClient.Inventory LightGrayTerracotta, LightGrayWool, LightGrayBundle, + LightGrayHarness, LightWeightedPressurePlate, LightningRod, Lilac, @@ -722,6 +732,7 @@ namespace MinecraftClient.Inventory LimeTerracotta, LimeWool, LimeBundle, + LimeHarness, LingeringPotion, LlamaSpawnEgg, Lodestone, @@ -741,6 +752,7 @@ namespace MinecraftClient.Inventory MagentaTerracotta, MagentaWool, MagentaBundle, + MagentaHarness, MagmaBlock, MagmaCream, MagmaCubeSpawnEgg, @@ -809,6 +821,7 @@ namespace MinecraftClient.Inventory MusicDiscRelic, MusicDiscStal, MusicDiscStrad, + MusicDiscTears, MusicDiscWait, MusicDiscWard, Mutton, @@ -881,6 +894,7 @@ namespace MinecraftClient.Inventory OrangeTulip, OrangeWool, OrangeBundle, + OrangeHarness, OxeyeDaisy, OxidizedChiseledCopper, OxidizedCopper, @@ -944,6 +958,7 @@ namespace MinecraftClient.Inventory PinkTulip, PinkWool, PinkBundle, + PinkHarness, Piston, PitcherPlant, PitcherPod, @@ -1018,6 +1033,7 @@ namespace MinecraftClient.Inventory PurpleTerracotta, PurpleWool, PurpleBundle, + PurpleHarness, PurpurBlock, PurpurPillar, PurpurSlab, @@ -1069,6 +1085,7 @@ namespace MinecraftClient.Inventory RedTulip, RedWool, RedBundle, + RedHarness, Redstone, RedstoneBlock, RedstoneLamp, @@ -1373,6 +1390,7 @@ namespace MinecraftClient.Inventory WhiteTulip, WhiteWool, WhiteBundle, + WhiteHarness, WildArmorTrimSmithingTemplate, Wildflowers, // wildflowers WindCharge, @@ -1404,6 +1422,7 @@ namespace MinecraftClient.Inventory YellowTerracotta, YellowWool, YellowBundle, + YellowHarness, ZoglinSpawnEgg, ZombieHead, ZombieHorseSpawnEgg, diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 2dc813c8..6e75efce 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -79,6 +79,7 @@ namespace MinecraftClient.Mapping GlowSquid, Goat, Guardian, + HappyGhast, Hoglin, HopperMinecart, Horse, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 9485e760..d0c71840 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -364,6 +364,7 @@ namespace MinecraftClient.Mapping DragonEgg, DragonHead, DragonWallHead, + DriedGhast, DriedKelpBlock, DripstoneBlock, Dropper, diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs index 0648601a..edc48e82 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs @@ -19,6 +19,8 @@ public enum ConfigurationPacketTypesIn StoreCookie, Transfer, UpdateTags, + ClearDialog, // Added in 1.21.6 + ShowDialog, // Added in 1.21.6 Unknown } diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs index 32a99ec2..d3f7dd0b 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs @@ -10,6 +10,7 @@ public enum ConfigurationPacketTypesOut ResourcePackResponse, CookieResponse, KnownDataPacks, + CustomClickAction, // Added in 1.21.6 Unknown } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 7defe5e7..7e257b27 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -161,5 +161,8 @@ namespace MinecraftClient.Protocol.Handlers WorldBorderSize, // WorldBorderWarningDelay, // WorldBorderWarningReach, // + Waypoint, // Added in 1.21.6 + ClearDialog, // Added in 1.21.6 + ShowDialog, // Added in 1.21.6 } } diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index 3b1523eb..111f3653 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -76,5 +76,7 @@ namespace MinecraftClient.Protocol.Handlers UseItem, // VehicleMove, // WindowConfirmation, // + ChangeGameMode, // Added in 1.21.6 + CustomClickAction, // Added in 1.21.6 } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 9beae52e..8f4f0d99 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -76,6 +76,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_2_Version = 768; internal const int MC_1_21_4_Version = 769; internal const int MC_1_21_5_Version = 770; + internal const int MC_1_21_6_Version = 771; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -127,21 +128,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_5_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_6_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_5_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_6_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_5_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_6_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -150,7 +151,7 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_5_Version when handler.GetTerrainEnabled() => + > MC_1_21_6_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), >= MC_1_21_5_Version => new Palette1215(), >= MC_1_21_4_Version => new Palette1214(), @@ -172,7 +173,7 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_5_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_6_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), >= MC_1_21_5_Version => new EntityPalette1215(), >= MC_1_21_4_Version => new EntityPalette1214(), @@ -198,7 +199,7 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_5_Version when handler.GetInventoryEnabled() => + > MC_1_21_6_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), >= MC_1_21_5_Version => new ItemPalette1215(), >= MC_1_21_4_Version => new ItemPalette1214(), @@ -2655,7 +2656,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_5_Version => throw new NotImplementedException(Translations + > MC_1_21_6_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 684e351b..7c7d69ba 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -154,7 +154,7 @@ namespace MinecraftClient.Protocol { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769, 770 + 769, 770, 771 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -360,6 +360,8 @@ namespace MinecraftClient.Protocol return 769; case "1.21.5": return 770; + case "1.21.6": + return 771; default: return 0; } @@ -444,6 +446,7 @@ namespace MinecraftClient.Protocol 768 => "1.21.2", 769 => "1.21.4", 770 => "1.21.5", + 771 => "1.21.6", _ => "0.0" }; } From 1b0e27fde71b09a3b1f9bf3613bb6c4d89cb6954 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 11:44:12 +0800 Subject: [PATCH 068/484] feat: add palettes and version routing for MC 1.21.6 - ItemPalette1216: 1415 items (generated from decompiled Items.java) - EntityPalette1216: 151 entities (HappyGhast at index 56, all after +1) - Palette1216: block states (DriedGhast 32 states at 13826-13857, all after +32) - PacketPalette1216: clientbound +3 (Waypoint, ClearDialog, ShowDialog), serverbound +2 (ChangeGameMode at 0x04 shifting all after, CustomClickAction at end), config clientbound +2 (ClearDialog, ShowDialog), config serverbound +1 (CustomClickAction) - Version routing in Protocol18.cs, PacketType18Handler.cs, EntityMetadataPalette.cs updated to select 1216 palettes for protocol >= 771 - EntityMetadataPalette reuses 1215 (EntityDataSerializers unchanged) Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1216.cs | 1433 +++++++++++++ .../Mapping/BlockPalettes/Palette1216.cs | 1840 +++++++++++++++++ .../Mapping/EntityMetadataPalette.cs | 2 +- .../EntityPalettes/EntityPalette1216.cs | 169 ++ .../PacketPalettes/PacketPalette1216.cs | 255 +++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- .../Protocol/Handlers/Protocol18.cs | 3 + 7 files changed, 3703 insertions(+), 2 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1216.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1216.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1216.cs create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1216.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1216.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1216.cs new file mode 100644 index 00000000..91472a53 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1216.cs @@ -0,0 +1,1433 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1216 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1216() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.DryShortGrass; + mappings[210] = ItemType.DryTallGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.OpenEyeblossom; + mappings[231] = ItemType.ClosedEyeblossom; + mappings[232] = ItemType.Poppy; + mappings[233] = ItemType.BlueOrchid; + mappings[234] = ItemType.Allium; + mappings[235] = ItemType.AzureBluet; + mappings[236] = ItemType.RedTulip; + mappings[237] = ItemType.OrangeTulip; + mappings[238] = ItemType.WhiteTulip; + mappings[239] = ItemType.PinkTulip; + mappings[240] = ItemType.OxeyeDaisy; + mappings[241] = ItemType.Cornflower; + mappings[242] = ItemType.LilyOfTheValley; + mappings[243] = ItemType.WitherRose; + mappings[244] = ItemType.Torchflower; + mappings[245] = ItemType.PitcherPlant; + mappings[246] = ItemType.SporeBlossom; + mappings[247] = ItemType.BrownMushroom; + mappings[248] = ItemType.RedMushroom; + mappings[249] = ItemType.CrimsonFungus; + mappings[250] = ItemType.WarpedFungus; + mappings[251] = ItemType.CrimsonRoots; + mappings[252] = ItemType.WarpedRoots; + mappings[253] = ItemType.NetherSprouts; + mappings[254] = ItemType.WeepingVines; + mappings[255] = ItemType.TwistingVines; + mappings[256] = ItemType.SugarCane; + mappings[257] = ItemType.Kelp; + mappings[258] = ItemType.PinkPetals; + mappings[259] = ItemType.Wildflowers; + mappings[260] = ItemType.LeafLitter; + mappings[261] = ItemType.MossCarpet; + mappings[262] = ItemType.MossBlock; + mappings[263] = ItemType.PaleMossCarpet; + mappings[264] = ItemType.PaleHangingMoss; + mappings[265] = ItemType.PaleMossBlock; + mappings[266] = ItemType.HangingRoots; + mappings[267] = ItemType.BigDripleaf; + mappings[268] = ItemType.SmallDripleaf; + mappings[269] = ItemType.Bamboo; + mappings[270] = ItemType.OakSlab; + mappings[271] = ItemType.SpruceSlab; + mappings[272] = ItemType.BirchSlab; + mappings[273] = ItemType.JungleSlab; + mappings[274] = ItemType.AcaciaSlab; + mappings[275] = ItemType.CherrySlab; + mappings[276] = ItemType.DarkOakSlab; + mappings[277] = ItemType.PaleOakSlab; + mappings[278] = ItemType.MangroveSlab; + mappings[279] = ItemType.BambooSlab; + mappings[280] = ItemType.BambooMosaicSlab; + mappings[281] = ItemType.CrimsonSlab; + mappings[282] = ItemType.WarpedSlab; + mappings[283] = ItemType.StoneSlab; + mappings[284] = ItemType.SmoothStoneSlab; + mappings[285] = ItemType.SandstoneSlab; + mappings[286] = ItemType.CutSandstoneSlab; + mappings[287] = ItemType.PetrifiedOakSlab; + mappings[288] = ItemType.CobblestoneSlab; + mappings[289] = ItemType.BrickSlab; + mappings[290] = ItemType.StoneBrickSlab; + mappings[291] = ItemType.MudBrickSlab; + mappings[292] = ItemType.NetherBrickSlab; + mappings[293] = ItemType.QuartzSlab; + mappings[294] = ItemType.RedSandstoneSlab; + mappings[295] = ItemType.CutRedSandstoneSlab; + mappings[296] = ItemType.PurpurSlab; + mappings[297] = ItemType.PrismarineSlab; + mappings[298] = ItemType.PrismarineBrickSlab; + mappings[299] = ItemType.DarkPrismarineSlab; + mappings[300] = ItemType.SmoothQuartz; + mappings[301] = ItemType.SmoothRedSandstone; + mappings[302] = ItemType.SmoothSandstone; + mappings[303] = ItemType.SmoothStone; + mappings[304] = ItemType.Bricks; + mappings[305] = ItemType.Bookshelf; + mappings[306] = ItemType.ChiseledBookshelf; + mappings[307] = ItemType.DecoratedPot; + mappings[308] = ItemType.MossyCobblestone; + mappings[309] = ItemType.Obsidian; + mappings[310] = ItemType.Torch; + mappings[311] = ItemType.EndRod; + mappings[312] = ItemType.ChorusPlant; + mappings[313] = ItemType.ChorusFlower; + mappings[314] = ItemType.PurpurBlock; + mappings[315] = ItemType.PurpurPillar; + mappings[316] = ItemType.PurpurStairs; + mappings[317] = ItemType.Spawner; + mappings[318] = ItemType.CreakingHeart; + mappings[319] = ItemType.Chest; + mappings[320] = ItemType.CraftingTable; + mappings[321] = ItemType.Farmland; + mappings[322] = ItemType.Furnace; + mappings[323] = ItemType.Ladder; + mappings[324] = ItemType.CobblestoneStairs; + mappings[325] = ItemType.Snow; + mappings[326] = ItemType.Ice; + mappings[327] = ItemType.SnowBlock; + mappings[328] = ItemType.Cactus; + mappings[329] = ItemType.CactusFlower; + mappings[330] = ItemType.Clay; + mappings[331] = ItemType.Jukebox; + mappings[332] = ItemType.OakFence; + mappings[333] = ItemType.SpruceFence; + mappings[334] = ItemType.BirchFence; + mappings[335] = ItemType.JungleFence; + mappings[336] = ItemType.AcaciaFence; + mappings[337] = ItemType.CherryFence; + mappings[338] = ItemType.DarkOakFence; + mappings[339] = ItemType.PaleOakFence; + mappings[340] = ItemType.MangroveFence; + mappings[341] = ItemType.BambooFence; + mappings[342] = ItemType.CrimsonFence; + mappings[343] = ItemType.WarpedFence; + mappings[344] = ItemType.Pumpkin; + mappings[345] = ItemType.CarvedPumpkin; + mappings[346] = ItemType.JackOLantern; + mappings[347] = ItemType.Netherrack; + mappings[348] = ItemType.SoulSand; + mappings[349] = ItemType.SoulSoil; + mappings[350] = ItemType.Basalt; + mappings[351] = ItemType.PolishedBasalt; + mappings[352] = ItemType.SmoothBasalt; + mappings[353] = ItemType.SoulTorch; + mappings[354] = ItemType.Glowstone; + mappings[355] = ItemType.InfestedStone; + mappings[356] = ItemType.InfestedCobblestone; + mappings[357] = ItemType.InfestedStoneBricks; + mappings[358] = ItemType.InfestedMossyStoneBricks; + mappings[359] = ItemType.InfestedCrackedStoneBricks; + mappings[360] = ItemType.InfestedChiseledStoneBricks; + mappings[361] = ItemType.InfestedDeepslate; + mappings[362] = ItemType.StoneBricks; + mappings[363] = ItemType.MossyStoneBricks; + mappings[364] = ItemType.CrackedStoneBricks; + mappings[365] = ItemType.ChiseledStoneBricks; + mappings[366] = ItemType.PackedMud; + mappings[367] = ItemType.MudBricks; + mappings[368] = ItemType.DeepslateBricks; + mappings[369] = ItemType.CrackedDeepslateBricks; + mappings[370] = ItemType.DeepslateTiles; + mappings[371] = ItemType.CrackedDeepslateTiles; + mappings[372] = ItemType.ChiseledDeepslate; + mappings[373] = ItemType.ReinforcedDeepslate; + mappings[374] = ItemType.BrownMushroomBlock; + mappings[375] = ItemType.RedMushroomBlock; + mappings[376] = ItemType.MushroomStem; + mappings[377] = ItemType.IronBars; + mappings[378] = ItemType.Chain; + mappings[379] = ItemType.GlassPane; + mappings[380] = ItemType.Melon; + mappings[381] = ItemType.Vine; + mappings[382] = ItemType.GlowLichen; + mappings[383] = ItemType.ResinClump; + mappings[384] = ItemType.ResinBlock; + mappings[385] = ItemType.ResinBricks; + mappings[386] = ItemType.ResinBrickStairs; + mappings[387] = ItemType.ResinBrickSlab; + mappings[388] = ItemType.ResinBrickWall; + mappings[389] = ItemType.ChiseledResinBricks; + mappings[390] = ItemType.BrickStairs; + mappings[391] = ItemType.StoneBrickStairs; + mappings[392] = ItemType.MudBrickStairs; + mappings[393] = ItemType.Mycelium; + mappings[394] = ItemType.LilyPad; + mappings[395] = ItemType.NetherBricks; + mappings[396] = ItemType.CrackedNetherBricks; + mappings[397] = ItemType.ChiseledNetherBricks; + mappings[398] = ItemType.NetherBrickFence; + mappings[399] = ItemType.NetherBrickStairs; + mappings[400] = ItemType.Sculk; + mappings[401] = ItemType.SculkVein; + mappings[402] = ItemType.SculkCatalyst; + mappings[403] = ItemType.SculkShrieker; + mappings[404] = ItemType.EnchantingTable; + mappings[405] = ItemType.EndPortalFrame; + mappings[406] = ItemType.EndStone; + mappings[407] = ItemType.EndStoneBricks; + mappings[408] = ItemType.DragonEgg; + mappings[409] = ItemType.SandstoneStairs; + mappings[410] = ItemType.EnderChest; + mappings[411] = ItemType.EmeraldBlock; + mappings[412] = ItemType.OakStairs; + mappings[413] = ItemType.SpruceStairs; + mappings[414] = ItemType.BirchStairs; + mappings[415] = ItemType.JungleStairs; + mappings[416] = ItemType.AcaciaStairs; + mappings[417] = ItemType.CherryStairs; + mappings[418] = ItemType.DarkOakStairs; + mappings[419] = ItemType.PaleOakStairs; + mappings[420] = ItemType.MangroveStairs; + mappings[421] = ItemType.BambooStairs; + mappings[422] = ItemType.BambooMosaicStairs; + mappings[423] = ItemType.CrimsonStairs; + mappings[424] = ItemType.WarpedStairs; + mappings[425] = ItemType.CommandBlock; + mappings[426] = ItemType.Beacon; + mappings[427] = ItemType.CobblestoneWall; + mappings[428] = ItemType.MossyCobblestoneWall; + mappings[429] = ItemType.BrickWall; + mappings[430] = ItemType.PrismarineWall; + mappings[431] = ItemType.RedSandstoneWall; + mappings[432] = ItemType.MossyStoneBrickWall; + mappings[433] = ItemType.GraniteWall; + mappings[434] = ItemType.StoneBrickWall; + mappings[435] = ItemType.MudBrickWall; + mappings[436] = ItemType.NetherBrickWall; + mappings[437] = ItemType.AndesiteWall; + mappings[438] = ItemType.RedNetherBrickWall; + mappings[439] = ItemType.SandstoneWall; + mappings[440] = ItemType.EndStoneBrickWall; + mappings[441] = ItemType.DioriteWall; + mappings[442] = ItemType.BlackstoneWall; + mappings[443] = ItemType.PolishedBlackstoneWall; + mappings[444] = ItemType.PolishedBlackstoneBrickWall; + mappings[445] = ItemType.CobbledDeepslateWall; + mappings[446] = ItemType.PolishedDeepslateWall; + mappings[447] = ItemType.DeepslateBrickWall; + mappings[448] = ItemType.DeepslateTileWall; + mappings[449] = ItemType.Anvil; + mappings[450] = ItemType.ChippedAnvil; + mappings[451] = ItemType.DamagedAnvil; + mappings[452] = ItemType.ChiseledQuartzBlock; + mappings[453] = ItemType.QuartzBlock; + mappings[454] = ItemType.QuartzBricks; + mappings[455] = ItemType.QuartzPillar; + mappings[456] = ItemType.QuartzStairs; + mappings[457] = ItemType.WhiteTerracotta; + mappings[458] = ItemType.OrangeTerracotta; + mappings[459] = ItemType.MagentaTerracotta; + mappings[460] = ItemType.LightBlueTerracotta; + mappings[461] = ItemType.YellowTerracotta; + mappings[462] = ItemType.LimeTerracotta; + mappings[463] = ItemType.PinkTerracotta; + mappings[464] = ItemType.GrayTerracotta; + mappings[465] = ItemType.LightGrayTerracotta; + mappings[466] = ItemType.CyanTerracotta; + mappings[467] = ItemType.PurpleTerracotta; + mappings[468] = ItemType.BlueTerracotta; + mappings[469] = ItemType.BrownTerracotta; + mappings[470] = ItemType.GreenTerracotta; + mappings[471] = ItemType.RedTerracotta; + mappings[472] = ItemType.BlackTerracotta; + mappings[473] = ItemType.Barrier; + mappings[474] = ItemType.Light; + mappings[475] = ItemType.HayBlock; + mappings[476] = ItemType.WhiteCarpet; + mappings[477] = ItemType.OrangeCarpet; + mappings[478] = ItemType.MagentaCarpet; + mappings[479] = ItemType.LightBlueCarpet; + mappings[480] = ItemType.YellowCarpet; + mappings[481] = ItemType.LimeCarpet; + mappings[482] = ItemType.PinkCarpet; + mappings[483] = ItemType.GrayCarpet; + mappings[484] = ItemType.LightGrayCarpet; + mappings[485] = ItemType.CyanCarpet; + mappings[486] = ItemType.PurpleCarpet; + mappings[487] = ItemType.BlueCarpet; + mappings[488] = ItemType.BrownCarpet; + mappings[489] = ItemType.GreenCarpet; + mappings[490] = ItemType.RedCarpet; + mappings[491] = ItemType.BlackCarpet; + mappings[492] = ItemType.Terracotta; + mappings[493] = ItemType.PackedIce; + mappings[494] = ItemType.DirtPath; + mappings[495] = ItemType.Sunflower; + mappings[496] = ItemType.Lilac; + mappings[497] = ItemType.RoseBush; + mappings[498] = ItemType.Peony; + mappings[499] = ItemType.TallGrass; + mappings[500] = ItemType.LargeFern; + mappings[501] = ItemType.WhiteStainedGlass; + mappings[502] = ItemType.OrangeStainedGlass; + mappings[503] = ItemType.MagentaStainedGlass; + mappings[504] = ItemType.LightBlueStainedGlass; + mappings[505] = ItemType.YellowStainedGlass; + mappings[506] = ItemType.LimeStainedGlass; + mappings[507] = ItemType.PinkStainedGlass; + mappings[508] = ItemType.GrayStainedGlass; + mappings[509] = ItemType.LightGrayStainedGlass; + mappings[510] = ItemType.CyanStainedGlass; + mappings[511] = ItemType.PurpleStainedGlass; + mappings[512] = ItemType.BlueStainedGlass; + mappings[513] = ItemType.BrownStainedGlass; + mappings[514] = ItemType.GreenStainedGlass; + mappings[515] = ItemType.RedStainedGlass; + mappings[516] = ItemType.BlackStainedGlass; + mappings[517] = ItemType.WhiteStainedGlassPane; + mappings[518] = ItemType.OrangeStainedGlassPane; + mappings[519] = ItemType.MagentaStainedGlassPane; + mappings[520] = ItemType.LightBlueStainedGlassPane; + mappings[521] = ItemType.YellowStainedGlassPane; + mappings[522] = ItemType.LimeStainedGlassPane; + mappings[523] = ItemType.PinkStainedGlassPane; + mappings[524] = ItemType.GrayStainedGlassPane; + mappings[525] = ItemType.LightGrayStainedGlassPane; + mappings[526] = ItemType.CyanStainedGlassPane; + mappings[527] = ItemType.PurpleStainedGlassPane; + mappings[528] = ItemType.BlueStainedGlassPane; + mappings[529] = ItemType.BrownStainedGlassPane; + mappings[530] = ItemType.GreenStainedGlassPane; + mappings[531] = ItemType.RedStainedGlassPane; + mappings[532] = ItemType.BlackStainedGlassPane; + mappings[533] = ItemType.Prismarine; + mappings[534] = ItemType.PrismarineBricks; + mappings[535] = ItemType.DarkPrismarine; + mappings[536] = ItemType.PrismarineStairs; + mappings[537] = ItemType.PrismarineBrickStairs; + mappings[538] = ItemType.DarkPrismarineStairs; + mappings[539] = ItemType.SeaLantern; + mappings[540] = ItemType.RedSandstone; + mappings[541] = ItemType.ChiseledRedSandstone; + mappings[542] = ItemType.CutRedSandstone; + mappings[543] = ItemType.RedSandstoneStairs; + mappings[544] = ItemType.RepeatingCommandBlock; + mappings[545] = ItemType.ChainCommandBlock; + mappings[546] = ItemType.MagmaBlock; + mappings[547] = ItemType.NetherWartBlock; + mappings[548] = ItemType.WarpedWartBlock; + mappings[549] = ItemType.RedNetherBricks; + mappings[550] = ItemType.BoneBlock; + mappings[551] = ItemType.StructureVoid; + mappings[552] = ItemType.ShulkerBox; + mappings[553] = ItemType.WhiteShulkerBox; + mappings[554] = ItemType.OrangeShulkerBox; + mappings[555] = ItemType.MagentaShulkerBox; + mappings[556] = ItemType.LightBlueShulkerBox; + mappings[557] = ItemType.YellowShulkerBox; + mappings[558] = ItemType.LimeShulkerBox; + mappings[559] = ItemType.PinkShulkerBox; + mappings[560] = ItemType.GrayShulkerBox; + mappings[561] = ItemType.LightGrayShulkerBox; + mappings[562] = ItemType.CyanShulkerBox; + mappings[563] = ItemType.PurpleShulkerBox; + mappings[564] = ItemType.BlueShulkerBox; + mappings[565] = ItemType.BrownShulkerBox; + mappings[566] = ItemType.GreenShulkerBox; + mappings[567] = ItemType.RedShulkerBox; + mappings[568] = ItemType.BlackShulkerBox; + mappings[569] = ItemType.WhiteGlazedTerracotta; + mappings[570] = ItemType.OrangeGlazedTerracotta; + mappings[571] = ItemType.MagentaGlazedTerracotta; + mappings[572] = ItemType.LightBlueGlazedTerracotta; + mappings[573] = ItemType.YellowGlazedTerracotta; + mappings[574] = ItemType.LimeGlazedTerracotta; + mappings[575] = ItemType.PinkGlazedTerracotta; + mappings[576] = ItemType.GrayGlazedTerracotta; + mappings[577] = ItemType.LightGrayGlazedTerracotta; + mappings[578] = ItemType.CyanGlazedTerracotta; + mappings[579] = ItemType.PurpleGlazedTerracotta; + mappings[580] = ItemType.BlueGlazedTerracotta; + mappings[581] = ItemType.BrownGlazedTerracotta; + mappings[582] = ItemType.GreenGlazedTerracotta; + mappings[583] = ItemType.RedGlazedTerracotta; + mappings[584] = ItemType.BlackGlazedTerracotta; + mappings[585] = ItemType.WhiteConcrete; + mappings[586] = ItemType.OrangeConcrete; + mappings[587] = ItemType.MagentaConcrete; + mappings[588] = ItemType.LightBlueConcrete; + mappings[589] = ItemType.YellowConcrete; + mappings[590] = ItemType.LimeConcrete; + mappings[591] = ItemType.PinkConcrete; + mappings[592] = ItemType.GrayConcrete; + mappings[593] = ItemType.LightGrayConcrete; + mappings[594] = ItemType.CyanConcrete; + mappings[595] = ItemType.PurpleConcrete; + mappings[596] = ItemType.BlueConcrete; + mappings[597] = ItemType.BrownConcrete; + mappings[598] = ItemType.GreenConcrete; + mappings[599] = ItemType.RedConcrete; + mappings[600] = ItemType.BlackConcrete; + mappings[601] = ItemType.WhiteConcretePowder; + mappings[602] = ItemType.OrangeConcretePowder; + mappings[603] = ItemType.MagentaConcretePowder; + mappings[604] = ItemType.LightBlueConcretePowder; + mappings[605] = ItemType.YellowConcretePowder; + mappings[606] = ItemType.LimeConcretePowder; + mappings[607] = ItemType.PinkConcretePowder; + mappings[608] = ItemType.GrayConcretePowder; + mappings[609] = ItemType.LightGrayConcretePowder; + mappings[610] = ItemType.CyanConcretePowder; + mappings[611] = ItemType.PurpleConcretePowder; + mappings[612] = ItemType.BlueConcretePowder; + mappings[613] = ItemType.BrownConcretePowder; + mappings[614] = ItemType.GreenConcretePowder; + mappings[615] = ItemType.RedConcretePowder; + mappings[616] = ItemType.BlackConcretePowder; + mappings[617] = ItemType.TurtleEgg; + mappings[618] = ItemType.SnifferEgg; + mappings[619] = ItemType.DriedGhast; + mappings[620] = ItemType.DeadTubeCoralBlock; + mappings[621] = ItemType.DeadBrainCoralBlock; + mappings[622] = ItemType.DeadBubbleCoralBlock; + mappings[623] = ItemType.DeadFireCoralBlock; + mappings[624] = ItemType.DeadHornCoralBlock; + mappings[625] = ItemType.TubeCoralBlock; + mappings[626] = ItemType.BrainCoralBlock; + mappings[627] = ItemType.BubbleCoralBlock; + mappings[628] = ItemType.FireCoralBlock; + mappings[629] = ItemType.HornCoralBlock; + mappings[630] = ItemType.TubeCoral; + mappings[631] = ItemType.BrainCoral; + mappings[632] = ItemType.BubbleCoral; + mappings[633] = ItemType.FireCoral; + mappings[634] = ItemType.HornCoral; + mappings[635] = ItemType.DeadBrainCoral; + mappings[636] = ItemType.DeadBubbleCoral; + mappings[637] = ItemType.DeadFireCoral; + mappings[638] = ItemType.DeadHornCoral; + mappings[639] = ItemType.DeadTubeCoral; + mappings[640] = ItemType.TubeCoralFan; + mappings[641] = ItemType.BrainCoralFan; + mappings[642] = ItemType.BubbleCoralFan; + mappings[643] = ItemType.FireCoralFan; + mappings[644] = ItemType.HornCoralFan; + mappings[645] = ItemType.DeadTubeCoralFan; + mappings[646] = ItemType.DeadBrainCoralFan; + mappings[647] = ItemType.DeadBubbleCoralFan; + mappings[648] = ItemType.DeadFireCoralFan; + mappings[649] = ItemType.DeadHornCoralFan; + mappings[650] = ItemType.BlueIce; + mappings[651] = ItemType.Conduit; + mappings[652] = ItemType.PolishedGraniteStairs; + mappings[653] = ItemType.SmoothRedSandstoneStairs; + mappings[654] = ItemType.MossyStoneBrickStairs; + mappings[655] = ItemType.PolishedDioriteStairs; + mappings[656] = ItemType.MossyCobblestoneStairs; + mappings[657] = ItemType.EndStoneBrickStairs; + mappings[658] = ItemType.StoneStairs; + mappings[659] = ItemType.SmoothSandstoneStairs; + mappings[660] = ItemType.SmoothQuartzStairs; + mappings[661] = ItemType.GraniteStairs; + mappings[662] = ItemType.AndesiteStairs; + mappings[663] = ItemType.RedNetherBrickStairs; + mappings[664] = ItemType.PolishedAndesiteStairs; + mappings[665] = ItemType.DioriteStairs; + mappings[666] = ItemType.CobbledDeepslateStairs; + mappings[667] = ItemType.PolishedDeepslateStairs; + mappings[668] = ItemType.DeepslateBrickStairs; + mappings[669] = ItemType.DeepslateTileStairs; + mappings[670] = ItemType.PolishedGraniteSlab; + mappings[671] = ItemType.SmoothRedSandstoneSlab; + mappings[672] = ItemType.MossyStoneBrickSlab; + mappings[673] = ItemType.PolishedDioriteSlab; + mappings[674] = ItemType.MossyCobblestoneSlab; + mappings[675] = ItemType.EndStoneBrickSlab; + mappings[676] = ItemType.SmoothSandstoneSlab; + mappings[677] = ItemType.SmoothQuartzSlab; + mappings[678] = ItemType.GraniteSlab; + mappings[679] = ItemType.AndesiteSlab; + mappings[680] = ItemType.RedNetherBrickSlab; + mappings[681] = ItemType.PolishedAndesiteSlab; + mappings[682] = ItemType.DioriteSlab; + mappings[683] = ItemType.CobbledDeepslateSlab; + mappings[684] = ItemType.PolishedDeepslateSlab; + mappings[685] = ItemType.DeepslateBrickSlab; + mappings[686] = ItemType.DeepslateTileSlab; + mappings[687] = ItemType.Scaffolding; + mappings[688] = ItemType.Redstone; + mappings[689] = ItemType.RedstoneTorch; + mappings[690] = ItemType.RedstoneBlock; + mappings[691] = ItemType.Repeater; + mappings[692] = ItemType.Comparator; + mappings[693] = ItemType.Piston; + mappings[694] = ItemType.StickyPiston; + mappings[695] = ItemType.SlimeBlock; + mappings[696] = ItemType.HoneyBlock; + mappings[697] = ItemType.Observer; + mappings[698] = ItemType.Hopper; + mappings[699] = ItemType.Dispenser; + mappings[700] = ItemType.Dropper; + mappings[701] = ItemType.Lectern; + mappings[702] = ItemType.Target; + mappings[703] = ItemType.Lever; + mappings[704] = ItemType.LightningRod; + mappings[705] = ItemType.DaylightDetector; + mappings[706] = ItemType.SculkSensor; + mappings[707] = ItemType.CalibratedSculkSensor; + mappings[708] = ItemType.TripwireHook; + mappings[709] = ItemType.TrappedChest; + mappings[710] = ItemType.Tnt; + mappings[711] = ItemType.RedstoneLamp; + mappings[712] = ItemType.NoteBlock; + mappings[713] = ItemType.StoneButton; + mappings[714] = ItemType.PolishedBlackstoneButton; + mappings[715] = ItemType.OakButton; + mappings[716] = ItemType.SpruceButton; + mappings[717] = ItemType.BirchButton; + mappings[718] = ItemType.JungleButton; + mappings[719] = ItemType.AcaciaButton; + mappings[720] = ItemType.CherryButton; + mappings[721] = ItemType.DarkOakButton; + mappings[722] = ItemType.PaleOakButton; + mappings[723] = ItemType.MangroveButton; + mappings[724] = ItemType.BambooButton; + mappings[725] = ItemType.CrimsonButton; + mappings[726] = ItemType.WarpedButton; + mappings[727] = ItemType.StonePressurePlate; + mappings[728] = ItemType.PolishedBlackstonePressurePlate; + mappings[729] = ItemType.LightWeightedPressurePlate; + mappings[730] = ItemType.HeavyWeightedPressurePlate; + mappings[731] = ItemType.OakPressurePlate; + mappings[732] = ItemType.SprucePressurePlate; + mappings[733] = ItemType.BirchPressurePlate; + mappings[734] = ItemType.JunglePressurePlate; + mappings[735] = ItemType.AcaciaPressurePlate; + mappings[736] = ItemType.CherryPressurePlate; + mappings[737] = ItemType.DarkOakPressurePlate; + mappings[738] = ItemType.PaleOakPressurePlate; + mappings[739] = ItemType.MangrovePressurePlate; + mappings[740] = ItemType.BambooPressurePlate; + mappings[741] = ItemType.CrimsonPressurePlate; + mappings[742] = ItemType.WarpedPressurePlate; + mappings[743] = ItemType.IronDoor; + mappings[744] = ItemType.OakDoor; + mappings[745] = ItemType.SpruceDoor; + mappings[746] = ItemType.BirchDoor; + mappings[747] = ItemType.JungleDoor; + mappings[748] = ItemType.AcaciaDoor; + mappings[749] = ItemType.CherryDoor; + mappings[750] = ItemType.DarkOakDoor; + mappings[751] = ItemType.PaleOakDoor; + mappings[752] = ItemType.MangroveDoor; + mappings[753] = ItemType.BambooDoor; + mappings[754] = ItemType.CrimsonDoor; + mappings[755] = ItemType.WarpedDoor; + mappings[756] = ItemType.CopperDoor; + mappings[757] = ItemType.ExposedCopperDoor; + mappings[758] = ItemType.WeatheredCopperDoor; + mappings[759] = ItemType.OxidizedCopperDoor; + mappings[760] = ItemType.WaxedCopperDoor; + mappings[761] = ItemType.WaxedExposedCopperDoor; + mappings[762] = ItemType.WaxedWeatheredCopperDoor; + mappings[763] = ItemType.WaxedOxidizedCopperDoor; + mappings[764] = ItemType.IronTrapdoor; + mappings[765] = ItemType.OakTrapdoor; + mappings[766] = ItemType.SpruceTrapdoor; + mappings[767] = ItemType.BirchTrapdoor; + mappings[768] = ItemType.JungleTrapdoor; + mappings[769] = ItemType.AcaciaTrapdoor; + mappings[770] = ItemType.CherryTrapdoor; + mappings[771] = ItemType.DarkOakTrapdoor; + mappings[772] = ItemType.PaleOakTrapdoor; + mappings[773] = ItemType.MangroveTrapdoor; + mappings[774] = ItemType.BambooTrapdoor; + mappings[775] = ItemType.CrimsonTrapdoor; + mappings[776] = ItemType.WarpedTrapdoor; + mappings[777] = ItemType.CopperTrapdoor; + mappings[778] = ItemType.ExposedCopperTrapdoor; + mappings[779] = ItemType.WeatheredCopperTrapdoor; + mappings[780] = ItemType.OxidizedCopperTrapdoor; + mappings[781] = ItemType.WaxedCopperTrapdoor; + mappings[782] = ItemType.WaxedExposedCopperTrapdoor; + mappings[783] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[784] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[785] = ItemType.OakFenceGate; + mappings[786] = ItemType.SpruceFenceGate; + mappings[787] = ItemType.BirchFenceGate; + mappings[788] = ItemType.JungleFenceGate; + mappings[789] = ItemType.AcaciaFenceGate; + mappings[790] = ItemType.CherryFenceGate; + mappings[791] = ItemType.DarkOakFenceGate; + mappings[792] = ItemType.PaleOakFenceGate; + mappings[793] = ItemType.MangroveFenceGate; + mappings[794] = ItemType.BambooFenceGate; + mappings[795] = ItemType.CrimsonFenceGate; + mappings[796] = ItemType.WarpedFenceGate; + mappings[797] = ItemType.PoweredRail; + mappings[798] = ItemType.DetectorRail; + mappings[799] = ItemType.Rail; + mappings[800] = ItemType.ActivatorRail; + mappings[801] = ItemType.Saddle; + mappings[802] = ItemType.WhiteHarness; + mappings[803] = ItemType.OrangeHarness; + mappings[804] = ItemType.MagentaHarness; + mappings[805] = ItemType.LightBlueHarness; + mappings[806] = ItemType.YellowHarness; + mappings[807] = ItemType.LimeHarness; + mappings[808] = ItemType.PinkHarness; + mappings[809] = ItemType.GrayHarness; + mappings[810] = ItemType.LightGrayHarness; + mappings[811] = ItemType.CyanHarness; + mappings[812] = ItemType.PurpleHarness; + mappings[813] = ItemType.BlueHarness; + mappings[814] = ItemType.BrownHarness; + mappings[815] = ItemType.GreenHarness; + mappings[816] = ItemType.RedHarness; + mappings[817] = ItemType.BlackHarness; + mappings[818] = ItemType.Minecart; + mappings[819] = ItemType.ChestMinecart; + mappings[820] = ItemType.FurnaceMinecart; + mappings[821] = ItemType.TntMinecart; + mappings[822] = ItemType.HopperMinecart; + mappings[823] = ItemType.CarrotOnAStick; + mappings[824] = ItemType.WarpedFungusOnAStick; + mappings[825] = ItemType.PhantomMembrane; + mappings[826] = ItemType.Elytra; + mappings[827] = ItemType.OakBoat; + mappings[828] = ItemType.OakChestBoat; + mappings[829] = ItemType.SpruceBoat; + mappings[830] = ItemType.SpruceChestBoat; + mappings[831] = ItemType.BirchBoat; + mappings[832] = ItemType.BirchChestBoat; + mappings[833] = ItemType.JungleBoat; + mappings[834] = ItemType.JungleChestBoat; + mappings[835] = ItemType.AcaciaBoat; + mappings[836] = ItemType.AcaciaChestBoat; + mappings[837] = ItemType.CherryBoat; + mappings[838] = ItemType.CherryChestBoat; + mappings[839] = ItemType.DarkOakBoat; + mappings[840] = ItemType.DarkOakChestBoat; + mappings[841] = ItemType.PaleOakBoat; + mappings[842] = ItemType.PaleOakChestBoat; + mappings[843] = ItemType.MangroveBoat; + mappings[844] = ItemType.MangroveChestBoat; + mappings[845] = ItemType.BambooRaft; + mappings[846] = ItemType.BambooChestRaft; + mappings[847] = ItemType.StructureBlock; + mappings[848] = ItemType.Jigsaw; + mappings[849] = ItemType.TestBlock; + mappings[850] = ItemType.TestInstanceBlock; + mappings[851] = ItemType.TurtleHelmet; + mappings[852] = ItemType.TurtleScute; + mappings[853] = ItemType.ArmadilloScute; + mappings[854] = ItemType.WolfArmor; + mappings[855] = ItemType.FlintAndSteel; + mappings[856] = ItemType.Bowl; + mappings[857] = ItemType.Apple; + mappings[858] = ItemType.Bow; + mappings[859] = ItemType.Arrow; + mappings[860] = ItemType.Coal; + mappings[861] = ItemType.Charcoal; + mappings[862] = ItemType.Diamond; + mappings[863] = ItemType.Emerald; + mappings[864] = ItemType.LapisLazuli; + mappings[865] = ItemType.Quartz; + mappings[866] = ItemType.AmethystShard; + mappings[867] = ItemType.RawIron; + mappings[868] = ItemType.IronIngot; + mappings[869] = ItemType.RawCopper; + mappings[870] = ItemType.CopperIngot; + mappings[871] = ItemType.RawGold; + mappings[872] = ItemType.GoldIngot; + mappings[873] = ItemType.NetheriteIngot; + mappings[874] = ItemType.NetheriteScrap; + mappings[875] = ItemType.WoodenSword; + mappings[876] = ItemType.WoodenShovel; + mappings[877] = ItemType.WoodenPickaxe; + mappings[878] = ItemType.WoodenAxe; + mappings[879] = ItemType.WoodenHoe; + mappings[880] = ItemType.StoneSword; + mappings[881] = ItemType.StoneShovel; + mappings[882] = ItemType.StonePickaxe; + mappings[883] = ItemType.StoneAxe; + mappings[884] = ItemType.StoneHoe; + mappings[885] = ItemType.GoldenSword; + mappings[886] = ItemType.GoldenShovel; + mappings[887] = ItemType.GoldenPickaxe; + mappings[888] = ItemType.GoldenAxe; + mappings[889] = ItemType.GoldenHoe; + mappings[890] = ItemType.IronSword; + mappings[891] = ItemType.IronShovel; + mappings[892] = ItemType.IronPickaxe; + mappings[893] = ItemType.IronAxe; + mappings[894] = ItemType.IronHoe; + mappings[895] = ItemType.DiamondSword; + mappings[896] = ItemType.DiamondShovel; + mappings[897] = ItemType.DiamondPickaxe; + mappings[898] = ItemType.DiamondAxe; + mappings[899] = ItemType.DiamondHoe; + mappings[900] = ItemType.NetheriteSword; + mappings[901] = ItemType.NetheriteShovel; + mappings[902] = ItemType.NetheritePickaxe; + mappings[903] = ItemType.NetheriteAxe; + mappings[904] = ItemType.NetheriteHoe; + mappings[905] = ItemType.Stick; + mappings[906] = ItemType.MushroomStew; + mappings[907] = ItemType.String; + mappings[908] = ItemType.Feather; + mappings[909] = ItemType.Gunpowder; + mappings[910] = ItemType.WheatSeeds; + mappings[911] = ItemType.Wheat; + mappings[912] = ItemType.Bread; + mappings[913] = ItemType.LeatherHelmet; + mappings[914] = ItemType.LeatherChestplate; + mappings[915] = ItemType.LeatherLeggings; + mappings[916] = ItemType.LeatherBoots; + mappings[917] = ItemType.ChainmailHelmet; + mappings[918] = ItemType.ChainmailChestplate; + mappings[919] = ItemType.ChainmailLeggings; + mappings[920] = ItemType.ChainmailBoots; + mappings[921] = ItemType.IronHelmet; + mappings[922] = ItemType.IronChestplate; + mappings[923] = ItemType.IronLeggings; + mappings[924] = ItemType.IronBoots; + mappings[925] = ItemType.DiamondHelmet; + mappings[926] = ItemType.DiamondChestplate; + mappings[927] = ItemType.DiamondLeggings; + mappings[928] = ItemType.DiamondBoots; + mappings[929] = ItemType.GoldenHelmet; + mappings[930] = ItemType.GoldenChestplate; + mappings[931] = ItemType.GoldenLeggings; + mappings[932] = ItemType.GoldenBoots; + mappings[933] = ItemType.NetheriteHelmet; + mappings[934] = ItemType.NetheriteChestplate; + mappings[935] = ItemType.NetheriteLeggings; + mappings[936] = ItemType.NetheriteBoots; + mappings[937] = ItemType.Flint; + mappings[938] = ItemType.Porkchop; + mappings[939] = ItemType.CookedPorkchop; + mappings[940] = ItemType.Painting; + mappings[941] = ItemType.GoldenApple; + mappings[942] = ItemType.EnchantedGoldenApple; + mappings[943] = ItemType.OakSign; + mappings[944] = ItemType.SpruceSign; + mappings[945] = ItemType.BirchSign; + mappings[946] = ItemType.JungleSign; + mappings[947] = ItemType.AcaciaSign; + mappings[948] = ItemType.CherrySign; + mappings[949] = ItemType.DarkOakSign; + mappings[950] = ItemType.PaleOakSign; + mappings[951] = ItemType.MangroveSign; + mappings[952] = ItemType.BambooSign; + mappings[953] = ItemType.CrimsonSign; + mappings[954] = ItemType.WarpedSign; + mappings[955] = ItemType.OakHangingSign; + mappings[956] = ItemType.SpruceHangingSign; + mappings[957] = ItemType.BirchHangingSign; + mappings[958] = ItemType.JungleHangingSign; + mappings[959] = ItemType.AcaciaHangingSign; + mappings[960] = ItemType.CherryHangingSign; + mappings[961] = ItemType.DarkOakHangingSign; + mappings[962] = ItemType.PaleOakHangingSign; + mappings[963] = ItemType.MangroveHangingSign; + mappings[964] = ItemType.BambooHangingSign; + mappings[965] = ItemType.CrimsonHangingSign; + mappings[966] = ItemType.WarpedHangingSign; + mappings[967] = ItemType.Bucket; + mappings[968] = ItemType.WaterBucket; + mappings[969] = ItemType.LavaBucket; + mappings[970] = ItemType.PowderSnowBucket; + mappings[971] = ItemType.Snowball; + mappings[972] = ItemType.Leather; + mappings[973] = ItemType.MilkBucket; + mappings[974] = ItemType.PufferfishBucket; + mappings[975] = ItemType.SalmonBucket; + mappings[976] = ItemType.CodBucket; + mappings[977] = ItemType.TropicalFishBucket; + mappings[978] = ItemType.AxolotlBucket; + mappings[979] = ItemType.TadpoleBucket; + mappings[980] = ItemType.Brick; + mappings[981] = ItemType.ClayBall; + mappings[982] = ItemType.DriedKelpBlock; + mappings[983] = ItemType.Paper; + mappings[984] = ItemType.Book; + mappings[985] = ItemType.SlimeBall; + mappings[986] = ItemType.Egg; + mappings[987] = ItemType.BlueEgg; + mappings[988] = ItemType.BrownEgg; + mappings[989] = ItemType.Compass; + mappings[990] = ItemType.RecoveryCompass; + mappings[991] = ItemType.Bundle; + mappings[992] = ItemType.WhiteBundle; + mappings[993] = ItemType.OrangeBundle; + mappings[994] = ItemType.MagentaBundle; + mappings[995] = ItemType.LightBlueBundle; + mappings[996] = ItemType.YellowBundle; + mappings[997] = ItemType.LimeBundle; + mappings[998] = ItemType.PinkBundle; + mappings[999] = ItemType.GrayBundle; + mappings[1000] = ItemType.LightGrayBundle; + mappings[1001] = ItemType.CyanBundle; + mappings[1002] = ItemType.PurpleBundle; + mappings[1003] = ItemType.BlueBundle; + mappings[1004] = ItemType.BrownBundle; + mappings[1005] = ItemType.GreenBundle; + mappings[1006] = ItemType.RedBundle; + mappings[1007] = ItemType.BlackBundle; + mappings[1008] = ItemType.FishingRod; + mappings[1009] = ItemType.Clock; + mappings[1010] = ItemType.Spyglass; + mappings[1011] = ItemType.GlowstoneDust; + mappings[1012] = ItemType.Cod; + mappings[1013] = ItemType.Salmon; + mappings[1014] = ItemType.TropicalFish; + mappings[1015] = ItemType.Pufferfish; + mappings[1016] = ItemType.CookedCod; + mappings[1017] = ItemType.CookedSalmon; + mappings[1018] = ItemType.InkSac; + mappings[1019] = ItemType.GlowInkSac; + mappings[1020] = ItemType.CocoaBeans; + mappings[1021] = ItemType.WhiteDye; + mappings[1022] = ItemType.OrangeDye; + mappings[1023] = ItemType.MagentaDye; + mappings[1024] = ItemType.LightBlueDye; + mappings[1025] = ItemType.YellowDye; + mappings[1026] = ItemType.LimeDye; + mappings[1027] = ItemType.PinkDye; + mappings[1028] = ItemType.GrayDye; + mappings[1029] = ItemType.LightGrayDye; + mappings[1030] = ItemType.CyanDye; + mappings[1031] = ItemType.PurpleDye; + mappings[1032] = ItemType.BlueDye; + mappings[1033] = ItemType.BrownDye; + mappings[1034] = ItemType.GreenDye; + mappings[1035] = ItemType.RedDye; + mappings[1036] = ItemType.BlackDye; + mappings[1037] = ItemType.BoneMeal; + mappings[1038] = ItemType.Bone; + mappings[1039] = ItemType.Sugar; + mappings[1040] = ItemType.Cake; + mappings[1041] = ItemType.WhiteBed; + mappings[1042] = ItemType.OrangeBed; + mappings[1043] = ItemType.MagentaBed; + mappings[1044] = ItemType.LightBlueBed; + mappings[1045] = ItemType.YellowBed; + mappings[1046] = ItemType.LimeBed; + mappings[1047] = ItemType.PinkBed; + mappings[1048] = ItemType.GrayBed; + mappings[1049] = ItemType.LightGrayBed; + mappings[1050] = ItemType.CyanBed; + mappings[1051] = ItemType.PurpleBed; + mappings[1052] = ItemType.BlueBed; + mappings[1053] = ItemType.BrownBed; + mappings[1054] = ItemType.GreenBed; + mappings[1055] = ItemType.RedBed; + mappings[1056] = ItemType.BlackBed; + mappings[1057] = ItemType.Cookie; + mappings[1058] = ItemType.Crafter; + mappings[1059] = ItemType.FilledMap; + mappings[1060] = ItemType.Shears; + mappings[1061] = ItemType.MelonSlice; + mappings[1062] = ItemType.DriedKelp; + mappings[1063] = ItemType.PumpkinSeeds; + mappings[1064] = ItemType.MelonSeeds; + mappings[1065] = ItemType.Beef; + mappings[1066] = ItemType.CookedBeef; + mappings[1067] = ItemType.Chicken; + mappings[1068] = ItemType.CookedChicken; + mappings[1069] = ItemType.RottenFlesh; + mappings[1070] = ItemType.EnderPearl; + mappings[1071] = ItemType.BlazeRod; + mappings[1072] = ItemType.GhastTear; + mappings[1073] = ItemType.GoldNugget; + mappings[1074] = ItemType.NetherWart; + mappings[1075] = ItemType.GlassBottle; + mappings[1076] = ItemType.Potion; + mappings[1077] = ItemType.SpiderEye; + mappings[1078] = ItemType.FermentedSpiderEye; + mappings[1079] = ItemType.BlazePowder; + mappings[1080] = ItemType.MagmaCream; + mappings[1081] = ItemType.BrewingStand; + mappings[1082] = ItemType.Cauldron; + mappings[1083] = ItemType.EnderEye; + mappings[1084] = ItemType.GlisteringMelonSlice; + mappings[1085] = ItemType.ArmadilloSpawnEgg; + mappings[1086] = ItemType.AllaySpawnEgg; + mappings[1087] = ItemType.AxolotlSpawnEgg; + mappings[1088] = ItemType.BatSpawnEgg; + mappings[1089] = ItemType.BeeSpawnEgg; + mappings[1090] = ItemType.BlazeSpawnEgg; + mappings[1091] = ItemType.BoggedSpawnEgg; + mappings[1092] = ItemType.BreezeSpawnEgg; + mappings[1093] = ItemType.CatSpawnEgg; + mappings[1094] = ItemType.CamelSpawnEgg; + mappings[1095] = ItemType.CaveSpiderSpawnEgg; + mappings[1096] = ItemType.ChickenSpawnEgg; + mappings[1097] = ItemType.CodSpawnEgg; + mappings[1098] = ItemType.CowSpawnEgg; + mappings[1099] = ItemType.CreeperSpawnEgg; + mappings[1100] = ItemType.DolphinSpawnEgg; + mappings[1101] = ItemType.DonkeySpawnEgg; + mappings[1102] = ItemType.DrownedSpawnEgg; + mappings[1103] = ItemType.ElderGuardianSpawnEgg; + mappings[1104] = ItemType.EnderDragonSpawnEgg; + mappings[1105] = ItemType.EndermanSpawnEgg; + mappings[1106] = ItemType.EndermiteSpawnEgg; + mappings[1107] = ItemType.EvokerSpawnEgg; + mappings[1108] = ItemType.FoxSpawnEgg; + mappings[1109] = ItemType.FrogSpawnEgg; + mappings[1110] = ItemType.GhastSpawnEgg; + mappings[1111] = ItemType.HappyGhastSpawnEgg; + mappings[1112] = ItemType.GlowSquidSpawnEgg; + mappings[1113] = ItemType.GoatSpawnEgg; + mappings[1114] = ItemType.GuardianSpawnEgg; + mappings[1115] = ItemType.HoglinSpawnEgg; + mappings[1116] = ItemType.HorseSpawnEgg; + mappings[1117] = ItemType.HuskSpawnEgg; + mappings[1118] = ItemType.IronGolemSpawnEgg; + mappings[1119] = ItemType.LlamaSpawnEgg; + mappings[1120] = ItemType.MagmaCubeSpawnEgg; + mappings[1121] = ItemType.MooshroomSpawnEgg; + mappings[1122] = ItemType.MuleSpawnEgg; + mappings[1123] = ItemType.OcelotSpawnEgg; + mappings[1124] = ItemType.PandaSpawnEgg; + mappings[1125] = ItemType.ParrotSpawnEgg; + mappings[1126] = ItemType.PhantomSpawnEgg; + mappings[1127] = ItemType.PigSpawnEgg; + mappings[1128] = ItemType.PiglinSpawnEgg; + mappings[1129] = ItemType.PiglinBruteSpawnEgg; + mappings[1130] = ItemType.PillagerSpawnEgg; + mappings[1131] = ItemType.PolarBearSpawnEgg; + mappings[1132] = ItemType.PufferfishSpawnEgg; + mappings[1133] = ItemType.RabbitSpawnEgg; + mappings[1134] = ItemType.RavagerSpawnEgg; + mappings[1135] = ItemType.SalmonSpawnEgg; + mappings[1136] = ItemType.SheepSpawnEgg; + mappings[1137] = ItemType.ShulkerSpawnEgg; + mappings[1138] = ItemType.SilverfishSpawnEgg; + mappings[1139] = ItemType.SkeletonSpawnEgg; + mappings[1140] = ItemType.SkeletonHorseSpawnEgg; + mappings[1141] = ItemType.SlimeSpawnEgg; + mappings[1142] = ItemType.SnifferSpawnEgg; + mappings[1143] = ItemType.SnowGolemSpawnEgg; + mappings[1144] = ItemType.SpiderSpawnEgg; + mappings[1145] = ItemType.SquidSpawnEgg; + mappings[1146] = ItemType.StraySpawnEgg; + mappings[1147] = ItemType.StriderSpawnEgg; + mappings[1148] = ItemType.TadpoleSpawnEgg; + mappings[1149] = ItemType.TraderLlamaSpawnEgg; + mappings[1150] = ItemType.TropicalFishSpawnEgg; + mappings[1151] = ItemType.TurtleSpawnEgg; + mappings[1152] = ItemType.VexSpawnEgg; + mappings[1153] = ItemType.VillagerSpawnEgg; + mappings[1154] = ItemType.VindicatorSpawnEgg; + mappings[1155] = ItemType.WanderingTraderSpawnEgg; + mappings[1156] = ItemType.WardenSpawnEgg; + mappings[1157] = ItemType.WitchSpawnEgg; + mappings[1158] = ItemType.WitherSpawnEgg; + mappings[1159] = ItemType.WitherSkeletonSpawnEgg; + mappings[1160] = ItemType.WolfSpawnEgg; + mappings[1161] = ItemType.ZoglinSpawnEgg; + mappings[1162] = ItemType.CreakingSpawnEgg; + mappings[1163] = ItemType.ZombieSpawnEgg; + mappings[1164] = ItemType.ZombieHorseSpawnEgg; + mappings[1165] = ItemType.ZombieVillagerSpawnEgg; + mappings[1166] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1167] = ItemType.ExperienceBottle; + mappings[1168] = ItemType.FireCharge; + mappings[1169] = ItemType.WindCharge; + mappings[1170] = ItemType.WritableBook; + mappings[1171] = ItemType.WrittenBook; + mappings[1172] = ItemType.BreezeRod; + mappings[1173] = ItemType.Mace; + mappings[1174] = ItemType.ItemFrame; + mappings[1175] = ItemType.GlowItemFrame; + mappings[1176] = ItemType.FlowerPot; + mappings[1177] = ItemType.Carrot; + mappings[1178] = ItemType.Potato; + mappings[1179] = ItemType.BakedPotato; + mappings[1180] = ItemType.PoisonousPotato; + mappings[1181] = ItemType.Map; + mappings[1182] = ItemType.GoldenCarrot; + mappings[1183] = ItemType.SkeletonSkull; + mappings[1184] = ItemType.WitherSkeletonSkull; + mappings[1185] = ItemType.PlayerHead; + mappings[1186] = ItemType.ZombieHead; + mappings[1187] = ItemType.CreeperHead; + mappings[1188] = ItemType.DragonHead; + mappings[1189] = ItemType.PiglinHead; + mappings[1190] = ItemType.NetherStar; + mappings[1191] = ItemType.PumpkinPie; + mappings[1192] = ItemType.FireworkRocket; + mappings[1193] = ItemType.FireworkStar; + mappings[1194] = ItemType.EnchantedBook; + mappings[1195] = ItemType.NetherBrick; + mappings[1196] = ItemType.ResinBrick; + mappings[1197] = ItemType.PrismarineShard; + mappings[1198] = ItemType.PrismarineCrystals; + mappings[1199] = ItemType.Rabbit; + mappings[1200] = ItemType.CookedRabbit; + mappings[1201] = ItemType.RabbitStew; + mappings[1202] = ItemType.RabbitFoot; + mappings[1203] = ItemType.RabbitHide; + mappings[1204] = ItemType.ArmorStand; + mappings[1205] = ItemType.IronHorseArmor; + mappings[1206] = ItemType.GoldenHorseArmor; + mappings[1207] = ItemType.DiamondHorseArmor; + mappings[1208] = ItemType.LeatherHorseArmor; + mappings[1209] = ItemType.Lead; + mappings[1210] = ItemType.NameTag; + mappings[1211] = ItemType.CommandBlockMinecart; + mappings[1212] = ItemType.Mutton; + mappings[1213] = ItemType.CookedMutton; + mappings[1214] = ItemType.WhiteBanner; + mappings[1215] = ItemType.OrangeBanner; + mappings[1216] = ItemType.MagentaBanner; + mappings[1217] = ItemType.LightBlueBanner; + mappings[1218] = ItemType.YellowBanner; + mappings[1219] = ItemType.LimeBanner; + mappings[1220] = ItemType.PinkBanner; + mappings[1221] = ItemType.GrayBanner; + mappings[1222] = ItemType.LightGrayBanner; + mappings[1223] = ItemType.CyanBanner; + mappings[1224] = ItemType.PurpleBanner; + mappings[1225] = ItemType.BlueBanner; + mappings[1226] = ItemType.BrownBanner; + mappings[1227] = ItemType.GreenBanner; + mappings[1228] = ItemType.RedBanner; + mappings[1229] = ItemType.BlackBanner; + mappings[1230] = ItemType.EndCrystal; + mappings[1231] = ItemType.ChorusFruit; + mappings[1232] = ItemType.PoppedChorusFruit; + mappings[1233] = ItemType.TorchflowerSeeds; + mappings[1234] = ItemType.PitcherPod; + mappings[1235] = ItemType.Beetroot; + mappings[1236] = ItemType.BeetrootSeeds; + mappings[1237] = ItemType.BeetrootSoup; + mappings[1238] = ItemType.DragonBreath; + mappings[1239] = ItemType.SplashPotion; + mappings[1240] = ItemType.SpectralArrow; + mappings[1241] = ItemType.TippedArrow; + mappings[1242] = ItemType.LingeringPotion; + mappings[1243] = ItemType.Shield; + mappings[1244] = ItemType.TotemOfUndying; + mappings[1245] = ItemType.ShulkerShell; + mappings[1246] = ItemType.IronNugget; + mappings[1247] = ItemType.KnowledgeBook; + mappings[1248] = ItemType.DebugStick; + mappings[1249] = ItemType.MusicDisc13; + mappings[1250] = ItemType.MusicDiscCat; + mappings[1251] = ItemType.MusicDiscBlocks; + mappings[1252] = ItemType.MusicDiscChirp; + mappings[1253] = ItemType.MusicDiscCreator; + mappings[1254] = ItemType.MusicDiscCreatorMusicBox; + mappings[1255] = ItemType.MusicDiscFar; + mappings[1256] = ItemType.MusicDiscMall; + mappings[1257] = ItemType.MusicDiscMellohi; + mappings[1258] = ItemType.MusicDiscStal; + mappings[1259] = ItemType.MusicDiscStrad; + mappings[1260] = ItemType.MusicDiscWard; + mappings[1261] = ItemType.MusicDisc11; + mappings[1262] = ItemType.MusicDiscWait; + mappings[1263] = ItemType.MusicDiscOtherside; + mappings[1264] = ItemType.MusicDiscRelic; + mappings[1265] = ItemType.MusicDisc5; + mappings[1266] = ItemType.MusicDiscPigstep; + mappings[1267] = ItemType.MusicDiscPrecipice; + mappings[1268] = ItemType.MusicDiscTears; + mappings[1269] = ItemType.DiscFragment5; + mappings[1270] = ItemType.Trident; + mappings[1271] = ItemType.NautilusShell; + mappings[1272] = ItemType.HeartOfTheSea; + mappings[1273] = ItemType.Crossbow; + mappings[1274] = ItemType.SuspiciousStew; + mappings[1275] = ItemType.Loom; + mappings[1276] = ItemType.FlowerBannerPattern; + mappings[1277] = ItemType.CreeperBannerPattern; + mappings[1278] = ItemType.SkullBannerPattern; + mappings[1279] = ItemType.MojangBannerPattern; + mappings[1280] = ItemType.GlobeBannerPattern; + mappings[1281] = ItemType.PiglinBannerPattern; + mappings[1282] = ItemType.FlowBannerPattern; + mappings[1283] = ItemType.GusterBannerPattern; + mappings[1284] = ItemType.FieldMasonedBannerPattern; + mappings[1285] = ItemType.BordureIndentedBannerPattern; + mappings[1286] = ItemType.GoatHorn; + mappings[1287] = ItemType.Composter; + mappings[1288] = ItemType.Barrel; + mappings[1289] = ItemType.Smoker; + mappings[1290] = ItemType.BlastFurnace; + mappings[1291] = ItemType.CartographyTable; + mappings[1292] = ItemType.FletchingTable; + mappings[1293] = ItemType.Grindstone; + mappings[1294] = ItemType.SmithingTable; + mappings[1295] = ItemType.Stonecutter; + mappings[1296] = ItemType.Bell; + mappings[1297] = ItemType.Lantern; + mappings[1298] = ItemType.SoulLantern; + mappings[1299] = ItemType.SweetBerries; + mappings[1300] = ItemType.GlowBerries; + mappings[1301] = ItemType.Campfire; + mappings[1302] = ItemType.SoulCampfire; + mappings[1303] = ItemType.Shroomlight; + mappings[1304] = ItemType.Honeycomb; + mappings[1305] = ItemType.BeeNest; + mappings[1306] = ItemType.Beehive; + mappings[1307] = ItemType.HoneyBottle; + mappings[1308] = ItemType.HoneycombBlock; + mappings[1309] = ItemType.Lodestone; + mappings[1310] = ItemType.CryingObsidian; + mappings[1311] = ItemType.Blackstone; + mappings[1312] = ItemType.BlackstoneSlab; + mappings[1313] = ItemType.BlackstoneStairs; + mappings[1314] = ItemType.GildedBlackstone; + mappings[1315] = ItemType.PolishedBlackstone; + mappings[1316] = ItemType.PolishedBlackstoneSlab; + mappings[1317] = ItemType.PolishedBlackstoneStairs; + mappings[1318] = ItemType.ChiseledPolishedBlackstone; + mappings[1319] = ItemType.PolishedBlackstoneBricks; + mappings[1320] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1321] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1322] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1323] = ItemType.RespawnAnchor; + mappings[1324] = ItemType.Candle; + mappings[1325] = ItemType.WhiteCandle; + mappings[1326] = ItemType.OrangeCandle; + mappings[1327] = ItemType.MagentaCandle; + mappings[1328] = ItemType.LightBlueCandle; + mappings[1329] = ItemType.YellowCandle; + mappings[1330] = ItemType.LimeCandle; + mappings[1331] = ItemType.PinkCandle; + mappings[1332] = ItemType.GrayCandle; + mappings[1333] = ItemType.LightGrayCandle; + mappings[1334] = ItemType.CyanCandle; + mappings[1335] = ItemType.PurpleCandle; + mappings[1336] = ItemType.BlueCandle; + mappings[1337] = ItemType.BrownCandle; + mappings[1338] = ItemType.GreenCandle; + mappings[1339] = ItemType.RedCandle; + mappings[1340] = ItemType.BlackCandle; + mappings[1341] = ItemType.SmallAmethystBud; + mappings[1342] = ItemType.MediumAmethystBud; + mappings[1343] = ItemType.LargeAmethystBud; + mappings[1344] = ItemType.AmethystCluster; + mappings[1345] = ItemType.PointedDripstone; + mappings[1346] = ItemType.OchreFroglight; + mappings[1347] = ItemType.VerdantFroglight; + mappings[1348] = ItemType.PearlescentFroglight; + mappings[1349] = ItemType.Frogspawn; + mappings[1350] = ItemType.EchoShard; + mappings[1351] = ItemType.Brush; + mappings[1352] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1353] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1354] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1355] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1356] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1357] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1358] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1359] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1360] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1361] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1362] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1363] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1364] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1365] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1366] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1367] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1368] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1369] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1370] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1371] = ItemType.AnglerPotterySherd; + mappings[1372] = ItemType.ArcherPotterySherd; + mappings[1373] = ItemType.ArmsUpPotterySherd; + mappings[1374] = ItemType.BladePotterySherd; + mappings[1375] = ItemType.BrewerPotterySherd; + mappings[1376] = ItemType.BurnPotterySherd; + mappings[1377] = ItemType.DangerPotterySherd; + mappings[1378] = ItemType.ExplorerPotterySherd; + mappings[1379] = ItemType.FlowPotterySherd; + mappings[1380] = ItemType.FriendPotterySherd; + mappings[1381] = ItemType.GusterPotterySherd; + mappings[1382] = ItemType.HeartPotterySherd; + mappings[1383] = ItemType.HeartbreakPotterySherd; + mappings[1384] = ItemType.HowlPotterySherd; + mappings[1385] = ItemType.MinerPotterySherd; + mappings[1386] = ItemType.MournerPotterySherd; + mappings[1387] = ItemType.PlentyPotterySherd; + mappings[1388] = ItemType.PrizePotterySherd; + mappings[1389] = ItemType.ScrapePotterySherd; + mappings[1390] = ItemType.SheafPotterySherd; + mappings[1391] = ItemType.ShelterPotterySherd; + mappings[1392] = ItemType.SkullPotterySherd; + mappings[1393] = ItemType.SnortPotterySherd; + mappings[1394] = ItemType.CopperGrate; + mappings[1395] = ItemType.ExposedCopperGrate; + mappings[1396] = ItemType.WeatheredCopperGrate; + mappings[1397] = ItemType.OxidizedCopperGrate; + mappings[1398] = ItemType.WaxedCopperGrate; + mappings[1399] = ItemType.WaxedExposedCopperGrate; + mappings[1400] = ItemType.WaxedWeatheredCopperGrate; + mappings[1401] = ItemType.WaxedOxidizedCopperGrate; + mappings[1402] = ItemType.CopperBulb; + mappings[1403] = ItemType.ExposedCopperBulb; + mappings[1404] = ItemType.WeatheredCopperBulb; + mappings[1405] = ItemType.OxidizedCopperBulb; + mappings[1406] = ItemType.WaxedCopperBulb; + mappings[1407] = ItemType.WaxedExposedCopperBulb; + mappings[1408] = ItemType.WaxedWeatheredCopperBulb; + mappings[1409] = ItemType.WaxedOxidizedCopperBulb; + mappings[1410] = ItemType.TrialSpawner; + mappings[1411] = ItemType.TrialKey; + mappings[1412] = ItemType.OminousTrialKey; + mappings[1413] = ItemType.Vault; + mappings[1414] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1216.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1216.cs new file mode 100644 index 00000000..f235183c --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1216.cs @@ -0,0 +1,1840 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1216 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1216() + { + for (int i = 9492; i <= 9515; i++) + materials[i] = Material.AcaciaButton; + for (int i = 12973; i <= 13036; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 12589; i <= 12620; i++) + materials[i] = Material.AcaciaFence; + for (int i = 12301; i <= 12332; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5130; i <= 5193; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 5900; i <= 5901; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 4462; i <= 4493; i++) + materials[i] = Material.AcaciaSign; + for (int i = 12075; i <= 12080; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 10693; i <= 10772; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 6396; i <= 6459; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 5730; i <= 5737; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 4882; i <= 4889; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 10129; i <= 10152; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2125] = Material.Allium; + materials[22091] = Material.AmethystBlock; + for (int i = 22093; i <= 22104; i++) + materials[i] = Material.AmethystCluster; + materials[20508] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 15191; i <= 15196; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 14817; i <= 14896; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 17807; i <= 18130; i++) + materials[i] = Material.AndesiteWall; + for (int i = 9916; i <= 9919; i++) + materials[i] = Material.Anvil; + for (int i = 7060; i <= 7063; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 7056; i <= 7059; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[25884] = Material.Azalea; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + materials[2126] = Material.AzureBluet; + for (int i = 14000; i <= 14011; i++) + materials[i] = Material.Bamboo; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 9612; i <= 9635; i++) + materials[i] = Material.BambooButton; + for (int i = 13293; i <= 13356; i++) + materials[i] = Material.BambooDoor; + for (int i = 12749; i <= 12780; i++) + materials[i] = Material.BambooFence; + for (int i = 12461; i <= 12492; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 5642; i <= 5705; i++) + materials[i] = Material.BambooHangingSign; + materials[28] = Material.BambooMosaic; + for (int i = 12111; i <= 12116; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 11173; i <= 11252; i++) + materials[i] = Material.BambooMosaicStairs; + materials[27] = Material.BambooPlanks; + for (int i = 5910; i <= 5911; i++) + materials[i] = Material.BambooPressurePlate; + materials[13999] = Material.BambooSapling; + for (int i = 4654; i <= 4685; i++) + materials[i] = Material.BambooSign; + for (int i = 12105; i <= 12110; i++) + materials[i] = Material.BambooSlab; + for (int i = 11093; i <= 11172; i++) + materials[i] = Material.BambooStairs; + for (int i = 6716; i <= 6779; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 5794; i <= 5801; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 4930; i <= 4937; i++) + materials[i] = Material.BambooWallSign; + for (int i = 19463; i <= 19474; i++) + materials[i] = Material.Barrel; + for (int i = 11254; i <= 11255; i++) + materials[i] = Material.Barrier; + for (int i = 6031; i <= 6033; i++) + materials[i] = Material.Basalt; + materials[8702] = Material.Beacon; + materials[85] = Material.Bedrock; + for (int i = 20457; i <= 20480; i++) + materials[i] = Material.BeeNest; + for (int i = 20481; i <= 20504; i++) + materials[i] = Material.Beehive; + for (int i = 13532; i <= 13535; i++) + materials[i] = Material.Beetroots; + for (int i = 19526; i <= 19557; i++) + materials[i] = Material.Bell; + for (int i = 25936; i <= 25967; i++) + materials[i] = Material.BigDripleaf; + for (int i = 25968; i <= 25975; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 9444; i <= 9467; i++) + materials[i] = Material.BirchButton; + for (int i = 12845; i <= 12908; i++) + materials[i] = Material.BirchDoor; + for (int i = 12525; i <= 12556; i++) + materials[i] = Material.BirchFence; + for (int i = 12237; i <= 12268; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 5066; i <= 5129; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 5896; i <= 5897; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 4430; i <= 4461; i++) + materials[i] = Material.BirchSign; + for (int i = 12063; i <= 12068; i++) + materials[i] = Material.BirchSlab; + for (int i = 8530; i <= 8609; i++) + materials[i] = Material.BirchStairs; + for (int i = 6268; i <= 6331; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 5722; i <= 5729; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 4874; i <= 4881; i++) + materials[i] = Material.BirchWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 11888; i <= 11903; i++) + materials[i] = Material.BlackBanner; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 22041; i <= 22056; i++) + materials[i] = Material.BlackCandle; + for (int i = 22089; i <= 22090; i++) + materials[i] = Material.BlackCandleCake; + materials[11632] = Material.BlackCarpet; + materials[13766] = Material.BlackConcrete; + materials[13782] = Material.BlackConcretePowder; + for (int i = 13747; i <= 13750; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 13681; i <= 13686; i++) + materials[i] = Material.BlackShulkerBox; + materials[6139] = Material.BlackStainedGlass; + for (int i = 10661; i <= 10692; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[10180] = Material.BlackTerracotta; + for (int i = 11964; i <= 11967; i++) + materials[i] = Material.BlackWallBanner; + materials[2108] = Material.BlackWool; + materials[20520] = Material.Blackstone; + for (int i = 20925; i <= 20930; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 20521; i <= 20600; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 20601; i <= 20924; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 19483; i <= 19490; i++) + materials[i] = Material.BlastFurnace; + for (int i = 11824; i <= 11839; i++) + materials[i] = Material.BlueBanner; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 21977; i <= 21992; i++) + materials[i] = Material.BlueCandle; + for (int i = 22081; i <= 22082; i++) + materials[i] = Material.BlueCandleCake; + materials[11628] = Material.BlueCarpet; + materials[13762] = Material.BlueConcrete; + materials[13778] = Material.BlueConcretePowder; + for (int i = 13731; i <= 13734; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[13996] = Material.BlueIce; + materials[2124] = Material.BlueOrchid; + for (int i = 13657; i <= 13662; i++) + materials[i] = Material.BlueShulkerBox; + materials[6135] = Material.BlueStainedGlass; + for (int i = 10533; i <= 10564; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[10176] = Material.BlueTerracotta; + for (int i = 11948; i <= 11951; i++) + materials[i] = Material.BlueWallBanner; + materials[2104] = Material.BlueWool; + for (int i = 13569; i <= 13571; i++) + materials[i] = Material.BoneBlock; + materials[2142] = Material.Bookshelf; + for (int i = 13880; i <= 13881; i++) + materials[i] = Material.BrainCoral; + materials[13864] = Material.BrainCoralBlock; + for (int i = 13900; i <= 13901; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 13956; i <= 13963; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 8174; i <= 8181; i++) + materials[i] = Material.BrewingStand; + for (int i = 12153; i <= 12158; i++) + materials[i] = Material.BrickSlab; + for (int i = 7400; i <= 7479; i++) + materials[i] = Material.BrickStairs; + for (int i = 15215; i <= 15538; i++) + materials[i] = Material.BrickWall; + materials[2139] = Material.Bricks; + for (int i = 11840; i <= 11855; i++) + materials[i] = Material.BrownBanner; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 21993; i <= 22008; i++) + materials[i] = Material.BrownCandle; + for (int i = 22083; i <= 22084; i++) + materials[i] = Material.BrownCandleCake; + materials[11629] = Material.BrownCarpet; + materials[13763] = Material.BrownConcrete; + materials[13779] = Material.BrownConcretePowder; + for (int i = 13735; i <= 13738; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2135] = Material.BrownMushroom; + for (int i = 6792; i <= 6855; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 13663; i <= 13668; i++) + materials[i] = Material.BrownShulkerBox; + materials[6136] = Material.BrownStainedGlass; + for (int i = 10565; i <= 10596; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[10177] = Material.BrownTerracotta; + for (int i = 11952; i <= 11955; i++) + materials[i] = Material.BrownWallBanner; + materials[2105] = Material.BrownWool; + for (int i = 14015; i <= 14016; i++) + materials[i] = Material.BubbleColumn; + for (int i = 13882; i <= 13883; i++) + materials[i] = Material.BubbleCoral; + materials[13865] = Material.BubbleCoralBlock; + for (int i = 13902; i <= 13903; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 13964; i <= 13971; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[22092] = Material.BuddingAmethyst; + materials[2051] = Material.Bush; + for (int i = 5960; i <= 5975; i++) + materials[i] = Material.Cactus; + materials[5976] = Material.CactusFlower; + for (int i = 6053; i <= 6059; i++) + materials[i] = Material.Cake; + materials[23376] = Material.Calcite; + for (int i = 23475; i <= 23858; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 19566; i <= 19597; i++) + materials[i] = Material.Campfire; + for (int i = 21785; i <= 21800; i++) + materials[i] = Material.Candle; + for (int i = 22057; i <= 22058; i++) + materials[i] = Material.CandleCake; + for (int i = 9380; i <= 9387; i++) + materials[i] = Material.Carrots; + materials[19491] = Material.CartographyTable; + for (int i = 6045; i <= 6048; i++) + materials[i] = Material.CarvedPumpkin; + materials[8182] = Material.Cauldron; + materials[14014] = Material.CaveAir; + for (int i = 25829; i <= 25880; i++) + materials[i] = Material.CaveVines; + for (int i = 25881; i <= 25882; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 7016; i <= 7021; i++) + materials[i] = Material.Chain; + for (int i = 13550; i <= 13561; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 9516; i <= 9539; i++) + materials[i] = Material.CherryButton; + for (int i = 13037; i <= 13100; i++) + materials[i] = Material.CherryDoor; + for (int i = 12621; i <= 12652; i++) + materials[i] = Material.CherryFence; + for (int i = 12333; i <= 12364; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5194; i <= 5257; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 5902; i <= 5903; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 4494; i <= 4525; i++) + materials[i] = Material.CherrySign; + for (int i = 12081; i <= 12086; i++) + materials[i] = Material.CherrySlab; + for (int i = 10773; i <= 10852; i++) + materials[i] = Material.CherryStairs; + for (int i = 6460; i <= 6523; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 5738; i <= 5745; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 4890; i <= 4897; i++) + materials[i] = Material.CherryWallSign; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 3018; i <= 3041; i++) + materials[i] = Material.Chest; + for (int i = 9920; i <= 9923; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2143; i <= 2398; i++) + materials[i] = Material.ChiseledBookshelf; + materials[24011] = Material.ChiseledCopper; + materials[27643] = Material.ChiseledDeepslate; + materials[21782] = Material.ChiseledNetherBricks; + materials[20934] = Material.ChiseledPolishedBlackstone; + materials[10045] = Material.ChiseledQuartzBlock; + materials[11969] = Material.ChiseledRedSandstone; + materials[8055] = Material.ChiseledResinBricks; + materials[579] = Material.ChiseledSandstone; + materials[6783] = Material.ChiseledStoneBricks; + materials[22963] = Material.ChiseledTuff; + materials[23375] = Material.ChiseledTuffBricks; + for (int i = 13427; i <= 13432; i++) + materials[i] = Material.ChorusFlower; + for (int i = 13363; i <= 13426; i++) + materials[i] = Material.ChorusPlant; + materials[5977] = Material.Clay; + materials[27942] = Material.ClosedEyeblossom; + materials[11634] = Material.CoalBlock; + materials[133] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[25999] = Material.CobbledDeepslate; + for (int i = 26080; i <= 26085; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 26000; i <= 26079; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 26086; i <= 26409; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 12147; i <= 12152; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 4778; i <= 4857; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 8703; i <= 9026; i++) + materials[i] = Material.CobblestoneWall; + materials[2047] = Material.Cobweb; + for (int i = 8203; i <= 8214; i++) + materials[i] = Material.Cocoa; + for (int i = 8690; i <= 8701; i++) + materials[i] = Material.CommandBlock; + for (int i = 9984; i <= 9999; i++) + materials[i] = Material.Comparator; + for (int i = 20432; i <= 20440; i++) + materials[i] = Material.Composter; + for (int i = 13997; i <= 13998; i++) + materials[i] = Material.Conduit; + materials[23998] = Material.CopperBlock; + for (int i = 25752; i <= 25755; i++) + materials[i] = Material.CopperBulb; + for (int i = 24712; i <= 24775; i++) + materials[i] = Material.CopperDoor; + for (int i = 25736; i <= 25737; i++) + materials[i] = Material.CopperGrate; + materials[24002] = Material.CopperOre; + for (int i = 25224; i <= 25287; i++) + materials[i] = Material.CopperTrapdoor; + materials[2132] = Material.Cornflower; + materials[27644] = Material.CrackedDeepslateBricks; + materials[27645] = Material.CrackedDeepslateTiles; + materials[21783] = Material.CrackedNetherBricks; + materials[20933] = Material.CrackedPolishedBlackstoneBricks; + materials[6782] = Material.CrackedStoneBricks; + for (int i = 27682; i <= 27729; i++) + materials[i] = Material.Crafter; + materials[4341] = Material.CraftingTable; + for (int i = 2920; i <= 2937; i++) + materials[i] = Material.CreakingHeart; + for (int i = 9796; i <= 9827; i++) + materials[i] = Material.CreeperHead; + for (int i = 9828; i <= 9835; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 20155; i <= 20178; i++) + materials[i] = Material.CrimsonButton; + for (int i = 20203; i <= 20266; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 19739; i <= 19770; i++) + materials[i] = Material.CrimsonFence; + for (int i = 19931; i <= 19962; i++) + materials[i] = Material.CrimsonFenceGate; + materials[19664] = Material.CrimsonFungus; + for (int i = 5450; i <= 5513; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 19657; i <= 19659; i++) + materials[i] = Material.CrimsonHyphae; + materials[19663] = Material.CrimsonNylium; + materials[19721] = Material.CrimsonPlanks; + for (int i = 19735; i <= 19736; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[19720] = Material.CrimsonRoots; + for (int i = 20331; i <= 20362; i++) + materials[i] = Material.CrimsonSign; + for (int i = 19723; i <= 19728; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 19995; i <= 20074; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 19651; i <= 19653; i++) + materials[i] = Material.CrimsonStem; + for (int i = 19803; i <= 19866; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 5778; i <= 5785; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 20395; i <= 20402; i++) + materials[i] = Material.CrimsonWallSign; + materials[20509] = Material.CryingObsidian; + materials[24007] = Material.CutCopper; + for (int i = 24354; i <= 24359; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 24256; i <= 24335; i++) + materials[i] = Material.CutCopperStairs; + materials[11970] = Material.CutRedSandstone; + for (int i = 12189; i <= 12194; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[580] = Material.CutSandstone; + for (int i = 12135; i <= 12140; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 11792; i <= 11807; i++) + materials[i] = Material.CyanBanner; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 21945; i <= 21960; i++) + materials[i] = Material.CyanCandle; + for (int i = 22077; i <= 22078; i++) + materials[i] = Material.CyanCandleCake; + materials[11626] = Material.CyanCarpet; + materials[13760] = Material.CyanConcrete; + materials[13776] = Material.CyanConcretePowder; + for (int i = 13723; i <= 13726; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 13645; i <= 13650; i++) + materials[i] = Material.CyanShulkerBox; + materials[6133] = Material.CyanStainedGlass; + for (int i = 10469; i <= 10500; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[10174] = Material.CyanTerracotta; + for (int i = 11940; i <= 11943; i++) + materials[i] = Material.CyanWallBanner; + materials[2102] = Material.CyanWool; + for (int i = 9924; i <= 9927; i++) + materials[i] = Material.DamagedAnvil; + materials[2121] = Material.Dandelion; + for (int i = 9540; i <= 9563; i++) + materials[i] = Material.DarkOakButton; + for (int i = 13101; i <= 13164; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 12653; i <= 12684; i++) + materials[i] = Material.DarkOakFence; + for (int i = 12365; i <= 12396; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 5322; i <= 5385; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 5904; i <= 5905; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 4558; i <= 4589; i++) + materials[i] = Material.DarkOakSign; + for (int i = 12087; i <= 12092; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 10853; i <= 10932; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 6524; i <= 6587; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 5754; i <= 5761; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 4906; i <= 4913; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + materials[11354] = Material.DarkPrismarine; + for (int i = 11607; i <= 11612; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 11515; i <= 11594; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 10000; i <= 10031; i++) + materials[i] = Material.DaylightDetector; + for (int i = 13870; i <= 13871; i++) + materials[i] = Material.DeadBrainCoral; + materials[13859] = Material.DeadBrainCoralBlock; + for (int i = 13890; i <= 13891; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 13916; i <= 13923; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 13872; i <= 13873; i++) + materials[i] = Material.DeadBubbleCoral; + materials[13860] = Material.DeadBubbleCoralBlock; + for (int i = 13892; i <= 13893; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 13924; i <= 13931; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2050] = Material.DeadBush; + for (int i = 13874; i <= 13875; i++) + materials[i] = Material.DeadFireCoral; + materials[13861] = Material.DeadFireCoralBlock; + for (int i = 13894; i <= 13895; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 13932; i <= 13939; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 13876; i <= 13877; i++) + materials[i] = Material.DeadHornCoral; + materials[13862] = Material.DeadHornCoralBlock; + for (int i = 13896; i <= 13897; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 13940; i <= 13947; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 13868; i <= 13869; i++) + materials[i] = Material.DeadTubeCoral; + materials[13858] = Material.DeadTubeCoralBlock; + for (int i = 13888; i <= 13889; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 13908; i <= 13915; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 27666; i <= 27681; i++) + materials[i] = Material.DecoratedPot; + for (int i = 25996; i <= 25998; i++) + materials[i] = Material.Deepslate; + for (int i = 27313; i <= 27318; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 27233; i <= 27312; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 27319; i <= 27642; i++) + materials[i] = Material.DeepslateBrickWall; + materials[27232] = Material.DeepslateBricks; + materials[134] = Material.DeepslateCoalOre; + materials[24003] = Material.DeepslateCopperOre; + materials[4339] = Material.DeepslateDiamondOre; + materials[8296] = Material.DeepslateEmeraldOre; + materials[130] = Material.DeepslateGoldOre; + materials[132] = Material.DeepslateIronOre; + materials[564] = Material.DeepslateLapisOre; + for (int i = 5914; i <= 5915; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 26902; i <= 26907; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 26822; i <= 26901; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 26908; i <= 27231; i++) + materials[i] = Material.DeepslateTileWall; + materials[26821] = Material.DeepslateTiles; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + materials[4340] = Material.DiamondBlock; + materials[4338] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 15209; i <= 15214; i++) + materials[i] = Material.DioriteSlab; + for (int i = 15057; i <= 15136; i++) + materials[i] = Material.DioriteStairs; + for (int i = 19103; i <= 19426; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[13536] = Material.DirtPath; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + materials[8200] = Material.DragonEgg; + for (int i = 9836; i <= 9867; i++) + materials[i] = Material.DragonHead; + for (int i = 9868; i <= 9875; i++) + materials[i] = Material.DragonWallHead; + for (int i = 13826; i <= 13857; i++) + materials[i] = Material.DriedGhast; + materials[13810] = Material.DriedKelpBlock; + materials[25828] = Material.DripstoneBlock; + for (int i = 10153; i <= 10164; i++) + materials[i] = Material.Dropper; + materials[8449] = Material.EmeraldBlock; + materials[8295] = Material.EmeraldOre; + materials[8173] = Material.EnchantingTable; + materials[13537] = Material.EndGateway; + materials[8190] = Material.EndPortal; + for (int i = 8191; i <= 8198; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 13357; i <= 13362; i++) + materials[i] = Material.EndRod; + materials[8199] = Material.EndStone; + for (int i = 15167; i <= 15172; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 14417; i <= 14496; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 18779; i <= 19102; i++) + materials[i] = Material.EndStoneBrickWall; + materials[13517] = Material.EndStoneBricks; + for (int i = 8297; i <= 8304; i++) + materials[i] = Material.EnderChest; + materials[24010] = Material.ExposedChiseledCopper; + materials[23999] = Material.ExposedCopper; + for (int i = 25756; i <= 25759; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 24776; i <= 24839; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 25738; i <= 25739; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 25288; i <= 25351; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[24006] = Material.ExposedCutCopper; + for (int i = 24348; i <= 24353; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 24176; i <= 24255; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 4350; i <= 4357; i++) + materials[i] = Material.Farmland; + materials[2049] = Material.Fern; + for (int i = 2406; i <= 2917; i++) + materials[i] = Material.Fire; + for (int i = 13884; i <= 13885; i++) + materials[i] = Material.FireCoral; + materials[13866] = Material.FireCoralBlock; + for (int i = 13904; i <= 13905; i++) + materials[i] = Material.FireCoralFan; + for (int i = 13972; i <= 13979; i++) + materials[i] = Material.FireCoralWallFan; + materials[27945] = Material.FireflyBush; + materials[19492] = Material.FletchingTable; + materials[9351] = Material.FlowerPot; + materials[25885] = Material.FloweringAzalea; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[27664] = Material.Frogspawn; + for (int i = 13562; i <= 13565; i++) + materials[i] = Material.FrostedIce; + for (int i = 4358; i <= 4365; i++) + materials[i] = Material.Furnace; + materials[21345] = Material.GildedBlackstone; + materials[562] = Material.Glass; + for (int i = 7022; i <= 7053; i++) + materials[i] = Material.GlassPane; + for (int i = 7112; i <= 7239; i++) + materials[i] = Material.GlowLichen; + materials[6042] = Material.Glowstone; + materials[2137] = Material.GoldBlock; + materials[129] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 15185; i <= 15190; i++) + materials[i] = Material.GraniteSlab; + for (int i = 14737; i <= 14816; i++) + materials[i] = Material.GraniteStairs; + for (int i = 16511; i <= 16834; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[124] = Material.Gravel; + for (int i = 11760; i <= 11775; i++) + materials[i] = Material.GrayBanner; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 21913; i <= 21928; i++) + materials[i] = Material.GrayCandle; + for (int i = 22073; i <= 22074; i++) + materials[i] = Material.GrayCandleCake; + materials[11624] = Material.GrayCarpet; + materials[13758] = Material.GrayConcrete; + materials[13774] = Material.GrayConcretePowder; + for (int i = 13715; i <= 13718; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 13633; i <= 13638; i++) + materials[i] = Material.GrayShulkerBox; + materials[6131] = Material.GrayStainedGlass; + for (int i = 10405; i <= 10436; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[10172] = Material.GrayTerracotta; + for (int i = 11932; i <= 11935; i++) + materials[i] = Material.GrayWallBanner; + materials[2100] = Material.GrayWool; + for (int i = 11856; i <= 11871; i++) + materials[i] = Material.GreenBanner; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 22009; i <= 22024; i++) + materials[i] = Material.GreenCandle; + for (int i = 22085; i <= 22086; i++) + materials[i] = Material.GreenCandleCake; + materials[11630] = Material.GreenCarpet; + materials[13764] = Material.GreenConcrete; + materials[13780] = Material.GreenConcretePowder; + for (int i = 13739; i <= 13742; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 13669; i <= 13674; i++) + materials[i] = Material.GreenShulkerBox; + materials[6137] = Material.GreenStainedGlass; + for (int i = 10597; i <= 10628; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[10178] = Material.GreenTerracotta; + for (int i = 11956; i <= 11959; i++) + materials[i] = Material.GreenWallBanner; + materials[2106] = Material.GreenWool; + for (int i = 19493; i <= 19504; i++) + materials[i] = Material.Grindstone; + for (int i = 25992; i <= 25993; i++) + materials[i] = Material.HangingRoots; + for (int i = 11614; i <= 11616; i++) + materials[i] = Material.HayBlock; + for (int i = 27774; i <= 27775; i++) + materials[i] = Material.HeavyCore; + for (int i = 9968; i <= 9983; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[20505] = Material.HoneyBlock; + materials[20506] = Material.HoneycombBlock; + for (int i = 10034; i <= 10043; i++) + materials[i] = Material.Hopper; + for (int i = 13886; i <= 13887; i++) + materials[i] = Material.HornCoral; + materials[13867] = Material.HornCoralBlock; + for (int i = 13906; i <= 13907; i++) + materials[i] = Material.HornCoralFan; + for (int i = 13980; i <= 13987; i++) + materials[i] = Material.HornCoralWallFan; + materials[5958] = Material.Ice; + materials[6791] = Material.InfestedChiseledStoneBricks; + materials[6787] = Material.InfestedCobblestone; + materials[6790] = Material.InfestedCrackedStoneBricks; + for (int i = 27646; i <= 27648; i++) + materials[i] = Material.InfestedDeepslate; + materials[6789] = Material.InfestedMossyStoneBricks; + materials[6786] = Material.InfestedStone; + materials[6788] = Material.InfestedStoneBricks; + for (int i = 6984; i <= 7015; i++) + materials[i] = Material.IronBars; + materials[2138] = Material.IronBlock; + for (int i = 5828; i <= 5891; i++) + materials[i] = Material.IronDoor; + materials[131] = Material.IronOre; + for (int i = 11288; i <= 11351; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 6049; i <= 6052; i++) + materials[i] = Material.JackOLantern; + for (int i = 20415; i <= 20426; i++) + materials[i] = Material.Jigsaw; + for (int i = 5994; i <= 5995; i++) + materials[i] = Material.Jukebox; + for (int i = 9468; i <= 9491; i++) + materials[i] = Material.JungleButton; + for (int i = 12909; i <= 12972; i++) + materials[i] = Material.JungleDoor; + for (int i = 12557; i <= 12588; i++) + materials[i] = Material.JungleFence; + for (int i = 12269; i <= 12300; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 5258; i <= 5321; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 5898; i <= 5899; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 4526; i <= 4557; i++) + materials[i] = Material.JungleSign; + for (int i = 12069; i <= 12074; i++) + materials[i] = Material.JungleSlab; + for (int i = 8610; i <= 8689; i++) + materials[i] = Material.JungleStairs; + for (int i = 6332; i <= 6395; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 5746; i <= 5753; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 4898; i <= 4905; i++) + materials[i] = Material.JungleWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 13783; i <= 13808; i++) + materials[i] = Material.Kelp; + materials[13809] = Material.KelpPlant; + for (int i = 4750; i <= 4757; i++) + materials[i] = Material.Ladder; + for (int i = 19558; i <= 19561; i++) + materials[i] = Material.Lantern; + materials[565] = Material.LapisBlock; + materials[563] = Material.LapisOre; + for (int i = 22105; i <= 22116; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 11646; i <= 11647; i++) + materials[i] = Material.LargeFern; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + materials[8186] = Material.LavaCauldron; + for (int i = 25919; i <= 25934; i++) + materials[i] = Material.LeafLitter; + for (int i = 19505; i <= 19520; i++) + materials[i] = Material.Lectern; + for (int i = 5802; i <= 5825; i++) + materials[i] = Material.Lever; + for (int i = 11256; i <= 11287; i++) + materials[i] = Material.Light; + for (int i = 11696; i <= 11711; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 21849; i <= 21864; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 22065; i <= 22066; i++) + materials[i] = Material.LightBlueCandleCake; + materials[11620] = Material.LightBlueCarpet; + materials[13754] = Material.LightBlueConcrete; + materials[13770] = Material.LightBlueConcretePowder; + for (int i = 13699; i <= 13702; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 13609; i <= 13614; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[6127] = Material.LightBlueStainedGlass; + for (int i = 10277; i <= 10308; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[10168] = Material.LightBlueTerracotta; + for (int i = 11916; i <= 11919; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2096] = Material.LightBlueWool; + for (int i = 11776; i <= 11791; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 21929; i <= 21944; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 22075; i <= 22076; i++) + materials[i] = Material.LightGrayCandleCake; + materials[11625] = Material.LightGrayCarpet; + materials[13759] = Material.LightGrayConcrete; + materials[13775] = Material.LightGrayConcretePowder; + for (int i = 13719; i <= 13722; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 13639; i <= 13644; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[6132] = Material.LightGrayStainedGlass; + for (int i = 10437; i <= 10468; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[10173] = Material.LightGrayTerracotta; + for (int i = 11936; i <= 11939; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2101] = Material.LightGrayWool; + for (int i = 9952; i <= 9967; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 25784; i <= 25807; i++) + materials[i] = Material.LightningRod; + for (int i = 11638; i <= 11639; i++) + materials[i] = Material.Lilac; + materials[2134] = Material.LilyOfTheValley; + materials[7642] = Material.LilyPad; + for (int i = 11728; i <= 11743; i++) + materials[i] = Material.LimeBanner; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; + for (int i = 21881; i <= 21896; i++) + materials[i] = Material.LimeCandle; + for (int i = 22069; i <= 22070; i++) + materials[i] = Material.LimeCandleCake; + materials[11622] = Material.LimeCarpet; + materials[13756] = Material.LimeConcrete; + materials[13772] = Material.LimeConcretePowder; + for (int i = 13707; i <= 13710; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 13621; i <= 13626; i++) + materials[i] = Material.LimeShulkerBox; + materials[6129] = Material.LimeStainedGlass; + for (int i = 10341; i <= 10372; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[10170] = Material.LimeTerracotta; + for (int i = 11924; i <= 11927; i++) + materials[i] = Material.LimeWallBanner; + materials[2098] = Material.LimeWool; + materials[20519] = Material.Lodestone; + for (int i = 19459; i <= 19462; i++) + materials[i] = Material.Loom; + for (int i = 11680; i <= 11695; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 21833; i <= 21848; i++) + materials[i] = Material.MagentaCandle; + for (int i = 22063; i <= 22064; i++) + materials[i] = Material.MagentaCandleCake; + materials[11619] = Material.MagentaCarpet; + materials[13753] = Material.MagentaConcrete; + materials[13769] = Material.MagentaConcretePowder; + for (int i = 13695; i <= 13698; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 13603; i <= 13608; i++) + materials[i] = Material.MagentaShulkerBox; + materials[6126] = Material.MagentaStainedGlass; + for (int i = 10245; i <= 10276; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[10167] = Material.MagentaTerracotta; + for (int i = 11912; i <= 11915; i++) + materials[i] = Material.MagentaWallBanner; + materials[2095] = Material.MagentaWool; + materials[13566] = Material.MagmaBlock; + for (int i = 9588; i <= 9611; i++) + materials[i] = Material.MangroveButton; + for (int i = 13229; i <= 13292; i++) + materials[i] = Material.MangroveDoor; + for (int i = 12717; i <= 12748; i++) + materials[i] = Material.MangroveFence; + for (int i = 12429; i <= 12460; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 5578; i <= 5641; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + materials[26] = Material.MangrovePlanks; + for (int i = 5908; i <= 5909; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 4622; i <= 4653; i++) + materials[i] = Material.MangroveSign; + for (int i = 12099; i <= 12104; i++) + materials[i] = Material.MangroveSlab; + for (int i = 11013; i <= 11092; i++) + materials[i] = Material.MangroveStairs; + for (int i = 6652; i <= 6715; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 5770; i <= 5777; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 4922; i <= 4929; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 22117; i <= 22128; i++) + materials[i] = Material.MediumAmethystBud; + materials[7055] = Material.Melon; + for (int i = 7072; i <= 7079; i++) + materials[i] = Material.MelonStem; + materials[25935] = Material.MossBlock; + materials[25886] = Material.MossCarpet; + materials[2399] = Material.MossyCobblestone; + for (int i = 15161; i <= 15166; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 14337; i <= 14416; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 9027; i <= 9350; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 15149; i <= 15154; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 14177; i <= 14256; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 16187; i <= 16510; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[6781] = Material.MossyStoneBricks; + for (int i = 2109; i <= 2120; i++) + materials[i] = Material.MovingPiston; + materials[25995] = Material.Mud; + for (int i = 12165; i <= 12170; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 7560; i <= 7639; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 17159; i <= 17482; i++) + materials[i] = Material.MudBrickWall; + materials[6785] = Material.MudBricks; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 6920; i <= 6983; i++) + materials[i] = Material.MushroomStem; + for (int i = 7640; i <= 7641; i++) + materials[i] = Material.Mycelium; + for (int i = 8057; i <= 8088; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 12171; i <= 12176; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 8089; i <= 8168; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 17483; i <= 17806; i++) + materials[i] = Material.NetherBrickWall; + materials[8056] = Material.NetherBricks; + materials[135] = Material.NetherGoldOre; + for (int i = 6043; i <= 6044; i++) + materials[i] = Material.NetherPortal; + materials[10033] = Material.NetherQuartzOre; + materials[19650] = Material.NetherSprouts; + for (int i = 8169; i <= 8172; i++) + materials[i] = Material.NetherWart; + materials[13567] = Material.NetherWartBlock; + materials[20507] = Material.NetheriteBlock; + materials[6028] = Material.Netherrack; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 9396; i <= 9419; i++) + materials[i] = Material.OakButton; + for (int i = 4686; i <= 4749; i++) + materials[i] = Material.OakDoor; + for (int i = 5996; i <= 6027; i++) + materials[i] = Material.OakFence; + for (int i = 7368; i <= 7399; i++) + materials[i] = Material.OakFenceGate; + for (int i = 4938; i <= 5001; i++) + materials[i] = Material.OakHangingSign; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 5892; i <= 5893; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 4366; i <= 4397; i++) + materials[i] = Material.OakSign; + for (int i = 12051; i <= 12056; i++) + materials[i] = Material.OakSlab; + for (int i = 2938; i <= 3017; i++) + materials[i] = Material.OakStairs; + for (int i = 6140; i <= 6203; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 5706; i <= 5713; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 4858; i <= 4865; i++) + materials[i] = Material.OakWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 13573; i <= 13584; i++) + materials[i] = Material.Observer; + materials[2400] = Material.Obsidian; + for (int i = 27655; i <= 27657; i++) + materials[i] = Material.OchreFroglight; + materials[27941] = Material.OpenEyeblossom; + for (int i = 11664; i <= 11679; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 21817; i <= 21832; i++) + materials[i] = Material.OrangeCandle; + for (int i = 22061; i <= 22062; i++) + materials[i] = Material.OrangeCandleCake; + materials[11618] = Material.OrangeCarpet; + materials[13752] = Material.OrangeConcrete; + materials[13768] = Material.OrangeConcretePowder; + for (int i = 13691; i <= 13694; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 13597; i <= 13602; i++) + materials[i] = Material.OrangeShulkerBox; + materials[6125] = Material.OrangeStainedGlass; + for (int i = 10213; i <= 10244; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[10166] = Material.OrangeTerracotta; + materials[2128] = Material.OrangeTulip; + for (int i = 11908; i <= 11911; i++) + materials[i] = Material.OrangeWallBanner; + materials[2094] = Material.OrangeWool; + materials[2131] = Material.OxeyeDaisy; + materials[24008] = Material.OxidizedChiseledCopper; + materials[24001] = Material.OxidizedCopper; + for (int i = 25764; i <= 25767; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 24840; i <= 24903; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 25742; i <= 25743; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 25352; i <= 25415; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[24004] = Material.OxidizedCutCopper; + for (int i = 24336; i <= 24341; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 24016; i <= 24095; i++) + materials[i] = Material.OxidizedCutCopperStairs; + materials[11635] = Material.PackedIce; + materials[6784] = Material.PackedMud; + for (int i = 27939; i <= 27940; i++) + materials[i] = Material.PaleHangingMoss; + materials[27776] = Material.PaleMossBlock; + for (int i = 27777; i <= 27938; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 9564; i <= 9587; i++) + materials[i] = Material.PaleOakButton; + for (int i = 13165; i <= 13228; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 12685; i <= 12716; i++) + materials[i] = Material.PaleOakFence; + for (int i = 12397; i <= 12428; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 5386; i <= 5449; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + materials[25] = Material.PaleOakPlanks; + for (int i = 5906; i <= 5907; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 4590; i <= 4621; i++) + materials[i] = Material.PaleOakSign; + for (int i = 12093; i <= 12098; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 10933; i <= 11012; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 6588; i <= 6651; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 5762; i <= 5769; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 4914; i <= 4921; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 27661; i <= 27663; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 11642; i <= 11643; i++) + materials[i] = Material.Peony; + for (int i = 12141; i <= 12146; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 9876; i <= 9907; i++) + materials[i] = Material.PiglinHead; + for (int i = 9908; i <= 9915; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 11744; i <= 11759; i++) + materials[i] = Material.PinkBanner; + for (int i = 1827; i <= 1842; i++) + materials[i] = Material.PinkBed; + for (int i = 21897; i <= 21912; i++) + materials[i] = Material.PinkCandle; + for (int i = 22071; i <= 22072; i++) + materials[i] = Material.PinkCandleCake; + materials[11623] = Material.PinkCarpet; + materials[13757] = Material.PinkConcrete; + materials[13773] = Material.PinkConcretePowder; + for (int i = 13711; i <= 13714; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 25887; i <= 25902; i++) + materials[i] = Material.PinkPetals; + for (int i = 13627; i <= 13632; i++) + materials[i] = Material.PinkShulkerBox; + materials[6130] = Material.PinkStainedGlass; + for (int i = 10373; i <= 10404; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[10171] = Material.PinkTerracotta; + materials[2130] = Material.PinkTulip; + for (int i = 11928; i <= 11931; i++) + materials[i] = Material.PinkWallBanner; + materials[2099] = Material.PinkWool; + for (int i = 2057; i <= 2068; i++) + materials[i] = Material.Piston; + for (int i = 2069; i <= 2092; i++) + materials[i] = Material.PistonHead; + for (int i = 13520; i <= 13529; i++) + materials[i] = Material.PitcherCrop; + for (int i = 13530; i <= 13531; i++) + materials[i] = Material.PitcherPlant; + for (int i = 9756; i <= 9787; i++) + materials[i] = Material.PlayerHead; + for (int i = 9788; i <= 9795; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 25808; i <= 25827; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 15203; i <= 15208; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 14977; i <= 15056; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 6034; i <= 6036; i++) + materials[i] = Material.PolishedBasalt; + materials[20931] = Material.PolishedBlackstone; + for (int i = 20935; i <= 20940; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 20941; i <= 21020; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 21021; i <= 21344; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[20932] = Material.PolishedBlackstoneBricks; + for (int i = 21434; i <= 21457; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 21432; i <= 21433; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 21426; i <= 21431; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 21346; i <= 21425; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 21458; i <= 21781; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[26410] = Material.PolishedDeepslate; + for (int i = 26491; i <= 26496; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 26411; i <= 26490; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 26497; i <= 26820; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 15155; i <= 15160; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 14257; i <= 14336; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 15137; i <= 15142; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 14017; i <= 14096; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[22552] = Material.PolishedTuff; + for (int i = 22553; i <= 22558; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 22559; i <= 22638; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 22639; i <= 22962; i++) + materials[i] = Material.PolishedTuffWall; + materials[2123] = Material.Poppy; + for (int i = 9388; i <= 9395; i++) + materials[i] = Material.Potatoes; + materials[9357] = Material.PottedAcaciaSapling; + materials[9366] = Material.PottedAllium; + materials[27653] = Material.PottedAzaleaBush; + materials[9367] = Material.PottedAzureBluet; + materials[14012] = Material.PottedBamboo; + materials[9355] = Material.PottedBirchSapling; + materials[9365] = Material.PottedBlueOrchid; + materials[9377] = Material.PottedBrownMushroom; + materials[9379] = Material.PottedCactus; + materials[9358] = Material.PottedCherrySapling; + materials[27944] = Material.PottedClosedEyeblossom; + materials[9373] = Material.PottedCornflower; + materials[20515] = Material.PottedCrimsonFungus; + materials[20517] = Material.PottedCrimsonRoots; + materials[9363] = Material.PottedDandelion; + materials[9359] = Material.PottedDarkOakSapling; + materials[9378] = Material.PottedDeadBush; + materials[9362] = Material.PottedFern; + materials[27654] = Material.PottedFloweringAzaleaBush; + materials[9356] = Material.PottedJungleSapling; + materials[9374] = Material.PottedLilyOfTheValley; + materials[9361] = Material.PottedMangrovePropagule; + materials[9353] = Material.PottedOakSapling; + materials[27943] = Material.PottedOpenEyeblossom; + materials[9369] = Material.PottedOrangeTulip; + materials[9372] = Material.PottedOxeyeDaisy; + materials[9360] = Material.PottedPaleOakSapling; + materials[9371] = Material.PottedPinkTulip; + materials[9364] = Material.PottedPoppy; + materials[9376] = Material.PottedRedMushroom; + materials[9368] = Material.PottedRedTulip; + materials[9354] = Material.PottedSpruceSapling; + materials[9352] = Material.PottedTorchflower; + materials[20516] = Material.PottedWarpedFungus; + materials[20518] = Material.PottedWarpedRoots; + materials[9370] = Material.PottedWhiteTulip; + materials[9375] = Material.PottedWitherRose; + materials[23378] = Material.PowderSnow; + for (int i = 8187; i <= 8189; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + materials[11352] = Material.Prismarine; + for (int i = 11601; i <= 11606; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 11435; i <= 11514; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[11353] = Material.PrismarineBricks; + for (int i = 11595; i <= 11600; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 11355; i <= 11434; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 15539; i <= 15862; i++) + materials[i] = Material.PrismarineWall; + materials[7054] = Material.Pumpkin; + for (int i = 7064; i <= 7071; i++) + materials[i] = Material.PumpkinStem; + for (int i = 11808; i <= 11823; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 21961; i <= 21976; i++) + materials[i] = Material.PurpleCandle; + for (int i = 22079; i <= 22080; i++) + materials[i] = Material.PurpleCandleCake; + materials[11627] = Material.PurpleCarpet; + materials[13761] = Material.PurpleConcrete; + materials[13777] = Material.PurpleConcretePowder; + for (int i = 13727; i <= 13730; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 13651; i <= 13656; i++) + materials[i] = Material.PurpleShulkerBox; + materials[6134] = Material.PurpleStainedGlass; + for (int i = 10501; i <= 10532; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[10175] = Material.PurpleTerracotta; + for (int i = 11944; i <= 11947; i++) + materials[i] = Material.PurpleWallBanner; + materials[2103] = Material.PurpleWool; + materials[13433] = Material.PurpurBlock; + for (int i = 13434; i <= 13436; i++) + materials[i] = Material.PurpurPillar; + for (int i = 12195; i <= 12200; i++) + materials[i] = Material.PurpurSlab; + for (int i = 13437; i <= 13516; i++) + materials[i] = Material.PurpurStairs; + materials[10044] = Material.QuartzBlock; + materials[21784] = Material.QuartzBricks; + for (int i = 10046; i <= 10048; i++) + materials[i] = Material.QuartzPillar; + for (int i = 12177; i <= 12182; i++) + materials[i] = Material.QuartzSlab; + for (int i = 10049; i <= 10128; i++) + materials[i] = Material.QuartzStairs; + for (int i = 4758; i <= 4777; i++) + materials[i] = Material.Rail; + materials[27651] = Material.RawCopperBlock; + materials[27652] = Material.RawGoldBlock; + materials[27650] = Material.RawIronBlock; + for (int i = 11872; i <= 11887; i++) + materials[i] = Material.RedBanner; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 22025; i <= 22040; i++) + materials[i] = Material.RedCandle; + for (int i = 22087; i <= 22088; i++) + materials[i] = Material.RedCandleCake; + materials[11631] = Material.RedCarpet; + materials[13765] = Material.RedConcrete; + materials[13781] = Material.RedConcretePowder; + for (int i = 13743; i <= 13746; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2136] = Material.RedMushroom; + for (int i = 6856; i <= 6919; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 15197; i <= 15202; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 14897; i <= 14976; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 18131; i <= 18454; i++) + materials[i] = Material.RedNetherBrickWall; + materials[13568] = Material.RedNetherBricks; + materials[123] = Material.RedSand; + materials[11968] = Material.RedSandstone; + for (int i = 12183; i <= 12188; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 11971; i <= 12050; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 15863; i <= 16186; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 13675; i <= 13680; i++) + materials[i] = Material.RedShulkerBox; + materials[6138] = Material.RedStainedGlass; + for (int i = 10629; i <= 10660; i++) + materials[i] = Material.RedStainedGlassPane; + materials[10179] = Material.RedTerracotta; + materials[2127] = Material.RedTulip; + for (int i = 11960; i <= 11963; i++) + materials[i] = Material.RedWallBanner; + materials[2107] = Material.RedWool; + materials[10032] = Material.RedstoneBlock; + for (int i = 8201; i <= 8202; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 5912; i <= 5913; i++) + materials[i] = Material.RedstoneOre; + for (int i = 5916; i <= 5917; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 5918; i <= 5925; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 3042; i <= 4337; i++) + materials[i] = Material.RedstoneWire; + materials[27665] = Material.ReinforcedDeepslate; + for (int i = 6060; i <= 6123; i++) + materials[i] = Material.Repeater; + for (int i = 13538; i <= 13549; i++) + materials[i] = Material.RepeatingCommandBlock; + materials[7643] = Material.ResinBlock; + for (int i = 7725; i <= 7730; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 7645; i <= 7724; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 7731; i <= 8054; i++) + materials[i] = Material.ResinBrickWall; + materials[7644] = Material.ResinBricks; + for (int i = 7240; i <= 7367; i++) + materials[i] = Material.ResinClump; + for (int i = 20510; i <= 20514; i++) + materials[i] = Material.RespawnAnchor; + materials[25994] = Material.RootedDirt; + for (int i = 11640; i <= 11641; i++) + materials[i] = Material.RoseBush; + materials[118] = Material.Sand; + materials[578] = Material.Sandstone; + for (int i = 12129; i <= 12134; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 8215; i <= 8294; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 18455; i <= 18778; i++) + materials[i] = Material.SandstoneWall; + for (int i = 19427; i <= 19458; i++) + materials[i] = Material.Scaffolding; + materials[23859] = Material.Sculk; + for (int i = 23988; i <= 23989; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 23379; i <= 23474; i++) + materials[i] = Material.SculkSensor; + for (int i = 23990; i <= 23997; i++) + materials[i] = Material.SculkShrieker; + for (int i = 23860; i <= 23987; i++) + materials[i] = Material.SculkVein; + materials[11613] = Material.SeaLantern; + for (int i = 13988; i <= 13995; i++) + materials[i] = Material.SeaPickle; + materials[2054] = Material.Seagrass; + materials[2052] = Material.ShortDryGrass; + materials[2048] = Material.ShortGrass; + materials[19665] = Material.Shroomlight; + for (int i = 13585; i <= 13590; i++) + materials[i] = Material.ShulkerBox; + for (int i = 9636; i <= 9667; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 9668; i <= 9675; i++) + materials[i] = Material.SkeletonWallSkull; + materials[11253] = Material.SlimeBlock; + for (int i = 22129; i <= 22140; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 25976; i <= 25991; i++) + materials[i] = Material.SmallDripleaf; + materials[19521] = Material.SmithingTable; + for (int i = 19475; i <= 19482; i++) + materials[i] = Material.Smoker; + materials[27649] = Material.SmoothBasalt; + materials[12203] = Material.SmoothQuartz; + for (int i = 15179; i <= 15184; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 14657; i <= 14736; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[12204] = Material.SmoothRedSandstone; + for (int i = 15143; i <= 15148; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 14097; i <= 14176; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[12202] = Material.SmoothSandstone; + for (int i = 15173; i <= 15178; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 14577; i <= 14656; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[12201] = Material.SmoothStone; + for (int i = 12123; i <= 12128; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13823; i <= 13825; i++) + materials[i] = Material.SnifferEgg; + for (int i = 5950; i <= 5957; i++) + materials[i] = Material.Snow; + materials[5959] = Material.SnowBlock; + for (int i = 19598; i <= 19629; i++) + materials[i] = Material.SoulCampfire; + materials[2918] = Material.SoulFire; + for (int i = 19562; i <= 19565; i++) + materials[i] = Material.SoulLantern; + materials[6029] = Material.SoulSand; + materials[6030] = Material.SoulSoil; + materials[6037] = Material.SoulTorch; + for (int i = 6038; i <= 6041; i++) + materials[i] = Material.SoulWallTorch; + materials[2919] = Material.Spawner; + materials[560] = Material.Sponge; + materials[25883] = Material.SporeBlossom; + for (int i = 9420; i <= 9443; i++) + materials[i] = Material.SpruceButton; + for (int i = 12781; i <= 12844; i++) + materials[i] = Material.SpruceDoor; + for (int i = 12493; i <= 12524; i++) + materials[i] = Material.SpruceFence; + for (int i = 12205; i <= 12236; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 5002; i <= 5065; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 5894; i <= 5895; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 4398; i <= 4429; i++) + materials[i] = Material.SpruceSign; + for (int i = 12057; i <= 12062; i++) + materials[i] = Material.SpruceSlab; + for (int i = 8450; i <= 8529; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6204; i <= 6267; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 5714; i <= 5721; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 4866; i <= 4873; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 12159; i <= 12164; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 7480; i <= 7559; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 16835; i <= 17158; i++) + materials[i] = Material.StoneBrickWall; + materials[6780] = Material.StoneBricks; + for (int i = 5926; i <= 5949; i++) + materials[i] = Material.StoneButton; + for (int i = 5826; i <= 5827; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 12117; i <= 12122; i++) + materials[i] = Material.StoneSlab; + for (int i = 14497; i <= 14576; i++) + materials[i] = Material.StoneStairs; + for (int i = 19522; i <= 19525; i++) + materials[i] = Material.Stonecutter; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 19660; i <= 19662; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 19654; i <= 19656; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 19643; i <= 19645; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 19637; i <= 19639; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 20411; i <= 20414; i++) + materials[i] = Material.StructureBlock; + materials[13572] = Material.StructureVoid; + for (int i = 5978; i <= 5993; i++) + materials[i] = Material.SugarCane; + for (int i = 11636; i <= 11637; i++) + materials[i] = Material.Sunflower; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 19630; i <= 19633; i++) + materials[i] = Material.SweetBerryBush; + materials[2053] = Material.TallDryGrass; + for (int i = 11644; i <= 11645; i++) + materials[i] = Material.TallGrass; + for (int i = 2055; i <= 2056; i++) + materials[i] = Material.TallSeagrass; + for (int i = 20441; i <= 20456; i++) + materials[i] = Material.Target; + materials[11633] = Material.Terracotta; + for (int i = 20427; i <= 20430; i++) + materials[i] = Material.TestBlock; + materials[20431] = Material.TestInstanceBlock; + materials[23377] = Material.TintedGlass; + for (int i = 2140; i <= 2141; i++) + materials[i] = Material.Tnt; + materials[2401] = Material.Torch; + materials[2122] = Material.Torchflower; + for (int i = 13518; i <= 13519; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 9928; i <= 9951; i++) + materials[i] = Material.TrappedChest; + for (int i = 27730; i <= 27741; i++) + materials[i] = Material.TrialSpawner; + for (int i = 8321; i <= 8448; i++) + materials[i] = Material.Tripwire; + for (int i = 8305; i <= 8320; i++) + materials[i] = Material.TripwireHook; + for (int i = 13878; i <= 13879; i++) + materials[i] = Material.TubeCoral; + materials[13863] = Material.TubeCoralBlock; + for (int i = 13898; i <= 13899; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 13948; i <= 13955; i++) + materials[i] = Material.TubeCoralWallFan; + materials[22141] = Material.Tuff; + for (int i = 22965; i <= 22970; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 22971; i <= 23050; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 23051; i <= 23374; i++) + materials[i] = Material.TuffBrickWall; + materials[22964] = Material.TuffBricks; + for (int i = 22142; i <= 22147; i++) + materials[i] = Material.TuffSlab; + for (int i = 22148; i <= 22227; i++) + materials[i] = Material.TuffStairs; + for (int i = 22228; i <= 22551; i++) + materials[i] = Material.TuffWall; + for (int i = 13811; i <= 13822; i++) + materials[i] = Material.TurtleEgg; + for (int i = 19693; i <= 19718; i++) + materials[i] = Material.TwistingVines; + materials[19719] = Material.TwistingVinesPlant; + for (int i = 27742; i <= 27773; i++) + materials[i] = Material.Vault; + for (int i = 27658; i <= 27660; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 7080; i <= 7111; i++) + materials[i] = Material.Vine; + materials[14013] = Material.VoidAir; + for (int i = 2402; i <= 2405; i++) + materials[i] = Material.WallTorch; + for (int i = 20179; i <= 20202; i++) + materials[i] = Material.WarpedButton; + for (int i = 20267; i <= 20330; i++) + materials[i] = Material.WarpedDoor; + for (int i = 19771; i <= 19802; i++) + materials[i] = Material.WarpedFence; + for (int i = 19963; i <= 19994; i++) + materials[i] = Material.WarpedFenceGate; + materials[19647] = Material.WarpedFungus; + for (int i = 5514; i <= 5577; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 19640; i <= 19642; i++) + materials[i] = Material.WarpedHyphae; + materials[19646] = Material.WarpedNylium; + materials[19722] = Material.WarpedPlanks; + for (int i = 19737; i <= 19738; i++) + materials[i] = Material.WarpedPressurePlate; + materials[19649] = Material.WarpedRoots; + for (int i = 20363; i <= 20394; i++) + materials[i] = Material.WarpedSign; + for (int i = 19729; i <= 19734; i++) + materials[i] = Material.WarpedSlab; + for (int i = 20075; i <= 20154; i++) + materials[i] = Material.WarpedStairs; + for (int i = 19634; i <= 19636; i++) + materials[i] = Material.WarpedStem; + for (int i = 19867; i <= 19930; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 5786; i <= 5793; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 20403; i <= 20410; i++) + materials[i] = Material.WarpedWallSign; + materials[19648] = Material.WarpedWartBlock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 8183; i <= 8185; i++) + materials[i] = Material.WaterCauldron; + materials[24015] = Material.WaxedChiseledCopper; + materials[24360] = Material.WaxedCopperBlock; + for (int i = 25768; i <= 25771; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 24968; i <= 25031; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 25744; i <= 25745; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 25480; i <= 25543; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[24367] = Material.WaxedCutCopper; + for (int i = 24706; i <= 24711; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 24608; i <= 24687; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[24014] = Material.WaxedExposedChiseledCopper; + materials[24362] = Material.WaxedExposedCopper; + for (int i = 25772; i <= 25775; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 25032; i <= 25095; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 25746; i <= 25747; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 25544; i <= 25607; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[24366] = Material.WaxedExposedCutCopper; + for (int i = 24700; i <= 24705; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 24528; i <= 24607; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + materials[24012] = Material.WaxedOxidizedChiseledCopper; + materials[24363] = Material.WaxedOxidizedCopper; + for (int i = 25780; i <= 25783; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 25096; i <= 25159; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 25750; i <= 25751; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 25608; i <= 25671; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[24364] = Material.WaxedOxidizedCutCopper; + for (int i = 24688; i <= 24693; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 24368; i <= 24447; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + materials[24013] = Material.WaxedWeatheredChiseledCopper; + materials[24361] = Material.WaxedWeatheredCopper; + for (int i = 25776; i <= 25779; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 25160; i <= 25223; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 25748; i <= 25749; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 25672; i <= 25735; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[24365] = Material.WaxedWeatheredCutCopper; + for (int i = 24694; i <= 24699; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 24448; i <= 24527; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + materials[24009] = Material.WeatheredChiseledCopper; + materials[24000] = Material.WeatheredCopper; + for (int i = 25760; i <= 25763; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 24904; i <= 24967; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 25740; i <= 25741; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 25416; i <= 25479; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[24005] = Material.WeatheredCutCopper; + for (int i = 24342; i <= 24347; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 24096; i <= 24175; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 19666; i <= 19691; i++) + materials[i] = Material.WeepingVines; + materials[19692] = Material.WeepingVinesPlant; + materials[561] = Material.WetSponge; + for (int i = 4342; i <= 4349; i++) + materials[i] = Material.Wheat; + for (int i = 11648; i <= 11663; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 21801; i <= 21816; i++) + materials[i] = Material.WhiteCandle; + for (int i = 22059; i <= 22060; i++) + materials[i] = Material.WhiteCandleCake; + materials[11617] = Material.WhiteCarpet; + materials[13751] = Material.WhiteConcrete; + materials[13767] = Material.WhiteConcretePowder; + for (int i = 13687; i <= 13690; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 13591; i <= 13596; i++) + materials[i] = Material.WhiteShulkerBox; + materials[6124] = Material.WhiteStainedGlass; + for (int i = 10181; i <= 10212; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[10165] = Material.WhiteTerracotta; + materials[2129] = Material.WhiteTulip; + for (int i = 11904; i <= 11907; i++) + materials[i] = Material.WhiteWallBanner; + materials[2093] = Material.WhiteWool; + for (int i = 25903; i <= 25918; i++) + materials[i] = Material.Wildflowers; + materials[2133] = Material.WitherRose; + for (int i = 9676; i <= 9707; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 9708; i <= 9715; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 11712; i <= 11727; i++) + materials[i] = Material.YellowBanner; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 21865; i <= 21880; i++) + materials[i] = Material.YellowCandle; + for (int i = 22067; i <= 22068; i++) + materials[i] = Material.YellowCandleCake; + materials[11621] = Material.YellowCarpet; + materials[13755] = Material.YellowConcrete; + materials[13771] = Material.YellowConcretePowder; + for (int i = 13703; i <= 13706; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 13615; i <= 13620; i++) + materials[i] = Material.YellowShulkerBox; + materials[6128] = Material.YellowStainedGlass; + for (int i = 10309; i <= 10340; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[10169] = Material.YellowTerracotta; + for (int i = 11920; i <= 11923; i++) + materials[i] = Material.YellowWallBanner; + materials[2097] = Material.YellowWool; + for (int i = 9716; i <= 9747; i++) + materials[i] = Material.ZombieHead; + for (int i = 9748; i <= 9755; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index e9496d8b..9b1bbb57 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -24,7 +24,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 - <= Protocol18Handler.MC_1_21_5_Version => new EntityMetadataPalette1215(), // 1.21.5 + <= Protocol18Handler.MC_1_21_6_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.6 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1216.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1216.cs new file mode 100644 index 00000000..c0cb6b76 --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1216.cs @@ -0,0 +1,169 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1216 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1216() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.Cat; + mappings[21] = EntityType.CaveSpider; + mappings[22] = EntityType.CherryBoat; + mappings[23] = EntityType.CherryChestBoat; + mappings[24] = EntityType.ChestMinecart; + mappings[25] = EntityType.Chicken; + mappings[26] = EntityType.Cod; + mappings[27] = EntityType.CommandBlockMinecart; + mappings[28] = EntityType.Cow; + mappings[29] = EntityType.Creaking; + mappings[30] = EntityType.Creeper; + mappings[31] = EntityType.DarkOakBoat; + mappings[32] = EntityType.DarkOakChestBoat; + mappings[33] = EntityType.Dolphin; + mappings[34] = EntityType.Donkey; + mappings[35] = EntityType.DragonFireball; + mappings[36] = EntityType.Drowned; + mappings[37] = EntityType.Egg; + mappings[38] = EntityType.ElderGuardian; + mappings[39] = EntityType.Enderman; + mappings[40] = EntityType.Endermite; + mappings[41] = EntityType.EnderDragon; + mappings[42] = EntityType.EnderPearl; + mappings[43] = EntityType.EndCrystal; + mappings[44] = EntityType.Evoker; + mappings[45] = EntityType.EvokerFangs; + mappings[46] = EntityType.ExperienceBottle; + mappings[47] = EntityType.ExperienceOrb; + mappings[48] = EntityType.EyeOfEnder; + mappings[49] = EntityType.FallingBlock; + mappings[50] = EntityType.Fireball; + mappings[51] = EntityType.FireworkRocket; + mappings[52] = EntityType.Fox; + mappings[53] = EntityType.Frog; + mappings[54] = EntityType.FurnaceMinecart; + mappings[55] = EntityType.Ghast; + mappings[56] = EntityType.HappyGhast; + mappings[57] = EntityType.Giant; + mappings[58] = EntityType.GlowItemFrame; + mappings[59] = EntityType.GlowSquid; + mappings[60] = EntityType.Goat; + mappings[61] = EntityType.Guardian; + mappings[62] = EntityType.Hoglin; + mappings[63] = EntityType.HopperMinecart; + mappings[64] = EntityType.Horse; + mappings[65] = EntityType.Husk; + mappings[66] = EntityType.Illusioner; + mappings[67] = EntityType.Interaction; + mappings[68] = EntityType.IronGolem; + mappings[69] = EntityType.Item; + mappings[70] = EntityType.ItemDisplay; + mappings[71] = EntityType.ItemFrame; + mappings[72] = EntityType.JungleBoat; + mappings[73] = EntityType.JungleChestBoat; + mappings[74] = EntityType.LeashKnot; + mappings[75] = EntityType.LightningBolt; + mappings[76] = EntityType.Llama; + mappings[77] = EntityType.LlamaSpit; + mappings[78] = EntityType.MagmaCube; + mappings[79] = EntityType.MangroveBoat; + mappings[80] = EntityType.MangroveChestBoat; + mappings[81] = EntityType.Marker; + mappings[82] = EntityType.Minecart; + mappings[83] = EntityType.Mooshroom; + mappings[84] = EntityType.Mule; + mappings[85] = EntityType.OakBoat; + mappings[86] = EntityType.OakChestBoat; + mappings[87] = EntityType.Ocelot; + mappings[88] = EntityType.OminousItemSpawner; + mappings[89] = EntityType.Painting; + mappings[90] = EntityType.PaleOakBoat; + mappings[91] = EntityType.PaleOakChestBoat; + mappings[92] = EntityType.Panda; + mappings[93] = EntityType.Parrot; + mappings[94] = EntityType.Phantom; + mappings[95] = EntityType.Pig; + mappings[96] = EntityType.Piglin; + mappings[97] = EntityType.PiglinBrute; + mappings[98] = EntityType.Pillager; + mappings[99] = EntityType.PolarBear; + mappings[100] = EntityType.SplashPotion; + mappings[101] = EntityType.LingeringPotion; + mappings[102] = EntityType.Pufferfish; + mappings[103] = EntityType.Rabbit; + mappings[104] = EntityType.Ravager; + mappings[105] = EntityType.Salmon; + mappings[106] = EntityType.Sheep; + mappings[107] = EntityType.Shulker; + mappings[108] = EntityType.ShulkerBullet; + mappings[109] = EntityType.Silverfish; + mappings[110] = EntityType.Skeleton; + mappings[111] = EntityType.SkeletonHorse; + mappings[112] = EntityType.Slime; + mappings[113] = EntityType.SmallFireball; + mappings[114] = EntityType.Sniffer; + mappings[115] = EntityType.Snowball; + mappings[116] = EntityType.SnowGolem; + mappings[117] = EntityType.SpawnerMinecart; + mappings[118] = EntityType.SpectralArrow; + mappings[119] = EntityType.Spider; + mappings[120] = EntityType.SpruceBoat; + mappings[121] = EntityType.SpruceChestBoat; + mappings[122] = EntityType.Squid; + mappings[123] = EntityType.Stray; + mappings[124] = EntityType.Strider; + mappings[125] = EntityType.Tadpole; + mappings[126] = EntityType.TextDisplay; + mappings[127] = EntityType.Tnt; + mappings[128] = EntityType.TntMinecart; + mappings[129] = EntityType.TraderLlama; + mappings[130] = EntityType.Trident; + mappings[131] = EntityType.TropicalFish; + mappings[132] = EntityType.Turtle; + mappings[133] = EntityType.Vex; + mappings[134] = EntityType.Villager; + mappings[135] = EntityType.Vindicator; + mappings[136] = EntityType.WanderingTrader; + mappings[137] = EntityType.Warden; + mappings[138] = EntityType.WindCharge; + mappings[139] = EntityType.Witch; + mappings[140] = EntityType.Wither; + mappings[141] = EntityType.WitherSkeleton; + mappings[142] = EntityType.WitherSkull; + mappings[143] = EntityType.Wolf; + mappings[144] = EntityType.Zoglin; + mappings[145] = EntityType.Zombie; + mappings[146] = EntityType.ZombieHorse; + mappings[147] = EntityType.ZombieVillager; + mappings[148] = EntityType.ZombifiedPiglin; + mappings[149] = EntityType.Player; + mappings[150] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1216.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1216.cs new file mode 100644 index 00000000..e49504fd --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1216.cs @@ -0,0 +1,255 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1216 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.EntityAnimation }, // Animate + { 0x03, PacketTypesIn.Statistics }, // Award Stats + { 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x07, PacketTypesIn.BlockAction }, // Block Event + { 0x08, PacketTypesIn.BlockChange }, // Block Update + { 0x09, PacketTypesIn.BossBar }, // Boss Event + { 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x10, PacketTypesIn.DeclareCommands }, // Commands + { 0x11, PacketTypesIn.CloseWindow }, // Container Close + { 0x12, PacketTypesIn.WindowItems }, // Container Set Content + { 0x13, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x14, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x15, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x16, PacketTypesIn.SetCooldown }, // Cooldown + { 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x18, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x19, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1A, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1B, PacketTypesIn.HideMessage }, // Delete Chat + { 0x1C, PacketTypesIn.Disconnect }, // Disconnect + { 0x1D, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x1E, PacketTypesIn.EntityStatus }, // Entity Event + { 0x1F, PacketTypesIn.EntityPositionSync }, // Entity Position Sync + { 0x20, PacketTypesIn.Explosion }, // Explode + { 0x21, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x22, PacketTypesIn.ChangeGameState }, // Game Event + { 0x23, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open + { 0x24, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x25, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x26, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x27, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x28, PacketTypesIn.Effect }, // Level Event + { 0x29, PacketTypesIn.Particle }, // Level Particles + { 0x2A, PacketTypesIn.UpdateLight }, // Light Update + { 0x2B, PacketTypesIn.JoinGame }, // Login + { 0x2C, PacketTypesIn.MapData }, // Map Item Data + { 0x2D, PacketTypesIn.TradeList }, // Merchant Offers + { 0x2E, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x2F, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x30, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track + { 0x31, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x32, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x33, PacketTypesIn.OpenBook }, // Open Book + { 0x34, PacketTypesIn.OpenWindow }, // Open Screen + { 0x35, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x36, PacketTypesIn.Ping }, // Ping + { 0x37, PacketTypesIn.PingResponse }, // Pong Response + { 0x38, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x39, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x3A, PacketTypesIn.ChatMessage }, // Player Chat + { 0x3B, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x3C, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x3D, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x3E, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x3F, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x40, PacketTypesIn.FacePlayer }, // Player Look At + { 0x41, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x42, PacketTypesIn.PlayerRotation }, // Player Rotation + { 0x43, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add + { 0x44, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove + { 0x45, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings + { 0x46, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x47, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x48, PacketTypesIn.ResetScore }, // Reset Score + { 0x49, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x4A, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x4B, PacketTypesIn.Respawn }, // Respawn + { 0x4C, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x4D, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x4E, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x4F, PacketTypesIn.ServerData }, // Server Data + { 0x50, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x51, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x52, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x53, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x54, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x55, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x56, PacketTypesIn.Camera }, // Set Camera + { 0x57, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x58, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x59, PacketTypesIn.SetCursorItem }, // Set Cursor Item + { 0x5A, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x5B, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x5C, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x5D, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x5E, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x5F, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x60, PacketTypesIn.SetExperience }, // Set Experience + { 0x61, PacketTypesIn.UpdateHealth }, // Set Health + { 0x62, PacketTypesIn.SetHeldSlot }, // Set Held Slot + { 0x63, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x64, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x65, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory + { 0x66, PacketTypesIn.Teams }, // Set Player Team + { 0x67, PacketTypesIn.UpdateScore }, // Set Score + { 0x68, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x69, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x6A, PacketTypesIn.TimeUpdate }, // Set Time + { 0x6B, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x6C, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x6D, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x6E, PacketTypesIn.SoundEffect }, // Sound + { 0x6F, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x70, PacketTypesIn.StopSound }, // Stop Sound + { 0x71, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x72, PacketTypesIn.SystemChat }, // System Chat + { 0x73, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x74, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x75, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x76, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x77, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status + { 0x78, PacketTypesIn.SetTickingState }, // Ticking State + { 0x79, PacketTypesIn.StepTick }, // Ticking Step + { 0x7A, PacketTypesIn.Transfer }, // Transfer + { 0x7B, PacketTypesIn.Advancements }, // Update Advancements + { 0x7C, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x7D, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x7E, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x7F, PacketTypesIn.Tags }, // Update Tags + { 0x80, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x81, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x82, PacketTypesIn.ServerLinks }, // Server Links + { 0x83, PacketTypesIn.Waypoint }, // Waypoint (new in 1.21.6) + { 0x84, PacketTypesIn.ClearDialog }, // Clear Dialog (new in 1.21.6) + { 0x85, PacketTypesIn.ShowDialog } // Show Dialog (new in 1.21.6) + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected + { 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x04, PacketTypesOut.ChangeGameMode }, // Change Game Mode (new in 1.21.6) + { 0x05, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x06, PacketTypesOut.ChatCommand }, // Chat Command + { 0x07, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x08, PacketTypesOut.ChatMessage }, // Chat + { 0x09, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x0A, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0B, PacketTypesOut.ClientStatus }, // Client Command + { 0x0C, PacketTypesOut.ClientTickEnd }, // Client Tick End + { 0x0D, PacketTypesOut.ClientSettings }, // Client Information + { 0x0E, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x0F, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x10, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x11, PacketTypesOut.ClickWindow }, // Container Click + { 0x12, PacketTypesOut.CloseWindow }, // Container Close + { 0x13, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x14, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x15, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x16, PacketTypesOut.DebugSampleSubscription }, // Debug Sample Subscription + { 0x17, PacketTypesOut.EditBook }, // Edit Book + { 0x18, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x19, PacketTypesOut.InteractEntity }, // Interact + { 0x1A, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1B, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1C, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1D, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1E, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x1F, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x20, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x21, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x22, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x23, PacketTypesOut.PickItem }, // Pick Item From Block + { 0x24, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity + { 0x25, PacketTypesOut.PingRequest }, // Ping Request + { 0x26, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x27, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x28, PacketTypesOut.PlayerDigging }, // Player Action + { 0x29, PacketTypesOut.EntityAction }, // Player Command + { 0x2A, PacketTypesOut.SteerVehicle }, // Player Input + { 0x2B, PacketTypesOut.PlayerLoaded }, // Player Loaded + { 0x2C, PacketTypesOut.Pong }, // Pong + { 0x2D, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2E, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x2F, PacketTypesOut.NameItem }, // Rename Item + { 0x30, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x31, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x32, PacketTypesOut.SelectTrade }, // Select Trade + { 0x33, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x34, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x35, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x36, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x37, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x38, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x39, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x3A, PacketTypesOut.SetTestBlock }, // Set Test Block + { 0x3B, PacketTypesOut.UpdateSign }, // Sign Update + { 0x3C, PacketTypesOut.Animation }, // Swing + { 0x3D, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x3E, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action + { 0x3F, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x40, PacketTypesOut.UseItem }, // Use Item + { 0x41, PacketTypesOut.CustomClickAction } // Custom Click Action (new in 1.21.6) + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks }, + { 0x11, ConfigurationPacketTypesIn.ClearDialog }, // New in 1.21.6 + { 0x12, ConfigurationPacketTypesIn.ShowDialog } // New in 1.21.6 + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks }, + { 0x08, ConfigurationPacketTypesOut.CustomClickAction } // New in 1.21.6 + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index ab800bb6..256a9472 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_5_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_6_Version => throw new NotImplementedException(Translations .exception_palette_packet), + <= Protocol18Handler.MC_1_21_6_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 8f4f0d99..aefac1f7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -153,6 +153,7 @@ namespace MinecraftClient.Protocol.Handlers // Block palette > MC_1_21_6_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + >= MC_1_21_6_Version => new Palette1216(), >= MC_1_21_5_Version => new Palette1215(), >= MC_1_21_4_Version => new Palette1214(), >= MC_1_21_2_Version => new Palette1212(), @@ -175,6 +176,7 @@ namespace MinecraftClient.Protocol.Handlers // Entity palette > MC_1_21_6_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_1_21_6_Version => new EntityPalette1216(), >= MC_1_21_5_Version => new EntityPalette1215(), >= MC_1_21_4_Version => new EntityPalette1214(), >= MC_1_21_2_Version => new EntityPalette1212(), @@ -201,6 +203,7 @@ namespace MinecraftClient.Protocol.Handlers // Item palette > MC_1_21_6_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_6_Version => new ItemPalette1216(), >= MC_1_21_5_Version => new ItemPalette1215(), >= MC_1_21_4_Version => new ItemPalette1214(), >= MC_1_21_2_Version => new ItemPalette1212(), From 067395ab2a6966f02a2b1538104d866e2880042d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 12:11:18 +0800 Subject: [PATCH 069/484] fix: correct biome data array length calculation for 1.21.5+ terrain parsing The biome PalettedContainer data array length was calculated as ceil(64 * bitsPerEntry / 64) which is incorrect for non-power-of-2 bit widths. The correct calculation uses SimpleBitStorage's formula: valuesPerLong = 64 / bitsPerEntry, then ceil(64 / valuesPerLong). For example, with bitsPerEntry=3: old formula gave 3 longs but the actual data contains 4 longs (valuesPerLong=21, ceil(64/21)=4). This bug was masked in 1.21.5 by excess padding bytes in chunk buffers (due to PalettedContainer.Data.getSerializedSize over-counting). MC 1.21.6 fixed the size calculation server-side, removing the padding and exposing this pre-existing MCC bug. Made-with: Cursor --- MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs index 75bf7b34..09f99cf5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs @@ -213,7 +213,9 @@ namespace MinecraftClient.Protocol.Handlers { // 1.21.5: No VarInt length prefix; calculate from bits per entry // Biome container has 64 entries (4x4x4) - int dataArrayLength = (64 * bitsPerEntryBiome + 63) / 64; + // Uses SimpleBitStorage: valuesPerLong = 64/bitsPerEntry, longs = ceil(64/valuesPerLong) + int valuesPerLong = 64 / bitsPerEntryBiome; + int dataArrayLength = (64 + valuesPerLong - 1) / valuesPerLong; dataTypes.DropData(dataArrayLength * 8, cache); } else From 5e8d715358c44dc4ca4ccba383a60fd27e583ee0 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 13:10:30 +0800 Subject: [PATCH 070/484] feat: add MC 1.21.7/1.21.8 (protocol 772) support 1.21.7 and 1.21.8 share protocol 772. The only registry change from 1.21.6 is one new item (music_disc_lava_chicken). All other palettes (blocks, entities, packets, entity metadata, structured components) are unchanged and reuse 1.21.6 versions. Changes: - Add MC_1_21_7_Version (772) constant - Add "1.21.7" / "1.21.8" version mappings in ProtocolHandler - Add MusicDiscLavaChicken to ItemType enum - Generate ItemPalette1217 (1416 items) for the new item palette - Update all version upper-bound checks from MC_1_21_6 to MC_1_21_7 - Update MCHighestVersion to "1.21.8" Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1217.cs | 1434 +++++++++++++++++ MinecraftClient/Inventory/ItemType.cs | 1 + .../Mapping/EntityMetadataPalette.cs | 2 +- MinecraftClient/Program.cs | 2 +- .../Protocol/Handlers/PacketType18Handler.cs | 4 +- .../Protocol/Handlers/Protocol18.cs | 20 +- MinecraftClient/Protocol/ProtocolHandler.cs | 6 +- 7 files changed, 1455 insertions(+), 14 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1217.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1217.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1217.cs new file mode 100644 index 00000000..a7026b92 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1217.cs @@ -0,0 +1,1434 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1217 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1217() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.DryShortGrass; + mappings[210] = ItemType.DryTallGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.OpenEyeblossom; + mappings[231] = ItemType.ClosedEyeblossom; + mappings[232] = ItemType.Poppy; + mappings[233] = ItemType.BlueOrchid; + mappings[234] = ItemType.Allium; + mappings[235] = ItemType.AzureBluet; + mappings[236] = ItemType.RedTulip; + mappings[237] = ItemType.OrangeTulip; + mappings[238] = ItemType.WhiteTulip; + mappings[239] = ItemType.PinkTulip; + mappings[240] = ItemType.OxeyeDaisy; + mappings[241] = ItemType.Cornflower; + mappings[242] = ItemType.LilyOfTheValley; + mappings[243] = ItemType.WitherRose; + mappings[244] = ItemType.Torchflower; + mappings[245] = ItemType.PitcherPlant; + mappings[246] = ItemType.SporeBlossom; + mappings[247] = ItemType.BrownMushroom; + mappings[248] = ItemType.RedMushroom; + mappings[249] = ItemType.CrimsonFungus; + mappings[250] = ItemType.WarpedFungus; + mappings[251] = ItemType.CrimsonRoots; + mappings[252] = ItemType.WarpedRoots; + mappings[253] = ItemType.NetherSprouts; + mappings[254] = ItemType.WeepingVines; + mappings[255] = ItemType.TwistingVines; + mappings[256] = ItemType.SugarCane; + mappings[257] = ItemType.Kelp; + mappings[258] = ItemType.PinkPetals; + mappings[259] = ItemType.Wildflowers; + mappings[260] = ItemType.LeafLitter; + mappings[261] = ItemType.MossCarpet; + mappings[262] = ItemType.MossBlock; + mappings[263] = ItemType.PaleMossCarpet; + mappings[264] = ItemType.PaleHangingMoss; + mappings[265] = ItemType.PaleMossBlock; + mappings[266] = ItemType.HangingRoots; + mappings[267] = ItemType.BigDripleaf; + mappings[268] = ItemType.SmallDripleaf; + mappings[269] = ItemType.Bamboo; + mappings[270] = ItemType.OakSlab; + mappings[271] = ItemType.SpruceSlab; + mappings[272] = ItemType.BirchSlab; + mappings[273] = ItemType.JungleSlab; + mappings[274] = ItemType.AcaciaSlab; + mappings[275] = ItemType.CherrySlab; + mappings[276] = ItemType.DarkOakSlab; + mappings[277] = ItemType.PaleOakSlab; + mappings[278] = ItemType.MangroveSlab; + mappings[279] = ItemType.BambooSlab; + mappings[280] = ItemType.BambooMosaicSlab; + mappings[281] = ItemType.CrimsonSlab; + mappings[282] = ItemType.WarpedSlab; + mappings[283] = ItemType.StoneSlab; + mappings[284] = ItemType.SmoothStoneSlab; + mappings[285] = ItemType.SandstoneSlab; + mappings[286] = ItemType.CutSandstoneSlab; + mappings[287] = ItemType.PetrifiedOakSlab; + mappings[288] = ItemType.CobblestoneSlab; + mappings[289] = ItemType.BrickSlab; + mappings[290] = ItemType.StoneBrickSlab; + mappings[291] = ItemType.MudBrickSlab; + mappings[292] = ItemType.NetherBrickSlab; + mappings[293] = ItemType.QuartzSlab; + mappings[294] = ItemType.RedSandstoneSlab; + mappings[295] = ItemType.CutRedSandstoneSlab; + mappings[296] = ItemType.PurpurSlab; + mappings[297] = ItemType.PrismarineSlab; + mappings[298] = ItemType.PrismarineBrickSlab; + mappings[299] = ItemType.DarkPrismarineSlab; + mappings[300] = ItemType.SmoothQuartz; + mappings[301] = ItemType.SmoothRedSandstone; + mappings[302] = ItemType.SmoothSandstone; + mappings[303] = ItemType.SmoothStone; + mappings[304] = ItemType.Bricks; + mappings[305] = ItemType.Bookshelf; + mappings[306] = ItemType.ChiseledBookshelf; + mappings[307] = ItemType.DecoratedPot; + mappings[308] = ItemType.MossyCobblestone; + mappings[309] = ItemType.Obsidian; + mappings[310] = ItemType.Torch; + mappings[311] = ItemType.EndRod; + mappings[312] = ItemType.ChorusPlant; + mappings[313] = ItemType.ChorusFlower; + mappings[314] = ItemType.PurpurBlock; + mappings[315] = ItemType.PurpurPillar; + mappings[316] = ItemType.PurpurStairs; + mappings[317] = ItemType.Spawner; + mappings[318] = ItemType.CreakingHeart; + mappings[319] = ItemType.Chest; + mappings[320] = ItemType.CraftingTable; + mappings[321] = ItemType.Farmland; + mappings[322] = ItemType.Furnace; + mappings[323] = ItemType.Ladder; + mappings[324] = ItemType.CobblestoneStairs; + mappings[325] = ItemType.Snow; + mappings[326] = ItemType.Ice; + mappings[327] = ItemType.SnowBlock; + mappings[328] = ItemType.Cactus; + mappings[329] = ItemType.CactusFlower; + mappings[330] = ItemType.Clay; + mappings[331] = ItemType.Jukebox; + mappings[332] = ItemType.OakFence; + mappings[333] = ItemType.SpruceFence; + mappings[334] = ItemType.BirchFence; + mappings[335] = ItemType.JungleFence; + mappings[336] = ItemType.AcaciaFence; + mappings[337] = ItemType.CherryFence; + mappings[338] = ItemType.DarkOakFence; + mappings[339] = ItemType.PaleOakFence; + mappings[340] = ItemType.MangroveFence; + mappings[341] = ItemType.BambooFence; + mappings[342] = ItemType.CrimsonFence; + mappings[343] = ItemType.WarpedFence; + mappings[344] = ItemType.Pumpkin; + mappings[345] = ItemType.CarvedPumpkin; + mappings[346] = ItemType.JackOLantern; + mappings[347] = ItemType.Netherrack; + mappings[348] = ItemType.SoulSand; + mappings[349] = ItemType.SoulSoil; + mappings[350] = ItemType.Basalt; + mappings[351] = ItemType.PolishedBasalt; + mappings[352] = ItemType.SmoothBasalt; + mappings[353] = ItemType.SoulTorch; + mappings[354] = ItemType.Glowstone; + mappings[355] = ItemType.InfestedStone; + mappings[356] = ItemType.InfestedCobblestone; + mappings[357] = ItemType.InfestedStoneBricks; + mappings[358] = ItemType.InfestedMossyStoneBricks; + mappings[359] = ItemType.InfestedCrackedStoneBricks; + mappings[360] = ItemType.InfestedChiseledStoneBricks; + mappings[361] = ItemType.InfestedDeepslate; + mappings[362] = ItemType.StoneBricks; + mappings[363] = ItemType.MossyStoneBricks; + mappings[364] = ItemType.CrackedStoneBricks; + mappings[365] = ItemType.ChiseledStoneBricks; + mappings[366] = ItemType.PackedMud; + mappings[367] = ItemType.MudBricks; + mappings[368] = ItemType.DeepslateBricks; + mappings[369] = ItemType.CrackedDeepslateBricks; + mappings[370] = ItemType.DeepslateTiles; + mappings[371] = ItemType.CrackedDeepslateTiles; + mappings[372] = ItemType.ChiseledDeepslate; + mappings[373] = ItemType.ReinforcedDeepslate; + mappings[374] = ItemType.BrownMushroomBlock; + mappings[375] = ItemType.RedMushroomBlock; + mappings[376] = ItemType.MushroomStem; + mappings[377] = ItemType.IronBars; + mappings[378] = ItemType.Chain; + mappings[379] = ItemType.GlassPane; + mappings[380] = ItemType.Melon; + mappings[381] = ItemType.Vine; + mappings[382] = ItemType.GlowLichen; + mappings[383] = ItemType.ResinClump; + mappings[384] = ItemType.ResinBlock; + mappings[385] = ItemType.ResinBricks; + mappings[386] = ItemType.ResinBrickStairs; + mappings[387] = ItemType.ResinBrickSlab; + mappings[388] = ItemType.ResinBrickWall; + mappings[389] = ItemType.ChiseledResinBricks; + mappings[390] = ItemType.BrickStairs; + mappings[391] = ItemType.StoneBrickStairs; + mappings[392] = ItemType.MudBrickStairs; + mappings[393] = ItemType.Mycelium; + mappings[394] = ItemType.LilyPad; + mappings[395] = ItemType.NetherBricks; + mappings[396] = ItemType.CrackedNetherBricks; + mappings[397] = ItemType.ChiseledNetherBricks; + mappings[398] = ItemType.NetherBrickFence; + mappings[399] = ItemType.NetherBrickStairs; + mappings[400] = ItemType.Sculk; + mappings[401] = ItemType.SculkVein; + mappings[402] = ItemType.SculkCatalyst; + mappings[403] = ItemType.SculkShrieker; + mappings[404] = ItemType.EnchantingTable; + mappings[405] = ItemType.EndPortalFrame; + mappings[406] = ItemType.EndStone; + mappings[407] = ItemType.EndStoneBricks; + mappings[408] = ItemType.DragonEgg; + mappings[409] = ItemType.SandstoneStairs; + mappings[410] = ItemType.EnderChest; + mappings[411] = ItemType.EmeraldBlock; + mappings[412] = ItemType.OakStairs; + mappings[413] = ItemType.SpruceStairs; + mappings[414] = ItemType.BirchStairs; + mappings[415] = ItemType.JungleStairs; + mappings[416] = ItemType.AcaciaStairs; + mappings[417] = ItemType.CherryStairs; + mappings[418] = ItemType.DarkOakStairs; + mappings[419] = ItemType.PaleOakStairs; + mappings[420] = ItemType.MangroveStairs; + mappings[421] = ItemType.BambooStairs; + mappings[422] = ItemType.BambooMosaicStairs; + mappings[423] = ItemType.CrimsonStairs; + mappings[424] = ItemType.WarpedStairs; + mappings[425] = ItemType.CommandBlock; + mappings[426] = ItemType.Beacon; + mappings[427] = ItemType.CobblestoneWall; + mappings[428] = ItemType.MossyCobblestoneWall; + mappings[429] = ItemType.BrickWall; + mappings[430] = ItemType.PrismarineWall; + mappings[431] = ItemType.RedSandstoneWall; + mappings[432] = ItemType.MossyStoneBrickWall; + mappings[433] = ItemType.GraniteWall; + mappings[434] = ItemType.StoneBrickWall; + mappings[435] = ItemType.MudBrickWall; + mappings[436] = ItemType.NetherBrickWall; + mappings[437] = ItemType.AndesiteWall; + mappings[438] = ItemType.RedNetherBrickWall; + mappings[439] = ItemType.SandstoneWall; + mappings[440] = ItemType.EndStoneBrickWall; + mappings[441] = ItemType.DioriteWall; + mappings[442] = ItemType.BlackstoneWall; + mappings[443] = ItemType.PolishedBlackstoneWall; + mappings[444] = ItemType.PolishedBlackstoneBrickWall; + mappings[445] = ItemType.CobbledDeepslateWall; + mappings[446] = ItemType.PolishedDeepslateWall; + mappings[447] = ItemType.DeepslateBrickWall; + mappings[448] = ItemType.DeepslateTileWall; + mappings[449] = ItemType.Anvil; + mappings[450] = ItemType.ChippedAnvil; + mappings[451] = ItemType.DamagedAnvil; + mappings[452] = ItemType.ChiseledQuartzBlock; + mappings[453] = ItemType.QuartzBlock; + mappings[454] = ItemType.QuartzBricks; + mappings[455] = ItemType.QuartzPillar; + mappings[456] = ItemType.QuartzStairs; + mappings[457] = ItemType.WhiteTerracotta; + mappings[458] = ItemType.OrangeTerracotta; + mappings[459] = ItemType.MagentaTerracotta; + mappings[460] = ItemType.LightBlueTerracotta; + mappings[461] = ItemType.YellowTerracotta; + mappings[462] = ItemType.LimeTerracotta; + mappings[463] = ItemType.PinkTerracotta; + mappings[464] = ItemType.GrayTerracotta; + mappings[465] = ItemType.LightGrayTerracotta; + mappings[466] = ItemType.CyanTerracotta; + mappings[467] = ItemType.PurpleTerracotta; + mappings[468] = ItemType.BlueTerracotta; + mappings[469] = ItemType.BrownTerracotta; + mappings[470] = ItemType.GreenTerracotta; + mappings[471] = ItemType.RedTerracotta; + mappings[472] = ItemType.BlackTerracotta; + mappings[473] = ItemType.Barrier; + mappings[474] = ItemType.Light; + mappings[475] = ItemType.HayBlock; + mappings[476] = ItemType.WhiteCarpet; + mappings[477] = ItemType.OrangeCarpet; + mappings[478] = ItemType.MagentaCarpet; + mappings[479] = ItemType.LightBlueCarpet; + mappings[480] = ItemType.YellowCarpet; + mappings[481] = ItemType.LimeCarpet; + mappings[482] = ItemType.PinkCarpet; + mappings[483] = ItemType.GrayCarpet; + mappings[484] = ItemType.LightGrayCarpet; + mappings[485] = ItemType.CyanCarpet; + mappings[486] = ItemType.PurpleCarpet; + mappings[487] = ItemType.BlueCarpet; + mappings[488] = ItemType.BrownCarpet; + mappings[489] = ItemType.GreenCarpet; + mappings[490] = ItemType.RedCarpet; + mappings[491] = ItemType.BlackCarpet; + mappings[492] = ItemType.Terracotta; + mappings[493] = ItemType.PackedIce; + mappings[494] = ItemType.DirtPath; + mappings[495] = ItemType.Sunflower; + mappings[496] = ItemType.Lilac; + mappings[497] = ItemType.RoseBush; + mappings[498] = ItemType.Peony; + mappings[499] = ItemType.TallGrass; + mappings[500] = ItemType.LargeFern; + mappings[501] = ItemType.WhiteStainedGlass; + mappings[502] = ItemType.OrangeStainedGlass; + mappings[503] = ItemType.MagentaStainedGlass; + mappings[504] = ItemType.LightBlueStainedGlass; + mappings[505] = ItemType.YellowStainedGlass; + mappings[506] = ItemType.LimeStainedGlass; + mappings[507] = ItemType.PinkStainedGlass; + mappings[508] = ItemType.GrayStainedGlass; + mappings[509] = ItemType.LightGrayStainedGlass; + mappings[510] = ItemType.CyanStainedGlass; + mappings[511] = ItemType.PurpleStainedGlass; + mappings[512] = ItemType.BlueStainedGlass; + mappings[513] = ItemType.BrownStainedGlass; + mappings[514] = ItemType.GreenStainedGlass; + mappings[515] = ItemType.RedStainedGlass; + mappings[516] = ItemType.BlackStainedGlass; + mappings[517] = ItemType.WhiteStainedGlassPane; + mappings[518] = ItemType.OrangeStainedGlassPane; + mappings[519] = ItemType.MagentaStainedGlassPane; + mappings[520] = ItemType.LightBlueStainedGlassPane; + mappings[521] = ItemType.YellowStainedGlassPane; + mappings[522] = ItemType.LimeStainedGlassPane; + mappings[523] = ItemType.PinkStainedGlassPane; + mappings[524] = ItemType.GrayStainedGlassPane; + mappings[525] = ItemType.LightGrayStainedGlassPane; + mappings[526] = ItemType.CyanStainedGlassPane; + mappings[527] = ItemType.PurpleStainedGlassPane; + mappings[528] = ItemType.BlueStainedGlassPane; + mappings[529] = ItemType.BrownStainedGlassPane; + mappings[530] = ItemType.GreenStainedGlassPane; + mappings[531] = ItemType.RedStainedGlassPane; + mappings[532] = ItemType.BlackStainedGlassPane; + mappings[533] = ItemType.Prismarine; + mappings[534] = ItemType.PrismarineBricks; + mappings[535] = ItemType.DarkPrismarine; + mappings[536] = ItemType.PrismarineStairs; + mappings[537] = ItemType.PrismarineBrickStairs; + mappings[538] = ItemType.DarkPrismarineStairs; + mappings[539] = ItemType.SeaLantern; + mappings[540] = ItemType.RedSandstone; + mappings[541] = ItemType.ChiseledRedSandstone; + mappings[542] = ItemType.CutRedSandstone; + mappings[543] = ItemType.RedSandstoneStairs; + mappings[544] = ItemType.RepeatingCommandBlock; + mappings[545] = ItemType.ChainCommandBlock; + mappings[546] = ItemType.MagmaBlock; + mappings[547] = ItemType.NetherWartBlock; + mappings[548] = ItemType.WarpedWartBlock; + mappings[549] = ItemType.RedNetherBricks; + mappings[550] = ItemType.BoneBlock; + mappings[551] = ItemType.StructureVoid; + mappings[552] = ItemType.ShulkerBox; + mappings[553] = ItemType.WhiteShulkerBox; + mappings[554] = ItemType.OrangeShulkerBox; + mappings[555] = ItemType.MagentaShulkerBox; + mappings[556] = ItemType.LightBlueShulkerBox; + mappings[557] = ItemType.YellowShulkerBox; + mappings[558] = ItemType.LimeShulkerBox; + mappings[559] = ItemType.PinkShulkerBox; + mappings[560] = ItemType.GrayShulkerBox; + mappings[561] = ItemType.LightGrayShulkerBox; + mappings[562] = ItemType.CyanShulkerBox; + mappings[563] = ItemType.PurpleShulkerBox; + mappings[564] = ItemType.BlueShulkerBox; + mappings[565] = ItemType.BrownShulkerBox; + mappings[566] = ItemType.GreenShulkerBox; + mappings[567] = ItemType.RedShulkerBox; + mappings[568] = ItemType.BlackShulkerBox; + mappings[569] = ItemType.WhiteGlazedTerracotta; + mappings[570] = ItemType.OrangeGlazedTerracotta; + mappings[571] = ItemType.MagentaGlazedTerracotta; + mappings[572] = ItemType.LightBlueGlazedTerracotta; + mappings[573] = ItemType.YellowGlazedTerracotta; + mappings[574] = ItemType.LimeGlazedTerracotta; + mappings[575] = ItemType.PinkGlazedTerracotta; + mappings[576] = ItemType.GrayGlazedTerracotta; + mappings[577] = ItemType.LightGrayGlazedTerracotta; + mappings[578] = ItemType.CyanGlazedTerracotta; + mappings[579] = ItemType.PurpleGlazedTerracotta; + mappings[580] = ItemType.BlueGlazedTerracotta; + mappings[581] = ItemType.BrownGlazedTerracotta; + mappings[582] = ItemType.GreenGlazedTerracotta; + mappings[583] = ItemType.RedGlazedTerracotta; + mappings[584] = ItemType.BlackGlazedTerracotta; + mappings[585] = ItemType.WhiteConcrete; + mappings[586] = ItemType.OrangeConcrete; + mappings[587] = ItemType.MagentaConcrete; + mappings[588] = ItemType.LightBlueConcrete; + mappings[589] = ItemType.YellowConcrete; + mappings[590] = ItemType.LimeConcrete; + mappings[591] = ItemType.PinkConcrete; + mappings[592] = ItemType.GrayConcrete; + mappings[593] = ItemType.LightGrayConcrete; + mappings[594] = ItemType.CyanConcrete; + mappings[595] = ItemType.PurpleConcrete; + mappings[596] = ItemType.BlueConcrete; + mappings[597] = ItemType.BrownConcrete; + mappings[598] = ItemType.GreenConcrete; + mappings[599] = ItemType.RedConcrete; + mappings[600] = ItemType.BlackConcrete; + mappings[601] = ItemType.WhiteConcretePowder; + mappings[602] = ItemType.OrangeConcretePowder; + mappings[603] = ItemType.MagentaConcretePowder; + mappings[604] = ItemType.LightBlueConcretePowder; + mappings[605] = ItemType.YellowConcretePowder; + mappings[606] = ItemType.LimeConcretePowder; + mappings[607] = ItemType.PinkConcretePowder; + mappings[608] = ItemType.GrayConcretePowder; + mappings[609] = ItemType.LightGrayConcretePowder; + mappings[610] = ItemType.CyanConcretePowder; + mappings[611] = ItemType.PurpleConcretePowder; + mappings[612] = ItemType.BlueConcretePowder; + mappings[613] = ItemType.BrownConcretePowder; + mappings[614] = ItemType.GreenConcretePowder; + mappings[615] = ItemType.RedConcretePowder; + mappings[616] = ItemType.BlackConcretePowder; + mappings[617] = ItemType.TurtleEgg; + mappings[618] = ItemType.SnifferEgg; + mappings[619] = ItemType.DriedGhast; + mappings[620] = ItemType.DeadTubeCoralBlock; + mappings[621] = ItemType.DeadBrainCoralBlock; + mappings[622] = ItemType.DeadBubbleCoralBlock; + mappings[623] = ItemType.DeadFireCoralBlock; + mappings[624] = ItemType.DeadHornCoralBlock; + mappings[625] = ItemType.TubeCoralBlock; + mappings[626] = ItemType.BrainCoralBlock; + mappings[627] = ItemType.BubbleCoralBlock; + mappings[628] = ItemType.FireCoralBlock; + mappings[629] = ItemType.HornCoralBlock; + mappings[630] = ItemType.TubeCoral; + mappings[631] = ItemType.BrainCoral; + mappings[632] = ItemType.BubbleCoral; + mappings[633] = ItemType.FireCoral; + mappings[634] = ItemType.HornCoral; + mappings[635] = ItemType.DeadBrainCoral; + mappings[636] = ItemType.DeadBubbleCoral; + mappings[637] = ItemType.DeadFireCoral; + mappings[638] = ItemType.DeadHornCoral; + mappings[639] = ItemType.DeadTubeCoral; + mappings[640] = ItemType.TubeCoralFan; + mappings[641] = ItemType.BrainCoralFan; + mappings[642] = ItemType.BubbleCoralFan; + mappings[643] = ItemType.FireCoralFan; + mappings[644] = ItemType.HornCoralFan; + mappings[645] = ItemType.DeadTubeCoralFan; + mappings[646] = ItemType.DeadBrainCoralFan; + mappings[647] = ItemType.DeadBubbleCoralFan; + mappings[648] = ItemType.DeadFireCoralFan; + mappings[649] = ItemType.DeadHornCoralFan; + mappings[650] = ItemType.BlueIce; + mappings[651] = ItemType.Conduit; + mappings[652] = ItemType.PolishedGraniteStairs; + mappings[653] = ItemType.SmoothRedSandstoneStairs; + mappings[654] = ItemType.MossyStoneBrickStairs; + mappings[655] = ItemType.PolishedDioriteStairs; + mappings[656] = ItemType.MossyCobblestoneStairs; + mappings[657] = ItemType.EndStoneBrickStairs; + mappings[658] = ItemType.StoneStairs; + mappings[659] = ItemType.SmoothSandstoneStairs; + mappings[660] = ItemType.SmoothQuartzStairs; + mappings[661] = ItemType.GraniteStairs; + mappings[662] = ItemType.AndesiteStairs; + mappings[663] = ItemType.RedNetherBrickStairs; + mappings[664] = ItemType.PolishedAndesiteStairs; + mappings[665] = ItemType.DioriteStairs; + mappings[666] = ItemType.CobbledDeepslateStairs; + mappings[667] = ItemType.PolishedDeepslateStairs; + mappings[668] = ItemType.DeepslateBrickStairs; + mappings[669] = ItemType.DeepslateTileStairs; + mappings[670] = ItemType.PolishedGraniteSlab; + mappings[671] = ItemType.SmoothRedSandstoneSlab; + mappings[672] = ItemType.MossyStoneBrickSlab; + mappings[673] = ItemType.PolishedDioriteSlab; + mappings[674] = ItemType.MossyCobblestoneSlab; + mappings[675] = ItemType.EndStoneBrickSlab; + mappings[676] = ItemType.SmoothSandstoneSlab; + mappings[677] = ItemType.SmoothQuartzSlab; + mappings[678] = ItemType.GraniteSlab; + mappings[679] = ItemType.AndesiteSlab; + mappings[680] = ItemType.RedNetherBrickSlab; + mappings[681] = ItemType.PolishedAndesiteSlab; + mappings[682] = ItemType.DioriteSlab; + mappings[683] = ItemType.CobbledDeepslateSlab; + mappings[684] = ItemType.PolishedDeepslateSlab; + mappings[685] = ItemType.DeepslateBrickSlab; + mappings[686] = ItemType.DeepslateTileSlab; + mappings[687] = ItemType.Scaffolding; + mappings[688] = ItemType.Redstone; + mappings[689] = ItemType.RedstoneTorch; + mappings[690] = ItemType.RedstoneBlock; + mappings[691] = ItemType.Repeater; + mappings[692] = ItemType.Comparator; + mappings[693] = ItemType.Piston; + mappings[694] = ItemType.StickyPiston; + mappings[695] = ItemType.SlimeBlock; + mappings[696] = ItemType.HoneyBlock; + mappings[697] = ItemType.Observer; + mappings[698] = ItemType.Hopper; + mappings[699] = ItemType.Dispenser; + mappings[700] = ItemType.Dropper; + mappings[701] = ItemType.Lectern; + mappings[702] = ItemType.Target; + mappings[703] = ItemType.Lever; + mappings[704] = ItemType.LightningRod; + mappings[705] = ItemType.DaylightDetector; + mappings[706] = ItemType.SculkSensor; + mappings[707] = ItemType.CalibratedSculkSensor; + mappings[708] = ItemType.TripwireHook; + mappings[709] = ItemType.TrappedChest; + mappings[710] = ItemType.Tnt; + mappings[711] = ItemType.RedstoneLamp; + mappings[712] = ItemType.NoteBlock; + mappings[713] = ItemType.StoneButton; + mappings[714] = ItemType.PolishedBlackstoneButton; + mappings[715] = ItemType.OakButton; + mappings[716] = ItemType.SpruceButton; + mappings[717] = ItemType.BirchButton; + mappings[718] = ItemType.JungleButton; + mappings[719] = ItemType.AcaciaButton; + mappings[720] = ItemType.CherryButton; + mappings[721] = ItemType.DarkOakButton; + mappings[722] = ItemType.PaleOakButton; + mappings[723] = ItemType.MangroveButton; + mappings[724] = ItemType.BambooButton; + mappings[725] = ItemType.CrimsonButton; + mappings[726] = ItemType.WarpedButton; + mappings[727] = ItemType.StonePressurePlate; + mappings[728] = ItemType.PolishedBlackstonePressurePlate; + mappings[729] = ItemType.LightWeightedPressurePlate; + mappings[730] = ItemType.HeavyWeightedPressurePlate; + mappings[731] = ItemType.OakPressurePlate; + mappings[732] = ItemType.SprucePressurePlate; + mappings[733] = ItemType.BirchPressurePlate; + mappings[734] = ItemType.JunglePressurePlate; + mappings[735] = ItemType.AcaciaPressurePlate; + mappings[736] = ItemType.CherryPressurePlate; + mappings[737] = ItemType.DarkOakPressurePlate; + mappings[738] = ItemType.PaleOakPressurePlate; + mappings[739] = ItemType.MangrovePressurePlate; + mappings[740] = ItemType.BambooPressurePlate; + mappings[741] = ItemType.CrimsonPressurePlate; + mappings[742] = ItemType.WarpedPressurePlate; + mappings[743] = ItemType.IronDoor; + mappings[744] = ItemType.OakDoor; + mappings[745] = ItemType.SpruceDoor; + mappings[746] = ItemType.BirchDoor; + mappings[747] = ItemType.JungleDoor; + mappings[748] = ItemType.AcaciaDoor; + mappings[749] = ItemType.CherryDoor; + mappings[750] = ItemType.DarkOakDoor; + mappings[751] = ItemType.PaleOakDoor; + mappings[752] = ItemType.MangroveDoor; + mappings[753] = ItemType.BambooDoor; + mappings[754] = ItemType.CrimsonDoor; + mappings[755] = ItemType.WarpedDoor; + mappings[756] = ItemType.CopperDoor; + mappings[757] = ItemType.ExposedCopperDoor; + mappings[758] = ItemType.WeatheredCopperDoor; + mappings[759] = ItemType.OxidizedCopperDoor; + mappings[760] = ItemType.WaxedCopperDoor; + mappings[761] = ItemType.WaxedExposedCopperDoor; + mappings[762] = ItemType.WaxedWeatheredCopperDoor; + mappings[763] = ItemType.WaxedOxidizedCopperDoor; + mappings[764] = ItemType.IronTrapdoor; + mappings[765] = ItemType.OakTrapdoor; + mappings[766] = ItemType.SpruceTrapdoor; + mappings[767] = ItemType.BirchTrapdoor; + mappings[768] = ItemType.JungleTrapdoor; + mappings[769] = ItemType.AcaciaTrapdoor; + mappings[770] = ItemType.CherryTrapdoor; + mappings[771] = ItemType.DarkOakTrapdoor; + mappings[772] = ItemType.PaleOakTrapdoor; + mappings[773] = ItemType.MangroveTrapdoor; + mappings[774] = ItemType.BambooTrapdoor; + mappings[775] = ItemType.CrimsonTrapdoor; + mappings[776] = ItemType.WarpedTrapdoor; + mappings[777] = ItemType.CopperTrapdoor; + mappings[778] = ItemType.ExposedCopperTrapdoor; + mappings[779] = ItemType.WeatheredCopperTrapdoor; + mappings[780] = ItemType.OxidizedCopperTrapdoor; + mappings[781] = ItemType.WaxedCopperTrapdoor; + mappings[782] = ItemType.WaxedExposedCopperTrapdoor; + mappings[783] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[784] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[785] = ItemType.OakFenceGate; + mappings[786] = ItemType.SpruceFenceGate; + mappings[787] = ItemType.BirchFenceGate; + mappings[788] = ItemType.JungleFenceGate; + mappings[789] = ItemType.AcaciaFenceGate; + mappings[790] = ItemType.CherryFenceGate; + mappings[791] = ItemType.DarkOakFenceGate; + mappings[792] = ItemType.PaleOakFenceGate; + mappings[793] = ItemType.MangroveFenceGate; + mappings[794] = ItemType.BambooFenceGate; + mappings[795] = ItemType.CrimsonFenceGate; + mappings[796] = ItemType.WarpedFenceGate; + mappings[797] = ItemType.PoweredRail; + mappings[798] = ItemType.DetectorRail; + mappings[799] = ItemType.Rail; + mappings[800] = ItemType.ActivatorRail; + mappings[801] = ItemType.Saddle; + mappings[802] = ItemType.WhiteHarness; + mappings[803] = ItemType.OrangeHarness; + mappings[804] = ItemType.MagentaHarness; + mappings[805] = ItemType.LightBlueHarness; + mappings[806] = ItemType.YellowHarness; + mappings[807] = ItemType.LimeHarness; + mappings[808] = ItemType.PinkHarness; + mappings[809] = ItemType.GrayHarness; + mappings[810] = ItemType.LightGrayHarness; + mappings[811] = ItemType.CyanHarness; + mappings[812] = ItemType.PurpleHarness; + mappings[813] = ItemType.BlueHarness; + mappings[814] = ItemType.BrownHarness; + mappings[815] = ItemType.GreenHarness; + mappings[816] = ItemType.RedHarness; + mappings[817] = ItemType.BlackHarness; + mappings[818] = ItemType.Minecart; + mappings[819] = ItemType.ChestMinecart; + mappings[820] = ItemType.FurnaceMinecart; + mappings[821] = ItemType.TntMinecart; + mappings[822] = ItemType.HopperMinecart; + mappings[823] = ItemType.CarrotOnAStick; + mappings[824] = ItemType.WarpedFungusOnAStick; + mappings[825] = ItemType.PhantomMembrane; + mappings[826] = ItemType.Elytra; + mappings[827] = ItemType.OakBoat; + mappings[828] = ItemType.OakChestBoat; + mappings[829] = ItemType.SpruceBoat; + mappings[830] = ItemType.SpruceChestBoat; + mappings[831] = ItemType.BirchBoat; + mappings[832] = ItemType.BirchChestBoat; + mappings[833] = ItemType.JungleBoat; + mappings[834] = ItemType.JungleChestBoat; + mappings[835] = ItemType.AcaciaBoat; + mappings[836] = ItemType.AcaciaChestBoat; + mappings[837] = ItemType.CherryBoat; + mappings[838] = ItemType.CherryChestBoat; + mappings[839] = ItemType.DarkOakBoat; + mappings[840] = ItemType.DarkOakChestBoat; + mappings[841] = ItemType.PaleOakBoat; + mappings[842] = ItemType.PaleOakChestBoat; + mappings[843] = ItemType.MangroveBoat; + mappings[844] = ItemType.MangroveChestBoat; + mappings[845] = ItemType.BambooRaft; + mappings[846] = ItemType.BambooChestRaft; + mappings[847] = ItemType.StructureBlock; + mappings[848] = ItemType.Jigsaw; + mappings[849] = ItemType.TestBlock; + mappings[850] = ItemType.TestInstanceBlock; + mappings[851] = ItemType.TurtleHelmet; + mappings[852] = ItemType.TurtleScute; + mappings[853] = ItemType.ArmadilloScute; + mappings[854] = ItemType.WolfArmor; + mappings[855] = ItemType.FlintAndSteel; + mappings[856] = ItemType.Bowl; + mappings[857] = ItemType.Apple; + mappings[858] = ItemType.Bow; + mappings[859] = ItemType.Arrow; + mappings[860] = ItemType.Coal; + mappings[861] = ItemType.Charcoal; + mappings[862] = ItemType.Diamond; + mappings[863] = ItemType.Emerald; + mappings[864] = ItemType.LapisLazuli; + mappings[865] = ItemType.Quartz; + mappings[866] = ItemType.AmethystShard; + mappings[867] = ItemType.RawIron; + mappings[868] = ItemType.IronIngot; + mappings[869] = ItemType.RawCopper; + mappings[870] = ItemType.CopperIngot; + mappings[871] = ItemType.RawGold; + mappings[872] = ItemType.GoldIngot; + mappings[873] = ItemType.NetheriteIngot; + mappings[874] = ItemType.NetheriteScrap; + mappings[875] = ItemType.WoodenSword; + mappings[876] = ItemType.WoodenShovel; + mappings[877] = ItemType.WoodenPickaxe; + mappings[878] = ItemType.WoodenAxe; + mappings[879] = ItemType.WoodenHoe; + mappings[880] = ItemType.StoneSword; + mappings[881] = ItemType.StoneShovel; + mappings[882] = ItemType.StonePickaxe; + mappings[883] = ItemType.StoneAxe; + mappings[884] = ItemType.StoneHoe; + mappings[885] = ItemType.GoldenSword; + mappings[886] = ItemType.GoldenShovel; + mappings[887] = ItemType.GoldenPickaxe; + mappings[888] = ItemType.GoldenAxe; + mappings[889] = ItemType.GoldenHoe; + mappings[890] = ItemType.IronSword; + mappings[891] = ItemType.IronShovel; + mappings[892] = ItemType.IronPickaxe; + mappings[893] = ItemType.IronAxe; + mappings[894] = ItemType.IronHoe; + mappings[895] = ItemType.DiamondSword; + mappings[896] = ItemType.DiamondShovel; + mappings[897] = ItemType.DiamondPickaxe; + mappings[898] = ItemType.DiamondAxe; + mappings[899] = ItemType.DiamondHoe; + mappings[900] = ItemType.NetheriteSword; + mappings[901] = ItemType.NetheriteShovel; + mappings[902] = ItemType.NetheritePickaxe; + mappings[903] = ItemType.NetheriteAxe; + mappings[904] = ItemType.NetheriteHoe; + mappings[905] = ItemType.Stick; + mappings[906] = ItemType.MushroomStew; + mappings[907] = ItemType.String; + mappings[908] = ItemType.Feather; + mappings[909] = ItemType.Gunpowder; + mappings[910] = ItemType.WheatSeeds; + mappings[911] = ItemType.Wheat; + mappings[912] = ItemType.Bread; + mappings[913] = ItemType.LeatherHelmet; + mappings[914] = ItemType.LeatherChestplate; + mappings[915] = ItemType.LeatherLeggings; + mappings[916] = ItemType.LeatherBoots; + mappings[917] = ItemType.ChainmailHelmet; + mappings[918] = ItemType.ChainmailChestplate; + mappings[919] = ItemType.ChainmailLeggings; + mappings[920] = ItemType.ChainmailBoots; + mappings[921] = ItemType.IronHelmet; + mappings[922] = ItemType.IronChestplate; + mappings[923] = ItemType.IronLeggings; + mappings[924] = ItemType.IronBoots; + mappings[925] = ItemType.DiamondHelmet; + mappings[926] = ItemType.DiamondChestplate; + mappings[927] = ItemType.DiamondLeggings; + mappings[928] = ItemType.DiamondBoots; + mappings[929] = ItemType.GoldenHelmet; + mappings[930] = ItemType.GoldenChestplate; + mappings[931] = ItemType.GoldenLeggings; + mappings[932] = ItemType.GoldenBoots; + mappings[933] = ItemType.NetheriteHelmet; + mappings[934] = ItemType.NetheriteChestplate; + mappings[935] = ItemType.NetheriteLeggings; + mappings[936] = ItemType.NetheriteBoots; + mappings[937] = ItemType.Flint; + mappings[938] = ItemType.Porkchop; + mappings[939] = ItemType.CookedPorkchop; + mappings[940] = ItemType.Painting; + mappings[941] = ItemType.GoldenApple; + mappings[942] = ItemType.EnchantedGoldenApple; + mappings[943] = ItemType.OakSign; + mappings[944] = ItemType.SpruceSign; + mappings[945] = ItemType.BirchSign; + mappings[946] = ItemType.JungleSign; + mappings[947] = ItemType.AcaciaSign; + mappings[948] = ItemType.CherrySign; + mappings[949] = ItemType.DarkOakSign; + mappings[950] = ItemType.PaleOakSign; + mappings[951] = ItemType.MangroveSign; + mappings[952] = ItemType.BambooSign; + mappings[953] = ItemType.CrimsonSign; + mappings[954] = ItemType.WarpedSign; + mappings[955] = ItemType.OakHangingSign; + mappings[956] = ItemType.SpruceHangingSign; + mappings[957] = ItemType.BirchHangingSign; + mappings[958] = ItemType.JungleHangingSign; + mappings[959] = ItemType.AcaciaHangingSign; + mappings[960] = ItemType.CherryHangingSign; + mappings[961] = ItemType.DarkOakHangingSign; + mappings[962] = ItemType.PaleOakHangingSign; + mappings[963] = ItemType.MangroveHangingSign; + mappings[964] = ItemType.BambooHangingSign; + mappings[965] = ItemType.CrimsonHangingSign; + mappings[966] = ItemType.WarpedHangingSign; + mappings[967] = ItemType.Bucket; + mappings[968] = ItemType.WaterBucket; + mappings[969] = ItemType.LavaBucket; + mappings[970] = ItemType.PowderSnowBucket; + mappings[971] = ItemType.Snowball; + mappings[972] = ItemType.Leather; + mappings[973] = ItemType.MilkBucket; + mappings[974] = ItemType.PufferfishBucket; + mappings[975] = ItemType.SalmonBucket; + mappings[976] = ItemType.CodBucket; + mappings[977] = ItemType.TropicalFishBucket; + mappings[978] = ItemType.AxolotlBucket; + mappings[979] = ItemType.TadpoleBucket; + mappings[980] = ItemType.Brick; + mappings[981] = ItemType.ClayBall; + mappings[982] = ItemType.DriedKelpBlock; + mappings[983] = ItemType.Paper; + mappings[984] = ItemType.Book; + mappings[985] = ItemType.SlimeBall; + mappings[986] = ItemType.Egg; + mappings[987] = ItemType.BlueEgg; + mappings[988] = ItemType.BrownEgg; + mappings[989] = ItemType.Compass; + mappings[990] = ItemType.RecoveryCompass; + mappings[991] = ItemType.Bundle; + mappings[992] = ItemType.WhiteBundle; + mappings[993] = ItemType.OrangeBundle; + mappings[994] = ItemType.MagentaBundle; + mappings[995] = ItemType.LightBlueBundle; + mappings[996] = ItemType.YellowBundle; + mappings[997] = ItemType.LimeBundle; + mappings[998] = ItemType.PinkBundle; + mappings[999] = ItemType.GrayBundle; + mappings[1000] = ItemType.LightGrayBundle; + mappings[1001] = ItemType.CyanBundle; + mappings[1002] = ItemType.PurpleBundle; + mappings[1003] = ItemType.BlueBundle; + mappings[1004] = ItemType.BrownBundle; + mappings[1005] = ItemType.GreenBundle; + mappings[1006] = ItemType.RedBundle; + mappings[1007] = ItemType.BlackBundle; + mappings[1008] = ItemType.FishingRod; + mappings[1009] = ItemType.Clock; + mappings[1010] = ItemType.Spyglass; + mappings[1011] = ItemType.GlowstoneDust; + mappings[1012] = ItemType.Cod; + mappings[1013] = ItemType.Salmon; + mappings[1014] = ItemType.TropicalFish; + mappings[1015] = ItemType.Pufferfish; + mappings[1016] = ItemType.CookedCod; + mappings[1017] = ItemType.CookedSalmon; + mappings[1018] = ItemType.InkSac; + mappings[1019] = ItemType.GlowInkSac; + mappings[1020] = ItemType.CocoaBeans; + mappings[1021] = ItemType.WhiteDye; + mappings[1022] = ItemType.OrangeDye; + mappings[1023] = ItemType.MagentaDye; + mappings[1024] = ItemType.LightBlueDye; + mappings[1025] = ItemType.YellowDye; + mappings[1026] = ItemType.LimeDye; + mappings[1027] = ItemType.PinkDye; + mappings[1028] = ItemType.GrayDye; + mappings[1029] = ItemType.LightGrayDye; + mappings[1030] = ItemType.CyanDye; + mappings[1031] = ItemType.PurpleDye; + mappings[1032] = ItemType.BlueDye; + mappings[1033] = ItemType.BrownDye; + mappings[1034] = ItemType.GreenDye; + mappings[1035] = ItemType.RedDye; + mappings[1036] = ItemType.BlackDye; + mappings[1037] = ItemType.BoneMeal; + mappings[1038] = ItemType.Bone; + mappings[1039] = ItemType.Sugar; + mappings[1040] = ItemType.Cake; + mappings[1041] = ItemType.WhiteBed; + mappings[1042] = ItemType.OrangeBed; + mappings[1043] = ItemType.MagentaBed; + mappings[1044] = ItemType.LightBlueBed; + mappings[1045] = ItemType.YellowBed; + mappings[1046] = ItemType.LimeBed; + mappings[1047] = ItemType.PinkBed; + mappings[1048] = ItemType.GrayBed; + mappings[1049] = ItemType.LightGrayBed; + mappings[1050] = ItemType.CyanBed; + mappings[1051] = ItemType.PurpleBed; + mappings[1052] = ItemType.BlueBed; + mappings[1053] = ItemType.BrownBed; + mappings[1054] = ItemType.GreenBed; + mappings[1055] = ItemType.RedBed; + mappings[1056] = ItemType.BlackBed; + mappings[1057] = ItemType.Cookie; + mappings[1058] = ItemType.Crafter; + mappings[1059] = ItemType.FilledMap; + mappings[1060] = ItemType.Shears; + mappings[1061] = ItemType.MelonSlice; + mappings[1062] = ItemType.DriedKelp; + mappings[1063] = ItemType.PumpkinSeeds; + mappings[1064] = ItemType.MelonSeeds; + mappings[1065] = ItemType.Beef; + mappings[1066] = ItemType.CookedBeef; + mappings[1067] = ItemType.Chicken; + mappings[1068] = ItemType.CookedChicken; + mappings[1069] = ItemType.RottenFlesh; + mappings[1070] = ItemType.EnderPearl; + mappings[1071] = ItemType.BlazeRod; + mappings[1072] = ItemType.GhastTear; + mappings[1073] = ItemType.GoldNugget; + mappings[1074] = ItemType.NetherWart; + mappings[1075] = ItemType.GlassBottle; + mappings[1076] = ItemType.Potion; + mappings[1077] = ItemType.SpiderEye; + mappings[1078] = ItemType.FermentedSpiderEye; + mappings[1079] = ItemType.BlazePowder; + mappings[1080] = ItemType.MagmaCream; + mappings[1081] = ItemType.BrewingStand; + mappings[1082] = ItemType.Cauldron; + mappings[1083] = ItemType.EnderEye; + mappings[1084] = ItemType.GlisteringMelonSlice; + mappings[1085] = ItemType.ArmadilloSpawnEgg; + mappings[1086] = ItemType.AllaySpawnEgg; + mappings[1087] = ItemType.AxolotlSpawnEgg; + mappings[1088] = ItemType.BatSpawnEgg; + mappings[1089] = ItemType.BeeSpawnEgg; + mappings[1090] = ItemType.BlazeSpawnEgg; + mappings[1091] = ItemType.BoggedSpawnEgg; + mappings[1092] = ItemType.BreezeSpawnEgg; + mappings[1093] = ItemType.CatSpawnEgg; + mappings[1094] = ItemType.CamelSpawnEgg; + mappings[1095] = ItemType.CaveSpiderSpawnEgg; + mappings[1096] = ItemType.ChickenSpawnEgg; + mappings[1097] = ItemType.CodSpawnEgg; + mappings[1098] = ItemType.CowSpawnEgg; + mappings[1099] = ItemType.CreeperSpawnEgg; + mappings[1100] = ItemType.DolphinSpawnEgg; + mappings[1101] = ItemType.DonkeySpawnEgg; + mappings[1102] = ItemType.DrownedSpawnEgg; + mappings[1103] = ItemType.ElderGuardianSpawnEgg; + mappings[1104] = ItemType.EnderDragonSpawnEgg; + mappings[1105] = ItemType.EndermanSpawnEgg; + mappings[1106] = ItemType.EndermiteSpawnEgg; + mappings[1107] = ItemType.EvokerSpawnEgg; + mappings[1108] = ItemType.FoxSpawnEgg; + mappings[1109] = ItemType.FrogSpawnEgg; + mappings[1110] = ItemType.GhastSpawnEgg; + mappings[1111] = ItemType.HappyGhastSpawnEgg; + mappings[1112] = ItemType.GlowSquidSpawnEgg; + mappings[1113] = ItemType.GoatSpawnEgg; + mappings[1114] = ItemType.GuardianSpawnEgg; + mappings[1115] = ItemType.HoglinSpawnEgg; + mappings[1116] = ItemType.HorseSpawnEgg; + mappings[1117] = ItemType.HuskSpawnEgg; + mappings[1118] = ItemType.IronGolemSpawnEgg; + mappings[1119] = ItemType.LlamaSpawnEgg; + mappings[1120] = ItemType.MagmaCubeSpawnEgg; + mappings[1121] = ItemType.MooshroomSpawnEgg; + mappings[1122] = ItemType.MuleSpawnEgg; + mappings[1123] = ItemType.OcelotSpawnEgg; + mappings[1124] = ItemType.PandaSpawnEgg; + mappings[1125] = ItemType.ParrotSpawnEgg; + mappings[1126] = ItemType.PhantomSpawnEgg; + mappings[1127] = ItemType.PigSpawnEgg; + mappings[1128] = ItemType.PiglinSpawnEgg; + mappings[1129] = ItemType.PiglinBruteSpawnEgg; + mappings[1130] = ItemType.PillagerSpawnEgg; + mappings[1131] = ItemType.PolarBearSpawnEgg; + mappings[1132] = ItemType.PufferfishSpawnEgg; + mappings[1133] = ItemType.RabbitSpawnEgg; + mappings[1134] = ItemType.RavagerSpawnEgg; + mappings[1135] = ItemType.SalmonSpawnEgg; + mappings[1136] = ItemType.SheepSpawnEgg; + mappings[1137] = ItemType.ShulkerSpawnEgg; + mappings[1138] = ItemType.SilverfishSpawnEgg; + mappings[1139] = ItemType.SkeletonSpawnEgg; + mappings[1140] = ItemType.SkeletonHorseSpawnEgg; + mappings[1141] = ItemType.SlimeSpawnEgg; + mappings[1142] = ItemType.SnifferSpawnEgg; + mappings[1143] = ItemType.SnowGolemSpawnEgg; + mappings[1144] = ItemType.SpiderSpawnEgg; + mappings[1145] = ItemType.SquidSpawnEgg; + mappings[1146] = ItemType.StraySpawnEgg; + mappings[1147] = ItemType.StriderSpawnEgg; + mappings[1148] = ItemType.TadpoleSpawnEgg; + mappings[1149] = ItemType.TraderLlamaSpawnEgg; + mappings[1150] = ItemType.TropicalFishSpawnEgg; + mappings[1151] = ItemType.TurtleSpawnEgg; + mappings[1152] = ItemType.VexSpawnEgg; + mappings[1153] = ItemType.VillagerSpawnEgg; + mappings[1154] = ItemType.VindicatorSpawnEgg; + mappings[1155] = ItemType.WanderingTraderSpawnEgg; + mappings[1156] = ItemType.WardenSpawnEgg; + mappings[1157] = ItemType.WitchSpawnEgg; + mappings[1158] = ItemType.WitherSpawnEgg; + mappings[1159] = ItemType.WitherSkeletonSpawnEgg; + mappings[1160] = ItemType.WolfSpawnEgg; + mappings[1161] = ItemType.ZoglinSpawnEgg; + mappings[1162] = ItemType.CreakingSpawnEgg; + mappings[1163] = ItemType.ZombieSpawnEgg; + mappings[1164] = ItemType.ZombieHorseSpawnEgg; + mappings[1165] = ItemType.ZombieVillagerSpawnEgg; + mappings[1166] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1167] = ItemType.ExperienceBottle; + mappings[1168] = ItemType.FireCharge; + mappings[1169] = ItemType.WindCharge; + mappings[1170] = ItemType.WritableBook; + mappings[1171] = ItemType.WrittenBook; + mappings[1172] = ItemType.BreezeRod; + mappings[1173] = ItemType.Mace; + mappings[1174] = ItemType.ItemFrame; + mappings[1175] = ItemType.GlowItemFrame; + mappings[1176] = ItemType.FlowerPot; + mappings[1177] = ItemType.Carrot; + mappings[1178] = ItemType.Potato; + mappings[1179] = ItemType.BakedPotato; + mappings[1180] = ItemType.PoisonousPotato; + mappings[1181] = ItemType.Map; + mappings[1182] = ItemType.GoldenCarrot; + mappings[1183] = ItemType.SkeletonSkull; + mappings[1184] = ItemType.WitherSkeletonSkull; + mappings[1185] = ItemType.PlayerHead; + mappings[1186] = ItemType.ZombieHead; + mappings[1187] = ItemType.CreeperHead; + mappings[1188] = ItemType.DragonHead; + mappings[1189] = ItemType.PiglinHead; + mappings[1190] = ItemType.NetherStar; + mappings[1191] = ItemType.PumpkinPie; + mappings[1192] = ItemType.FireworkRocket; + mappings[1193] = ItemType.FireworkStar; + mappings[1194] = ItemType.EnchantedBook; + mappings[1195] = ItemType.NetherBrick; + mappings[1196] = ItemType.ResinBrick; + mappings[1197] = ItemType.PrismarineShard; + mappings[1198] = ItemType.PrismarineCrystals; + mappings[1199] = ItemType.Rabbit; + mappings[1200] = ItemType.CookedRabbit; + mappings[1201] = ItemType.RabbitStew; + mappings[1202] = ItemType.RabbitFoot; + mappings[1203] = ItemType.RabbitHide; + mappings[1204] = ItemType.ArmorStand; + mappings[1205] = ItemType.IronHorseArmor; + mappings[1206] = ItemType.GoldenHorseArmor; + mappings[1207] = ItemType.DiamondHorseArmor; + mappings[1208] = ItemType.LeatherHorseArmor; + mappings[1209] = ItemType.Lead; + mappings[1210] = ItemType.NameTag; + mappings[1211] = ItemType.CommandBlockMinecart; + mappings[1212] = ItemType.Mutton; + mappings[1213] = ItemType.CookedMutton; + mappings[1214] = ItemType.WhiteBanner; + mappings[1215] = ItemType.OrangeBanner; + mappings[1216] = ItemType.MagentaBanner; + mappings[1217] = ItemType.LightBlueBanner; + mappings[1218] = ItemType.YellowBanner; + mappings[1219] = ItemType.LimeBanner; + mappings[1220] = ItemType.PinkBanner; + mappings[1221] = ItemType.GrayBanner; + mappings[1222] = ItemType.LightGrayBanner; + mappings[1223] = ItemType.CyanBanner; + mappings[1224] = ItemType.PurpleBanner; + mappings[1225] = ItemType.BlueBanner; + mappings[1226] = ItemType.BrownBanner; + mappings[1227] = ItemType.GreenBanner; + mappings[1228] = ItemType.RedBanner; + mappings[1229] = ItemType.BlackBanner; + mappings[1230] = ItemType.EndCrystal; + mappings[1231] = ItemType.ChorusFruit; + mappings[1232] = ItemType.PoppedChorusFruit; + mappings[1233] = ItemType.TorchflowerSeeds; + mappings[1234] = ItemType.PitcherPod; + mappings[1235] = ItemType.Beetroot; + mappings[1236] = ItemType.BeetrootSeeds; + mappings[1237] = ItemType.BeetrootSoup; + mappings[1238] = ItemType.DragonBreath; + mappings[1239] = ItemType.SplashPotion; + mappings[1240] = ItemType.SpectralArrow; + mappings[1241] = ItemType.TippedArrow; + mappings[1242] = ItemType.LingeringPotion; + mappings[1243] = ItemType.Shield; + mappings[1244] = ItemType.TotemOfUndying; + mappings[1245] = ItemType.ShulkerShell; + mappings[1246] = ItemType.IronNugget; + mappings[1247] = ItemType.KnowledgeBook; + mappings[1248] = ItemType.DebugStick; + mappings[1249] = ItemType.MusicDisc13; + mappings[1250] = ItemType.MusicDiscCat; + mappings[1251] = ItemType.MusicDiscBlocks; + mappings[1252] = ItemType.MusicDiscChirp; + mappings[1253] = ItemType.MusicDiscCreator; + mappings[1254] = ItemType.MusicDiscCreatorMusicBox; + mappings[1255] = ItemType.MusicDiscFar; + mappings[1256] = ItemType.MusicDiscLavaChicken; + mappings[1257] = ItemType.MusicDiscMall; + mappings[1258] = ItemType.MusicDiscMellohi; + mappings[1259] = ItemType.MusicDiscStal; + mappings[1260] = ItemType.MusicDiscStrad; + mappings[1261] = ItemType.MusicDiscWard; + mappings[1262] = ItemType.MusicDisc11; + mappings[1263] = ItemType.MusicDiscWait; + mappings[1264] = ItemType.MusicDiscOtherside; + mappings[1265] = ItemType.MusicDiscRelic; + mappings[1266] = ItemType.MusicDisc5; + mappings[1267] = ItemType.MusicDiscPigstep; + mappings[1268] = ItemType.MusicDiscPrecipice; + mappings[1269] = ItemType.MusicDiscTears; + mappings[1270] = ItemType.DiscFragment5; + mappings[1271] = ItemType.Trident; + mappings[1272] = ItemType.NautilusShell; + mappings[1273] = ItemType.HeartOfTheSea; + mappings[1274] = ItemType.Crossbow; + mappings[1275] = ItemType.SuspiciousStew; + mappings[1276] = ItemType.Loom; + mappings[1277] = ItemType.FlowerBannerPattern; + mappings[1278] = ItemType.CreeperBannerPattern; + mappings[1279] = ItemType.SkullBannerPattern; + mappings[1280] = ItemType.MojangBannerPattern; + mappings[1281] = ItemType.GlobeBannerPattern; + mappings[1282] = ItemType.PiglinBannerPattern; + mappings[1283] = ItemType.FlowBannerPattern; + mappings[1284] = ItemType.GusterBannerPattern; + mappings[1285] = ItemType.FieldMasonedBannerPattern; + mappings[1286] = ItemType.BordureIndentedBannerPattern; + mappings[1287] = ItemType.GoatHorn; + mappings[1288] = ItemType.Composter; + mappings[1289] = ItemType.Barrel; + mappings[1290] = ItemType.Smoker; + mappings[1291] = ItemType.BlastFurnace; + mappings[1292] = ItemType.CartographyTable; + mappings[1293] = ItemType.FletchingTable; + mappings[1294] = ItemType.Grindstone; + mappings[1295] = ItemType.SmithingTable; + mappings[1296] = ItemType.Stonecutter; + mappings[1297] = ItemType.Bell; + mappings[1298] = ItemType.Lantern; + mappings[1299] = ItemType.SoulLantern; + mappings[1300] = ItemType.SweetBerries; + mappings[1301] = ItemType.GlowBerries; + mappings[1302] = ItemType.Campfire; + mappings[1303] = ItemType.SoulCampfire; + mappings[1304] = ItemType.Shroomlight; + mappings[1305] = ItemType.Honeycomb; + mappings[1306] = ItemType.BeeNest; + mappings[1307] = ItemType.Beehive; + mappings[1308] = ItemType.HoneyBottle; + mappings[1309] = ItemType.HoneycombBlock; + mappings[1310] = ItemType.Lodestone; + mappings[1311] = ItemType.CryingObsidian; + mappings[1312] = ItemType.Blackstone; + mappings[1313] = ItemType.BlackstoneSlab; + mappings[1314] = ItemType.BlackstoneStairs; + mappings[1315] = ItemType.GildedBlackstone; + mappings[1316] = ItemType.PolishedBlackstone; + mappings[1317] = ItemType.PolishedBlackstoneSlab; + mappings[1318] = ItemType.PolishedBlackstoneStairs; + mappings[1319] = ItemType.ChiseledPolishedBlackstone; + mappings[1320] = ItemType.PolishedBlackstoneBricks; + mappings[1321] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1322] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1323] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1324] = ItemType.RespawnAnchor; + mappings[1325] = ItemType.Candle; + mappings[1326] = ItemType.WhiteCandle; + mappings[1327] = ItemType.OrangeCandle; + mappings[1328] = ItemType.MagentaCandle; + mappings[1329] = ItemType.LightBlueCandle; + mappings[1330] = ItemType.YellowCandle; + mappings[1331] = ItemType.LimeCandle; + mappings[1332] = ItemType.PinkCandle; + mappings[1333] = ItemType.GrayCandle; + mappings[1334] = ItemType.LightGrayCandle; + mappings[1335] = ItemType.CyanCandle; + mappings[1336] = ItemType.PurpleCandle; + mappings[1337] = ItemType.BlueCandle; + mappings[1338] = ItemType.BrownCandle; + mappings[1339] = ItemType.GreenCandle; + mappings[1340] = ItemType.RedCandle; + mappings[1341] = ItemType.BlackCandle; + mappings[1342] = ItemType.SmallAmethystBud; + mappings[1343] = ItemType.MediumAmethystBud; + mappings[1344] = ItemType.LargeAmethystBud; + mappings[1345] = ItemType.AmethystCluster; + mappings[1346] = ItemType.PointedDripstone; + mappings[1347] = ItemType.OchreFroglight; + mappings[1348] = ItemType.VerdantFroglight; + mappings[1349] = ItemType.PearlescentFroglight; + mappings[1350] = ItemType.Frogspawn; + mappings[1351] = ItemType.EchoShard; + mappings[1352] = ItemType.Brush; + mappings[1353] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1354] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1355] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1356] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1357] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1358] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1359] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1360] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1361] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1362] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1363] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1364] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1365] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1366] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1367] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1368] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1369] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1370] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1371] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1372] = ItemType.AnglerPotterySherd; + mappings[1373] = ItemType.ArcherPotterySherd; + mappings[1374] = ItemType.ArmsUpPotterySherd; + mappings[1375] = ItemType.BladePotterySherd; + mappings[1376] = ItemType.BrewerPotterySherd; + mappings[1377] = ItemType.BurnPotterySherd; + mappings[1378] = ItemType.DangerPotterySherd; + mappings[1379] = ItemType.ExplorerPotterySherd; + mappings[1380] = ItemType.FlowPotterySherd; + mappings[1381] = ItemType.FriendPotterySherd; + mappings[1382] = ItemType.GusterPotterySherd; + mappings[1383] = ItemType.HeartPotterySherd; + mappings[1384] = ItemType.HeartbreakPotterySherd; + mappings[1385] = ItemType.HowlPotterySherd; + mappings[1386] = ItemType.MinerPotterySherd; + mappings[1387] = ItemType.MournerPotterySherd; + mappings[1388] = ItemType.PlentyPotterySherd; + mappings[1389] = ItemType.PrizePotterySherd; + mappings[1390] = ItemType.ScrapePotterySherd; + mappings[1391] = ItemType.SheafPotterySherd; + mappings[1392] = ItemType.ShelterPotterySherd; + mappings[1393] = ItemType.SkullPotterySherd; + mappings[1394] = ItemType.SnortPotterySherd; + mappings[1395] = ItemType.CopperGrate; + mappings[1396] = ItemType.ExposedCopperGrate; + mappings[1397] = ItemType.WeatheredCopperGrate; + mappings[1398] = ItemType.OxidizedCopperGrate; + mappings[1399] = ItemType.WaxedCopperGrate; + mappings[1400] = ItemType.WaxedExposedCopperGrate; + mappings[1401] = ItemType.WaxedWeatheredCopperGrate; + mappings[1402] = ItemType.WaxedOxidizedCopperGrate; + mappings[1403] = ItemType.CopperBulb; + mappings[1404] = ItemType.ExposedCopperBulb; + mappings[1405] = ItemType.WeatheredCopperBulb; + mappings[1406] = ItemType.OxidizedCopperBulb; + mappings[1407] = ItemType.WaxedCopperBulb; + mappings[1408] = ItemType.WaxedExposedCopperBulb; + mappings[1409] = ItemType.WaxedWeatheredCopperBulb; + mappings[1410] = ItemType.WaxedOxidizedCopperBulb; + mappings[1411] = ItemType.TrialSpawner; + mappings[1412] = ItemType.TrialKey; + mappings[1413] = ItemType.OminousTrialKey; + mappings[1414] = ItemType.Vault; + mappings[1415] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index a51d9d0f..e739e36a 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -813,6 +813,7 @@ namespace MinecraftClient.Inventory MusicDiscCreator, MusicDiscCreatorMusicBox, MusicDiscFar, + MusicDiscLavaChicken, MusicDiscMall, MusicDiscMellohi, MusicDiscOtherside, diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 9b1bbb57..7cdb194a 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -24,7 +24,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 - <= Protocol18Handler.MC_1_21_6_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.6 + <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.7 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index ee6eda74..9d97d03b 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.21.2"; + public const string MCHighestVersion = "1.21.8"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 256a9472..bcb3f466 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,9 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_6_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_7_Version => throw new NotImplementedException(Translations .exception_palette_packet), - <= Protocol18Handler.MC_1_21_6_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), + <= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), <= Protocol18Handler.MC_1_8_Version => new PacketPalette17(), diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index aefac1f7..f10ee1ed 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -77,6 +77,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_4_Version = 769; internal const int MC_1_21_5_Version = 770; internal const int MC_1_21_6_Version = 771; + internal const int MC_1_21_7_Version = 772; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -128,21 +129,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_6_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_7_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_6_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_7_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_6_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_7_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -151,9 +152,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_6_Version when handler.GetTerrainEnabled() => + > MC_1_21_7_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), - >= MC_1_21_6_Version => new Palette1216(), + >= MC_1_21_6_Version => new Palette1216(), // 1.21.7 blocks unchanged, reuse 1216 >= MC_1_21_5_Version => new Palette1215(), >= MC_1_21_4_Version => new Palette1214(), >= MC_1_21_2_Version => new Palette1212(), @@ -174,9 +175,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_6_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_7_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), - >= MC_1_21_6_Version => new EntityPalette1216(), + >= MC_1_21_6_Version => new EntityPalette1216(), // 1.21.7 entities unchanged, reuse 1216 >= MC_1_21_5_Version => new EntityPalette1215(), >= MC_1_21_4_Version => new EntityPalette1214(), >= MC_1_21_2_Version => new EntityPalette1212(), @@ -201,8 +202,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_6_Version when handler.GetInventoryEnabled() => + > MC_1_21_7_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_7_Version => new ItemPalette1217(), >= MC_1_21_6_Version => new ItemPalette1216(), >= MC_1_21_5_Version => new ItemPalette1215(), >= MC_1_21_4_Version => new ItemPalette1214(), @@ -2659,7 +2661,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_6_Version => throw new NotImplementedException(Translations + > MC_1_21_7_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 7c7d69ba..28ea07b3 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -154,7 +154,7 @@ namespace MinecraftClient.Protocol { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769, 770, 771 + 769, 770, 771, 772 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -362,6 +362,9 @@ namespace MinecraftClient.Protocol return 770; case "1.21.6": return 771; + case "1.21.7": + case "1.21.8": + return 772; default: return 0; } @@ -447,6 +450,7 @@ namespace MinecraftClient.Protocol 769 => "1.21.4", 770 => "1.21.5", 771 => "1.21.6", + 772 => "1.21.7", _ => "0.0" }; } From 2af0409d00b7cd831ab32b461a3b84dd64fe488c Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:04:42 +0800 Subject: [PATCH 071/484] feat: add MC 1.21.9/1.21.10 (protocol 773) version constants and enum values Register protocol 773 for Minecraft 1.21.9 and 1.21.10 (which share the same protocol as a hotfix release). Update MCHighestVersion to 1.21.10. Add 49 new item types (copper tools/armor, shelves, copper chests, copper golem statue variants, oxidized lightning rods, iron chain, etc.), 2 new entity types (CopperGolem, Mannequin), 38 new block materials, 3 new entity metadata serializer types (CopperGolemState, WeatheringCopperState, ResolvableProfile), and 6 new packet types (DebugBlockValue, DebugChunkValue, DebugEntityValue, DebugEvent, GameTestHighlightPos, CodeOfConduct, AcceptCodeOfConduct). Chain item/block renamed to IronChain in 1.21.9; old enum values retained for backward compatibility with older palettes. Made-with: Cursor --- MinecraftClient/Inventory/ItemType.cs | 49 ++++++++++++++ MinecraftClient/Mapping/EntityMetaDataType.cs | 14 +++- MinecraftClient/Mapping/EntityType.cs | 2 + MinecraftClient/Mapping/Material.cs | 64 ++++++++++++++++++- MinecraftClient/Program.cs | 2 +- .../Handlers/ConfigurationPacketTypesIn.cs | 1 + .../Handlers/ConfigurationPacketTypesOut.cs | 1 + .../Protocol/Handlers/PacketTypesIn.cs | 5 ++ .../Protocol/Handlers/Protocol18.cs | 22 ++++--- MinecraftClient/Protocol/ProtocolHandler.cs | 6 +- 10 files changed, 153 insertions(+), 13 deletions(-) diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index e739e36a..479c10fa 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -26,6 +26,7 @@ namespace MinecraftClient.Inventory AcaciaPlanks, AcaciaPressurePlate, AcaciaSapling, + AcaciaShelf, AcaciaSign, AcaciaSlab, AcaciaStairs, @@ -72,6 +73,7 @@ namespace MinecraftClient.Inventory BambooPlanks, BambooPressurePlate, BambooRaft, + BambooShelf, BambooSign, BambooSlab, BambooStairs, @@ -103,6 +105,7 @@ namespace MinecraftClient.Inventory BirchPlanks, BirchPressurePlate, BirchSapling, + BirchShelf, BirchSign, BirchSlab, BirchStairs, @@ -234,6 +237,7 @@ namespace MinecraftClient.Inventory CherryPlanks, CherryPressurePlate, CherrySapling, + CherryShelf, CherrySign, CherrySlab, CherryStairs, @@ -295,12 +299,27 @@ namespace MinecraftClient.Inventory CookedRabbit, CookedSalmon, Cookie, + CopperAxe, CopperBlock, + CopperBoots, CopperBulb, + CopperChest, + CopperChestplate, CopperDoor, + CopperGolemSpawnEgg, + CopperGolemStatue, CopperGrate, + CopperHelmet, + CopperHoe, + CopperHorseArmor, CopperIngot, + CopperLeggings, + CopperNugget, CopperOre, + CopperPickaxe, + CopperShovel, + CopperSword, + CopperTorch, CopperTrapdoor, Cornflower, CowSpawnEgg, @@ -327,6 +346,7 @@ namespace MinecraftClient.Inventory CrimsonPlanks, CrimsonPressurePlate, CrimsonRoots, + CrimsonShelf, CrimsonSign, CrimsonSlab, CrimsonStairs, @@ -371,6 +391,7 @@ namespace MinecraftClient.Inventory DarkOakPlanks, DarkOakPressurePlate, DarkOakSapling, + DarkOakShelf, DarkOakSign, DarkOakSlab, DarkOakStairs, @@ -481,12 +502,15 @@ namespace MinecraftClient.Inventory ExposedChiseledCopper, ExposedCopper, ExposedCopperBulb, + ExposedCopperChest, ExposedCopperDoor, + ExposedCopperGolemStatue, ExposedCopperGrate, ExposedCopperTrapdoor, ExposedCutCopper, ExposedCutCopperSlab, ExposedCutCopperStairs, + ExposedLightningRod, EyeArmorTrimSmithingTemplate, Farmland, Feather, @@ -627,6 +651,7 @@ namespace MinecraftClient.Inventory IronBars, IronBlock, IronBoots, + IronChain, IronChestplate, IronDoor, IronGolemSpawnEgg, @@ -657,6 +682,7 @@ namespace MinecraftClient.Inventory JunglePlanks, JunglePressurePlate, JungleSapling, + JungleShelf, JungleSign, JungleSlab, JungleStairs, @@ -769,6 +795,7 @@ namespace MinecraftClient.Inventory MangrovePressurePlate, MangrovePropagule, MangroveRoots, + MangroveShelf, MangroveSign, MangroveSlab, MangroveStairs, @@ -868,6 +895,7 @@ namespace MinecraftClient.Inventory OakPlanks, OakPressurePlate, OakSapling, + OakShelf, OakSign, OakSlab, OakStairs, @@ -900,12 +928,15 @@ namespace MinecraftClient.Inventory OxidizedChiseledCopper, OxidizedCopper, OxidizedCopperBulb, + OxidizedCopperChest, OxidizedCopperDoor, + OxidizedCopperGolemStatue, OxidizedCopperGrate, OxidizedCopperTrapdoor, OxidizedCutCopper, OxidizedCutCopperSlab, OxidizedCutCopperStairs, + OxidizedLightningRod, PackedIce, PackedMud, Painting, @@ -924,6 +955,7 @@ namespace MinecraftClient.Inventory PaleOakPlanks, PaleOakPressurePlate, PaleOakSapling, + PaleOakShelf, PaleOakSign, PaleOakSlab, PaleOakStairs, @@ -1197,6 +1229,7 @@ namespace MinecraftClient.Inventory SprucePlanks, SprucePressurePlate, SpruceSapling, + SpruceShelf, SpruceSign, SpruceSlab, SpruceStairs, @@ -1319,6 +1352,7 @@ namespace MinecraftClient.Inventory WarpedPlanks, WarpedPressurePlate, WarpedRoots, + WarpedShelf, WarpedSign, WarpedSlab, WarpedStairs, @@ -1329,7 +1363,9 @@ namespace MinecraftClient.Inventory WaxedChiseledCopper, WaxedCopperBlock, WaxedCopperBulb, + WaxedCopperChest, WaxedCopperDoor, + WaxedCopperGolemStatue, WaxedCopperGrate, WaxedCopperTrapdoor, WaxedCutCopper, @@ -1338,40 +1374,53 @@ namespace MinecraftClient.Inventory WaxedExposedChiseledCopper, WaxedExposedCopper, WaxedExposedCopperBulb, + WaxedExposedCopperChest, WaxedExposedCopperDoor, + WaxedExposedCopperGolemStatue, WaxedExposedCopperGrate, WaxedExposedCopperTrapdoor, WaxedExposedCutCopper, WaxedExposedCutCopperSlab, WaxedExposedCutCopperStairs, + WaxedExposedLightningRod, + WaxedLightningRod, WaxedOxidizedChiseledCopper, WaxedOxidizedCopper, WaxedOxidizedCopperBulb, + WaxedOxidizedCopperChest, WaxedOxidizedCopperDoor, + WaxedOxidizedCopperGolemStatue, WaxedOxidizedCopperGrate, WaxedOxidizedCopperTrapdoor, WaxedOxidizedCutCopper, WaxedOxidizedCutCopperSlab, WaxedOxidizedCutCopperStairs, + WaxedOxidizedLightningRod, WaxedWeatheredChiseledCopper, WaxedWeatheredCopper, WaxedWeatheredCopperBulb, + WaxedWeatheredCopperChest, WaxedWeatheredCopperDoor, + WaxedWeatheredCopperGolemStatue, WaxedWeatheredCopperGrate, WaxedWeatheredCopperTrapdoor, WaxedWeatheredCutCopper, WaxedWeatheredCutCopperSlab, WaxedWeatheredCutCopperStairs, + WaxedWeatheredLightningRod, WayfinderArmorTrimSmithingTemplate, WeatheredChiseledCopper, WeatheredCopper, WeatheredCopperBulb, + WeatheredCopperChest, WeatheredCopperDoor, + WeatheredCopperGolemStatue, WeatheredCopperGrate, WeatheredCopperTrapdoor, WeatheredCutCopper, WeatheredCutCopperSlab, WeatheredCutCopperStairs, + WeatheredLightningRod, WeepingVines, WetSponge, Wheat, diff --git a/MinecraftClient/Mapping/EntityMetaDataType.cs b/MinecraftClient/Mapping/EntityMetaDataType.cs index 075bb52d..a9204a8e 100644 --- a/MinecraftClient/Mapping/EntityMetaDataType.cs +++ b/MinecraftClient/Mapping/EntityMetaDataType.cs @@ -98,11 +98,23 @@ public enum EntityMetaDataType /// ArmadilloState, /// + /// VarInt (1.21.9+) + /// + CopperGolemState, + /// + /// VarInt (1.21.9+) + /// + WeatheringCopperState, + /// /// Float x3 /// Vector3, /// /// Float x4 /// - Quaternion + Quaternion, + /// + /// Either<GameProfile, Partial> + PlayerSkin.Patch (1.21.9+) + /// + ResolvableProfile } \ No newline at end of file diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 6e75efce..4dca83f7 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -44,6 +44,7 @@ namespace MinecraftClient.Mapping Chicken, Cod, CommandBlockMinecart, + CopperGolem, Cow, Creaking, CreakingTransient, @@ -99,6 +100,7 @@ namespace MinecraftClient.Mapping MagmaCube, MangroveBoat, MangroveChestBoat, + Mannequin, Marker, Minecart, Mooshroom, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index d0c71840..a34b6d70 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -24,6 +24,7 @@ namespace MinecraftClient.Mapping AcaciaPlanks, AcaciaPressurePlate, AcaciaSapling, + AcaciaShelf, AcaciaSign, AcaciaSlab, AcaciaStairs, @@ -60,6 +61,7 @@ namespace MinecraftClient.Mapping BambooPlanks, BambooPressurePlate, BambooSapling, + BambooShelf, BambooSign, BambooSlab, BambooStairs, @@ -87,6 +89,7 @@ namespace MinecraftClient.Mapping BirchPlanks, BirchPressurePlate, BirchSapling, + BirchShelf, BirchSign, BirchSlab, BirchStairs, @@ -190,6 +193,7 @@ namespace MinecraftClient.Mapping CherryPlanks, CherryPressurePlate, CherrySapling, + CherryShelf, CherrySign, CherrySlab, CherryStairs, @@ -232,12 +236,19 @@ namespace MinecraftClient.Mapping Comparator, Composter, Conduit, + CopperBars, CopperBlock, CopperBulb, + CopperChain, + CopperChest, CopperDoor, + CopperGolemStatue, CopperGrate, + CopperLantern, CopperOre, + CopperTorch, CopperTrapdoor, + CopperWallTorch, Cornflower, CrackedDeepslateBricks, CrackedDeepslateTiles, @@ -260,6 +271,7 @@ namespace MinecraftClient.Mapping CrimsonPlanks, CrimsonPressurePlate, CrimsonRoots, + CrimsonShelf, CrimsonSign, CrimsonSlab, CrimsonStairs, @@ -301,6 +313,7 @@ namespace MinecraftClient.Mapping DarkOakPlanks, DarkOakPressurePlate, DarkOakSapling, + DarkOakShelf, DarkOakSign, DarkOakSlab, DarkOakStairs, @@ -383,13 +396,19 @@ namespace MinecraftClient.Mapping EnderChest, ExposedChiseledCopper, ExposedCopper, + ExposedCopperBars, ExposedCopperBulb, + ExposedCopperChain, + ExposedCopperChest, ExposedCopperDoor, + ExposedCopperGolemStatue, ExposedCopperGrate, + ExposedCopperLantern, ExposedCopperTrapdoor, ExposedCutCopper, ExposedCutCopperSlab, ExposedCutCopperStairs, + ExposedLightningRod, Farmland, Fern, Fire, @@ -468,6 +487,7 @@ namespace MinecraftClient.Mapping InfestedStoneBricks, IronBars, IronBlock, + IronChain, IronDoor, IronOre, IronTrapdoor, @@ -484,6 +504,7 @@ namespace MinecraftClient.Mapping JunglePlanks, JunglePressurePlate, JungleSapling, + JungleShelf, JungleSign, JungleSlab, JungleStairs, @@ -580,6 +601,7 @@ namespace MinecraftClient.Mapping MangrovePressurePlate, MangrovePropagule, MangroveRoots, + MangroveShelf, MangroveSign, MangroveSlab, MangroveStairs, @@ -633,6 +655,7 @@ namespace MinecraftClient.Mapping OakPlanks, OakPressurePlate, OakSapling, + OakShelf, OakSign, OakSlab, OakStairs, @@ -662,13 +685,19 @@ namespace MinecraftClient.Mapping OxeyeDaisy, OxidizedChiseledCopper, OxidizedCopper, + OxidizedCopperBars, OxidizedCopperBulb, + OxidizedCopperChain, + OxidizedCopperChest, OxidizedCopperDoor, + OxidizedCopperGolemStatue, OxidizedCopperGrate, + OxidizedCopperLantern, OxidizedCopperTrapdoor, OxidizedCutCopper, OxidizedCutCopperSlab, OxidizedCutCopperStairs, + OxidizedLightningRod, PackedIce, PackedMud, PaleHangingMoss, @@ -684,6 +713,7 @@ namespace MinecraftClient.Mapping PaleOakPlanks, PaleOakPressurePlate, PaleOakSapling, + PaleOakShelf, PaleOakSign, PaleOakSlab, PaleOakStairs, @@ -930,6 +960,7 @@ namespace MinecraftClient.Mapping SprucePlanks, SprucePressurePlate, SpruceSapling, + SpruceShelf, SpruceSign, SpruceSlab, SpruceStairs, @@ -1025,6 +1056,7 @@ namespace MinecraftClient.Mapping WarpedPlanks, WarpedPressurePlate, WarpedRoots, + WarpedShelf, WarpedSign, WarpedSlab, WarpedStairs, @@ -1036,50 +1068,80 @@ namespace MinecraftClient.Mapping Water, WaterCauldron, WaxedChiseledCopper, + WaxedCopperBars, WaxedCopperBlock, WaxedCopperBulb, + WaxedCopperChain, + WaxedCopperChest, WaxedCopperDoor, + WaxedCopperGolemStatue, WaxedCopperGrate, + WaxedCopperLantern, WaxedCopperTrapdoor, WaxedCutCopper, WaxedCutCopperSlab, WaxedCutCopperStairs, WaxedExposedChiseledCopper, WaxedExposedCopper, + WaxedExposedCopperBars, WaxedExposedCopperBulb, + WaxedExposedCopperChain, + WaxedExposedCopperChest, WaxedExposedCopperDoor, + WaxedExposedCopperGolemStatue, WaxedExposedCopperGrate, + WaxedExposedCopperLantern, WaxedExposedCopperTrapdoor, WaxedExposedCutCopper, WaxedExposedCutCopperSlab, WaxedExposedCutCopperStairs, + WaxedExposedLightningRod, + WaxedLightningRod, WaxedOxidizedChiseledCopper, WaxedOxidizedCopper, + WaxedOxidizedCopperBars, WaxedOxidizedCopperBulb, + WaxedOxidizedCopperChain, + WaxedOxidizedCopperChest, WaxedOxidizedCopperDoor, + WaxedOxidizedCopperGolemStatue, WaxedOxidizedCopperGrate, + WaxedOxidizedCopperLantern, WaxedOxidizedCopperTrapdoor, WaxedOxidizedCutCopper, WaxedOxidizedCutCopperSlab, WaxedOxidizedCutCopperStairs, + WaxedOxidizedLightningRod, WaxedWeatheredChiseledCopper, WaxedWeatheredCopper, + WaxedWeatheredCopperBars, WaxedWeatheredCopperBulb, + WaxedWeatheredCopperChain, + WaxedWeatheredCopperChest, WaxedWeatheredCopperDoor, + WaxedWeatheredCopperGolemStatue, WaxedWeatheredCopperGrate, + WaxedWeatheredCopperLantern, WaxedWeatheredCopperTrapdoor, WaxedWeatheredCutCopper, WaxedWeatheredCutCopperSlab, WaxedWeatheredCutCopperStairs, + WaxedWeatheredLightningRod, WeatheredChiseledCopper, WeatheredCopper, + WeatheredCopperBars, WeatheredCopperBulb, + WeatheredCopperChain, + WeatheredCopperChest, WeatheredCopperDoor, + WeatheredCopperGolemStatue, WeatheredCopperGrate, + WeatheredCopperLantern, WeatheredCopperTrapdoor, WeatheredCutCopper, WeatheredCutCopperSlab, WeatheredCutCopperStairs, + WeatheredLightningRod, WeepingVines, WeepingVinesPlant, WetSponge, @@ -1120,4 +1182,4 @@ namespace MinecraftClient.Mapping ZombieHead, ZombieWallHead, } -} +} \ No newline at end of file diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 9d97d03b..ee448708 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.21.8"; + public const string MCHighestVersion = "1.21.10"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs index edc48e82..f3b4be23 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs @@ -21,6 +21,7 @@ public enum ConfigurationPacketTypesIn UpdateTags, ClearDialog, // Added in 1.21.6 ShowDialog, // Added in 1.21.6 + CodeOfConduct, // Added in 1.21.9 Unknown } diff --git a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs index d3f7dd0b..30b7c909 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesOut.cs @@ -11,6 +11,7 @@ public enum ConfigurationPacketTypesOut CookieResponse, KnownDataPacks, CustomClickAction, // Added in 1.21.6 + AcceptCodeOfConduct, // Added in 1.21.9 Unknown } \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 7e257b27..5ff6ad2e 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -164,5 +164,10 @@ namespace MinecraftClient.Protocol.Handlers Waypoint, // Added in 1.21.6 ClearDialog, // Added in 1.21.6 ShowDialog, // Added in 1.21.6 + DebugBlockValue, // Added in 1.21.9 + DebugChunkValue, // Added in 1.21.9 + DebugEntityValue, // Added in 1.21.9 + DebugEvent, // Added in 1.21.9 + GameTestHighlightPos, // Added in 1.21.9 } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index f10ee1ed..6d102808 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -78,6 +78,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_5_Version = 770; internal const int MC_1_21_6_Version = 771; internal const int MC_1_21_7_Version = 772; + internal const int MC_1_21_9_Version = 773; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -129,21 +130,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_7_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_9_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_7_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_9_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_7_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_9_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -152,9 +153,10 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_7_Version when handler.GetTerrainEnabled() => + > MC_1_21_9_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), - >= MC_1_21_6_Version => new Palette1216(), // 1.21.7 blocks unchanged, reuse 1216 + >= MC_1_21_9_Version => new Palette1219(), + >= MC_1_21_6_Version => new Palette1216(), // 1.21.7/1.21.8 blocks unchanged, reuse 1216 >= MC_1_21_5_Version => new Palette1215(), >= MC_1_21_4_Version => new Palette1214(), >= MC_1_21_2_Version => new Palette1212(), @@ -175,9 +177,10 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_7_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_9_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), - >= MC_1_21_6_Version => new EntityPalette1216(), // 1.21.7 entities unchanged, reuse 1216 + >= MC_1_21_9_Version => new EntityPalette1219(), + >= MC_1_21_6_Version => new EntityPalette1216(), // 1.21.7/1.21.8 entities unchanged, reuse 1216 >= MC_1_21_5_Version => new EntityPalette1215(), >= MC_1_21_4_Version => new EntityPalette1214(), >= MC_1_21_2_Version => new EntityPalette1212(), @@ -202,8 +205,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_7_Version when handler.GetInventoryEnabled() => + > MC_1_21_9_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_9_Version => new ItemPalette1219(), >= MC_1_21_7_Version => new ItemPalette1217(), >= MC_1_21_6_Version => new ItemPalette1216(), >= MC_1_21_5_Version => new ItemPalette1215(), @@ -2661,7 +2665,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_7_Version => throw new NotImplementedException(Translations + > MC_1_21_9_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 28ea07b3..a71b9122 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -154,7 +154,7 @@ namespace MinecraftClient.Protocol { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769, 770, 771, 772 + 769, 770, 771, 772, 773 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -365,6 +365,9 @@ namespace MinecraftClient.Protocol case "1.21.7": case "1.21.8": return 772; + case "1.21.9": + case "1.21.10": + return 773; default: return 0; } @@ -451,6 +454,7 @@ namespace MinecraftClient.Protocol 770 => "1.21.5", 771 => "1.21.6", 772 => "1.21.7", + 773 => "1.21.9", _ => "0.0" }; } From 67ad5fcf97b2e3649b9df7adeb0f832a0211bbec Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:04:56 +0800 Subject: [PATCH 072/484] feat: add palettes for MC 1.21.9/1.21.10 (protocol 773) - Palette1219.cs: 1053 blocks with new copper chests, copper golem statues, copper torches, shelves, oxidized lightning rods, iron chain - EntityPalette1219.cs: 153 entities (+copper_golem at 27, mannequin at 82) - ItemPalette1219.cs: 1464 items (generated via gen_item_palette.py) - EntityMetadataPalette1219.cs: 37 serializers (COMPOUND_TAG removed, +CopperGolemState, WeatheringCopperState, ResolvableProfile) - PacketPalette1219.cs: updated clientbound IDs for 4 new debug packets and GameTestHighlightPos, plus config CodeOfConduct/AcceptCodeOfConduct Also update gen_entity_metadata_palette.py FIELD_TO_ENUM with the three new serializer type mappings. Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1219.cs | 1482 +++++++++++++ .../Mapping/BlockPalettes/Palette1219.cs | 1961 +++++++++++++++++ .../EntityMetadataPalette1219.cs | 52 + .../EntityPalettes/EntityPalette1219.cs | 171 ++ .../PacketPalettes/PacketPalette1219.cs | 262 +++ tools/gen_entity_metadata_palette.py | 3 + 6 files changed, 3931 insertions(+) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette1219.cs create mode 100644 MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1219.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette1219.cs create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1219.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs new file mode 100644 index 00000000..dc85be12 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs @@ -0,0 +1,1482 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette1219 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette1219() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.DryShortGrass; + mappings[210] = ItemType.DryTallGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.OpenEyeblossom; + mappings[231] = ItemType.ClosedEyeblossom; + mappings[232] = ItemType.Poppy; + mappings[233] = ItemType.BlueOrchid; + mappings[234] = ItemType.Allium; + mappings[235] = ItemType.AzureBluet; + mappings[236] = ItemType.RedTulip; + mappings[237] = ItemType.OrangeTulip; + mappings[238] = ItemType.WhiteTulip; + mappings[239] = ItemType.PinkTulip; + mappings[240] = ItemType.OxeyeDaisy; + mappings[241] = ItemType.Cornflower; + mappings[242] = ItemType.LilyOfTheValley; + mappings[243] = ItemType.WitherRose; + mappings[244] = ItemType.Torchflower; + mappings[245] = ItemType.PitcherPlant; + mappings[246] = ItemType.SporeBlossom; + mappings[247] = ItemType.BrownMushroom; + mappings[248] = ItemType.RedMushroom; + mappings[249] = ItemType.CrimsonFungus; + mappings[250] = ItemType.WarpedFungus; + mappings[251] = ItemType.CrimsonRoots; + mappings[252] = ItemType.WarpedRoots; + mappings[253] = ItemType.NetherSprouts; + mappings[254] = ItemType.WeepingVines; + mappings[255] = ItemType.TwistingVines; + mappings[256] = ItemType.SugarCane; + mappings[257] = ItemType.Kelp; + mappings[258] = ItemType.PinkPetals; + mappings[259] = ItemType.Wildflowers; + mappings[260] = ItemType.LeafLitter; + mappings[261] = ItemType.MossCarpet; + mappings[262] = ItemType.MossBlock; + mappings[263] = ItemType.PaleMossCarpet; + mappings[264] = ItemType.PaleHangingMoss; + mappings[265] = ItemType.PaleMossBlock; + mappings[266] = ItemType.HangingRoots; + mappings[267] = ItemType.BigDripleaf; + mappings[268] = ItemType.SmallDripleaf; + mappings[269] = ItemType.Bamboo; + mappings[270] = ItemType.OakSlab; + mappings[271] = ItemType.SpruceSlab; + mappings[272] = ItemType.BirchSlab; + mappings[273] = ItemType.JungleSlab; + mappings[274] = ItemType.AcaciaSlab; + mappings[275] = ItemType.CherrySlab; + mappings[276] = ItemType.DarkOakSlab; + mappings[277] = ItemType.PaleOakSlab; + mappings[278] = ItemType.MangroveSlab; + mappings[279] = ItemType.BambooSlab; + mappings[280] = ItemType.BambooMosaicSlab; + mappings[281] = ItemType.CrimsonSlab; + mappings[282] = ItemType.WarpedSlab; + mappings[283] = ItemType.StoneSlab; + mappings[284] = ItemType.SmoothStoneSlab; + mappings[285] = ItemType.SandstoneSlab; + mappings[286] = ItemType.CutSandstoneSlab; + mappings[287] = ItemType.PetrifiedOakSlab; + mappings[288] = ItemType.CobblestoneSlab; + mappings[289] = ItemType.BrickSlab; + mappings[290] = ItemType.StoneBrickSlab; + mappings[291] = ItemType.MudBrickSlab; + mappings[292] = ItemType.NetherBrickSlab; + mappings[293] = ItemType.QuartzSlab; + mappings[294] = ItemType.RedSandstoneSlab; + mappings[295] = ItemType.CutRedSandstoneSlab; + mappings[296] = ItemType.PurpurSlab; + mappings[297] = ItemType.PrismarineSlab; + mappings[298] = ItemType.PrismarineBrickSlab; + mappings[299] = ItemType.DarkPrismarineSlab; + mappings[300] = ItemType.SmoothQuartz; + mappings[301] = ItemType.SmoothRedSandstone; + mappings[302] = ItemType.SmoothSandstone; + mappings[303] = ItemType.SmoothStone; + mappings[304] = ItemType.Bricks; + mappings[305] = ItemType.AcaciaShelf; + mappings[306] = ItemType.BambooShelf; + mappings[307] = ItemType.BirchShelf; + mappings[308] = ItemType.CherryShelf; + mappings[309] = ItemType.CrimsonShelf; + mappings[310] = ItemType.DarkOakShelf; + mappings[311] = ItemType.JungleShelf; + mappings[312] = ItemType.MangroveShelf; + mappings[313] = ItemType.OakShelf; + mappings[314] = ItemType.PaleOakShelf; + mappings[315] = ItemType.SpruceShelf; + mappings[316] = ItemType.WarpedShelf; + mappings[317] = ItemType.Bookshelf; + mappings[318] = ItemType.ChiseledBookshelf; + mappings[319] = ItemType.DecoratedPot; + mappings[320] = ItemType.MossyCobblestone; + mappings[321] = ItemType.Obsidian; + mappings[322] = ItemType.Torch; + mappings[323] = ItemType.EndRod; + mappings[324] = ItemType.ChorusPlant; + mappings[325] = ItemType.ChorusFlower; + mappings[326] = ItemType.PurpurBlock; + mappings[327] = ItemType.PurpurPillar; + mappings[328] = ItemType.PurpurStairs; + mappings[329] = ItemType.Spawner; + mappings[330] = ItemType.CreakingHeart; + mappings[331] = ItemType.Chest; + mappings[332] = ItemType.CraftingTable; + mappings[333] = ItemType.Farmland; + mappings[334] = ItemType.Furnace; + mappings[335] = ItemType.Ladder; + mappings[336] = ItemType.CobblestoneStairs; + mappings[337] = ItemType.Snow; + mappings[338] = ItemType.Ice; + mappings[339] = ItemType.SnowBlock; + mappings[340] = ItemType.Cactus; + mappings[341] = ItemType.CactusFlower; + mappings[342] = ItemType.Clay; + mappings[343] = ItemType.Jukebox; + mappings[344] = ItemType.OakFence; + mappings[345] = ItemType.SpruceFence; + mappings[346] = ItemType.BirchFence; + mappings[347] = ItemType.JungleFence; + mappings[348] = ItemType.AcaciaFence; + mappings[349] = ItemType.CherryFence; + mappings[350] = ItemType.DarkOakFence; + mappings[351] = ItemType.PaleOakFence; + mappings[352] = ItemType.MangroveFence; + mappings[353] = ItemType.BambooFence; + mappings[354] = ItemType.CrimsonFence; + mappings[355] = ItemType.WarpedFence; + mappings[356] = ItemType.Pumpkin; + mappings[357] = ItemType.CarvedPumpkin; + mappings[358] = ItemType.JackOLantern; + mappings[359] = ItemType.Netherrack; + mappings[360] = ItemType.SoulSand; + mappings[361] = ItemType.SoulSoil; + mappings[362] = ItemType.Basalt; + mappings[363] = ItemType.PolishedBasalt; + mappings[364] = ItemType.SmoothBasalt; + mappings[365] = ItemType.SoulTorch; + mappings[366] = ItemType.CopperTorch; + mappings[367] = ItemType.Glowstone; + mappings[368] = ItemType.InfestedStone; + mappings[369] = ItemType.InfestedCobblestone; + mappings[370] = ItemType.InfestedStoneBricks; + mappings[371] = ItemType.InfestedMossyStoneBricks; + mappings[372] = ItemType.InfestedCrackedStoneBricks; + mappings[373] = ItemType.InfestedChiseledStoneBricks; + mappings[374] = ItemType.InfestedDeepslate; + mappings[375] = ItemType.StoneBricks; + mappings[376] = ItemType.MossyStoneBricks; + mappings[377] = ItemType.CrackedStoneBricks; + mappings[378] = ItemType.ChiseledStoneBricks; + mappings[379] = ItemType.PackedMud; + mappings[380] = ItemType.MudBricks; + mappings[381] = ItemType.DeepslateBricks; + mappings[382] = ItemType.CrackedDeepslateBricks; + mappings[383] = ItemType.DeepslateTiles; + mappings[384] = ItemType.CrackedDeepslateTiles; + mappings[385] = ItemType.ChiseledDeepslate; + mappings[386] = ItemType.ReinforcedDeepslate; + mappings[387] = ItemType.BrownMushroomBlock; + mappings[388] = ItemType.RedMushroomBlock; + mappings[389] = ItemType.MushroomStem; + mappings[390] = ItemType.IronBars; + mappings[391] = ItemType.IronChain; + mappings[392] = ItemType.GlassPane; + mappings[393] = ItemType.Melon; + mappings[394] = ItemType.Vine; + mappings[395] = ItemType.GlowLichen; + mappings[396] = ItemType.ResinClump; + mappings[397] = ItemType.ResinBlock; + mappings[398] = ItemType.ResinBricks; + mappings[399] = ItemType.ResinBrickStairs; + mappings[400] = ItemType.ResinBrickSlab; + mappings[401] = ItemType.ResinBrickWall; + mappings[402] = ItemType.ChiseledResinBricks; + mappings[403] = ItemType.BrickStairs; + mappings[404] = ItemType.StoneBrickStairs; + mappings[405] = ItemType.MudBrickStairs; + mappings[406] = ItemType.Mycelium; + mappings[407] = ItemType.LilyPad; + mappings[408] = ItemType.NetherBricks; + mappings[409] = ItemType.CrackedNetherBricks; + mappings[410] = ItemType.ChiseledNetherBricks; + mappings[411] = ItemType.NetherBrickFence; + mappings[412] = ItemType.NetherBrickStairs; + mappings[413] = ItemType.Sculk; + mappings[414] = ItemType.SculkVein; + mappings[415] = ItemType.SculkCatalyst; + mappings[416] = ItemType.SculkShrieker; + mappings[417] = ItemType.EnchantingTable; + mappings[418] = ItemType.EndPortalFrame; + mappings[419] = ItemType.EndStone; + mappings[420] = ItemType.EndStoneBricks; + mappings[421] = ItemType.DragonEgg; + mappings[422] = ItemType.SandstoneStairs; + mappings[423] = ItemType.EnderChest; + mappings[424] = ItemType.EmeraldBlock; + mappings[425] = ItemType.OakStairs; + mappings[426] = ItemType.SpruceStairs; + mappings[427] = ItemType.BirchStairs; + mappings[428] = ItemType.JungleStairs; + mappings[429] = ItemType.AcaciaStairs; + mappings[430] = ItemType.CherryStairs; + mappings[431] = ItemType.DarkOakStairs; + mappings[432] = ItemType.PaleOakStairs; + mappings[433] = ItemType.MangroveStairs; + mappings[434] = ItemType.BambooStairs; + mappings[435] = ItemType.BambooMosaicStairs; + mappings[436] = ItemType.CrimsonStairs; + mappings[437] = ItemType.WarpedStairs; + mappings[438] = ItemType.CommandBlock; + mappings[439] = ItemType.Beacon; + mappings[440] = ItemType.CobblestoneWall; + mappings[441] = ItemType.MossyCobblestoneWall; + mappings[442] = ItemType.BrickWall; + mappings[443] = ItemType.PrismarineWall; + mappings[444] = ItemType.RedSandstoneWall; + mappings[445] = ItemType.MossyStoneBrickWall; + mappings[446] = ItemType.GraniteWall; + mappings[447] = ItemType.StoneBrickWall; + mappings[448] = ItemType.MudBrickWall; + mappings[449] = ItemType.NetherBrickWall; + mappings[450] = ItemType.AndesiteWall; + mappings[451] = ItemType.RedNetherBrickWall; + mappings[452] = ItemType.SandstoneWall; + mappings[453] = ItemType.EndStoneBrickWall; + mappings[454] = ItemType.DioriteWall; + mappings[455] = ItemType.BlackstoneWall; + mappings[456] = ItemType.PolishedBlackstoneWall; + mappings[457] = ItemType.PolishedBlackstoneBrickWall; + mappings[458] = ItemType.CobbledDeepslateWall; + mappings[459] = ItemType.PolishedDeepslateWall; + mappings[460] = ItemType.DeepslateBrickWall; + mappings[461] = ItemType.DeepslateTileWall; + mappings[462] = ItemType.Anvil; + mappings[463] = ItemType.ChippedAnvil; + mappings[464] = ItemType.DamagedAnvil; + mappings[465] = ItemType.ChiseledQuartzBlock; + mappings[466] = ItemType.QuartzBlock; + mappings[467] = ItemType.QuartzBricks; + mappings[468] = ItemType.QuartzPillar; + mappings[469] = ItemType.QuartzStairs; + mappings[470] = ItemType.WhiteTerracotta; + mappings[471] = ItemType.OrangeTerracotta; + mappings[472] = ItemType.MagentaTerracotta; + mappings[473] = ItemType.LightBlueTerracotta; + mappings[474] = ItemType.YellowTerracotta; + mappings[475] = ItemType.LimeTerracotta; + mappings[476] = ItemType.PinkTerracotta; + mappings[477] = ItemType.GrayTerracotta; + mappings[478] = ItemType.LightGrayTerracotta; + mappings[479] = ItemType.CyanTerracotta; + mappings[480] = ItemType.PurpleTerracotta; + mappings[481] = ItemType.BlueTerracotta; + mappings[482] = ItemType.BrownTerracotta; + mappings[483] = ItemType.GreenTerracotta; + mappings[484] = ItemType.RedTerracotta; + mappings[485] = ItemType.BlackTerracotta; + mappings[486] = ItemType.Barrier; + mappings[487] = ItemType.Light; + mappings[488] = ItemType.HayBlock; + mappings[489] = ItemType.WhiteCarpet; + mappings[490] = ItemType.OrangeCarpet; + mappings[491] = ItemType.MagentaCarpet; + mappings[492] = ItemType.LightBlueCarpet; + mappings[493] = ItemType.YellowCarpet; + mappings[494] = ItemType.LimeCarpet; + mappings[495] = ItemType.PinkCarpet; + mappings[496] = ItemType.GrayCarpet; + mappings[497] = ItemType.LightGrayCarpet; + mappings[498] = ItemType.CyanCarpet; + mappings[499] = ItemType.PurpleCarpet; + mappings[500] = ItemType.BlueCarpet; + mappings[501] = ItemType.BrownCarpet; + mappings[502] = ItemType.GreenCarpet; + mappings[503] = ItemType.RedCarpet; + mappings[504] = ItemType.BlackCarpet; + mappings[505] = ItemType.Terracotta; + mappings[506] = ItemType.PackedIce; + mappings[507] = ItemType.DirtPath; + mappings[508] = ItemType.Sunflower; + mappings[509] = ItemType.Lilac; + mappings[510] = ItemType.RoseBush; + mappings[511] = ItemType.Peony; + mappings[512] = ItemType.TallGrass; + mappings[513] = ItemType.LargeFern; + mappings[514] = ItemType.WhiteStainedGlass; + mappings[515] = ItemType.OrangeStainedGlass; + mappings[516] = ItemType.MagentaStainedGlass; + mappings[517] = ItemType.LightBlueStainedGlass; + mappings[518] = ItemType.YellowStainedGlass; + mappings[519] = ItemType.LimeStainedGlass; + mappings[520] = ItemType.PinkStainedGlass; + mappings[521] = ItemType.GrayStainedGlass; + mappings[522] = ItemType.LightGrayStainedGlass; + mappings[523] = ItemType.CyanStainedGlass; + mappings[524] = ItemType.PurpleStainedGlass; + mappings[525] = ItemType.BlueStainedGlass; + mappings[526] = ItemType.BrownStainedGlass; + mappings[527] = ItemType.GreenStainedGlass; + mappings[528] = ItemType.RedStainedGlass; + mappings[529] = ItemType.BlackStainedGlass; + mappings[530] = ItemType.WhiteStainedGlassPane; + mappings[531] = ItemType.OrangeStainedGlassPane; + mappings[532] = ItemType.MagentaStainedGlassPane; + mappings[533] = ItemType.LightBlueStainedGlassPane; + mappings[534] = ItemType.YellowStainedGlassPane; + mappings[535] = ItemType.LimeStainedGlassPane; + mappings[536] = ItemType.PinkStainedGlassPane; + mappings[537] = ItemType.GrayStainedGlassPane; + mappings[538] = ItemType.LightGrayStainedGlassPane; + mappings[539] = ItemType.CyanStainedGlassPane; + mappings[540] = ItemType.PurpleStainedGlassPane; + mappings[541] = ItemType.BlueStainedGlassPane; + mappings[542] = ItemType.BrownStainedGlassPane; + mappings[543] = ItemType.GreenStainedGlassPane; + mappings[544] = ItemType.RedStainedGlassPane; + mappings[545] = ItemType.BlackStainedGlassPane; + mappings[546] = ItemType.Prismarine; + mappings[547] = ItemType.PrismarineBricks; + mappings[548] = ItemType.DarkPrismarine; + mappings[549] = ItemType.PrismarineStairs; + mappings[550] = ItemType.PrismarineBrickStairs; + mappings[551] = ItemType.DarkPrismarineStairs; + mappings[552] = ItemType.SeaLantern; + mappings[553] = ItemType.RedSandstone; + mappings[554] = ItemType.ChiseledRedSandstone; + mappings[555] = ItemType.CutRedSandstone; + mappings[556] = ItemType.RedSandstoneStairs; + mappings[557] = ItemType.RepeatingCommandBlock; + mappings[558] = ItemType.ChainCommandBlock; + mappings[559] = ItemType.MagmaBlock; + mappings[560] = ItemType.NetherWartBlock; + mappings[561] = ItemType.WarpedWartBlock; + mappings[562] = ItemType.RedNetherBricks; + mappings[563] = ItemType.BoneBlock; + mappings[564] = ItemType.StructureVoid; + mappings[565] = ItemType.ShulkerBox; + mappings[566] = ItemType.WhiteShulkerBox; + mappings[567] = ItemType.OrangeShulkerBox; + mappings[568] = ItemType.MagentaShulkerBox; + mappings[569] = ItemType.LightBlueShulkerBox; + mappings[570] = ItemType.YellowShulkerBox; + mappings[571] = ItemType.LimeShulkerBox; + mappings[572] = ItemType.PinkShulkerBox; + mappings[573] = ItemType.GrayShulkerBox; + mappings[574] = ItemType.LightGrayShulkerBox; + mappings[575] = ItemType.CyanShulkerBox; + mappings[576] = ItemType.PurpleShulkerBox; + mappings[577] = ItemType.BlueShulkerBox; + mappings[578] = ItemType.BrownShulkerBox; + mappings[579] = ItemType.GreenShulkerBox; + mappings[580] = ItemType.RedShulkerBox; + mappings[581] = ItemType.BlackShulkerBox; + mappings[582] = ItemType.WhiteGlazedTerracotta; + mappings[583] = ItemType.OrangeGlazedTerracotta; + mappings[584] = ItemType.MagentaGlazedTerracotta; + mappings[585] = ItemType.LightBlueGlazedTerracotta; + mappings[586] = ItemType.YellowGlazedTerracotta; + mappings[587] = ItemType.LimeGlazedTerracotta; + mappings[588] = ItemType.PinkGlazedTerracotta; + mappings[589] = ItemType.GrayGlazedTerracotta; + mappings[590] = ItemType.LightGrayGlazedTerracotta; + mappings[591] = ItemType.CyanGlazedTerracotta; + mappings[592] = ItemType.PurpleGlazedTerracotta; + mappings[593] = ItemType.BlueGlazedTerracotta; + mappings[594] = ItemType.BrownGlazedTerracotta; + mappings[595] = ItemType.GreenGlazedTerracotta; + mappings[596] = ItemType.RedGlazedTerracotta; + mappings[597] = ItemType.BlackGlazedTerracotta; + mappings[598] = ItemType.WhiteConcrete; + mappings[599] = ItemType.OrangeConcrete; + mappings[600] = ItemType.MagentaConcrete; + mappings[601] = ItemType.LightBlueConcrete; + mappings[602] = ItemType.YellowConcrete; + mappings[603] = ItemType.LimeConcrete; + mappings[604] = ItemType.PinkConcrete; + mappings[605] = ItemType.GrayConcrete; + mappings[606] = ItemType.LightGrayConcrete; + mappings[607] = ItemType.CyanConcrete; + mappings[608] = ItemType.PurpleConcrete; + mappings[609] = ItemType.BlueConcrete; + mappings[610] = ItemType.BrownConcrete; + mappings[611] = ItemType.GreenConcrete; + mappings[612] = ItemType.RedConcrete; + mappings[613] = ItemType.BlackConcrete; + mappings[614] = ItemType.WhiteConcretePowder; + mappings[615] = ItemType.OrangeConcretePowder; + mappings[616] = ItemType.MagentaConcretePowder; + mappings[617] = ItemType.LightBlueConcretePowder; + mappings[618] = ItemType.YellowConcretePowder; + mappings[619] = ItemType.LimeConcretePowder; + mappings[620] = ItemType.PinkConcretePowder; + mappings[621] = ItemType.GrayConcretePowder; + mappings[622] = ItemType.LightGrayConcretePowder; + mappings[623] = ItemType.CyanConcretePowder; + mappings[624] = ItemType.PurpleConcretePowder; + mappings[625] = ItemType.BlueConcretePowder; + mappings[626] = ItemType.BrownConcretePowder; + mappings[627] = ItemType.GreenConcretePowder; + mappings[628] = ItemType.RedConcretePowder; + mappings[629] = ItemType.BlackConcretePowder; + mappings[630] = ItemType.TurtleEgg; + mappings[631] = ItemType.SnifferEgg; + mappings[632] = ItemType.DriedGhast; + mappings[633] = ItemType.DeadTubeCoralBlock; + mappings[634] = ItemType.DeadBrainCoralBlock; + mappings[635] = ItemType.DeadBubbleCoralBlock; + mappings[636] = ItemType.DeadFireCoralBlock; + mappings[637] = ItemType.DeadHornCoralBlock; + mappings[638] = ItemType.TubeCoralBlock; + mappings[639] = ItemType.BrainCoralBlock; + mappings[640] = ItemType.BubbleCoralBlock; + mappings[641] = ItemType.FireCoralBlock; + mappings[642] = ItemType.HornCoralBlock; + mappings[643] = ItemType.TubeCoral; + mappings[644] = ItemType.BrainCoral; + mappings[645] = ItemType.BubbleCoral; + mappings[646] = ItemType.FireCoral; + mappings[647] = ItemType.HornCoral; + mappings[648] = ItemType.DeadBrainCoral; + mappings[649] = ItemType.DeadBubbleCoral; + mappings[650] = ItemType.DeadFireCoral; + mappings[651] = ItemType.DeadHornCoral; + mappings[652] = ItemType.DeadTubeCoral; + mappings[653] = ItemType.TubeCoralFan; + mappings[654] = ItemType.BrainCoralFan; + mappings[655] = ItemType.BubbleCoralFan; + mappings[656] = ItemType.FireCoralFan; + mappings[657] = ItemType.HornCoralFan; + mappings[658] = ItemType.DeadTubeCoralFan; + mappings[659] = ItemType.DeadBrainCoralFan; + mappings[660] = ItemType.DeadBubbleCoralFan; + mappings[661] = ItemType.DeadFireCoralFan; + mappings[662] = ItemType.DeadHornCoralFan; + mappings[663] = ItemType.BlueIce; + mappings[664] = ItemType.Conduit; + mappings[665] = ItemType.PolishedGraniteStairs; + mappings[666] = ItemType.SmoothRedSandstoneStairs; + mappings[667] = ItemType.MossyStoneBrickStairs; + mappings[668] = ItemType.PolishedDioriteStairs; + mappings[669] = ItemType.MossyCobblestoneStairs; + mappings[670] = ItemType.EndStoneBrickStairs; + mappings[671] = ItemType.StoneStairs; + mappings[672] = ItemType.SmoothSandstoneStairs; + mappings[673] = ItemType.SmoothQuartzStairs; + mappings[674] = ItemType.GraniteStairs; + mappings[675] = ItemType.AndesiteStairs; + mappings[676] = ItemType.RedNetherBrickStairs; + mappings[677] = ItemType.PolishedAndesiteStairs; + mappings[678] = ItemType.DioriteStairs; + mappings[679] = ItemType.CobbledDeepslateStairs; + mappings[680] = ItemType.PolishedDeepslateStairs; + mappings[681] = ItemType.DeepslateBrickStairs; + mappings[682] = ItemType.DeepslateTileStairs; + mappings[683] = ItemType.PolishedGraniteSlab; + mappings[684] = ItemType.SmoothRedSandstoneSlab; + mappings[685] = ItemType.MossyStoneBrickSlab; + mappings[686] = ItemType.PolishedDioriteSlab; + mappings[687] = ItemType.MossyCobblestoneSlab; + mappings[688] = ItemType.EndStoneBrickSlab; + mappings[689] = ItemType.SmoothSandstoneSlab; + mappings[690] = ItemType.SmoothQuartzSlab; + mappings[691] = ItemType.GraniteSlab; + mappings[692] = ItemType.AndesiteSlab; + mappings[693] = ItemType.RedNetherBrickSlab; + mappings[694] = ItemType.PolishedAndesiteSlab; + mappings[695] = ItemType.DioriteSlab; + mappings[696] = ItemType.CobbledDeepslateSlab; + mappings[697] = ItemType.PolishedDeepslateSlab; + mappings[698] = ItemType.DeepslateBrickSlab; + mappings[699] = ItemType.DeepslateTileSlab; + mappings[700] = ItemType.Scaffolding; + mappings[701] = ItemType.Redstone; + mappings[702] = ItemType.RedstoneTorch; + mappings[703] = ItemType.RedstoneBlock; + mappings[704] = ItemType.Repeater; + mappings[705] = ItemType.Comparator; + mappings[706] = ItemType.Piston; + mappings[707] = ItemType.StickyPiston; + mappings[708] = ItemType.SlimeBlock; + mappings[709] = ItemType.HoneyBlock; + mappings[710] = ItemType.Observer; + mappings[711] = ItemType.Hopper; + mappings[712] = ItemType.Dispenser; + mappings[713] = ItemType.Dropper; + mappings[714] = ItemType.Lectern; + mappings[715] = ItemType.Target; + mappings[716] = ItemType.Lever; + mappings[717] = ItemType.LightningRod; + mappings[718] = ItemType.ExposedLightningRod; + mappings[719] = ItemType.WeatheredLightningRod; + mappings[720] = ItemType.OxidizedLightningRod; + mappings[721] = ItemType.WaxedLightningRod; + mappings[722] = ItemType.WaxedExposedLightningRod; + mappings[723] = ItemType.WaxedWeatheredLightningRod; + mappings[724] = ItemType.WaxedOxidizedLightningRod; + mappings[725] = ItemType.DaylightDetector; + mappings[726] = ItemType.SculkSensor; + mappings[727] = ItemType.CalibratedSculkSensor; + mappings[728] = ItemType.TripwireHook; + mappings[729] = ItemType.TrappedChest; + mappings[730] = ItemType.Tnt; + mappings[731] = ItemType.RedstoneLamp; + mappings[732] = ItemType.NoteBlock; + mappings[733] = ItemType.StoneButton; + mappings[734] = ItemType.PolishedBlackstoneButton; + mappings[735] = ItemType.OakButton; + mappings[736] = ItemType.SpruceButton; + mappings[737] = ItemType.BirchButton; + mappings[738] = ItemType.JungleButton; + mappings[739] = ItemType.AcaciaButton; + mappings[740] = ItemType.CherryButton; + mappings[741] = ItemType.DarkOakButton; + mappings[742] = ItemType.PaleOakButton; + mappings[743] = ItemType.MangroveButton; + mappings[744] = ItemType.BambooButton; + mappings[745] = ItemType.CrimsonButton; + mappings[746] = ItemType.WarpedButton; + mappings[747] = ItemType.StonePressurePlate; + mappings[748] = ItemType.PolishedBlackstonePressurePlate; + mappings[749] = ItemType.LightWeightedPressurePlate; + mappings[750] = ItemType.HeavyWeightedPressurePlate; + mappings[751] = ItemType.OakPressurePlate; + mappings[752] = ItemType.SprucePressurePlate; + mappings[753] = ItemType.BirchPressurePlate; + mappings[754] = ItemType.JunglePressurePlate; + mappings[755] = ItemType.AcaciaPressurePlate; + mappings[756] = ItemType.CherryPressurePlate; + mappings[757] = ItemType.DarkOakPressurePlate; + mappings[758] = ItemType.PaleOakPressurePlate; + mappings[759] = ItemType.MangrovePressurePlate; + mappings[760] = ItemType.BambooPressurePlate; + mappings[761] = ItemType.CrimsonPressurePlate; + mappings[762] = ItemType.WarpedPressurePlate; + mappings[763] = ItemType.IronDoor; + mappings[764] = ItemType.OakDoor; + mappings[765] = ItemType.SpruceDoor; + mappings[766] = ItemType.BirchDoor; + mappings[767] = ItemType.JungleDoor; + mappings[768] = ItemType.AcaciaDoor; + mappings[769] = ItemType.CherryDoor; + mappings[770] = ItemType.DarkOakDoor; + mappings[771] = ItemType.PaleOakDoor; + mappings[772] = ItemType.MangroveDoor; + mappings[773] = ItemType.BambooDoor; + mappings[774] = ItemType.CrimsonDoor; + mappings[775] = ItemType.WarpedDoor; + mappings[776] = ItemType.CopperDoor; + mappings[777] = ItemType.ExposedCopperDoor; + mappings[778] = ItemType.WeatheredCopperDoor; + mappings[779] = ItemType.OxidizedCopperDoor; + mappings[780] = ItemType.WaxedCopperDoor; + mappings[781] = ItemType.WaxedExposedCopperDoor; + mappings[782] = ItemType.WaxedWeatheredCopperDoor; + mappings[783] = ItemType.WaxedOxidizedCopperDoor; + mappings[784] = ItemType.IronTrapdoor; + mappings[785] = ItemType.OakTrapdoor; + mappings[786] = ItemType.SpruceTrapdoor; + mappings[787] = ItemType.BirchTrapdoor; + mappings[788] = ItemType.JungleTrapdoor; + mappings[789] = ItemType.AcaciaTrapdoor; + mappings[790] = ItemType.CherryTrapdoor; + mappings[791] = ItemType.DarkOakTrapdoor; + mappings[792] = ItemType.PaleOakTrapdoor; + mappings[793] = ItemType.MangroveTrapdoor; + mappings[794] = ItemType.BambooTrapdoor; + mappings[795] = ItemType.CrimsonTrapdoor; + mappings[796] = ItemType.WarpedTrapdoor; + mappings[797] = ItemType.CopperTrapdoor; + mappings[798] = ItemType.ExposedCopperTrapdoor; + mappings[799] = ItemType.WeatheredCopperTrapdoor; + mappings[800] = ItemType.OxidizedCopperTrapdoor; + mappings[801] = ItemType.WaxedCopperTrapdoor; + mappings[802] = ItemType.WaxedExposedCopperTrapdoor; + mappings[803] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[804] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[805] = ItemType.OakFenceGate; + mappings[806] = ItemType.SpruceFenceGate; + mappings[807] = ItemType.BirchFenceGate; + mappings[808] = ItemType.JungleFenceGate; + mappings[809] = ItemType.AcaciaFenceGate; + mappings[810] = ItemType.CherryFenceGate; + mappings[811] = ItemType.DarkOakFenceGate; + mappings[812] = ItemType.PaleOakFenceGate; + mappings[813] = ItemType.MangroveFenceGate; + mappings[814] = ItemType.BambooFenceGate; + mappings[815] = ItemType.CrimsonFenceGate; + mappings[816] = ItemType.WarpedFenceGate; + mappings[817] = ItemType.PoweredRail; + mappings[818] = ItemType.DetectorRail; + mappings[819] = ItemType.Rail; + mappings[820] = ItemType.ActivatorRail; + mappings[821] = ItemType.Saddle; + mappings[822] = ItemType.WhiteHarness; + mappings[823] = ItemType.OrangeHarness; + mappings[824] = ItemType.MagentaHarness; + mappings[825] = ItemType.LightBlueHarness; + mappings[826] = ItemType.YellowHarness; + mappings[827] = ItemType.LimeHarness; + mappings[828] = ItemType.PinkHarness; + mappings[829] = ItemType.GrayHarness; + mappings[830] = ItemType.LightGrayHarness; + mappings[831] = ItemType.CyanHarness; + mappings[832] = ItemType.PurpleHarness; + mappings[833] = ItemType.BlueHarness; + mappings[834] = ItemType.BrownHarness; + mappings[835] = ItemType.GreenHarness; + mappings[836] = ItemType.RedHarness; + mappings[837] = ItemType.BlackHarness; + mappings[838] = ItemType.Minecart; + mappings[839] = ItemType.ChestMinecart; + mappings[840] = ItemType.FurnaceMinecart; + mappings[841] = ItemType.TntMinecart; + mappings[842] = ItemType.HopperMinecart; + mappings[843] = ItemType.CarrotOnAStick; + mappings[844] = ItemType.WarpedFungusOnAStick; + mappings[845] = ItemType.PhantomMembrane; + mappings[846] = ItemType.Elytra; + mappings[847] = ItemType.OakBoat; + mappings[848] = ItemType.OakChestBoat; + mappings[849] = ItemType.SpruceBoat; + mappings[850] = ItemType.SpruceChestBoat; + mappings[851] = ItemType.BirchBoat; + mappings[852] = ItemType.BirchChestBoat; + mappings[853] = ItemType.JungleBoat; + mappings[854] = ItemType.JungleChestBoat; + mappings[855] = ItemType.AcaciaBoat; + mappings[856] = ItemType.AcaciaChestBoat; + mappings[857] = ItemType.CherryBoat; + mappings[858] = ItemType.CherryChestBoat; + mappings[859] = ItemType.DarkOakBoat; + mappings[860] = ItemType.DarkOakChestBoat; + mappings[861] = ItemType.PaleOakBoat; + mappings[862] = ItemType.PaleOakChestBoat; + mappings[863] = ItemType.MangroveBoat; + mappings[864] = ItemType.MangroveChestBoat; + mappings[865] = ItemType.BambooRaft; + mappings[866] = ItemType.BambooChestRaft; + mappings[867] = ItemType.StructureBlock; + mappings[868] = ItemType.Jigsaw; + mappings[869] = ItemType.TestBlock; + mappings[870] = ItemType.TestInstanceBlock; + mappings[871] = ItemType.TurtleHelmet; + mappings[872] = ItemType.TurtleScute; + mappings[873] = ItemType.ArmadilloScute; + mappings[874] = ItemType.WolfArmor; + mappings[875] = ItemType.FlintAndSteel; + mappings[876] = ItemType.Bowl; + mappings[877] = ItemType.Apple; + mappings[878] = ItemType.Bow; + mappings[879] = ItemType.Arrow; + mappings[880] = ItemType.Coal; + mappings[881] = ItemType.Charcoal; + mappings[882] = ItemType.Diamond; + mappings[883] = ItemType.Emerald; + mappings[884] = ItemType.LapisLazuli; + mappings[885] = ItemType.Quartz; + mappings[886] = ItemType.AmethystShard; + mappings[887] = ItemType.RawIron; + mappings[888] = ItemType.IronIngot; + mappings[889] = ItemType.RawCopper; + mappings[890] = ItemType.CopperIngot; + mappings[891] = ItemType.RawGold; + mappings[892] = ItemType.GoldIngot; + mappings[893] = ItemType.NetheriteIngot; + mappings[894] = ItemType.NetheriteScrap; + mappings[895] = ItemType.WoodenSword; + mappings[896] = ItemType.WoodenShovel; + mappings[897] = ItemType.WoodenPickaxe; + mappings[898] = ItemType.WoodenAxe; + mappings[899] = ItemType.WoodenHoe; + mappings[900] = ItemType.CopperSword; + mappings[901] = ItemType.CopperShovel; + mappings[902] = ItemType.CopperPickaxe; + mappings[903] = ItemType.CopperAxe; + mappings[904] = ItemType.CopperHoe; + mappings[905] = ItemType.StoneSword; + mappings[906] = ItemType.StoneShovel; + mappings[907] = ItemType.StonePickaxe; + mappings[908] = ItemType.StoneAxe; + mappings[909] = ItemType.StoneHoe; + mappings[910] = ItemType.GoldenSword; + mappings[911] = ItemType.GoldenShovel; + mappings[912] = ItemType.GoldenPickaxe; + mappings[913] = ItemType.GoldenAxe; + mappings[914] = ItemType.GoldenHoe; + mappings[915] = ItemType.IronSword; + mappings[916] = ItemType.IronShovel; + mappings[917] = ItemType.IronPickaxe; + mappings[918] = ItemType.IronAxe; + mappings[919] = ItemType.IronHoe; + mappings[920] = ItemType.DiamondSword; + mappings[921] = ItemType.DiamondShovel; + mappings[922] = ItemType.DiamondPickaxe; + mappings[923] = ItemType.DiamondAxe; + mappings[924] = ItemType.DiamondHoe; + mappings[925] = ItemType.NetheriteSword; + mappings[926] = ItemType.NetheriteShovel; + mappings[927] = ItemType.NetheritePickaxe; + mappings[928] = ItemType.NetheriteAxe; + mappings[929] = ItemType.NetheriteHoe; + mappings[930] = ItemType.Stick; + mappings[931] = ItemType.MushroomStew; + mappings[932] = ItemType.String; + mappings[933] = ItemType.Feather; + mappings[934] = ItemType.Gunpowder; + mappings[935] = ItemType.WheatSeeds; + mappings[936] = ItemType.Wheat; + mappings[937] = ItemType.Bread; + mappings[938] = ItemType.LeatherHelmet; + mappings[939] = ItemType.LeatherChestplate; + mappings[940] = ItemType.LeatherLeggings; + mappings[941] = ItemType.LeatherBoots; + mappings[942] = ItemType.CopperHelmet; + mappings[943] = ItemType.CopperChestplate; + mappings[944] = ItemType.CopperLeggings; + mappings[945] = ItemType.CopperBoots; + mappings[946] = ItemType.ChainmailHelmet; + mappings[947] = ItemType.ChainmailChestplate; + mappings[948] = ItemType.ChainmailLeggings; + mappings[949] = ItemType.ChainmailBoots; + mappings[950] = ItemType.IronHelmet; + mappings[951] = ItemType.IronChestplate; + mappings[952] = ItemType.IronLeggings; + mappings[953] = ItemType.IronBoots; + mappings[954] = ItemType.DiamondHelmet; + mappings[955] = ItemType.DiamondChestplate; + mappings[956] = ItemType.DiamondLeggings; + mappings[957] = ItemType.DiamondBoots; + mappings[958] = ItemType.GoldenHelmet; + mappings[959] = ItemType.GoldenChestplate; + mappings[960] = ItemType.GoldenLeggings; + mappings[961] = ItemType.GoldenBoots; + mappings[962] = ItemType.NetheriteHelmet; + mappings[963] = ItemType.NetheriteChestplate; + mappings[964] = ItemType.NetheriteLeggings; + mappings[965] = ItemType.NetheriteBoots; + mappings[966] = ItemType.Flint; + mappings[967] = ItemType.Porkchop; + mappings[968] = ItemType.CookedPorkchop; + mappings[969] = ItemType.Painting; + mappings[970] = ItemType.GoldenApple; + mappings[971] = ItemType.EnchantedGoldenApple; + mappings[972] = ItemType.OakSign; + mappings[973] = ItemType.SpruceSign; + mappings[974] = ItemType.BirchSign; + mappings[975] = ItemType.JungleSign; + mappings[976] = ItemType.AcaciaSign; + mappings[977] = ItemType.CherrySign; + mappings[978] = ItemType.DarkOakSign; + mappings[979] = ItemType.PaleOakSign; + mappings[980] = ItemType.MangroveSign; + mappings[981] = ItemType.BambooSign; + mappings[982] = ItemType.CrimsonSign; + mappings[983] = ItemType.WarpedSign; + mappings[984] = ItemType.OakHangingSign; + mappings[985] = ItemType.SpruceHangingSign; + mappings[986] = ItemType.BirchHangingSign; + mappings[987] = ItemType.JungleHangingSign; + mappings[988] = ItemType.AcaciaHangingSign; + mappings[989] = ItemType.CherryHangingSign; + mappings[990] = ItemType.DarkOakHangingSign; + mappings[991] = ItemType.PaleOakHangingSign; + mappings[992] = ItemType.MangroveHangingSign; + mappings[993] = ItemType.BambooHangingSign; + mappings[994] = ItemType.CrimsonHangingSign; + mappings[995] = ItemType.WarpedHangingSign; + mappings[996] = ItemType.Bucket; + mappings[997] = ItemType.WaterBucket; + mappings[998] = ItemType.LavaBucket; + mappings[999] = ItemType.PowderSnowBucket; + mappings[1000] = ItemType.Snowball; + mappings[1001] = ItemType.Leather; + mappings[1002] = ItemType.MilkBucket; + mappings[1003] = ItemType.PufferfishBucket; + mappings[1004] = ItemType.SalmonBucket; + mappings[1005] = ItemType.CodBucket; + mappings[1006] = ItemType.TropicalFishBucket; + mappings[1007] = ItemType.AxolotlBucket; + mappings[1008] = ItemType.TadpoleBucket; + mappings[1009] = ItemType.Brick; + mappings[1010] = ItemType.ClayBall; + mappings[1011] = ItemType.DriedKelpBlock; + mappings[1012] = ItemType.Paper; + mappings[1013] = ItemType.Book; + mappings[1014] = ItemType.SlimeBall; + mappings[1015] = ItemType.Egg; + mappings[1016] = ItemType.BlueEgg; + mappings[1017] = ItemType.BrownEgg; + mappings[1018] = ItemType.Compass; + mappings[1019] = ItemType.RecoveryCompass; + mappings[1020] = ItemType.Bundle; + mappings[1021] = ItemType.WhiteBundle; + mappings[1022] = ItemType.OrangeBundle; + mappings[1023] = ItemType.MagentaBundle; + mappings[1024] = ItemType.LightBlueBundle; + mappings[1025] = ItemType.YellowBundle; + mappings[1026] = ItemType.LimeBundle; + mappings[1027] = ItemType.PinkBundle; + mappings[1028] = ItemType.GrayBundle; + mappings[1029] = ItemType.LightGrayBundle; + mappings[1030] = ItemType.CyanBundle; + mappings[1031] = ItemType.PurpleBundle; + mappings[1032] = ItemType.BlueBundle; + mappings[1033] = ItemType.BrownBundle; + mappings[1034] = ItemType.GreenBundle; + mappings[1035] = ItemType.RedBundle; + mappings[1036] = ItemType.BlackBundle; + mappings[1037] = ItemType.FishingRod; + mappings[1038] = ItemType.Clock; + mappings[1039] = ItemType.Spyglass; + mappings[1040] = ItemType.GlowstoneDust; + mappings[1041] = ItemType.Cod; + mappings[1042] = ItemType.Salmon; + mappings[1043] = ItemType.TropicalFish; + mappings[1044] = ItemType.Pufferfish; + mappings[1045] = ItemType.CookedCod; + mappings[1046] = ItemType.CookedSalmon; + mappings[1047] = ItemType.InkSac; + mappings[1048] = ItemType.GlowInkSac; + mappings[1049] = ItemType.CocoaBeans; + mappings[1050] = ItemType.WhiteDye; + mappings[1051] = ItemType.OrangeDye; + mappings[1052] = ItemType.MagentaDye; + mappings[1053] = ItemType.LightBlueDye; + mappings[1054] = ItemType.YellowDye; + mappings[1055] = ItemType.LimeDye; + mappings[1056] = ItemType.PinkDye; + mappings[1057] = ItemType.GrayDye; + mappings[1058] = ItemType.LightGrayDye; + mappings[1059] = ItemType.CyanDye; + mappings[1060] = ItemType.PurpleDye; + mappings[1061] = ItemType.BlueDye; + mappings[1062] = ItemType.BrownDye; + mappings[1063] = ItemType.GreenDye; + mappings[1064] = ItemType.RedDye; + mappings[1065] = ItemType.BlackDye; + mappings[1066] = ItemType.BoneMeal; + mappings[1067] = ItemType.Bone; + mappings[1068] = ItemType.Sugar; + mappings[1069] = ItemType.Cake; + mappings[1070] = ItemType.WhiteBed; + mappings[1071] = ItemType.OrangeBed; + mappings[1072] = ItemType.MagentaBed; + mappings[1073] = ItemType.LightBlueBed; + mappings[1074] = ItemType.YellowBed; + mappings[1075] = ItemType.LimeBed; + mappings[1076] = ItemType.PinkBed; + mappings[1077] = ItemType.GrayBed; + mappings[1078] = ItemType.LightGrayBed; + mappings[1079] = ItemType.CyanBed; + mappings[1080] = ItemType.PurpleBed; + mappings[1081] = ItemType.BlueBed; + mappings[1082] = ItemType.BrownBed; + mappings[1083] = ItemType.GreenBed; + mappings[1084] = ItemType.RedBed; + mappings[1085] = ItemType.BlackBed; + mappings[1086] = ItemType.Cookie; + mappings[1087] = ItemType.Crafter; + mappings[1088] = ItemType.FilledMap; + mappings[1089] = ItemType.Shears; + mappings[1090] = ItemType.MelonSlice; + mappings[1091] = ItemType.DriedKelp; + mappings[1092] = ItemType.PumpkinSeeds; + mappings[1093] = ItemType.MelonSeeds; + mappings[1094] = ItemType.Beef; + mappings[1095] = ItemType.CookedBeef; + mappings[1096] = ItemType.Chicken; + mappings[1097] = ItemType.CookedChicken; + mappings[1098] = ItemType.RottenFlesh; + mappings[1099] = ItemType.EnderPearl; + mappings[1100] = ItemType.BlazeRod; + mappings[1101] = ItemType.GhastTear; + mappings[1102] = ItemType.GoldNugget; + mappings[1103] = ItemType.NetherWart; + mappings[1104] = ItemType.GlassBottle; + mappings[1105] = ItemType.Potion; + mappings[1106] = ItemType.SpiderEye; + mappings[1107] = ItemType.FermentedSpiderEye; + mappings[1108] = ItemType.BlazePowder; + mappings[1109] = ItemType.MagmaCream; + mappings[1110] = ItemType.BrewingStand; + mappings[1111] = ItemType.Cauldron; + mappings[1112] = ItemType.EnderEye; + mappings[1113] = ItemType.GlisteringMelonSlice; + mappings[1114] = ItemType.ArmadilloSpawnEgg; + mappings[1115] = ItemType.AllaySpawnEgg; + mappings[1116] = ItemType.AxolotlSpawnEgg; + mappings[1117] = ItemType.BatSpawnEgg; + mappings[1118] = ItemType.BeeSpawnEgg; + mappings[1119] = ItemType.BlazeSpawnEgg; + mappings[1120] = ItemType.BoggedSpawnEgg; + mappings[1121] = ItemType.BreezeSpawnEgg; + mappings[1122] = ItemType.CatSpawnEgg; + mappings[1123] = ItemType.CamelSpawnEgg; + mappings[1124] = ItemType.CaveSpiderSpawnEgg; + mappings[1125] = ItemType.ChickenSpawnEgg; + mappings[1126] = ItemType.CodSpawnEgg; + mappings[1127] = ItemType.CopperGolemSpawnEgg; + mappings[1128] = ItemType.CowSpawnEgg; + mappings[1129] = ItemType.CreeperSpawnEgg; + mappings[1130] = ItemType.DolphinSpawnEgg; + mappings[1131] = ItemType.DonkeySpawnEgg; + mappings[1132] = ItemType.DrownedSpawnEgg; + mappings[1133] = ItemType.ElderGuardianSpawnEgg; + mappings[1134] = ItemType.EnderDragonSpawnEgg; + mappings[1135] = ItemType.EndermanSpawnEgg; + mappings[1136] = ItemType.EndermiteSpawnEgg; + mappings[1137] = ItemType.EvokerSpawnEgg; + mappings[1138] = ItemType.FoxSpawnEgg; + mappings[1139] = ItemType.FrogSpawnEgg; + mappings[1140] = ItemType.GhastSpawnEgg; + mappings[1141] = ItemType.HappyGhastSpawnEgg; + mappings[1142] = ItemType.GlowSquidSpawnEgg; + mappings[1143] = ItemType.GoatSpawnEgg; + mappings[1144] = ItemType.GuardianSpawnEgg; + mappings[1145] = ItemType.HoglinSpawnEgg; + mappings[1146] = ItemType.HorseSpawnEgg; + mappings[1147] = ItemType.HuskSpawnEgg; + mappings[1148] = ItemType.IronGolemSpawnEgg; + mappings[1149] = ItemType.LlamaSpawnEgg; + mappings[1150] = ItemType.MagmaCubeSpawnEgg; + mappings[1151] = ItemType.MooshroomSpawnEgg; + mappings[1152] = ItemType.MuleSpawnEgg; + mappings[1153] = ItemType.OcelotSpawnEgg; + mappings[1154] = ItemType.PandaSpawnEgg; + mappings[1155] = ItemType.ParrotSpawnEgg; + mappings[1156] = ItemType.PhantomSpawnEgg; + mappings[1157] = ItemType.PigSpawnEgg; + mappings[1158] = ItemType.PiglinSpawnEgg; + mappings[1159] = ItemType.PiglinBruteSpawnEgg; + mappings[1160] = ItemType.PillagerSpawnEgg; + mappings[1161] = ItemType.PolarBearSpawnEgg; + mappings[1162] = ItemType.PufferfishSpawnEgg; + mappings[1163] = ItemType.RabbitSpawnEgg; + mappings[1164] = ItemType.RavagerSpawnEgg; + mappings[1165] = ItemType.SalmonSpawnEgg; + mappings[1166] = ItemType.SheepSpawnEgg; + mappings[1167] = ItemType.ShulkerSpawnEgg; + mappings[1168] = ItemType.SilverfishSpawnEgg; + mappings[1169] = ItemType.SkeletonSpawnEgg; + mappings[1170] = ItemType.SkeletonHorseSpawnEgg; + mappings[1171] = ItemType.SlimeSpawnEgg; + mappings[1172] = ItemType.SnifferSpawnEgg; + mappings[1173] = ItemType.SnowGolemSpawnEgg; + mappings[1174] = ItemType.SpiderSpawnEgg; + mappings[1175] = ItemType.SquidSpawnEgg; + mappings[1176] = ItemType.StraySpawnEgg; + mappings[1177] = ItemType.StriderSpawnEgg; + mappings[1178] = ItemType.TadpoleSpawnEgg; + mappings[1179] = ItemType.TraderLlamaSpawnEgg; + mappings[1180] = ItemType.TropicalFishSpawnEgg; + mappings[1181] = ItemType.TurtleSpawnEgg; + mappings[1182] = ItemType.VexSpawnEgg; + mappings[1183] = ItemType.VillagerSpawnEgg; + mappings[1184] = ItemType.VindicatorSpawnEgg; + mappings[1185] = ItemType.WanderingTraderSpawnEgg; + mappings[1186] = ItemType.WardenSpawnEgg; + mappings[1187] = ItemType.WitchSpawnEgg; + mappings[1188] = ItemType.WitherSpawnEgg; + mappings[1189] = ItemType.WitherSkeletonSpawnEgg; + mappings[1190] = ItemType.WolfSpawnEgg; + mappings[1191] = ItemType.ZoglinSpawnEgg; + mappings[1192] = ItemType.CreakingSpawnEgg; + mappings[1193] = ItemType.ZombieSpawnEgg; + mappings[1194] = ItemType.ZombieHorseSpawnEgg; + mappings[1195] = ItemType.ZombieVillagerSpawnEgg; + mappings[1196] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1197] = ItemType.ExperienceBottle; + mappings[1198] = ItemType.FireCharge; + mappings[1199] = ItemType.WindCharge; + mappings[1200] = ItemType.WritableBook; + mappings[1201] = ItemType.WrittenBook; + mappings[1202] = ItemType.BreezeRod; + mappings[1203] = ItemType.Mace; + mappings[1204] = ItemType.ItemFrame; + mappings[1205] = ItemType.GlowItemFrame; + mappings[1206] = ItemType.FlowerPot; + mappings[1207] = ItemType.Carrot; + mappings[1208] = ItemType.Potato; + mappings[1209] = ItemType.BakedPotato; + mappings[1210] = ItemType.PoisonousPotato; + mappings[1211] = ItemType.Map; + mappings[1212] = ItemType.GoldenCarrot; + mappings[1213] = ItemType.SkeletonSkull; + mappings[1214] = ItemType.WitherSkeletonSkull; + mappings[1215] = ItemType.PlayerHead; + mappings[1216] = ItemType.ZombieHead; + mappings[1217] = ItemType.CreeperHead; + mappings[1218] = ItemType.DragonHead; + mappings[1219] = ItemType.PiglinHead; + mappings[1220] = ItemType.NetherStar; + mappings[1221] = ItemType.PumpkinPie; + mappings[1222] = ItemType.FireworkRocket; + mappings[1223] = ItemType.FireworkStar; + mappings[1224] = ItemType.EnchantedBook; + mappings[1225] = ItemType.NetherBrick; + mappings[1226] = ItemType.ResinBrick; + mappings[1227] = ItemType.PrismarineShard; + mappings[1228] = ItemType.PrismarineCrystals; + mappings[1229] = ItemType.Rabbit; + mappings[1230] = ItemType.CookedRabbit; + mappings[1231] = ItemType.RabbitStew; + mappings[1232] = ItemType.RabbitFoot; + mappings[1233] = ItemType.RabbitHide; + mappings[1234] = ItemType.ArmorStand; + mappings[1235] = ItemType.CopperHorseArmor; + mappings[1236] = ItemType.IronHorseArmor; + mappings[1237] = ItemType.GoldenHorseArmor; + mappings[1238] = ItemType.DiamondHorseArmor; + mappings[1239] = ItemType.LeatherHorseArmor; + mappings[1240] = ItemType.Lead; + mappings[1241] = ItemType.NameTag; + mappings[1242] = ItemType.CommandBlockMinecart; + mappings[1243] = ItemType.Mutton; + mappings[1244] = ItemType.CookedMutton; + mappings[1245] = ItemType.WhiteBanner; + mappings[1246] = ItemType.OrangeBanner; + mappings[1247] = ItemType.MagentaBanner; + mappings[1248] = ItemType.LightBlueBanner; + mappings[1249] = ItemType.YellowBanner; + mappings[1250] = ItemType.LimeBanner; + mappings[1251] = ItemType.PinkBanner; + mappings[1252] = ItemType.GrayBanner; + mappings[1253] = ItemType.LightGrayBanner; + mappings[1254] = ItemType.CyanBanner; + mappings[1255] = ItemType.PurpleBanner; + mappings[1256] = ItemType.BlueBanner; + mappings[1257] = ItemType.BrownBanner; + mappings[1258] = ItemType.GreenBanner; + mappings[1259] = ItemType.RedBanner; + mappings[1260] = ItemType.BlackBanner; + mappings[1261] = ItemType.EndCrystal; + mappings[1262] = ItemType.ChorusFruit; + mappings[1263] = ItemType.PoppedChorusFruit; + mappings[1264] = ItemType.TorchflowerSeeds; + mappings[1265] = ItemType.PitcherPod; + mappings[1266] = ItemType.Beetroot; + mappings[1267] = ItemType.BeetrootSeeds; + mappings[1268] = ItemType.BeetrootSoup; + mappings[1269] = ItemType.DragonBreath; + mappings[1270] = ItemType.SplashPotion; + mappings[1271] = ItemType.SpectralArrow; + mappings[1272] = ItemType.TippedArrow; + mappings[1273] = ItemType.LingeringPotion; + mappings[1274] = ItemType.Shield; + mappings[1275] = ItemType.TotemOfUndying; + mappings[1276] = ItemType.ShulkerShell; + mappings[1277] = ItemType.IronNugget; + mappings[1278] = ItemType.CopperNugget; + mappings[1279] = ItemType.KnowledgeBook; + mappings[1280] = ItemType.DebugStick; + mappings[1281] = ItemType.MusicDisc13; + mappings[1282] = ItemType.MusicDiscCat; + mappings[1283] = ItemType.MusicDiscBlocks; + mappings[1284] = ItemType.MusicDiscChirp; + mappings[1285] = ItemType.MusicDiscCreator; + mappings[1286] = ItemType.MusicDiscCreatorMusicBox; + mappings[1287] = ItemType.MusicDiscFar; + mappings[1288] = ItemType.MusicDiscLavaChicken; + mappings[1289] = ItemType.MusicDiscMall; + mappings[1290] = ItemType.MusicDiscMellohi; + mappings[1291] = ItemType.MusicDiscStal; + mappings[1292] = ItemType.MusicDiscStrad; + mappings[1293] = ItemType.MusicDiscWard; + mappings[1294] = ItemType.MusicDisc11; + mappings[1295] = ItemType.MusicDiscWait; + mappings[1296] = ItemType.MusicDiscOtherside; + mappings[1297] = ItemType.MusicDiscRelic; + mappings[1298] = ItemType.MusicDisc5; + mappings[1299] = ItemType.MusicDiscPigstep; + mappings[1300] = ItemType.MusicDiscPrecipice; + mappings[1301] = ItemType.MusicDiscTears; + mappings[1302] = ItemType.DiscFragment5; + mappings[1303] = ItemType.Trident; + mappings[1304] = ItemType.NautilusShell; + mappings[1305] = ItemType.HeartOfTheSea; + mappings[1306] = ItemType.Crossbow; + mappings[1307] = ItemType.SuspiciousStew; + mappings[1308] = ItemType.Loom; + mappings[1309] = ItemType.FlowerBannerPattern; + mappings[1310] = ItemType.CreeperBannerPattern; + mappings[1311] = ItemType.SkullBannerPattern; + mappings[1312] = ItemType.MojangBannerPattern; + mappings[1313] = ItemType.GlobeBannerPattern; + mappings[1314] = ItemType.PiglinBannerPattern; + mappings[1315] = ItemType.FlowBannerPattern; + mappings[1316] = ItemType.GusterBannerPattern; + mappings[1317] = ItemType.FieldMasonedBannerPattern; + mappings[1318] = ItemType.BordureIndentedBannerPattern; + mappings[1319] = ItemType.GoatHorn; + mappings[1320] = ItemType.Composter; + mappings[1321] = ItemType.Barrel; + mappings[1322] = ItemType.Smoker; + mappings[1323] = ItemType.BlastFurnace; + mappings[1324] = ItemType.CartographyTable; + mappings[1325] = ItemType.FletchingTable; + mappings[1326] = ItemType.Grindstone; + mappings[1327] = ItemType.SmithingTable; + mappings[1328] = ItemType.Stonecutter; + mappings[1329] = ItemType.Bell; + mappings[1330] = ItemType.Lantern; + mappings[1331] = ItemType.SoulLantern; + mappings[1332] = ItemType.SweetBerries; + mappings[1333] = ItemType.GlowBerries; + mappings[1334] = ItemType.Campfire; + mappings[1335] = ItemType.SoulCampfire; + mappings[1336] = ItemType.Shroomlight; + mappings[1337] = ItemType.Honeycomb; + mappings[1338] = ItemType.BeeNest; + mappings[1339] = ItemType.Beehive; + mappings[1340] = ItemType.HoneyBottle; + mappings[1341] = ItemType.HoneycombBlock; + mappings[1342] = ItemType.Lodestone; + mappings[1343] = ItemType.CryingObsidian; + mappings[1344] = ItemType.Blackstone; + mappings[1345] = ItemType.BlackstoneSlab; + mappings[1346] = ItemType.BlackstoneStairs; + mappings[1347] = ItemType.GildedBlackstone; + mappings[1348] = ItemType.PolishedBlackstone; + mappings[1349] = ItemType.PolishedBlackstoneSlab; + mappings[1350] = ItemType.PolishedBlackstoneStairs; + mappings[1351] = ItemType.ChiseledPolishedBlackstone; + mappings[1352] = ItemType.PolishedBlackstoneBricks; + mappings[1353] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1354] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1355] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1356] = ItemType.RespawnAnchor; + mappings[1357] = ItemType.Candle; + mappings[1358] = ItemType.WhiteCandle; + mappings[1359] = ItemType.OrangeCandle; + mappings[1360] = ItemType.MagentaCandle; + mappings[1361] = ItemType.LightBlueCandle; + mappings[1362] = ItemType.YellowCandle; + mappings[1363] = ItemType.LimeCandle; + mappings[1364] = ItemType.PinkCandle; + mappings[1365] = ItemType.GrayCandle; + mappings[1366] = ItemType.LightGrayCandle; + mappings[1367] = ItemType.CyanCandle; + mappings[1368] = ItemType.PurpleCandle; + mappings[1369] = ItemType.BlueCandle; + mappings[1370] = ItemType.BrownCandle; + mappings[1371] = ItemType.GreenCandle; + mappings[1372] = ItemType.RedCandle; + mappings[1373] = ItemType.BlackCandle; + mappings[1374] = ItemType.SmallAmethystBud; + mappings[1375] = ItemType.MediumAmethystBud; + mappings[1376] = ItemType.LargeAmethystBud; + mappings[1377] = ItemType.AmethystCluster; + mappings[1378] = ItemType.PointedDripstone; + mappings[1379] = ItemType.OchreFroglight; + mappings[1380] = ItemType.VerdantFroglight; + mappings[1381] = ItemType.PearlescentFroglight; + mappings[1382] = ItemType.Frogspawn; + mappings[1383] = ItemType.EchoShard; + mappings[1384] = ItemType.Brush; + mappings[1385] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1386] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1387] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1388] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1389] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1390] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1391] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1392] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1393] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1394] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1395] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1396] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1397] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1398] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1399] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1400] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1401] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1402] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1403] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1404] = ItemType.AnglerPotterySherd; + mappings[1405] = ItemType.ArcherPotterySherd; + mappings[1406] = ItemType.ArmsUpPotterySherd; + mappings[1407] = ItemType.BladePotterySherd; + mappings[1408] = ItemType.BrewerPotterySherd; + mappings[1409] = ItemType.BurnPotterySherd; + mappings[1410] = ItemType.DangerPotterySherd; + mappings[1411] = ItemType.ExplorerPotterySherd; + mappings[1412] = ItemType.FlowPotterySherd; + mappings[1413] = ItemType.FriendPotterySherd; + mappings[1414] = ItemType.GusterPotterySherd; + mappings[1415] = ItemType.HeartPotterySherd; + mappings[1416] = ItemType.HeartbreakPotterySherd; + mappings[1417] = ItemType.HowlPotterySherd; + mappings[1418] = ItemType.MinerPotterySherd; + mappings[1419] = ItemType.MournerPotterySherd; + mappings[1420] = ItemType.PlentyPotterySherd; + mappings[1421] = ItemType.PrizePotterySherd; + mappings[1422] = ItemType.ScrapePotterySherd; + mappings[1423] = ItemType.SheafPotterySherd; + mappings[1424] = ItemType.ShelterPotterySherd; + mappings[1425] = ItemType.SkullPotterySherd; + mappings[1426] = ItemType.SnortPotterySherd; + mappings[1427] = ItemType.CopperGrate; + mappings[1428] = ItemType.ExposedCopperGrate; + mappings[1429] = ItemType.WeatheredCopperGrate; + mappings[1430] = ItemType.OxidizedCopperGrate; + mappings[1431] = ItemType.WaxedCopperGrate; + mappings[1432] = ItemType.WaxedExposedCopperGrate; + mappings[1433] = ItemType.WaxedWeatheredCopperGrate; + mappings[1434] = ItemType.WaxedOxidizedCopperGrate; + mappings[1435] = ItemType.CopperBulb; + mappings[1436] = ItemType.ExposedCopperBulb; + mappings[1437] = ItemType.WeatheredCopperBulb; + mappings[1438] = ItemType.OxidizedCopperBulb; + mappings[1439] = ItemType.WaxedCopperBulb; + mappings[1440] = ItemType.WaxedExposedCopperBulb; + mappings[1441] = ItemType.WaxedWeatheredCopperBulb; + mappings[1442] = ItemType.WaxedOxidizedCopperBulb; + mappings[1443] = ItemType.CopperChest; + mappings[1444] = ItemType.ExposedCopperChest; + mappings[1445] = ItemType.WeatheredCopperChest; + mappings[1446] = ItemType.OxidizedCopperChest; + mappings[1447] = ItemType.WaxedCopperChest; + mappings[1448] = ItemType.WaxedExposedCopperChest; + mappings[1449] = ItemType.WaxedWeatheredCopperChest; + mappings[1450] = ItemType.WaxedOxidizedCopperChest; + mappings[1451] = ItemType.CopperGolemStatue; + mappings[1452] = ItemType.ExposedCopperGolemStatue; + mappings[1453] = ItemType.WeatheredCopperGolemStatue; + mappings[1454] = ItemType.OxidizedCopperGolemStatue; + mappings[1455] = ItemType.WaxedCopperGolemStatue; + mappings[1456] = ItemType.WaxedExposedCopperGolemStatue; + mappings[1457] = ItemType.WaxedWeatheredCopperGolemStatue; + mappings[1458] = ItemType.WaxedOxidizedCopperGolemStatue; + mappings[1459] = ItemType.TrialSpawner; + mappings[1460] = ItemType.TrialKey; + mappings[1461] = ItemType.OminousTrialKey; + mappings[1462] = ItemType.Vault; + mappings[1463] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs new file mode 100644 index 00000000..2d94c921 --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs @@ -0,0 +1,1961 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette1219 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette1219() + { + for (int i = 10569; i <= 10592; i++) + materials[i] = Material.AcaciaButton; + for (int i = 14050; i <= 14113; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 13666; i <= 13697; i++) + materials[i] = Material.AcaciaFence; + for (int i = 13378; i <= 13409; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 5898; i <= 5961; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + materials[19] = Material.AcaciaPlanks; + for (int i = 6668; i <= 6669; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 2399; i <= 2462; i++) + materials[i] = Material.AcaciaShelf; + for (int i = 5230; i <= 5261; i++) + materials[i] = Material.AcaciaSign; + for (int i = 13152; i <= 13157; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 11770; i <= 11849; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 7169; i <= 7232; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 6498; i <= 6505; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 5650; i <= 5657; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 11206; i <= 11229; i++) + materials[i] = Material.ActivatorRail; + materials[0] = Material.Air; + materials[2125] = Material.Allium; + materials[23200] = Material.AmethystBlock; + for (int i = 23202; i <= 23213; i++) + materials[i] = Material.AmethystCluster; + materials[21617] = Material.AncientDebris; + materials[6] = Material.Andesite; + for (int i = 16268; i <= 16273; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 15894; i <= 15973; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 18884; i <= 19207; i++) + materials[i] = Material.AndesiteWall; + for (int i = 10993; i <= 10996; i++) + materials[i] = Material.Anvil; + for (int i = 8137; i <= 8140; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 8133; i <= 8136; i++) + materials[i] = Material.AttachedPumpkinStem; + materials[27609] = Material.Azalea; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + materials[2126] = Material.AzureBluet; + for (int i = 15077; i <= 15088; i++) + materials[i] = Material.Bamboo; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 10689; i <= 10712; i++) + materials[i] = Material.BambooButton; + for (int i = 14370; i <= 14433; i++) + materials[i] = Material.BambooDoor; + for (int i = 13826; i <= 13857; i++) + materials[i] = Material.BambooFence; + for (int i = 13538; i <= 13569; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 6410; i <= 6473; i++) + materials[i] = Material.BambooHangingSign; + materials[28] = Material.BambooMosaic; + for (int i = 13188; i <= 13193; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 12250; i <= 12329; i++) + materials[i] = Material.BambooMosaicStairs; + materials[27] = Material.BambooPlanks; + for (int i = 6678; i <= 6679; i++) + materials[i] = Material.BambooPressurePlate; + materials[15076] = Material.BambooSapling; + for (int i = 2463; i <= 2526; i++) + materials[i] = Material.BambooShelf; + for (int i = 5422; i <= 5453; i++) + materials[i] = Material.BambooSign; + for (int i = 13182; i <= 13187; i++) + materials[i] = Material.BambooSlab; + for (int i = 12170; i <= 12249; i++) + materials[i] = Material.BambooStairs; + for (int i = 7489; i <= 7552; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 6562; i <= 6569; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 5698; i <= 5705; i++) + materials[i] = Material.BambooWallSign; + for (int i = 20540; i <= 20551; i++) + materials[i] = Material.Barrel; + for (int i = 12331; i <= 12332; i++) + materials[i] = Material.Barrier; + for (int i = 6799; i <= 6801; i++) + materials[i] = Material.Basalt; + materials[9779] = Material.Beacon; + materials[85] = Material.Bedrock; + for (int i = 21566; i <= 21589; i++) + materials[i] = Material.BeeNest; + for (int i = 21590; i <= 21613; i++) + materials[i] = Material.Beehive; + for (int i = 14609; i <= 14612; i++) + materials[i] = Material.Beetroots; + for (int i = 20603; i <= 20634; i++) + materials[i] = Material.Bell; + for (int i = 27661; i <= 27692; i++) + materials[i] = Material.BigDripleaf; + for (int i = 27693; i <= 27700; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 10521; i <= 10544; i++) + materials[i] = Material.BirchButton; + for (int i = 13922; i <= 13985; i++) + materials[i] = Material.BirchDoor; + for (int i = 13602; i <= 13633; i++) + materials[i] = Material.BirchFence; + for (int i = 13314; i <= 13345; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 5834; i <= 5897; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + materials[17] = Material.BirchPlanks; + for (int i = 6664; i <= 6665; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 2527; i <= 2590; i++) + materials[i] = Material.BirchShelf; + for (int i = 5198; i <= 5229; i++) + materials[i] = Material.BirchSign; + for (int i = 13140; i <= 13145; i++) + materials[i] = Material.BirchSlab; + for (int i = 9607; i <= 9686; i++) + materials[i] = Material.BirchStairs; + for (int i = 7041; i <= 7104; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 6490; i <= 6497; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 5642; i <= 5649; i++) + materials[i] = Material.BirchWallSign; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 12965; i <= 12980; i++) + materials[i] = Material.BlackBanner; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 23150; i <= 23165; i++) + materials[i] = Material.BlackCandle; + for (int i = 23198; i <= 23199; i++) + materials[i] = Material.BlackCandleCake; + materials[12709] = Material.BlackCarpet; + materials[14843] = Material.BlackConcrete; + materials[14859] = Material.BlackConcretePowder; + for (int i = 14824; i <= 14827; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 14758; i <= 14763; i++) + materials[i] = Material.BlackShulkerBox; + materials[6912] = Material.BlackStainedGlass; + for (int i = 11738; i <= 11769; i++) + materials[i] = Material.BlackStainedGlassPane; + materials[11257] = Material.BlackTerracotta; + for (int i = 13041; i <= 13044; i++) + materials[i] = Material.BlackWallBanner; + materials[2108] = Material.BlackWool; + materials[21629] = Material.Blackstone; + for (int i = 22034; i <= 22039; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 21630; i <= 21709; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 21710; i <= 22033; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 20560; i <= 20567; i++) + materials[i] = Material.BlastFurnace; + for (int i = 12901; i <= 12916; i++) + materials[i] = Material.BlueBanner; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 23086; i <= 23101; i++) + materials[i] = Material.BlueCandle; + for (int i = 23190; i <= 23191; i++) + materials[i] = Material.BlueCandleCake; + materials[12705] = Material.BlueCarpet; + materials[14839] = Material.BlueConcrete; + materials[14855] = Material.BlueConcretePowder; + for (int i = 14808; i <= 14811; i++) + materials[i] = Material.BlueGlazedTerracotta; + materials[15073] = Material.BlueIce; + materials[2124] = Material.BlueOrchid; + for (int i = 14734; i <= 14739; i++) + materials[i] = Material.BlueShulkerBox; + materials[6908] = Material.BlueStainedGlass; + for (int i = 11610; i <= 11641; i++) + materials[i] = Material.BlueStainedGlassPane; + materials[11253] = Material.BlueTerracotta; + for (int i = 13025; i <= 13028; i++) + materials[i] = Material.BlueWallBanner; + materials[2104] = Material.BlueWool; + for (int i = 14646; i <= 14648; i++) + materials[i] = Material.BoneBlock; + materials[2142] = Material.Bookshelf; + for (int i = 14957; i <= 14958; i++) + materials[i] = Material.BrainCoral; + materials[14941] = Material.BrainCoralBlock; + for (int i = 14977; i <= 14978; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 15033; i <= 15040; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 9251; i <= 9258; i++) + materials[i] = Material.BrewingStand; + for (int i = 13230; i <= 13235; i++) + materials[i] = Material.BrickSlab; + for (int i = 8477; i <= 8556; i++) + materials[i] = Material.BrickStairs; + for (int i = 16292; i <= 16615; i++) + materials[i] = Material.BrickWall; + materials[2139] = Material.Bricks; + for (int i = 12917; i <= 12932; i++) + materials[i] = Material.BrownBanner; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 23102; i <= 23117; i++) + materials[i] = Material.BrownCandle; + for (int i = 23192; i <= 23193; i++) + materials[i] = Material.BrownCandleCake; + materials[12706] = Material.BrownCarpet; + materials[14840] = Material.BrownConcrete; + materials[14856] = Material.BrownConcretePowder; + for (int i = 14812; i <= 14815; i++) + materials[i] = Material.BrownGlazedTerracotta; + materials[2135] = Material.BrownMushroom; + for (int i = 7565; i <= 7628; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 14740; i <= 14745; i++) + materials[i] = Material.BrownShulkerBox; + materials[6909] = Material.BrownStainedGlass; + for (int i = 11642; i <= 11673; i++) + materials[i] = Material.BrownStainedGlassPane; + materials[11254] = Material.BrownTerracotta; + for (int i = 13029; i <= 13032; i++) + materials[i] = Material.BrownWallBanner; + materials[2105] = Material.BrownWool; + for (int i = 15092; i <= 15093; i++) + materials[i] = Material.BubbleColumn; + for (int i = 14959; i <= 14960; i++) + materials[i] = Material.BubbleCoral; + materials[14942] = Material.BubbleCoralBlock; + for (int i = 14979; i <= 14980; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 15041; i <= 15048; i++) + materials[i] = Material.BubbleCoralWallFan; + materials[23201] = Material.BuddingAmethyst; + materials[2051] = Material.Bush; + for (int i = 6728; i <= 6743; i++) + materials[i] = Material.Cactus; + materials[6744] = Material.CactusFlower; + for (int i = 6826; i <= 6832; i++) + materials[i] = Material.Cake; + materials[24485] = Material.Calcite; + for (int i = 24584; i <= 24967; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 20675; i <= 20706; i++) + materials[i] = Material.Campfire; + for (int i = 22894; i <= 22909; i++) + materials[i] = Material.Candle; + for (int i = 23166; i <= 23167; i++) + materials[i] = Material.CandleCake; + for (int i = 10457; i <= 10464; i++) + materials[i] = Material.Carrots; + materials[20568] = Material.CartographyTable; + for (int i = 6818; i <= 6821; i++) + materials[i] = Material.CarvedPumpkin; + materials[9259] = Material.Cauldron; + materials[15091] = Material.CaveAir; + for (int i = 27554; i <= 27605; i++) + materials[i] = Material.CaveVines; + for (int i = 27606; i <= 27607; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 14627; i <= 14638; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 10593; i <= 10616; i++) + materials[i] = Material.CherryButton; + for (int i = 14114; i <= 14177; i++) + materials[i] = Material.CherryDoor; + for (int i = 13698; i <= 13729; i++) + materials[i] = Material.CherryFence; + for (int i = 13410; i <= 13441; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 5962; i <= 6025; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + materials[20] = Material.CherryPlanks; + for (int i = 6670; i <= 6671; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 2591; i <= 2654; i++) + materials[i] = Material.CherryShelf; + for (int i = 5262; i <= 5293; i++) + materials[i] = Material.CherrySign; + for (int i = 13158; i <= 13163; i++) + materials[i] = Material.CherrySlab; + for (int i = 11850; i <= 11929; i++) + materials[i] = Material.CherryStairs; + for (int i = 7233; i <= 7296; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 6506; i <= 6513; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 5658; i <= 5665; i++) + materials[i] = Material.CherryWallSign; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 3786; i <= 3809; i++) + materials[i] = Material.Chest; + for (int i = 10997; i <= 11000; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 2143; i <= 2398; i++) + materials[i] = Material.ChiseledBookshelf; + materials[25120] = Material.ChiseledCopper; + materials[29368] = Material.ChiseledDeepslate; + materials[22891] = Material.ChiseledNetherBricks; + materials[22043] = Material.ChiseledPolishedBlackstone; + materials[11122] = Material.ChiseledQuartzBlock; + materials[13046] = Material.ChiseledRedSandstone; + materials[9132] = Material.ChiseledResinBricks; + materials[579] = Material.ChiseledSandstone; + materials[7556] = Material.ChiseledStoneBricks; + materials[24072] = Material.ChiseledTuff; + materials[24484] = Material.ChiseledTuffBricks; + for (int i = 14504; i <= 14509; i++) + materials[i] = Material.ChorusFlower; + for (int i = 14440; i <= 14503; i++) + materials[i] = Material.ChorusPlant; + materials[6745] = Material.Clay; + materials[29667] = Material.ClosedEyeblossom; + materials[12711] = Material.CoalBlock; + materials[133] = Material.CoalOre; + materials[11] = Material.CoarseDirt; + materials[27724] = Material.CobbledDeepslate; + for (int i = 27805; i <= 27810; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 27725; i <= 27804; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 27811; i <= 28134; i++) + materials[i] = Material.CobbledDeepslateWall; + materials[14] = Material.Cobblestone; + for (int i = 13224; i <= 13229; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 5546; i <= 5625; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 9780; i <= 10103; i++) + materials[i] = Material.CobblestoneWall; + materials[2047] = Material.Cobweb; + for (int i = 9280; i <= 9291; i++) + materials[i] = Material.Cocoa; + for (int i = 9767; i <= 9778; i++) + materials[i] = Material.CommandBlock; + for (int i = 11061; i <= 11076; i++) + materials[i] = Material.Comparator; + for (int i = 21541; i <= 21549; i++) + materials[i] = Material.Composter; + for (int i = 15074; i <= 15075; i++) + materials[i] = Material.Conduit; + for (int i = 7789; i <= 7820; i++) + materials[i] = Material.CopperBars; + materials[25107] = Material.CopperBlock; + for (int i = 26861; i <= 26864; i++) + materials[i] = Material.CopperBulb; + for (int i = 8051; i <= 8056; i++) + materials[i] = Material.CopperChain; + for (int i = 26893; i <= 26916; i++) + materials[i] = Material.CopperChest; + for (int i = 25821; i <= 25884; i++) + materials[i] = Material.CopperDoor; + for (int i = 27085; i <= 27116; i++) + materials[i] = Material.CopperGolemStatue; + for (int i = 26845; i <= 26846; i++) + materials[i] = Material.CopperGrate; + for (int i = 20643; i <= 20646; i++) + materials[i] = Material.CopperLantern; + materials[25111] = Material.CopperOre; + materials[6810] = Material.CopperTorch; + for (int i = 26333; i <= 26396; i++) + materials[i] = Material.CopperTrapdoor; + for (int i = 6811; i <= 6814; i++) + materials[i] = Material.CopperWallTorch; + materials[2132] = Material.Cornflower; + materials[29369] = Material.CrackedDeepslateBricks; + materials[29370] = Material.CrackedDeepslateTiles; + materials[22892] = Material.CrackedNetherBricks; + materials[22042] = Material.CrackedPolishedBlackstoneBricks; + materials[7555] = Material.CrackedStoneBricks; + for (int i = 29407; i <= 29454; i++) + materials[i] = Material.Crafter; + materials[5109] = Material.CraftingTable; + for (int i = 3688; i <= 3705; i++) + materials[i] = Material.CreakingHeart; + for (int i = 10873; i <= 10904; i++) + materials[i] = Material.CreeperHead; + for (int i = 10905; i <= 10912; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 21264; i <= 21287; i++) + materials[i] = Material.CrimsonButton; + for (int i = 21312; i <= 21375; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 20848; i <= 20879; i++) + materials[i] = Material.CrimsonFence; + for (int i = 21040; i <= 21071; i++) + materials[i] = Material.CrimsonFenceGate; + materials[20773] = Material.CrimsonFungus; + for (int i = 6218; i <= 6281; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 20766; i <= 20768; i++) + materials[i] = Material.CrimsonHyphae; + materials[20772] = Material.CrimsonNylium; + materials[20830] = Material.CrimsonPlanks; + for (int i = 20844; i <= 20845; i++) + materials[i] = Material.CrimsonPressurePlate; + materials[20829] = Material.CrimsonRoots; + for (int i = 2655; i <= 2718; i++) + materials[i] = Material.CrimsonShelf; + for (int i = 21440; i <= 21471; i++) + materials[i] = Material.CrimsonSign; + for (int i = 20832; i <= 20837; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 21104; i <= 21183; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 20760; i <= 20762; i++) + materials[i] = Material.CrimsonStem; + for (int i = 20912; i <= 20975; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 6546; i <= 6553; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 21504; i <= 21511; i++) + materials[i] = Material.CrimsonWallSign; + materials[21618] = Material.CryingObsidian; + materials[25116] = Material.CutCopper; + for (int i = 25463; i <= 25468; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 25365; i <= 25444; i++) + materials[i] = Material.CutCopperStairs; + materials[13047] = Material.CutRedSandstone; + for (int i = 13266; i <= 13271; i++) + materials[i] = Material.CutRedSandstoneSlab; + materials[580] = Material.CutSandstone; + for (int i = 13212; i <= 13217; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 12869; i <= 12884; i++) + materials[i] = Material.CyanBanner; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 23054; i <= 23069; i++) + materials[i] = Material.CyanCandle; + for (int i = 23186; i <= 23187; i++) + materials[i] = Material.CyanCandleCake; + materials[12703] = Material.CyanCarpet; + materials[14837] = Material.CyanConcrete; + materials[14853] = Material.CyanConcretePowder; + for (int i = 14800; i <= 14803; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 14722; i <= 14727; i++) + materials[i] = Material.CyanShulkerBox; + materials[6906] = Material.CyanStainedGlass; + for (int i = 11546; i <= 11577; i++) + materials[i] = Material.CyanStainedGlassPane; + materials[11251] = Material.CyanTerracotta; + for (int i = 13017; i <= 13020; i++) + materials[i] = Material.CyanWallBanner; + materials[2102] = Material.CyanWool; + for (int i = 11001; i <= 11004; i++) + materials[i] = Material.DamagedAnvil; + materials[2121] = Material.Dandelion; + for (int i = 10617; i <= 10640; i++) + materials[i] = Material.DarkOakButton; + for (int i = 14178; i <= 14241; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 13730; i <= 13761; i++) + materials[i] = Material.DarkOakFence; + for (int i = 13442; i <= 13473; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 6090; i <= 6153; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + materials[21] = Material.DarkOakPlanks; + for (int i = 6672; i <= 6673; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 2719; i <= 2782; i++) + materials[i] = Material.DarkOakShelf; + for (int i = 5326; i <= 5357; i++) + materials[i] = Material.DarkOakSign; + for (int i = 13164; i <= 13169; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 11930; i <= 12009; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 7297; i <= 7360; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 6522; i <= 6529; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 5674; i <= 5681; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + materials[12431] = Material.DarkPrismarine; + for (int i = 12684; i <= 12689; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 12592; i <= 12671; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 11077; i <= 11108; i++) + materials[i] = Material.DaylightDetector; + for (int i = 14947; i <= 14948; i++) + materials[i] = Material.DeadBrainCoral; + materials[14936] = Material.DeadBrainCoralBlock; + for (int i = 14967; i <= 14968; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 14993; i <= 15000; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 14949; i <= 14950; i++) + materials[i] = Material.DeadBubbleCoral; + materials[14937] = Material.DeadBubbleCoralBlock; + for (int i = 14969; i <= 14970; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 15001; i <= 15008; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + materials[2050] = Material.DeadBush; + for (int i = 14951; i <= 14952; i++) + materials[i] = Material.DeadFireCoral; + materials[14938] = Material.DeadFireCoralBlock; + for (int i = 14971; i <= 14972; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 15009; i <= 15016; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 14953; i <= 14954; i++) + materials[i] = Material.DeadHornCoral; + materials[14939] = Material.DeadHornCoralBlock; + for (int i = 14973; i <= 14974; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 15017; i <= 15024; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 14945; i <= 14946; i++) + materials[i] = Material.DeadTubeCoral; + materials[14935] = Material.DeadTubeCoralBlock; + for (int i = 14965; i <= 14966; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 14985; i <= 14992; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 29391; i <= 29406; i++) + materials[i] = Material.DecoratedPot; + for (int i = 27721; i <= 27723; i++) + materials[i] = Material.Deepslate; + for (int i = 29038; i <= 29043; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 28958; i <= 29037; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 29044; i <= 29367; i++) + materials[i] = Material.DeepslateBrickWall; + materials[28957] = Material.DeepslateBricks; + materials[134] = Material.DeepslateCoalOre; + materials[25112] = Material.DeepslateCopperOre; + materials[5107] = Material.DeepslateDiamondOre; + materials[9373] = Material.DeepslateEmeraldOre; + materials[130] = Material.DeepslateGoldOre; + materials[132] = Material.DeepslateIronOre; + materials[564] = Material.DeepslateLapisOre; + for (int i = 6682; i <= 6683; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 28627; i <= 28632; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 28547; i <= 28626; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 28633; i <= 28956; i++) + materials[i] = Material.DeepslateTileWall; + materials[28546] = Material.DeepslateTiles; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + materials[5108] = Material.DiamondBlock; + materials[5106] = Material.DiamondOre; + materials[4] = Material.Diorite; + for (int i = 16286; i <= 16291; i++) + materials[i] = Material.DioriteSlab; + for (int i = 16134; i <= 16213; i++) + materials[i] = Material.DioriteStairs; + for (int i = 20180; i <= 20503; i++) + materials[i] = Material.DioriteWall; + materials[10] = Material.Dirt; + materials[14613] = Material.DirtPath; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + materials[9277] = Material.DragonEgg; + for (int i = 10913; i <= 10944; i++) + materials[i] = Material.DragonHead; + for (int i = 10945; i <= 10952; i++) + materials[i] = Material.DragonWallHead; + for (int i = 14903; i <= 14934; i++) + materials[i] = Material.DriedGhast; + materials[14887] = Material.DriedKelpBlock; + materials[27553] = Material.DripstoneBlock; + for (int i = 11230; i <= 11241; i++) + materials[i] = Material.Dropper; + materials[9526] = Material.EmeraldBlock; + materials[9372] = Material.EmeraldOre; + materials[9250] = Material.EnchantingTable; + materials[14614] = Material.EndGateway; + materials[9267] = Material.EndPortal; + for (int i = 9268; i <= 9275; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 14434; i <= 14439; i++) + materials[i] = Material.EndRod; + materials[9276] = Material.EndStone; + for (int i = 16244; i <= 16249; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 15494; i <= 15573; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 19856; i <= 20179; i++) + materials[i] = Material.EndStoneBrickWall; + materials[14594] = Material.EndStoneBricks; + for (int i = 9374; i <= 9381; i++) + materials[i] = Material.EnderChest; + materials[25119] = Material.ExposedChiseledCopper; + materials[25108] = Material.ExposedCopper; + for (int i = 7821; i <= 7852; i++) + materials[i] = Material.ExposedCopperBars; + for (int i = 26865; i <= 26868; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 8057; i <= 8062; i++) + materials[i] = Material.ExposedCopperChain; + for (int i = 26917; i <= 26940; i++) + materials[i] = Material.ExposedCopperChest; + for (int i = 25885; i <= 25948; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 27117; i <= 27148; i++) + materials[i] = Material.ExposedCopperGolemStatue; + for (int i = 26847; i <= 26848; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 20647; i <= 20650; i++) + materials[i] = Material.ExposedCopperLantern; + for (int i = 26397; i <= 26460; i++) + materials[i] = Material.ExposedCopperTrapdoor; + materials[25115] = Material.ExposedCutCopper; + for (int i = 25457; i <= 25462; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 25285; i <= 25364; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 27365; i <= 27388; i++) + materials[i] = Material.ExposedLightningRod; + for (int i = 5118; i <= 5125; i++) + materials[i] = Material.Farmland; + materials[2049] = Material.Fern; + for (int i = 3174; i <= 3685; i++) + materials[i] = Material.Fire; + for (int i = 14961; i <= 14962; i++) + materials[i] = Material.FireCoral; + materials[14943] = Material.FireCoralBlock; + for (int i = 14981; i <= 14982; i++) + materials[i] = Material.FireCoralFan; + for (int i = 15049; i <= 15056; i++) + materials[i] = Material.FireCoralWallFan; + materials[29670] = Material.FireflyBush; + materials[20569] = Material.FletchingTable; + materials[10428] = Material.FlowerPot; + materials[27610] = Material.FloweringAzalea; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + materials[29389] = Material.Frogspawn; + for (int i = 14639; i <= 14642; i++) + materials[i] = Material.FrostedIce; + for (int i = 5126; i <= 5133; i++) + materials[i] = Material.Furnace; + materials[22454] = Material.GildedBlackstone; + materials[562] = Material.Glass; + for (int i = 8099; i <= 8130; i++) + materials[i] = Material.GlassPane; + for (int i = 8189; i <= 8316; i++) + materials[i] = Material.GlowLichen; + materials[6815] = Material.Glowstone; + materials[2137] = Material.GoldBlock; + materials[129] = Material.GoldOre; + materials[2] = Material.Granite; + for (int i = 16262; i <= 16267; i++) + materials[i] = Material.GraniteSlab; + for (int i = 15814; i <= 15893; i++) + materials[i] = Material.GraniteStairs; + for (int i = 17588; i <= 17911; i++) + materials[i] = Material.GraniteWall; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + materials[124] = Material.Gravel; + for (int i = 12837; i <= 12852; i++) + materials[i] = Material.GrayBanner; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 23022; i <= 23037; i++) + materials[i] = Material.GrayCandle; + for (int i = 23182; i <= 23183; i++) + materials[i] = Material.GrayCandleCake; + materials[12701] = Material.GrayCarpet; + materials[14835] = Material.GrayConcrete; + materials[14851] = Material.GrayConcretePowder; + for (int i = 14792; i <= 14795; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 14710; i <= 14715; i++) + materials[i] = Material.GrayShulkerBox; + materials[6904] = Material.GrayStainedGlass; + for (int i = 11482; i <= 11513; i++) + materials[i] = Material.GrayStainedGlassPane; + materials[11249] = Material.GrayTerracotta; + for (int i = 13009; i <= 13012; i++) + materials[i] = Material.GrayWallBanner; + materials[2100] = Material.GrayWool; + for (int i = 12933; i <= 12948; i++) + materials[i] = Material.GreenBanner; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 23118; i <= 23133; i++) + materials[i] = Material.GreenCandle; + for (int i = 23194; i <= 23195; i++) + materials[i] = Material.GreenCandleCake; + materials[12707] = Material.GreenCarpet; + materials[14841] = Material.GreenConcrete; + materials[14857] = Material.GreenConcretePowder; + for (int i = 14816; i <= 14819; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 14746; i <= 14751; i++) + materials[i] = Material.GreenShulkerBox; + materials[6910] = Material.GreenStainedGlass; + for (int i = 11674; i <= 11705; i++) + materials[i] = Material.GreenStainedGlassPane; + materials[11255] = Material.GreenTerracotta; + for (int i = 13033; i <= 13036; i++) + materials[i] = Material.GreenWallBanner; + materials[2106] = Material.GreenWool; + for (int i = 20570; i <= 20581; i++) + materials[i] = Material.Grindstone; + for (int i = 27717; i <= 27718; i++) + materials[i] = Material.HangingRoots; + for (int i = 12691; i <= 12693; i++) + materials[i] = Material.HayBlock; + for (int i = 29499; i <= 29500; i++) + materials[i] = Material.HeavyCore; + for (int i = 11045; i <= 11060; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + materials[21614] = Material.HoneyBlock; + materials[21615] = Material.HoneycombBlock; + for (int i = 11111; i <= 11120; i++) + materials[i] = Material.Hopper; + for (int i = 14963; i <= 14964; i++) + materials[i] = Material.HornCoral; + materials[14944] = Material.HornCoralBlock; + for (int i = 14983; i <= 14984; i++) + materials[i] = Material.HornCoralFan; + for (int i = 15057; i <= 15064; i++) + materials[i] = Material.HornCoralWallFan; + materials[6726] = Material.Ice; + materials[7564] = Material.InfestedChiseledStoneBricks; + materials[7560] = Material.InfestedCobblestone; + materials[7563] = Material.InfestedCrackedStoneBricks; + for (int i = 29371; i <= 29373; i++) + materials[i] = Material.InfestedDeepslate; + materials[7562] = Material.InfestedMossyStoneBricks; + materials[7559] = Material.InfestedStone; + materials[7561] = Material.InfestedStoneBricks; + for (int i = 7757; i <= 7788; i++) + materials[i] = Material.IronBars; + materials[2138] = Material.IronBlock; + for (int i = 8045; i <= 8050; i++) + materials[i] = Material.IronChain; + for (int i = 6596; i <= 6659; i++) + materials[i] = Material.IronDoor; + materials[131] = Material.IronOre; + for (int i = 12365; i <= 12428; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 6822; i <= 6825; i++) + materials[i] = Material.JackOLantern; + for (int i = 21524; i <= 21535; i++) + materials[i] = Material.Jigsaw; + for (int i = 6762; i <= 6763; i++) + materials[i] = Material.Jukebox; + for (int i = 10545; i <= 10568; i++) + materials[i] = Material.JungleButton; + for (int i = 13986; i <= 14049; i++) + materials[i] = Material.JungleDoor; + for (int i = 13634; i <= 13665; i++) + materials[i] = Material.JungleFence; + for (int i = 13346; i <= 13377; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 6026; i <= 6089; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + materials[18] = Material.JunglePlanks; + for (int i = 6666; i <= 6667; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 2783; i <= 2846; i++) + materials[i] = Material.JungleShelf; + for (int i = 5294; i <= 5325; i++) + materials[i] = Material.JungleSign; + for (int i = 13146; i <= 13151; i++) + materials[i] = Material.JungleSlab; + for (int i = 9687; i <= 9766; i++) + materials[i] = Material.JungleStairs; + for (int i = 7105; i <= 7168; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 6514; i <= 6521; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 5666; i <= 5673; i++) + materials[i] = Material.JungleWallSign; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 14860; i <= 14885; i++) + materials[i] = Material.Kelp; + materials[14886] = Material.KelpPlant; + for (int i = 5518; i <= 5525; i++) + materials[i] = Material.Ladder; + for (int i = 20635; i <= 20638; i++) + materials[i] = Material.Lantern; + materials[565] = Material.LapisBlock; + materials[563] = Material.LapisOre; + for (int i = 23214; i <= 23225; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 12723; i <= 12724; i++) + materials[i] = Material.LargeFern; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + materials[9263] = Material.LavaCauldron; + for (int i = 27644; i <= 27659; i++) + materials[i] = Material.LeafLitter; + for (int i = 20582; i <= 20597; i++) + materials[i] = Material.Lectern; + for (int i = 6570; i <= 6593; i++) + materials[i] = Material.Lever; + for (int i = 12333; i <= 12364; i++) + materials[i] = Material.Light; + for (int i = 12773; i <= 12788; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 22958; i <= 22973; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 23174; i <= 23175; i++) + materials[i] = Material.LightBlueCandleCake; + materials[12697] = Material.LightBlueCarpet; + materials[14831] = Material.LightBlueConcrete; + materials[14847] = Material.LightBlueConcretePowder; + for (int i = 14776; i <= 14779; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 14686; i <= 14691; i++) + materials[i] = Material.LightBlueShulkerBox; + materials[6900] = Material.LightBlueStainedGlass; + for (int i = 11354; i <= 11385; i++) + materials[i] = Material.LightBlueStainedGlassPane; + materials[11245] = Material.LightBlueTerracotta; + for (int i = 12993; i <= 12996; i++) + materials[i] = Material.LightBlueWallBanner; + materials[2096] = Material.LightBlueWool; + for (int i = 12853; i <= 12868; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 23038; i <= 23053; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 23184; i <= 23185; i++) + materials[i] = Material.LightGrayCandleCake; + materials[12702] = Material.LightGrayCarpet; + materials[14836] = Material.LightGrayConcrete; + materials[14852] = Material.LightGrayConcretePowder; + for (int i = 14796; i <= 14799; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 14716; i <= 14721; i++) + materials[i] = Material.LightGrayShulkerBox; + materials[6905] = Material.LightGrayStainedGlass; + for (int i = 11514; i <= 11545; i++) + materials[i] = Material.LightGrayStainedGlassPane; + materials[11250] = Material.LightGrayTerracotta; + for (int i = 13013; i <= 13016; i++) + materials[i] = Material.LightGrayWallBanner; + materials[2101] = Material.LightGrayWool; + for (int i = 11029; i <= 11044; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 27341; i <= 27364; i++) + materials[i] = Material.LightningRod; + for (int i = 12715; i <= 12716; i++) + materials[i] = Material.Lilac; + materials[2134] = Material.LilyOfTheValley; + materials[8719] = Material.LilyPad; + for (int i = 12805; i <= 12820; i++) + materials[i] = Material.LimeBanner; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; + for (int i = 22990; i <= 23005; i++) + materials[i] = Material.LimeCandle; + for (int i = 23178; i <= 23179; i++) + materials[i] = Material.LimeCandleCake; + materials[12699] = Material.LimeCarpet; + materials[14833] = Material.LimeConcrete; + materials[14849] = Material.LimeConcretePowder; + for (int i = 14784; i <= 14787; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 14698; i <= 14703; i++) + materials[i] = Material.LimeShulkerBox; + materials[6902] = Material.LimeStainedGlass; + for (int i = 11418; i <= 11449; i++) + materials[i] = Material.LimeStainedGlassPane; + materials[11247] = Material.LimeTerracotta; + for (int i = 13001; i <= 13004; i++) + materials[i] = Material.LimeWallBanner; + materials[2098] = Material.LimeWool; + materials[21628] = Material.Lodestone; + for (int i = 20536; i <= 20539; i++) + materials[i] = Material.Loom; + for (int i = 12757; i <= 12772; i++) + materials[i] = Material.MagentaBanner; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 22942; i <= 22957; i++) + materials[i] = Material.MagentaCandle; + for (int i = 23172; i <= 23173; i++) + materials[i] = Material.MagentaCandleCake; + materials[12696] = Material.MagentaCarpet; + materials[14830] = Material.MagentaConcrete; + materials[14846] = Material.MagentaConcretePowder; + for (int i = 14772; i <= 14775; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 14680; i <= 14685; i++) + materials[i] = Material.MagentaShulkerBox; + materials[6899] = Material.MagentaStainedGlass; + for (int i = 11322; i <= 11353; i++) + materials[i] = Material.MagentaStainedGlassPane; + materials[11244] = Material.MagentaTerracotta; + for (int i = 12989; i <= 12992; i++) + materials[i] = Material.MagentaWallBanner; + materials[2095] = Material.MagentaWool; + materials[14643] = Material.MagmaBlock; + for (int i = 10665; i <= 10688; i++) + materials[i] = Material.MangroveButton; + for (int i = 14306; i <= 14369; i++) + materials[i] = Material.MangroveDoor; + for (int i = 13794; i <= 13825; i++) + materials[i] = Material.MangroveFence; + for (int i = 13506; i <= 13537; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 6346; i <= 6409; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + materials[26] = Material.MangrovePlanks; + for (int i = 6676; i <= 6677; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 2847; i <= 2910; i++) + materials[i] = Material.MangroveShelf; + for (int i = 5390; i <= 5421; i++) + materials[i] = Material.MangroveSign; + for (int i = 13176; i <= 13181; i++) + materials[i] = Material.MangroveSlab; + for (int i = 12090; i <= 12169; i++) + materials[i] = Material.MangroveStairs; + for (int i = 7425; i <= 7488; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 6538; i <= 6545; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 5690; i <= 5697; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 23226; i <= 23237; i++) + materials[i] = Material.MediumAmethystBud; + materials[8132] = Material.Melon; + for (int i = 8149; i <= 8156; i++) + materials[i] = Material.MelonStem; + materials[27660] = Material.MossBlock; + materials[27611] = Material.MossCarpet; + materials[3167] = Material.MossyCobblestone; + for (int i = 16238; i <= 16243; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 15414; i <= 15493; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 10104; i <= 10427; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 16226; i <= 16231; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 15254; i <= 15333; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 17264; i <= 17587; i++) + materials[i] = Material.MossyStoneBrickWall; + materials[7554] = Material.MossyStoneBricks; + for (int i = 2109; i <= 2120; i++) + materials[i] = Material.MovingPiston; + materials[27720] = Material.Mud; + for (int i = 13242; i <= 13247; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 8637; i <= 8716; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 18236; i <= 18559; i++) + materials[i] = Material.MudBrickWall; + materials[7558] = Material.MudBricks; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 7693; i <= 7756; i++) + materials[i] = Material.MushroomStem; + for (int i = 8717; i <= 8718; i++) + materials[i] = Material.Mycelium; + for (int i = 9134; i <= 9165; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 13248; i <= 13253; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 9166; i <= 9245; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 18560; i <= 18883; i++) + materials[i] = Material.NetherBrickWall; + materials[9133] = Material.NetherBricks; + materials[135] = Material.NetherGoldOre; + for (int i = 6816; i <= 6817; i++) + materials[i] = Material.NetherPortal; + materials[11110] = Material.NetherQuartzOre; + materials[20759] = Material.NetherSprouts; + for (int i = 9246; i <= 9249; i++) + materials[i] = Material.NetherWart; + materials[14644] = Material.NetherWartBlock; + materials[21616] = Material.NetheriteBlock; + materials[6796] = Material.Netherrack; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 10473; i <= 10496; i++) + materials[i] = Material.OakButton; + for (int i = 5454; i <= 5517; i++) + materials[i] = Material.OakDoor; + for (int i = 6764; i <= 6795; i++) + materials[i] = Material.OakFence; + for (int i = 8445; i <= 8476; i++) + materials[i] = Material.OakFenceGate; + for (int i = 5706; i <= 5769; i++) + materials[i] = Material.OakHangingSign; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + materials[15] = Material.OakPlanks; + for (int i = 6660; i <= 6661; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 2911; i <= 2974; i++) + materials[i] = Material.OakShelf; + for (int i = 5134; i <= 5165; i++) + materials[i] = Material.OakSign; + for (int i = 13128; i <= 13133; i++) + materials[i] = Material.OakSlab; + for (int i = 3706; i <= 3785; i++) + materials[i] = Material.OakStairs; + for (int i = 6913; i <= 6976; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 6474; i <= 6481; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 5626; i <= 5633; i++) + materials[i] = Material.OakWallSign; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 14650; i <= 14661; i++) + materials[i] = Material.Observer; + materials[3168] = Material.Obsidian; + for (int i = 29380; i <= 29382; i++) + materials[i] = Material.OchreFroglight; + materials[29666] = Material.OpenEyeblossom; + for (int i = 12741; i <= 12756; i++) + materials[i] = Material.OrangeBanner; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 22926; i <= 22941; i++) + materials[i] = Material.OrangeCandle; + for (int i = 23170; i <= 23171; i++) + materials[i] = Material.OrangeCandleCake; + materials[12695] = Material.OrangeCarpet; + materials[14829] = Material.OrangeConcrete; + materials[14845] = Material.OrangeConcretePowder; + for (int i = 14768; i <= 14771; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 14674; i <= 14679; i++) + materials[i] = Material.OrangeShulkerBox; + materials[6898] = Material.OrangeStainedGlass; + for (int i = 11290; i <= 11321; i++) + materials[i] = Material.OrangeStainedGlassPane; + materials[11243] = Material.OrangeTerracotta; + materials[2128] = Material.OrangeTulip; + for (int i = 12985; i <= 12988; i++) + materials[i] = Material.OrangeWallBanner; + materials[2094] = Material.OrangeWool; + materials[2131] = Material.OxeyeDaisy; + materials[25117] = Material.OxidizedChiseledCopper; + materials[25110] = Material.OxidizedCopper; + for (int i = 7885; i <= 7916; i++) + materials[i] = Material.OxidizedCopperBars; + for (int i = 26873; i <= 26876; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 8069; i <= 8074; i++) + materials[i] = Material.OxidizedCopperChain; + for (int i = 26965; i <= 26988; i++) + materials[i] = Material.OxidizedCopperChest; + for (int i = 25949; i <= 26012; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 27181; i <= 27212; i++) + materials[i] = Material.OxidizedCopperGolemStatue; + for (int i = 26851; i <= 26852; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 20655; i <= 20658; i++) + materials[i] = Material.OxidizedCopperLantern; + for (int i = 26461; i <= 26524; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + materials[25113] = Material.OxidizedCutCopper; + for (int i = 25445; i <= 25450; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 25125; i <= 25204; i++) + materials[i] = Material.OxidizedCutCopperStairs; + for (int i = 27413; i <= 27436; i++) + materials[i] = Material.OxidizedLightningRod; + materials[12712] = Material.PackedIce; + materials[7557] = Material.PackedMud; + for (int i = 29664; i <= 29665; i++) + materials[i] = Material.PaleHangingMoss; + materials[29501] = Material.PaleMossBlock; + for (int i = 29502; i <= 29663; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 10641; i <= 10664; i++) + materials[i] = Material.PaleOakButton; + for (int i = 14242; i <= 14305; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 13762; i <= 13793; i++) + materials[i] = Material.PaleOakFence; + for (int i = 13474; i <= 13505; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 6154; i <= 6217; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + materials[25] = Material.PaleOakPlanks; + for (int i = 6674; i <= 6675; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 2975; i <= 3038; i++) + materials[i] = Material.PaleOakShelf; + for (int i = 5358; i <= 5389; i++) + materials[i] = Material.PaleOakSign; + for (int i = 13170; i <= 13175; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 12010; i <= 12089; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 7361; i <= 7424; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 6530; i <= 6537; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 5682; i <= 5689; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 29386; i <= 29388; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 12719; i <= 12720; i++) + materials[i] = Material.Peony; + for (int i = 13218; i <= 13223; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 10953; i <= 10984; i++) + materials[i] = Material.PiglinHead; + for (int i = 10985; i <= 10992; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 12821; i <= 12836; i++) + materials[i] = Material.PinkBanner; + for (int i = 1827; i <= 1842; i++) + materials[i] = Material.PinkBed; + for (int i = 23006; i <= 23021; i++) + materials[i] = Material.PinkCandle; + for (int i = 23180; i <= 23181; i++) + materials[i] = Material.PinkCandleCake; + materials[12700] = Material.PinkCarpet; + materials[14834] = Material.PinkConcrete; + materials[14850] = Material.PinkConcretePowder; + for (int i = 14788; i <= 14791; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 27612; i <= 27627; i++) + materials[i] = Material.PinkPetals; + for (int i = 14704; i <= 14709; i++) + materials[i] = Material.PinkShulkerBox; + materials[6903] = Material.PinkStainedGlass; + for (int i = 11450; i <= 11481; i++) + materials[i] = Material.PinkStainedGlassPane; + materials[11248] = Material.PinkTerracotta; + materials[2130] = Material.PinkTulip; + for (int i = 13005; i <= 13008; i++) + materials[i] = Material.PinkWallBanner; + materials[2099] = Material.PinkWool; + for (int i = 2057; i <= 2068; i++) + materials[i] = Material.Piston; + for (int i = 2069; i <= 2092; i++) + materials[i] = Material.PistonHead; + for (int i = 14597; i <= 14606; i++) + materials[i] = Material.PitcherCrop; + for (int i = 14607; i <= 14608; i++) + materials[i] = Material.PitcherPlant; + for (int i = 10833; i <= 10864; i++) + materials[i] = Material.PlayerHead; + for (int i = 10865; i <= 10872; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 27533; i <= 27552; i++) + materials[i] = Material.PointedDripstone; + materials[7] = Material.PolishedAndesite; + for (int i = 16280; i <= 16285; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 16054; i <= 16133; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 6802; i <= 6804; i++) + materials[i] = Material.PolishedBasalt; + materials[22040] = Material.PolishedBlackstone; + for (int i = 22044; i <= 22049; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 22050; i <= 22129; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 22130; i <= 22453; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + materials[22041] = Material.PolishedBlackstoneBricks; + for (int i = 22543; i <= 22566; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 22541; i <= 22542; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 22535; i <= 22540; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 22455; i <= 22534; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 22567; i <= 22890; i++) + materials[i] = Material.PolishedBlackstoneWall; + materials[28135] = Material.PolishedDeepslate; + for (int i = 28216; i <= 28221; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 28136; i <= 28215; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 28222; i <= 28545; i++) + materials[i] = Material.PolishedDeepslateWall; + materials[5] = Material.PolishedDiorite; + for (int i = 16232; i <= 16237; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 15334; i <= 15413; i++) + materials[i] = Material.PolishedDioriteStairs; + materials[3] = Material.PolishedGranite; + for (int i = 16214; i <= 16219; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 15094; i <= 15173; i++) + materials[i] = Material.PolishedGraniteStairs; + materials[23661] = Material.PolishedTuff; + for (int i = 23662; i <= 23667; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 23668; i <= 23747; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 23748; i <= 24071; i++) + materials[i] = Material.PolishedTuffWall; + materials[2123] = Material.Poppy; + for (int i = 10465; i <= 10472; i++) + materials[i] = Material.Potatoes; + materials[10434] = Material.PottedAcaciaSapling; + materials[10443] = Material.PottedAllium; + materials[29378] = Material.PottedAzaleaBush; + materials[10444] = Material.PottedAzureBluet; + materials[15089] = Material.PottedBamboo; + materials[10432] = Material.PottedBirchSapling; + materials[10442] = Material.PottedBlueOrchid; + materials[10454] = Material.PottedBrownMushroom; + materials[10456] = Material.PottedCactus; + materials[10435] = Material.PottedCherrySapling; + materials[29669] = Material.PottedClosedEyeblossom; + materials[10450] = Material.PottedCornflower; + materials[21624] = Material.PottedCrimsonFungus; + materials[21626] = Material.PottedCrimsonRoots; + materials[10440] = Material.PottedDandelion; + materials[10436] = Material.PottedDarkOakSapling; + materials[10455] = Material.PottedDeadBush; + materials[10439] = Material.PottedFern; + materials[29379] = Material.PottedFloweringAzaleaBush; + materials[10433] = Material.PottedJungleSapling; + materials[10451] = Material.PottedLilyOfTheValley; + materials[10438] = Material.PottedMangrovePropagule; + materials[10430] = Material.PottedOakSapling; + materials[29668] = Material.PottedOpenEyeblossom; + materials[10446] = Material.PottedOrangeTulip; + materials[10449] = Material.PottedOxeyeDaisy; + materials[10437] = Material.PottedPaleOakSapling; + materials[10448] = Material.PottedPinkTulip; + materials[10441] = Material.PottedPoppy; + materials[10453] = Material.PottedRedMushroom; + materials[10445] = Material.PottedRedTulip; + materials[10431] = Material.PottedSpruceSapling; + materials[10429] = Material.PottedTorchflower; + materials[21625] = Material.PottedWarpedFungus; + materials[21627] = Material.PottedWarpedRoots; + materials[10447] = Material.PottedWhiteTulip; + materials[10452] = Material.PottedWitherRose; + materials[24487] = Material.PowderSnow; + for (int i = 9264; i <= 9266; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + materials[12429] = Material.Prismarine; + for (int i = 12678; i <= 12683; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 12512; i <= 12591; i++) + materials[i] = Material.PrismarineBrickStairs; + materials[12430] = Material.PrismarineBricks; + for (int i = 12672; i <= 12677; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 12432; i <= 12511; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 16616; i <= 16939; i++) + materials[i] = Material.PrismarineWall; + materials[8131] = Material.Pumpkin; + for (int i = 8141; i <= 8148; i++) + materials[i] = Material.PumpkinStem; + for (int i = 12885; i <= 12900; i++) + materials[i] = Material.PurpleBanner; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 23070; i <= 23085; i++) + materials[i] = Material.PurpleCandle; + for (int i = 23188; i <= 23189; i++) + materials[i] = Material.PurpleCandleCake; + materials[12704] = Material.PurpleCarpet; + materials[14838] = Material.PurpleConcrete; + materials[14854] = Material.PurpleConcretePowder; + for (int i = 14804; i <= 14807; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 14728; i <= 14733; i++) + materials[i] = Material.PurpleShulkerBox; + materials[6907] = Material.PurpleStainedGlass; + for (int i = 11578; i <= 11609; i++) + materials[i] = Material.PurpleStainedGlassPane; + materials[11252] = Material.PurpleTerracotta; + for (int i = 13021; i <= 13024; i++) + materials[i] = Material.PurpleWallBanner; + materials[2103] = Material.PurpleWool; + materials[14510] = Material.PurpurBlock; + for (int i = 14511; i <= 14513; i++) + materials[i] = Material.PurpurPillar; + for (int i = 13272; i <= 13277; i++) + materials[i] = Material.PurpurSlab; + for (int i = 14514; i <= 14593; i++) + materials[i] = Material.PurpurStairs; + materials[11121] = Material.QuartzBlock; + materials[22893] = Material.QuartzBricks; + for (int i = 11123; i <= 11125; i++) + materials[i] = Material.QuartzPillar; + for (int i = 13254; i <= 13259; i++) + materials[i] = Material.QuartzSlab; + for (int i = 11126; i <= 11205; i++) + materials[i] = Material.QuartzStairs; + for (int i = 5526; i <= 5545; i++) + materials[i] = Material.Rail; + materials[29376] = Material.RawCopperBlock; + materials[29377] = Material.RawGoldBlock; + materials[29375] = Material.RawIronBlock; + for (int i = 12949; i <= 12964; i++) + materials[i] = Material.RedBanner; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 23134; i <= 23149; i++) + materials[i] = Material.RedCandle; + for (int i = 23196; i <= 23197; i++) + materials[i] = Material.RedCandleCake; + materials[12708] = Material.RedCarpet; + materials[14842] = Material.RedConcrete; + materials[14858] = Material.RedConcretePowder; + for (int i = 14820; i <= 14823; i++) + materials[i] = Material.RedGlazedTerracotta; + materials[2136] = Material.RedMushroom; + for (int i = 7629; i <= 7692; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 16274; i <= 16279; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 15974; i <= 16053; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 19208; i <= 19531; i++) + materials[i] = Material.RedNetherBrickWall; + materials[14645] = Material.RedNetherBricks; + materials[123] = Material.RedSand; + materials[13045] = Material.RedSandstone; + for (int i = 13260; i <= 13265; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 13048; i <= 13127; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 16940; i <= 17263; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 14752; i <= 14757; i++) + materials[i] = Material.RedShulkerBox; + materials[6911] = Material.RedStainedGlass; + for (int i = 11706; i <= 11737; i++) + materials[i] = Material.RedStainedGlassPane; + materials[11256] = Material.RedTerracotta; + materials[2127] = Material.RedTulip; + for (int i = 13037; i <= 13040; i++) + materials[i] = Material.RedWallBanner; + materials[2107] = Material.RedWool; + materials[11109] = Material.RedstoneBlock; + for (int i = 9278; i <= 9279; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 6680; i <= 6681; i++) + materials[i] = Material.RedstoneOre; + for (int i = 6684; i <= 6685; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 6686; i <= 6693; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 3810; i <= 5105; i++) + materials[i] = Material.RedstoneWire; + materials[29390] = Material.ReinforcedDeepslate; + for (int i = 6833; i <= 6896; i++) + materials[i] = Material.Repeater; + for (int i = 14615; i <= 14626; i++) + materials[i] = Material.RepeatingCommandBlock; + materials[8720] = Material.ResinBlock; + for (int i = 8802; i <= 8807; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 8722; i <= 8801; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 8808; i <= 9131; i++) + materials[i] = Material.ResinBrickWall; + materials[8721] = Material.ResinBricks; + for (int i = 8317; i <= 8444; i++) + materials[i] = Material.ResinClump; + for (int i = 21619; i <= 21623; i++) + materials[i] = Material.RespawnAnchor; + materials[27719] = Material.RootedDirt; + for (int i = 12717; i <= 12718; i++) + materials[i] = Material.RoseBush; + materials[118] = Material.Sand; + materials[578] = Material.Sandstone; + for (int i = 13206; i <= 13211; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 9292; i <= 9371; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 19532; i <= 19855; i++) + materials[i] = Material.SandstoneWall; + for (int i = 20504; i <= 20535; i++) + materials[i] = Material.Scaffolding; + materials[24968] = Material.Sculk; + for (int i = 25097; i <= 25098; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 24488; i <= 24583; i++) + materials[i] = Material.SculkSensor; + for (int i = 25099; i <= 25106; i++) + materials[i] = Material.SculkShrieker; + for (int i = 24969; i <= 25096; i++) + materials[i] = Material.SculkVein; + materials[12690] = Material.SeaLantern; + for (int i = 15065; i <= 15072; i++) + materials[i] = Material.SeaPickle; + materials[2054] = Material.Seagrass; + materials[2052] = Material.ShortDryGrass; + materials[2048] = Material.ShortGrass; + materials[20774] = Material.Shroomlight; + for (int i = 14662; i <= 14667; i++) + materials[i] = Material.ShulkerBox; + for (int i = 10713; i <= 10744; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 10745; i <= 10752; i++) + materials[i] = Material.SkeletonWallSkull; + materials[12330] = Material.SlimeBlock; + for (int i = 23238; i <= 23249; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 27701; i <= 27716; i++) + materials[i] = Material.SmallDripleaf; + materials[20598] = Material.SmithingTable; + for (int i = 20552; i <= 20559; i++) + materials[i] = Material.Smoker; + materials[29374] = Material.SmoothBasalt; + materials[13280] = Material.SmoothQuartz; + for (int i = 16256; i <= 16261; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 15734; i <= 15813; i++) + materials[i] = Material.SmoothQuartzStairs; + materials[13281] = Material.SmoothRedSandstone; + for (int i = 16220; i <= 16225; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 15174; i <= 15253; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + materials[13279] = Material.SmoothSandstone; + for (int i = 16250; i <= 16255; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 15654; i <= 15733; i++) + materials[i] = Material.SmoothSandstoneStairs; + materials[13278] = Material.SmoothStone; + for (int i = 13200; i <= 13205; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 14900; i <= 14902; i++) + materials[i] = Material.SnifferEgg; + for (int i = 6718; i <= 6725; i++) + materials[i] = Material.Snow; + materials[6727] = Material.SnowBlock; + for (int i = 20707; i <= 20738; i++) + materials[i] = Material.SoulCampfire; + materials[3686] = Material.SoulFire; + for (int i = 20639; i <= 20642; i++) + materials[i] = Material.SoulLantern; + materials[6797] = Material.SoulSand; + materials[6798] = Material.SoulSoil; + materials[6805] = Material.SoulTorch; + for (int i = 6806; i <= 6809; i++) + materials[i] = Material.SoulWallTorch; + materials[3687] = Material.Spawner; + materials[560] = Material.Sponge; + materials[27608] = Material.SporeBlossom; + for (int i = 10497; i <= 10520; i++) + materials[i] = Material.SpruceButton; + for (int i = 13858; i <= 13921; i++) + materials[i] = Material.SpruceDoor; + for (int i = 13570; i <= 13601; i++) + materials[i] = Material.SpruceFence; + for (int i = 13282; i <= 13313; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 5770; i <= 5833; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + materials[16] = Material.SprucePlanks; + for (int i = 6662; i <= 6663; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 3039; i <= 3102; i++) + materials[i] = Material.SpruceShelf; + for (int i = 5166; i <= 5197; i++) + materials[i] = Material.SpruceSign; + for (int i = 13134; i <= 13139; i++) + materials[i] = Material.SpruceSlab; + for (int i = 9527; i <= 9606; i++) + materials[i] = Material.SpruceStairs; + for (int i = 6977; i <= 7040; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 6482; i <= 6489; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 5634; i <= 5641; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + materials[1] = Material.Stone; + for (int i = 13236; i <= 13241; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 8557; i <= 8636; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 17912; i <= 18235; i++) + materials[i] = Material.StoneBrickWall; + materials[7553] = Material.StoneBricks; + for (int i = 6694; i <= 6717; i++) + materials[i] = Material.StoneButton; + for (int i = 6594; i <= 6595; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 13194; i <= 13199; i++) + materials[i] = Material.StoneSlab; + for (int i = 15574; i <= 15653; i++) + materials[i] = Material.StoneStairs; + for (int i = 20599; i <= 20602; i++) + materials[i] = Material.Stonecutter; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 20769; i <= 20771; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 20763; i <= 20765; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 20752; i <= 20754; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 20746; i <= 20748; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 21520; i <= 21523; i++) + materials[i] = Material.StructureBlock; + materials[14649] = Material.StructureVoid; + for (int i = 6746; i <= 6761; i++) + materials[i] = Material.SugarCane; + for (int i = 12713; i <= 12714; i++) + materials[i] = Material.Sunflower; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 20739; i <= 20742; i++) + materials[i] = Material.SweetBerryBush; + materials[2053] = Material.TallDryGrass; + for (int i = 12721; i <= 12722; i++) + materials[i] = Material.TallGrass; + for (int i = 2055; i <= 2056; i++) + materials[i] = Material.TallSeagrass; + for (int i = 21550; i <= 21565; i++) + materials[i] = Material.Target; + materials[12710] = Material.Terracotta; + for (int i = 21536; i <= 21539; i++) + materials[i] = Material.TestBlock; + materials[21540] = Material.TestInstanceBlock; + materials[24486] = Material.TintedGlass; + for (int i = 2140; i <= 2141; i++) + materials[i] = Material.Tnt; + materials[3169] = Material.Torch; + materials[2122] = Material.Torchflower; + for (int i = 14595; i <= 14596; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 11005; i <= 11028; i++) + materials[i] = Material.TrappedChest; + for (int i = 29455; i <= 29466; i++) + materials[i] = Material.TrialSpawner; + for (int i = 9398; i <= 9525; i++) + materials[i] = Material.Tripwire; + for (int i = 9382; i <= 9397; i++) + materials[i] = Material.TripwireHook; + for (int i = 14955; i <= 14956; i++) + materials[i] = Material.TubeCoral; + materials[14940] = Material.TubeCoralBlock; + for (int i = 14975; i <= 14976; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 15025; i <= 15032; i++) + materials[i] = Material.TubeCoralWallFan; + materials[23250] = Material.Tuff; + for (int i = 24074; i <= 24079; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 24080; i <= 24159; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 24160; i <= 24483; i++) + materials[i] = Material.TuffBrickWall; + materials[24073] = Material.TuffBricks; + for (int i = 23251; i <= 23256; i++) + materials[i] = Material.TuffSlab; + for (int i = 23257; i <= 23336; i++) + materials[i] = Material.TuffStairs; + for (int i = 23337; i <= 23660; i++) + materials[i] = Material.TuffWall; + for (int i = 14888; i <= 14899; i++) + materials[i] = Material.TurtleEgg; + for (int i = 20802; i <= 20827; i++) + materials[i] = Material.TwistingVines; + materials[20828] = Material.TwistingVinesPlant; + for (int i = 29467; i <= 29498; i++) + materials[i] = Material.Vault; + for (int i = 29383; i <= 29385; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 8157; i <= 8188; i++) + materials[i] = Material.Vine; + materials[15090] = Material.VoidAir; + for (int i = 3170; i <= 3173; i++) + materials[i] = Material.WallTorch; + for (int i = 21288; i <= 21311; i++) + materials[i] = Material.WarpedButton; + for (int i = 21376; i <= 21439; i++) + materials[i] = Material.WarpedDoor; + for (int i = 20880; i <= 20911; i++) + materials[i] = Material.WarpedFence; + for (int i = 21072; i <= 21103; i++) + materials[i] = Material.WarpedFenceGate; + materials[20756] = Material.WarpedFungus; + for (int i = 6282; i <= 6345; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 20749; i <= 20751; i++) + materials[i] = Material.WarpedHyphae; + materials[20755] = Material.WarpedNylium; + materials[20831] = Material.WarpedPlanks; + for (int i = 20846; i <= 20847; i++) + materials[i] = Material.WarpedPressurePlate; + materials[20758] = Material.WarpedRoots; + for (int i = 3103; i <= 3166; i++) + materials[i] = Material.WarpedShelf; + for (int i = 21472; i <= 21503; i++) + materials[i] = Material.WarpedSign; + for (int i = 20838; i <= 20843; i++) + materials[i] = Material.WarpedSlab; + for (int i = 21184; i <= 21263; i++) + materials[i] = Material.WarpedStairs; + for (int i = 20743; i <= 20745; i++) + materials[i] = Material.WarpedStem; + for (int i = 20976; i <= 21039; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 6554; i <= 6561; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 21512; i <= 21519; i++) + materials[i] = Material.WarpedWallSign; + materials[20757] = Material.WarpedWartBlock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 9260; i <= 9262; i++) + materials[i] = Material.WaterCauldron; + materials[25124] = Material.WaxedChiseledCopper; + for (int i = 7917; i <= 7948; i++) + materials[i] = Material.WaxedCopperBars; + materials[25469] = Material.WaxedCopperBlock; + for (int i = 26877; i <= 26880; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 8075; i <= 8080; i++) + materials[i] = Material.WaxedCopperChain; + for (int i = 26989; i <= 27012; i++) + materials[i] = Material.WaxedCopperChest; + for (int i = 26077; i <= 26140; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 27213; i <= 27244; i++) + materials[i] = Material.WaxedCopperGolemStatue; + for (int i = 26853; i <= 26854; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 20659; i <= 20662; i++) + materials[i] = Material.WaxedCopperLantern; + for (int i = 26589; i <= 26652; i++) + materials[i] = Material.WaxedCopperTrapdoor; + materials[25476] = Material.WaxedCutCopper; + for (int i = 25815; i <= 25820; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 25717; i <= 25796; i++) + materials[i] = Material.WaxedCutCopperStairs; + materials[25123] = Material.WaxedExposedChiseledCopper; + materials[25471] = Material.WaxedExposedCopper; + for (int i = 7949; i <= 7980; i++) + materials[i] = Material.WaxedExposedCopperBars; + for (int i = 26881; i <= 26884; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 8081; i <= 8086; i++) + materials[i] = Material.WaxedExposedCopperChain; + for (int i = 27013; i <= 27036; i++) + materials[i] = Material.WaxedExposedCopperChest; + for (int i = 26141; i <= 26204; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 27245; i <= 27276; i++) + materials[i] = Material.WaxedExposedCopperGolemStatue; + for (int i = 26855; i <= 26856; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 20663; i <= 20666; i++) + materials[i] = Material.WaxedExposedCopperLantern; + for (int i = 26653; i <= 26716; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + materials[25475] = Material.WaxedExposedCutCopper; + for (int i = 25809; i <= 25814; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 25637; i <= 25716; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + for (int i = 27461; i <= 27484; i++) + materials[i] = Material.WaxedExposedLightningRod; + for (int i = 27437; i <= 27460; i++) + materials[i] = Material.WaxedLightningRod; + materials[25121] = Material.WaxedOxidizedChiseledCopper; + materials[25472] = Material.WaxedOxidizedCopper; + for (int i = 8013; i <= 8044; i++) + materials[i] = Material.WaxedOxidizedCopperBars; + for (int i = 26889; i <= 26892; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 8093; i <= 8098; i++) + materials[i] = Material.WaxedOxidizedCopperChain; + for (int i = 27061; i <= 27084; i++) + materials[i] = Material.WaxedOxidizedCopperChest; + for (int i = 26205; i <= 26268; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 27309; i <= 27340; i++) + materials[i] = Material.WaxedOxidizedCopperGolemStatue; + for (int i = 26859; i <= 26860; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 20671; i <= 20674; i++) + materials[i] = Material.WaxedOxidizedCopperLantern; + for (int i = 26717; i <= 26780; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + materials[25473] = Material.WaxedOxidizedCutCopper; + for (int i = 25797; i <= 25802; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 25477; i <= 25556; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + for (int i = 27509; i <= 27532; i++) + materials[i] = Material.WaxedOxidizedLightningRod; + materials[25122] = Material.WaxedWeatheredChiseledCopper; + materials[25470] = Material.WaxedWeatheredCopper; + for (int i = 7981; i <= 8012; i++) + materials[i] = Material.WaxedWeatheredCopperBars; + for (int i = 26885; i <= 26888; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 8087; i <= 8092; i++) + materials[i] = Material.WaxedWeatheredCopperChain; + for (int i = 27037; i <= 27060; i++) + materials[i] = Material.WaxedWeatheredCopperChest; + for (int i = 26269; i <= 26332; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 27277; i <= 27308; i++) + materials[i] = Material.WaxedWeatheredCopperGolemStatue; + for (int i = 26857; i <= 26858; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 20667; i <= 20670; i++) + materials[i] = Material.WaxedWeatheredCopperLantern; + for (int i = 26781; i <= 26844; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + materials[25474] = Material.WaxedWeatheredCutCopper; + for (int i = 25803; i <= 25808; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 25557; i <= 25636; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + for (int i = 27485; i <= 27508; i++) + materials[i] = Material.WaxedWeatheredLightningRod; + materials[25118] = Material.WeatheredChiseledCopper; + materials[25109] = Material.WeatheredCopper; + for (int i = 7853; i <= 7884; i++) + materials[i] = Material.WeatheredCopperBars; + for (int i = 26869; i <= 26872; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 8063; i <= 8068; i++) + materials[i] = Material.WeatheredCopperChain; + for (int i = 26941; i <= 26964; i++) + materials[i] = Material.WeatheredCopperChest; + for (int i = 26013; i <= 26076; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 27149; i <= 27180; i++) + materials[i] = Material.WeatheredCopperGolemStatue; + for (int i = 26849; i <= 26850; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 20651; i <= 20654; i++) + materials[i] = Material.WeatheredCopperLantern; + for (int i = 26525; i <= 26588; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + materials[25114] = Material.WeatheredCutCopper; + for (int i = 25451; i <= 25456; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 25205; i <= 25284; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 27389; i <= 27412; i++) + materials[i] = Material.WeatheredLightningRod; + for (int i = 20775; i <= 20800; i++) + materials[i] = Material.WeepingVines; + materials[20801] = Material.WeepingVinesPlant; + materials[561] = Material.WetSponge; + for (int i = 5110; i <= 5117; i++) + materials[i] = Material.Wheat; + for (int i = 12725; i <= 12740; i++) + materials[i] = Material.WhiteBanner; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 22910; i <= 22925; i++) + materials[i] = Material.WhiteCandle; + for (int i = 23168; i <= 23169; i++) + materials[i] = Material.WhiteCandleCake; + materials[12694] = Material.WhiteCarpet; + materials[14828] = Material.WhiteConcrete; + materials[14844] = Material.WhiteConcretePowder; + for (int i = 14764; i <= 14767; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 14668; i <= 14673; i++) + materials[i] = Material.WhiteShulkerBox; + materials[6897] = Material.WhiteStainedGlass; + for (int i = 11258; i <= 11289; i++) + materials[i] = Material.WhiteStainedGlassPane; + materials[11242] = Material.WhiteTerracotta; + materials[2129] = Material.WhiteTulip; + for (int i = 12981; i <= 12984; i++) + materials[i] = Material.WhiteWallBanner; + materials[2093] = Material.WhiteWool; + for (int i = 27628; i <= 27643; i++) + materials[i] = Material.Wildflowers; + materials[2133] = Material.WitherRose; + for (int i = 10753; i <= 10784; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 10785; i <= 10792; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 12789; i <= 12804; i++) + materials[i] = Material.YellowBanner; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 22974; i <= 22989; i++) + materials[i] = Material.YellowCandle; + for (int i = 23176; i <= 23177; i++) + materials[i] = Material.YellowCandleCake; + materials[12698] = Material.YellowCarpet; + materials[14832] = Material.YellowConcrete; + materials[14848] = Material.YellowConcretePowder; + for (int i = 14780; i <= 14783; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 14692; i <= 14697; i++) + materials[i] = Material.YellowShulkerBox; + materials[6901] = Material.YellowStainedGlass; + for (int i = 11386; i <= 11417; i++) + materials[i] = Material.YellowStainedGlassPane; + materials[11246] = Material.YellowTerracotta; + for (int i = 12997; i <= 13000; i++) + materials[i] = Material.YellowWallBanner; + materials[2097] = Material.YellowWool; + for (int i = 10793; i <= 10824; i++) + materials[i] = Material.ZombieHead; + for (int i = 10825; i <= 10832; i++) + materials[i] = Material.ZombieWallHead; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1219.cs b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1219.cs new file mode 100644 index 00000000..2fa5d35e --- /dev/null +++ b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1219.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityMetadataPalettes; + +public class EntityMetadataPalette1219 : EntityMetadataPalette +{ + private readonly Dictionary entityMetadataMappings = new() + { + { 0, EntityMetaDataType.Byte }, + { 1, EntityMetaDataType.VarInt }, + { 2, EntityMetaDataType.VarLong }, + { 3, EntityMetaDataType.Float }, + { 4, EntityMetaDataType.String }, + { 5, EntityMetaDataType.Chat }, + { 6, EntityMetaDataType.OptionalChat }, + { 7, EntityMetaDataType.Slot }, + { 8, EntityMetaDataType.Boolean }, + { 9, EntityMetaDataType.Rotation }, + { 10, EntityMetaDataType.Position }, + { 11, EntityMetaDataType.OptionalPosition }, + { 12, EntityMetaDataType.Direction }, + { 13, EntityMetaDataType.OptionalLivingEntityReference }, + { 14, EntityMetaDataType.BlockId }, + { 15, EntityMetaDataType.OptionalBlockId }, + { 16, EntityMetaDataType.Particle }, + { 17, EntityMetaDataType.Particles }, + { 18, EntityMetaDataType.VillagerData }, + { 19, EntityMetaDataType.OptionalVarInt }, + { 20, EntityMetaDataType.Pose }, + { 21, EntityMetaDataType.CatVariant }, + { 22, EntityMetaDataType.CowVariant }, + { 23, EntityMetaDataType.WolfVariant }, + { 24, EntityMetaDataType.WolfSoundVariant }, + { 25, EntityMetaDataType.FrogVariant }, + { 26, EntityMetaDataType.PigVariant }, + { 27, EntityMetaDataType.ChickenVariant }, + { 28, EntityMetaDataType.OptionalGlobalPosition }, + { 29, EntityMetaDataType.PaintingVariant }, + { 30, EntityMetaDataType.SnifferState }, + { 31, EntityMetaDataType.ArmadilloState }, + { 32, EntityMetaDataType.CopperGolemState }, + { 33, EntityMetaDataType.WeatheringCopperState }, + { 34, EntityMetaDataType.Vector3 }, + { 35, EntityMetaDataType.Quaternion }, + { 36, EntityMetaDataType.ResolvableProfile }, + }; + + public override Dictionary GetEntityMetadataMappingsList() + { + return entityMetadataMappings; + } +} diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1219.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1219.cs new file mode 100644 index 00000000..448bdbcc --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1219.cs @@ -0,0 +1,171 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette1219 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette1219() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.Cat; + mappings[21] = EntityType.CaveSpider; + mappings[22] = EntityType.CherryBoat; + mappings[23] = EntityType.CherryChestBoat; + mappings[24] = EntityType.ChestMinecart; + mappings[25] = EntityType.Chicken; + mappings[26] = EntityType.Cod; + mappings[27] = EntityType.CopperGolem; + mappings[28] = EntityType.CommandBlockMinecart; + mappings[29] = EntityType.Cow; + mappings[30] = EntityType.Creaking; + mappings[31] = EntityType.Creeper; + mappings[32] = EntityType.DarkOakBoat; + mappings[33] = EntityType.DarkOakChestBoat; + mappings[34] = EntityType.Dolphin; + mappings[35] = EntityType.Donkey; + mappings[36] = EntityType.DragonFireball; + mappings[37] = EntityType.Drowned; + mappings[38] = EntityType.Egg; + mappings[39] = EntityType.ElderGuardian; + mappings[40] = EntityType.Enderman; + mappings[41] = EntityType.Endermite; + mappings[42] = EntityType.EnderDragon; + mappings[43] = EntityType.EnderPearl; + mappings[44] = EntityType.EndCrystal; + mappings[45] = EntityType.Evoker; + mappings[46] = EntityType.EvokerFangs; + mappings[47] = EntityType.ExperienceBottle; + mappings[48] = EntityType.ExperienceOrb; + mappings[49] = EntityType.EyeOfEnder; + mappings[50] = EntityType.FallingBlock; + mappings[51] = EntityType.Fireball; + mappings[52] = EntityType.FireworkRocket; + mappings[53] = EntityType.Fox; + mappings[54] = EntityType.Frog; + mappings[55] = EntityType.FurnaceMinecart; + mappings[56] = EntityType.Ghast; + mappings[57] = EntityType.HappyGhast; + mappings[58] = EntityType.Giant; + mappings[59] = EntityType.GlowItemFrame; + mappings[60] = EntityType.GlowSquid; + mappings[61] = EntityType.Goat; + mappings[62] = EntityType.Guardian; + mappings[63] = EntityType.Hoglin; + mappings[64] = EntityType.HopperMinecart; + mappings[65] = EntityType.Horse; + mappings[66] = EntityType.Husk; + mappings[67] = EntityType.Illusioner; + mappings[68] = EntityType.Interaction; + mappings[69] = EntityType.IronGolem; + mappings[70] = EntityType.Item; + mappings[71] = EntityType.ItemDisplay; + mappings[72] = EntityType.ItemFrame; + mappings[73] = EntityType.JungleBoat; + mappings[74] = EntityType.JungleChestBoat; + mappings[75] = EntityType.LeashKnot; + mappings[76] = EntityType.LightningBolt; + mappings[77] = EntityType.Llama; + mappings[78] = EntityType.LlamaSpit; + mappings[79] = EntityType.MagmaCube; + mappings[80] = EntityType.MangroveBoat; + mappings[81] = EntityType.MangroveChestBoat; + mappings[82] = EntityType.Mannequin; + mappings[83] = EntityType.Marker; + mappings[84] = EntityType.Minecart; + mappings[85] = EntityType.Mooshroom; + mappings[86] = EntityType.Mule; + mappings[87] = EntityType.OakBoat; + mappings[88] = EntityType.OakChestBoat; + mappings[89] = EntityType.Ocelot; + mappings[90] = EntityType.OminousItemSpawner; + mappings[91] = EntityType.Painting; + mappings[92] = EntityType.PaleOakBoat; + mappings[93] = EntityType.PaleOakChestBoat; + mappings[94] = EntityType.Panda; + mappings[95] = EntityType.Parrot; + mappings[96] = EntityType.Phantom; + mappings[97] = EntityType.Pig; + mappings[98] = EntityType.Piglin; + mappings[99] = EntityType.PiglinBrute; + mappings[100] = EntityType.Pillager; + mappings[101] = EntityType.PolarBear; + mappings[102] = EntityType.SplashPotion; + mappings[103] = EntityType.LingeringPotion; + mappings[104] = EntityType.Pufferfish; + mappings[105] = EntityType.Rabbit; + mappings[106] = EntityType.Ravager; + mappings[107] = EntityType.Salmon; + mappings[108] = EntityType.Sheep; + mappings[109] = EntityType.Shulker; + mappings[110] = EntityType.ShulkerBullet; + mappings[111] = EntityType.Silverfish; + mappings[112] = EntityType.Skeleton; + mappings[113] = EntityType.SkeletonHorse; + mappings[114] = EntityType.Slime; + mappings[115] = EntityType.SmallFireball; + mappings[116] = EntityType.Sniffer; + mappings[117] = EntityType.Snowball; + mappings[118] = EntityType.SnowGolem; + mappings[119] = EntityType.SpawnerMinecart; + mappings[120] = EntityType.SpectralArrow; + mappings[121] = EntityType.Spider; + mappings[122] = EntityType.SpruceBoat; + mappings[123] = EntityType.SpruceChestBoat; + mappings[124] = EntityType.Squid; + mappings[125] = EntityType.Stray; + mappings[126] = EntityType.Strider; + mappings[127] = EntityType.Tadpole; + mappings[128] = EntityType.TextDisplay; + mappings[129] = EntityType.Tnt; + mappings[130] = EntityType.TntMinecart; + mappings[131] = EntityType.TraderLlama; + mappings[132] = EntityType.Trident; + mappings[133] = EntityType.TropicalFish; + mappings[134] = EntityType.Turtle; + mappings[135] = EntityType.Vex; + mappings[136] = EntityType.Villager; + mappings[137] = EntityType.Vindicator; + mappings[138] = EntityType.WanderingTrader; + mappings[139] = EntityType.Warden; + mappings[140] = EntityType.WindCharge; + mappings[141] = EntityType.Witch; + mappings[142] = EntityType.Wither; + mappings[143] = EntityType.WitherSkeleton; + mappings[144] = EntityType.WitherSkull; + mappings[145] = EntityType.Wolf; + mappings[146] = EntityType.Zoglin; + mappings[147] = EntityType.Zombie; + mappings[148] = EntityType.ZombieHorse; + mappings[149] = EntityType.ZombieVillager; + mappings[150] = EntityType.ZombifiedPiglin; + mappings[151] = EntityType.Player; + mappings[152] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1219.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1219.cs new file mode 100644 index 00000000..0f4bfe90 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1219.cs @@ -0,0 +1,262 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette1219 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.EntityAnimation }, // Animate + { 0x03, PacketTypesIn.Statistics }, // Award Stats + { 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x07, PacketTypesIn.BlockAction }, // Block Event + { 0x08, PacketTypesIn.BlockChange }, // Block Update + { 0x09, PacketTypesIn.BossBar }, // Boss Event + { 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x10, PacketTypesIn.DeclareCommands }, // Commands + { 0x11, PacketTypesIn.CloseWindow }, // Container Close + { 0x12, PacketTypesIn.WindowItems }, // Container Set Content + { 0x13, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x14, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x15, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x16, PacketTypesIn.SetCooldown }, // Cooldown + { 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x18, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x19, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1A, PacketTypesIn.DebugBlockValue }, // Debug Block Value (new in 1.21.9) + { 0x1B, PacketTypesIn.DebugChunkValue }, // Debug Chunk Value (new in 1.21.9) + { 0x1C, PacketTypesIn.DebugEntityValue }, // Debug Entity Value (new in 1.21.9) + { 0x1D, PacketTypesIn.DebugEvent }, // Debug Event (new in 1.21.9) + { 0x1E, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1F, PacketTypesIn.HideMessage }, // Delete Chat + { 0x20, PacketTypesIn.Disconnect }, // Disconnect + { 0x21, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x22, PacketTypesIn.EntityStatus }, // Entity Event + { 0x23, PacketTypesIn.EntityPositionSync }, // Entity Position Sync + { 0x24, PacketTypesIn.Explosion }, // Explode + { 0x25, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x26, PacketTypesIn.ChangeGameState }, // Game Event + { 0x27, PacketTypesIn.GameTestHighlightPos }, // Game Test Highlight Pos (new in 1.21.9) + { 0x28, PacketTypesIn.OpenHorseWindow }, // Horse Screen Open + { 0x29, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x2A, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x2B, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x2C, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x2D, PacketTypesIn.Effect }, // Level Event + { 0x2E, PacketTypesIn.Particle }, // Level Particles + { 0x2F, PacketTypesIn.UpdateLight }, // Light Update + { 0x30, PacketTypesIn.JoinGame }, // Login + { 0x31, PacketTypesIn.MapData }, // Map Item Data + { 0x32, PacketTypesIn.TradeList }, // Merchant Offers + { 0x33, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x34, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x35, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track + { 0x36, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x37, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x38, PacketTypesIn.OpenBook }, // Open Book + { 0x39, PacketTypesIn.OpenWindow }, // Open Screen + { 0x3A, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x3B, PacketTypesIn.Ping }, // Ping + { 0x3C, PacketTypesIn.PingResponse }, // Pong Response + { 0x3D, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x3E, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x3F, PacketTypesIn.ChatMessage }, // Player Chat + { 0x40, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x41, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x42, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x43, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x44, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x45, PacketTypesIn.FacePlayer }, // Player Look At + { 0x46, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x47, PacketTypesIn.PlayerRotation }, // Player Rotation + { 0x48, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add + { 0x49, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove + { 0x4A, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings + { 0x4B, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x4C, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x4D, PacketTypesIn.ResetScore }, // Reset Score + { 0x4E, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x4F, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x50, PacketTypesIn.Respawn }, // Respawn + { 0x51, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x52, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x53, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x54, PacketTypesIn.ServerData }, // Server Data + { 0x55, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x56, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x57, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x58, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x59, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x5A, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x5B, PacketTypesIn.Camera }, // Set Camera + { 0x5C, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x5D, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x5E, PacketTypesIn.SetCursorItem }, // Set Cursor Item + { 0x5F, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x60, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x61, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x62, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x63, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x64, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x65, PacketTypesIn.SetExperience }, // Set Experience + { 0x66, PacketTypesIn.UpdateHealth }, // Set Health + { 0x67, PacketTypesIn.SetHeldSlot }, // Set Held Slot + { 0x68, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x69, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x6A, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory + { 0x6B, PacketTypesIn.Teams }, // Set Player Team + { 0x6C, PacketTypesIn.UpdateScore }, // Set Score + { 0x6D, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x6E, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x6F, PacketTypesIn.TimeUpdate }, // Set Time + { 0x70, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x71, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x72, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x73, PacketTypesIn.SoundEffect }, // Sound + { 0x74, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x75, PacketTypesIn.StopSound }, // Stop Sound + { 0x76, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x77, PacketTypesIn.SystemChat }, // System Chat + { 0x78, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x79, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x7A, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x7B, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x7C, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status + { 0x7D, PacketTypesIn.SetTickingState }, // Ticking State + { 0x7E, PacketTypesIn.StepTick }, // Ticking Step + { 0x7F, PacketTypesIn.Transfer }, // Transfer + { 0x80, PacketTypesIn.Advancements }, // Update Advancements + { 0x81, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x82, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x83, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x84, PacketTypesIn.Tags }, // Update Tags + { 0x85, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x86, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x87, PacketTypesIn.ServerLinks }, // Server Links + { 0x88, PacketTypesIn.Waypoint }, // Waypoint + { 0x89, PacketTypesIn.ClearDialog }, // Clear Dialog + { 0x8A, PacketTypesIn.ShowDialog } // Show Dialog + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x02, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected + { 0x03, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x04, PacketTypesOut.ChangeGameMode }, // Change Game Mode + { 0x05, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x06, PacketTypesOut.ChatCommand }, // Chat Command + { 0x07, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x08, PacketTypesOut.ChatMessage }, // Chat + { 0x09, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x0A, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0B, PacketTypesOut.ClientStatus }, // Client Command + { 0x0C, PacketTypesOut.ClientTickEnd }, // Client Tick End + { 0x0D, PacketTypesOut.ClientSettings }, // Client Information + { 0x0E, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x0F, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x10, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x11, PacketTypesOut.ClickWindow }, // Container Click + { 0x12, PacketTypesOut.CloseWindow }, // Container Close + { 0x13, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x14, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x15, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x16, PacketTypesOut.DebugSampleSubscription }, // Debug Subscription Request + { 0x17, PacketTypesOut.EditBook }, // Edit Book + { 0x18, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x19, PacketTypesOut.InteractEntity }, // Interact + { 0x1A, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1B, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1C, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1D, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1E, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x1F, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x20, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x21, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x22, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x23, PacketTypesOut.PickItem }, // Pick Item From Block + { 0x24, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity + { 0x25, PacketTypesOut.PingRequest }, // Ping Request + { 0x26, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x27, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x28, PacketTypesOut.PlayerDigging }, // Player Action + { 0x29, PacketTypesOut.EntityAction }, // Player Command + { 0x2A, PacketTypesOut.SteerVehicle }, // Player Input + { 0x2B, PacketTypesOut.PlayerLoaded }, // Player Loaded + { 0x2C, PacketTypesOut.Pong }, // Pong + { 0x2D, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2E, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x2F, PacketTypesOut.NameItem }, // Rename Item + { 0x30, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x31, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x32, PacketTypesOut.SelectTrade }, // Select Trade + { 0x33, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x34, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x35, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x36, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x37, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x38, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x39, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x3A, PacketTypesOut.SetTestBlock }, // Set Test Block + { 0x3B, PacketTypesOut.UpdateSign }, // Sign Update + { 0x3C, PacketTypesOut.Animation }, // Swing + { 0x3D, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x3E, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action + { 0x3F, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x40, PacketTypesOut.UseItem }, // Use Item + { 0x41, PacketTypesOut.CustomClickAction } // Custom Click Action + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks }, + { 0x11, ConfigurationPacketTypesIn.ClearDialog }, + { 0x12, ConfigurationPacketTypesIn.ShowDialog }, + { 0x13, ConfigurationPacketTypesIn.CodeOfConduct } // New in 1.21.9 + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks }, + { 0x08, ConfigurationPacketTypesOut.CustomClickAction }, + { 0x09, ConfigurationPacketTypesOut.AcceptCodeOfConduct } // New in 1.21.9 + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/tools/gen_entity_metadata_palette.py b/tools/gen_entity_metadata_palette.py index 260fe722..74932bc2 100644 --- a/tools/gen_entity_metadata_palette.py +++ b/tools/gen_entity_metadata_palette.py @@ -57,8 +57,11 @@ FIELD_TO_ENUM = { "PAINTING_VARIANT": "PaintingVariant", "SNIFFER_STATE": "SnifferState", "ARMADILLO_STATE": "ArmadilloState", + "COPPER_GOLEM_STATE": "CopperGolemState", + "WEATHERING_COPPER_STATE": "WeatheringCopperState", "VECTOR3": "Vector3", "QUATERNION": "Quaternion", + "RESOLVABLE_PROFILE": "ResolvableProfile", } From 88e9c671da3ea4244885fe16acc2fc4904facea8 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:05:06 +0800 Subject: [PATCH 073/484] feat: add version routing and metadata reading for MC 1.21.9 - Route block/entity/item/packet/metadata palettes to new 1219 variants for protocol >= 773, and raise upper-bound guards from MC_1_21_7 to MC_1_21_9 so terrain, inventory, and entity handling are enabled. - Add DataTypes readers for three new entity metadata serializer types: CopperGolemState and WeatheringCopperState (both VarInt), and ResolvableProfile (composite: Either with optional name/UUID/properties + PlayerSkin.Patch with 4 optional fields for body/cape/elytra texture ResourceLocations and model type). Made-with: Cursor --- .../Mapping/EntityMetadataPalette.cs | 3 +- .../Protocol/Handlers/DataTypes.cs | 61 +++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 7cdb194a..60acef8c 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -24,7 +24,8 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_19_3_Version => new EntityMetadataPalette1193(), // 1.19.3 < Protocol18Handler.MC_1_20_6_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 - <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.7 + <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.8 + <= Protocol18Handler.MC_1_21_9_Version => new EntityMetadataPalette1219(), // 1.21.9 - 1.21.10 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index ab46dca7..db6b8c1e 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -907,6 +907,13 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.ArmadilloState: // Armadillo state (1.20.6+) value = ReadNextVarInt(cache); break; + case EntityMetaDataType.CopperGolemState: // Copper Golem state (1.21.9+) + case EntityMetaDataType.WeatheringCopperState: // Weathering Copper state (1.21.9+) + value = ReadNextVarInt(cache); + break; + case EntityMetaDataType.ResolvableProfile: // ResolvableProfile (1.21.9+) + ReadNextResolvableProfile(cache); + break; case EntityMetaDataType.Vector3: // Vector 3f value = new List { @@ -938,6 +945,60 @@ namespace MinecraftClient.Protocol.Handlers } } + /// + /// Consume bytes for a ResolvableProfile (1.21.9+). + /// Wire: Either(GameProfile, Partial) + PlayerSkin.Patch + /// + private void ReadNextResolvableProfile(Queue cache) + { + bool isFullProfile = ReadNextBool(cache); // Either flag: true=GameProfile, false=Partial + if (isFullProfile) + { + ReadNextUUID(cache); // UUID + ReadNextString(cache); // player name (max 16 chars) + ReadGameProfileProperties(cache); + } + else + { + // Partial: optional name, optional UUID, properties + if (ReadNextBool(cache)) + ReadNextString(cache); // optional player name + if (ReadNextBool(cache)) + ReadNextUUID(cache); // optional UUID + ReadGameProfileProperties(cache); + } + + // PlayerSkin.Patch: 4 optional fields + // body (optional ResourceLocation string) + if (ReadNextBool(cache)) + ReadNextString(cache); + // cape + if (ReadNextBool(cache)) + ReadNextString(cache); + // elytra + if (ReadNextBool(cache)) + ReadNextString(cache); + // model (optional bool: true=SLIM, false=WIDE) + if (ReadNextBool(cache)) + ReadNextBool(cache); + } + + /// + /// Read GameProfile properties (PropertyMap): VarInt count, then per entry: + /// name string, value string, optional signature string. + /// + private void ReadGameProfileProperties(Queue cache) + { + int count = ReadNextVarInt(cache); + for (int i = 0; i < count; i++) + { + ReadNextString(cache); // property name + ReadNextString(cache); // property value + if (ReadNextBool(cache)) // has signature? + ReadNextString(cache); // signature + } + } + /// /// Currently not handled. Reading data only /// diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index bcb3f466..6a608dba 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_7_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_9_Version => throw new NotImplementedException(Translations .exception_palette_packet), + <= Protocol18Handler.MC_1_21_9_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(), <= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), From 6d3c58b29f0b2c3c3e1015bc182ef1adce94a96e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:11:23 +0800 Subject: [PATCH 074/484] fix: handle LpVec3 movement encoding in SpawnEntity for 1.21.9+ Minecraft 1.21.9 changed the SpawnEntity (Add Entity) packet layout: the velocity/movement field was moved before the angle fields and switched from 3 x Short to a new variable-length LpVec3 encoding. Add ReadNextLpVec3() to consume the LpVec3 wire format (1 byte header, optionally 5+ more bytes with a continuation VarInt), and update ReadNextEntity() to use the new field order for protocol >= 773. Made-with: Cursor --- .../Protocol/Handlers/DataTypes.cs | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index db6b8c1e..d669fc68 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -559,11 +559,32 @@ namespace MinecraftClient.Protocol.Handlers int data = -1; byte entityPitch, entityYaw; - if (living) + if (protocolversion >= Protocol18Handler.MC_1_21_9_Version) + { + // 1.21.9+: LpVec3 movement before angles, unified format + ReadNextLpVec3(cache); // Movement (LpVec3) + entityPitch = ReadNextByte(cache); // xRot + entityYaw = ReadNextByte(cache); // yRot + ReadNextByte(cache); // yHeadRot + data = ReadNextVarInt(cache); // Data + } + else if (living) { entityYaw = ReadNextByte(cache); // Yaw entityPitch = ReadNextByte(cache); // Pitch entityPitch = ReadNextByte(cache); // Head Pitch + + // Velocity (3 shorts) + if (protocolversion < Protocol18Handler.MC_1_9_Version) + { + // no velocity for living entities in <1.9 + } + else + { + ReadNextShort(cache); + ReadNextShort(cache); + ReadNextShort(cache); + } } else { @@ -577,24 +598,24 @@ namespace MinecraftClient.Protocol.Handlers data = protocolversion >= Protocol18Handler.MC_1_19_Version ? ReadNextVarInt(cache) : ReadNextInt(cache); - } - // In 1.8 those 3 fields for Velocity are optional - if (protocolversion < Protocol18Handler.MC_1_9_Version) - { - if (data != 0) + // Velocity (3 shorts) + if (protocolversion < Protocol18Handler.MC_1_9_Version) + { + if (data != 0) + { + ReadNextShort(cache); + ReadNextShort(cache); + ReadNextShort(cache); + } + } + else { ReadNextShort(cache); ReadNextShort(cache); ReadNextShort(cache); } } - else - { - ReadNextShort(cache); - ReadNextShort(cache); - ReadNextShort(cache); - } return new Entity(entityID, entityType, new Location(entityX, entityY, entityZ), entityYaw, entityPitch, data); @@ -945,6 +966,22 @@ namespace MinecraftClient.Protocol.Handlers } } + /// + /// Read an LpVec3 (low-precision vec3) from the cache (1.21.9+). + /// Variable-length encoding: first byte 0 = zero vector; otherwise + /// 2 bytes + 4 bytes (6 total), plus an optional VarInt continuation. + /// + public void ReadNextLpVec3(Queue cache) + { + int first = ReadNextByte(cache); + if (first == 0) + return; + ReadNextByte(cache); // second byte + ReadData(4, cache); // uint32 + if ((first & 4) == 4) // continuation bit set + ReadNextVarInt(cache); + } + /// /// Consume bytes for a ResolvableProfile (1.21.9+). /// Wire: Either(GameProfile, Partial) + PlayerSkin.Patch From aebfcd93e4aa36921d6f9b063233467b579eae36 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 14:43:56 +0800 Subject: [PATCH 075/484] fix: regenerate item/block palettes from server registry data for 1.21.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MC 1.21.9 changed how some items and blocks are registered — 24 block items (copper bars/chains/lanterns variants, potted azalea renames) and additional blocks are now registered outside of Items.java/Blocks.java field declarations, making the previous source-field-order-based palette generation produce incorrect protocol IDs. Regenerated ItemPalette1219.cs using server registries.json (1488 items, up from 1464) and Palette1219.cs using blocks.json (1166 blocks with correct state IDs). Added 37 new enum values to ItemType.cs (35 new + DryShortGrass/DryTallGrass for backward compat) and 9 new values to Material.cs. Verified all item/block/entity identification against a 1.21.10 server. Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette1219.cs | 2174 ++++----- MinecraftClient/Inventory/ItemType.cs | 116 +- .../Mapping/BlockPalettes/Palette1219.cs | 4183 +++++++++-------- MinecraftClient/Mapping/Material.cs | 18 +- 4 files changed, 3465 insertions(+), 3026 deletions(-) diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs index dc85be12..db6985f7 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1219.cs @@ -217,8 +217,8 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[206] = ItemType.FloweringAzalea; mappings[207] = ItemType.DeadBush; mappings[208] = ItemType.FireflyBush; - mappings[209] = ItemType.DryShortGrass; - mappings[210] = ItemType.DryTallGrass; + mappings[209] = ItemType.ShortDryGrass; + mappings[210] = ItemType.TallDryGrass; mappings[211] = ItemType.Seagrass; mappings[212] = ItemType.SeaPickle; mappings[213] = ItemType.WhiteWool; @@ -399,1079 +399,1103 @@ namespace MinecraftClient.Inventory.ItemPalettes mappings[388] = ItemType.RedMushroomBlock; mappings[389] = ItemType.MushroomStem; mappings[390] = ItemType.IronBars; - mappings[391] = ItemType.IronChain; - mappings[392] = ItemType.GlassPane; - mappings[393] = ItemType.Melon; - mappings[394] = ItemType.Vine; - mappings[395] = ItemType.GlowLichen; - mappings[396] = ItemType.ResinClump; - mappings[397] = ItemType.ResinBlock; - mappings[398] = ItemType.ResinBricks; - mappings[399] = ItemType.ResinBrickStairs; - mappings[400] = ItemType.ResinBrickSlab; - mappings[401] = ItemType.ResinBrickWall; - mappings[402] = ItemType.ChiseledResinBricks; - mappings[403] = ItemType.BrickStairs; - mappings[404] = ItemType.StoneBrickStairs; - mappings[405] = ItemType.MudBrickStairs; - mappings[406] = ItemType.Mycelium; - mappings[407] = ItemType.LilyPad; - mappings[408] = ItemType.NetherBricks; - mappings[409] = ItemType.CrackedNetherBricks; - mappings[410] = ItemType.ChiseledNetherBricks; - mappings[411] = ItemType.NetherBrickFence; - mappings[412] = ItemType.NetherBrickStairs; - mappings[413] = ItemType.Sculk; - mappings[414] = ItemType.SculkVein; - mappings[415] = ItemType.SculkCatalyst; - mappings[416] = ItemType.SculkShrieker; - mappings[417] = ItemType.EnchantingTable; - mappings[418] = ItemType.EndPortalFrame; - mappings[419] = ItemType.EndStone; - mappings[420] = ItemType.EndStoneBricks; - mappings[421] = ItemType.DragonEgg; - mappings[422] = ItemType.SandstoneStairs; - mappings[423] = ItemType.EnderChest; - mappings[424] = ItemType.EmeraldBlock; - mappings[425] = ItemType.OakStairs; - mappings[426] = ItemType.SpruceStairs; - mappings[427] = ItemType.BirchStairs; - mappings[428] = ItemType.JungleStairs; - mappings[429] = ItemType.AcaciaStairs; - mappings[430] = ItemType.CherryStairs; - mappings[431] = ItemType.DarkOakStairs; - mappings[432] = ItemType.PaleOakStairs; - mappings[433] = ItemType.MangroveStairs; - mappings[434] = ItemType.BambooStairs; - mappings[435] = ItemType.BambooMosaicStairs; - mappings[436] = ItemType.CrimsonStairs; - mappings[437] = ItemType.WarpedStairs; - mappings[438] = ItemType.CommandBlock; - mappings[439] = ItemType.Beacon; - mappings[440] = ItemType.CobblestoneWall; - mappings[441] = ItemType.MossyCobblestoneWall; - mappings[442] = ItemType.BrickWall; - mappings[443] = ItemType.PrismarineWall; - mappings[444] = ItemType.RedSandstoneWall; - mappings[445] = ItemType.MossyStoneBrickWall; - mappings[446] = ItemType.GraniteWall; - mappings[447] = ItemType.StoneBrickWall; - mappings[448] = ItemType.MudBrickWall; - mappings[449] = ItemType.NetherBrickWall; - mappings[450] = ItemType.AndesiteWall; - mappings[451] = ItemType.RedNetherBrickWall; - mappings[452] = ItemType.SandstoneWall; - mappings[453] = ItemType.EndStoneBrickWall; - mappings[454] = ItemType.DioriteWall; - mappings[455] = ItemType.BlackstoneWall; - mappings[456] = ItemType.PolishedBlackstoneWall; - mappings[457] = ItemType.PolishedBlackstoneBrickWall; - mappings[458] = ItemType.CobbledDeepslateWall; - mappings[459] = ItemType.PolishedDeepslateWall; - mappings[460] = ItemType.DeepslateBrickWall; - mappings[461] = ItemType.DeepslateTileWall; - mappings[462] = ItemType.Anvil; - mappings[463] = ItemType.ChippedAnvil; - mappings[464] = ItemType.DamagedAnvil; - mappings[465] = ItemType.ChiseledQuartzBlock; - mappings[466] = ItemType.QuartzBlock; - mappings[467] = ItemType.QuartzBricks; - mappings[468] = ItemType.QuartzPillar; - mappings[469] = ItemType.QuartzStairs; - mappings[470] = ItemType.WhiteTerracotta; - mappings[471] = ItemType.OrangeTerracotta; - mappings[472] = ItemType.MagentaTerracotta; - mappings[473] = ItemType.LightBlueTerracotta; - mappings[474] = ItemType.YellowTerracotta; - mappings[475] = ItemType.LimeTerracotta; - mappings[476] = ItemType.PinkTerracotta; - mappings[477] = ItemType.GrayTerracotta; - mappings[478] = ItemType.LightGrayTerracotta; - mappings[479] = ItemType.CyanTerracotta; - mappings[480] = ItemType.PurpleTerracotta; - mappings[481] = ItemType.BlueTerracotta; - mappings[482] = ItemType.BrownTerracotta; - mappings[483] = ItemType.GreenTerracotta; - mappings[484] = ItemType.RedTerracotta; - mappings[485] = ItemType.BlackTerracotta; - mappings[486] = ItemType.Barrier; - mappings[487] = ItemType.Light; - mappings[488] = ItemType.HayBlock; - mappings[489] = ItemType.WhiteCarpet; - mappings[490] = ItemType.OrangeCarpet; - mappings[491] = ItemType.MagentaCarpet; - mappings[492] = ItemType.LightBlueCarpet; - mappings[493] = ItemType.YellowCarpet; - mappings[494] = ItemType.LimeCarpet; - mappings[495] = ItemType.PinkCarpet; - mappings[496] = ItemType.GrayCarpet; - mappings[497] = ItemType.LightGrayCarpet; - mappings[498] = ItemType.CyanCarpet; - mappings[499] = ItemType.PurpleCarpet; - mappings[500] = ItemType.BlueCarpet; - mappings[501] = ItemType.BrownCarpet; - mappings[502] = ItemType.GreenCarpet; - mappings[503] = ItemType.RedCarpet; - mappings[504] = ItemType.BlackCarpet; - mappings[505] = ItemType.Terracotta; - mappings[506] = ItemType.PackedIce; - mappings[507] = ItemType.DirtPath; - mappings[508] = ItemType.Sunflower; - mappings[509] = ItemType.Lilac; - mappings[510] = ItemType.RoseBush; - mappings[511] = ItemType.Peony; - mappings[512] = ItemType.TallGrass; - mappings[513] = ItemType.LargeFern; - mappings[514] = ItemType.WhiteStainedGlass; - mappings[515] = ItemType.OrangeStainedGlass; - mappings[516] = ItemType.MagentaStainedGlass; - mappings[517] = ItemType.LightBlueStainedGlass; - mappings[518] = ItemType.YellowStainedGlass; - mappings[519] = ItemType.LimeStainedGlass; - mappings[520] = ItemType.PinkStainedGlass; - mappings[521] = ItemType.GrayStainedGlass; - mappings[522] = ItemType.LightGrayStainedGlass; - mappings[523] = ItemType.CyanStainedGlass; - mappings[524] = ItemType.PurpleStainedGlass; - mappings[525] = ItemType.BlueStainedGlass; - mappings[526] = ItemType.BrownStainedGlass; - mappings[527] = ItemType.GreenStainedGlass; - mappings[528] = ItemType.RedStainedGlass; - mappings[529] = ItemType.BlackStainedGlass; - mappings[530] = ItemType.WhiteStainedGlassPane; - mappings[531] = ItemType.OrangeStainedGlassPane; - mappings[532] = ItemType.MagentaStainedGlassPane; - mappings[533] = ItemType.LightBlueStainedGlassPane; - mappings[534] = ItemType.YellowStainedGlassPane; - mappings[535] = ItemType.LimeStainedGlassPane; - mappings[536] = ItemType.PinkStainedGlassPane; - mappings[537] = ItemType.GrayStainedGlassPane; - mappings[538] = ItemType.LightGrayStainedGlassPane; - mappings[539] = ItemType.CyanStainedGlassPane; - mappings[540] = ItemType.PurpleStainedGlassPane; - mappings[541] = ItemType.BlueStainedGlassPane; - mappings[542] = ItemType.BrownStainedGlassPane; - mappings[543] = ItemType.GreenStainedGlassPane; - mappings[544] = ItemType.RedStainedGlassPane; - mappings[545] = ItemType.BlackStainedGlassPane; - mappings[546] = ItemType.Prismarine; - mappings[547] = ItemType.PrismarineBricks; - mappings[548] = ItemType.DarkPrismarine; - mappings[549] = ItemType.PrismarineStairs; - mappings[550] = ItemType.PrismarineBrickStairs; - mappings[551] = ItemType.DarkPrismarineStairs; - mappings[552] = ItemType.SeaLantern; - mappings[553] = ItemType.RedSandstone; - mappings[554] = ItemType.ChiseledRedSandstone; - mappings[555] = ItemType.CutRedSandstone; - mappings[556] = ItemType.RedSandstoneStairs; - mappings[557] = ItemType.RepeatingCommandBlock; - mappings[558] = ItemType.ChainCommandBlock; - mappings[559] = ItemType.MagmaBlock; - mappings[560] = ItemType.NetherWartBlock; - mappings[561] = ItemType.WarpedWartBlock; - mappings[562] = ItemType.RedNetherBricks; - mappings[563] = ItemType.BoneBlock; - mappings[564] = ItemType.StructureVoid; - mappings[565] = ItemType.ShulkerBox; - mappings[566] = ItemType.WhiteShulkerBox; - mappings[567] = ItemType.OrangeShulkerBox; - mappings[568] = ItemType.MagentaShulkerBox; - mappings[569] = ItemType.LightBlueShulkerBox; - mappings[570] = ItemType.YellowShulkerBox; - mappings[571] = ItemType.LimeShulkerBox; - mappings[572] = ItemType.PinkShulkerBox; - mappings[573] = ItemType.GrayShulkerBox; - mappings[574] = ItemType.LightGrayShulkerBox; - mappings[575] = ItemType.CyanShulkerBox; - mappings[576] = ItemType.PurpleShulkerBox; - mappings[577] = ItemType.BlueShulkerBox; - mappings[578] = ItemType.BrownShulkerBox; - mappings[579] = ItemType.GreenShulkerBox; - mappings[580] = ItemType.RedShulkerBox; - mappings[581] = ItemType.BlackShulkerBox; - mappings[582] = ItemType.WhiteGlazedTerracotta; - mappings[583] = ItemType.OrangeGlazedTerracotta; - mappings[584] = ItemType.MagentaGlazedTerracotta; - mappings[585] = ItemType.LightBlueGlazedTerracotta; - mappings[586] = ItemType.YellowGlazedTerracotta; - mappings[587] = ItemType.LimeGlazedTerracotta; - mappings[588] = ItemType.PinkGlazedTerracotta; - mappings[589] = ItemType.GrayGlazedTerracotta; - mappings[590] = ItemType.LightGrayGlazedTerracotta; - mappings[591] = ItemType.CyanGlazedTerracotta; - mappings[592] = ItemType.PurpleGlazedTerracotta; - mappings[593] = ItemType.BlueGlazedTerracotta; - mappings[594] = ItemType.BrownGlazedTerracotta; - mappings[595] = ItemType.GreenGlazedTerracotta; - mappings[596] = ItemType.RedGlazedTerracotta; - mappings[597] = ItemType.BlackGlazedTerracotta; - mappings[598] = ItemType.WhiteConcrete; - mappings[599] = ItemType.OrangeConcrete; - mappings[600] = ItemType.MagentaConcrete; - mappings[601] = ItemType.LightBlueConcrete; - mappings[602] = ItemType.YellowConcrete; - mappings[603] = ItemType.LimeConcrete; - mappings[604] = ItemType.PinkConcrete; - mappings[605] = ItemType.GrayConcrete; - mappings[606] = ItemType.LightGrayConcrete; - mappings[607] = ItemType.CyanConcrete; - mappings[608] = ItemType.PurpleConcrete; - mappings[609] = ItemType.BlueConcrete; - mappings[610] = ItemType.BrownConcrete; - mappings[611] = ItemType.GreenConcrete; - mappings[612] = ItemType.RedConcrete; - mappings[613] = ItemType.BlackConcrete; - mappings[614] = ItemType.WhiteConcretePowder; - mappings[615] = ItemType.OrangeConcretePowder; - mappings[616] = ItemType.MagentaConcretePowder; - mappings[617] = ItemType.LightBlueConcretePowder; - mappings[618] = ItemType.YellowConcretePowder; - mappings[619] = ItemType.LimeConcretePowder; - mappings[620] = ItemType.PinkConcretePowder; - mappings[621] = ItemType.GrayConcretePowder; - mappings[622] = ItemType.LightGrayConcretePowder; - mappings[623] = ItemType.CyanConcretePowder; - mappings[624] = ItemType.PurpleConcretePowder; - mappings[625] = ItemType.BlueConcretePowder; - mappings[626] = ItemType.BrownConcretePowder; - mappings[627] = ItemType.GreenConcretePowder; - mappings[628] = ItemType.RedConcretePowder; - mappings[629] = ItemType.BlackConcretePowder; - mappings[630] = ItemType.TurtleEgg; - mappings[631] = ItemType.SnifferEgg; - mappings[632] = ItemType.DriedGhast; - mappings[633] = ItemType.DeadTubeCoralBlock; - mappings[634] = ItemType.DeadBrainCoralBlock; - mappings[635] = ItemType.DeadBubbleCoralBlock; - mappings[636] = ItemType.DeadFireCoralBlock; - mappings[637] = ItemType.DeadHornCoralBlock; - mappings[638] = ItemType.TubeCoralBlock; - mappings[639] = ItemType.BrainCoralBlock; - mappings[640] = ItemType.BubbleCoralBlock; - mappings[641] = ItemType.FireCoralBlock; - mappings[642] = ItemType.HornCoralBlock; - mappings[643] = ItemType.TubeCoral; - mappings[644] = ItemType.BrainCoral; - mappings[645] = ItemType.BubbleCoral; - mappings[646] = ItemType.FireCoral; - mappings[647] = ItemType.HornCoral; - mappings[648] = ItemType.DeadBrainCoral; - mappings[649] = ItemType.DeadBubbleCoral; - mappings[650] = ItemType.DeadFireCoral; - mappings[651] = ItemType.DeadHornCoral; - mappings[652] = ItemType.DeadTubeCoral; - mappings[653] = ItemType.TubeCoralFan; - mappings[654] = ItemType.BrainCoralFan; - mappings[655] = ItemType.BubbleCoralFan; - mappings[656] = ItemType.FireCoralFan; - mappings[657] = ItemType.HornCoralFan; - mappings[658] = ItemType.DeadTubeCoralFan; - mappings[659] = ItemType.DeadBrainCoralFan; - mappings[660] = ItemType.DeadBubbleCoralFan; - mappings[661] = ItemType.DeadFireCoralFan; - mappings[662] = ItemType.DeadHornCoralFan; - mappings[663] = ItemType.BlueIce; - mappings[664] = ItemType.Conduit; - mappings[665] = ItemType.PolishedGraniteStairs; - mappings[666] = ItemType.SmoothRedSandstoneStairs; - mappings[667] = ItemType.MossyStoneBrickStairs; - mappings[668] = ItemType.PolishedDioriteStairs; - mappings[669] = ItemType.MossyCobblestoneStairs; - mappings[670] = ItemType.EndStoneBrickStairs; - mappings[671] = ItemType.StoneStairs; - mappings[672] = ItemType.SmoothSandstoneStairs; - mappings[673] = ItemType.SmoothQuartzStairs; - mappings[674] = ItemType.GraniteStairs; - mappings[675] = ItemType.AndesiteStairs; - mappings[676] = ItemType.RedNetherBrickStairs; - mappings[677] = ItemType.PolishedAndesiteStairs; - mappings[678] = ItemType.DioriteStairs; - mappings[679] = ItemType.CobbledDeepslateStairs; - mappings[680] = ItemType.PolishedDeepslateStairs; - mappings[681] = ItemType.DeepslateBrickStairs; - mappings[682] = ItemType.DeepslateTileStairs; - mappings[683] = ItemType.PolishedGraniteSlab; - mappings[684] = ItemType.SmoothRedSandstoneSlab; - mappings[685] = ItemType.MossyStoneBrickSlab; - mappings[686] = ItemType.PolishedDioriteSlab; - mappings[687] = ItemType.MossyCobblestoneSlab; - mappings[688] = ItemType.EndStoneBrickSlab; - mappings[689] = ItemType.SmoothSandstoneSlab; - mappings[690] = ItemType.SmoothQuartzSlab; - mappings[691] = ItemType.GraniteSlab; - mappings[692] = ItemType.AndesiteSlab; - mappings[693] = ItemType.RedNetherBrickSlab; - mappings[694] = ItemType.PolishedAndesiteSlab; - mappings[695] = ItemType.DioriteSlab; - mappings[696] = ItemType.CobbledDeepslateSlab; - mappings[697] = ItemType.PolishedDeepslateSlab; - mappings[698] = ItemType.DeepslateBrickSlab; - mappings[699] = ItemType.DeepslateTileSlab; - mappings[700] = ItemType.Scaffolding; - mappings[701] = ItemType.Redstone; - mappings[702] = ItemType.RedstoneTorch; - mappings[703] = ItemType.RedstoneBlock; - mappings[704] = ItemType.Repeater; - mappings[705] = ItemType.Comparator; - mappings[706] = ItemType.Piston; - mappings[707] = ItemType.StickyPiston; - mappings[708] = ItemType.SlimeBlock; - mappings[709] = ItemType.HoneyBlock; - mappings[710] = ItemType.Observer; - mappings[711] = ItemType.Hopper; - mappings[712] = ItemType.Dispenser; - mappings[713] = ItemType.Dropper; - mappings[714] = ItemType.Lectern; - mappings[715] = ItemType.Target; - mappings[716] = ItemType.Lever; - mappings[717] = ItemType.LightningRod; - mappings[718] = ItemType.ExposedLightningRod; - mappings[719] = ItemType.WeatheredLightningRod; - mappings[720] = ItemType.OxidizedLightningRod; - mappings[721] = ItemType.WaxedLightningRod; - mappings[722] = ItemType.WaxedExposedLightningRod; - mappings[723] = ItemType.WaxedWeatheredLightningRod; - mappings[724] = ItemType.WaxedOxidizedLightningRod; - mappings[725] = ItemType.DaylightDetector; - mappings[726] = ItemType.SculkSensor; - mappings[727] = ItemType.CalibratedSculkSensor; - mappings[728] = ItemType.TripwireHook; - mappings[729] = ItemType.TrappedChest; - mappings[730] = ItemType.Tnt; - mappings[731] = ItemType.RedstoneLamp; - mappings[732] = ItemType.NoteBlock; - mappings[733] = ItemType.StoneButton; - mappings[734] = ItemType.PolishedBlackstoneButton; - mappings[735] = ItemType.OakButton; - mappings[736] = ItemType.SpruceButton; - mappings[737] = ItemType.BirchButton; - mappings[738] = ItemType.JungleButton; - mappings[739] = ItemType.AcaciaButton; - mappings[740] = ItemType.CherryButton; - mappings[741] = ItemType.DarkOakButton; - mappings[742] = ItemType.PaleOakButton; - mappings[743] = ItemType.MangroveButton; - mappings[744] = ItemType.BambooButton; - mappings[745] = ItemType.CrimsonButton; - mappings[746] = ItemType.WarpedButton; - mappings[747] = ItemType.StonePressurePlate; - mappings[748] = ItemType.PolishedBlackstonePressurePlate; - mappings[749] = ItemType.LightWeightedPressurePlate; - mappings[750] = ItemType.HeavyWeightedPressurePlate; - mappings[751] = ItemType.OakPressurePlate; - mappings[752] = ItemType.SprucePressurePlate; - mappings[753] = ItemType.BirchPressurePlate; - mappings[754] = ItemType.JunglePressurePlate; - mappings[755] = ItemType.AcaciaPressurePlate; - mappings[756] = ItemType.CherryPressurePlate; - mappings[757] = ItemType.DarkOakPressurePlate; - mappings[758] = ItemType.PaleOakPressurePlate; - mappings[759] = ItemType.MangrovePressurePlate; - mappings[760] = ItemType.BambooPressurePlate; - mappings[761] = ItemType.CrimsonPressurePlate; - mappings[762] = ItemType.WarpedPressurePlate; - mappings[763] = ItemType.IronDoor; - mappings[764] = ItemType.OakDoor; - mappings[765] = ItemType.SpruceDoor; - mappings[766] = ItemType.BirchDoor; - mappings[767] = ItemType.JungleDoor; - mappings[768] = ItemType.AcaciaDoor; - mappings[769] = ItemType.CherryDoor; - mappings[770] = ItemType.DarkOakDoor; - mappings[771] = ItemType.PaleOakDoor; - mappings[772] = ItemType.MangroveDoor; - mappings[773] = ItemType.BambooDoor; - mappings[774] = ItemType.CrimsonDoor; - mappings[775] = ItemType.WarpedDoor; - mappings[776] = ItemType.CopperDoor; - mappings[777] = ItemType.ExposedCopperDoor; - mappings[778] = ItemType.WeatheredCopperDoor; - mappings[779] = ItemType.OxidizedCopperDoor; - mappings[780] = ItemType.WaxedCopperDoor; - mappings[781] = ItemType.WaxedExposedCopperDoor; - mappings[782] = ItemType.WaxedWeatheredCopperDoor; - mappings[783] = ItemType.WaxedOxidizedCopperDoor; - mappings[784] = ItemType.IronTrapdoor; - mappings[785] = ItemType.OakTrapdoor; - mappings[786] = ItemType.SpruceTrapdoor; - mappings[787] = ItemType.BirchTrapdoor; - mappings[788] = ItemType.JungleTrapdoor; - mappings[789] = ItemType.AcaciaTrapdoor; - mappings[790] = ItemType.CherryTrapdoor; - mappings[791] = ItemType.DarkOakTrapdoor; - mappings[792] = ItemType.PaleOakTrapdoor; - mappings[793] = ItemType.MangroveTrapdoor; - mappings[794] = ItemType.BambooTrapdoor; - mappings[795] = ItemType.CrimsonTrapdoor; - mappings[796] = ItemType.WarpedTrapdoor; - mappings[797] = ItemType.CopperTrapdoor; - mappings[798] = ItemType.ExposedCopperTrapdoor; - mappings[799] = ItemType.WeatheredCopperTrapdoor; - mappings[800] = ItemType.OxidizedCopperTrapdoor; - mappings[801] = ItemType.WaxedCopperTrapdoor; - mappings[802] = ItemType.WaxedExposedCopperTrapdoor; - mappings[803] = ItemType.WaxedWeatheredCopperTrapdoor; - mappings[804] = ItemType.WaxedOxidizedCopperTrapdoor; - mappings[805] = ItemType.OakFenceGate; - mappings[806] = ItemType.SpruceFenceGate; - mappings[807] = ItemType.BirchFenceGate; - mappings[808] = ItemType.JungleFenceGate; - mappings[809] = ItemType.AcaciaFenceGate; - mappings[810] = ItemType.CherryFenceGate; - mappings[811] = ItemType.DarkOakFenceGate; - mappings[812] = ItemType.PaleOakFenceGate; - mappings[813] = ItemType.MangroveFenceGate; - mappings[814] = ItemType.BambooFenceGate; - mappings[815] = ItemType.CrimsonFenceGate; - mappings[816] = ItemType.WarpedFenceGate; - mappings[817] = ItemType.PoweredRail; - mappings[818] = ItemType.DetectorRail; - mappings[819] = ItemType.Rail; - mappings[820] = ItemType.ActivatorRail; - mappings[821] = ItemType.Saddle; - mappings[822] = ItemType.WhiteHarness; - mappings[823] = ItemType.OrangeHarness; - mappings[824] = ItemType.MagentaHarness; - mappings[825] = ItemType.LightBlueHarness; - mappings[826] = ItemType.YellowHarness; - mappings[827] = ItemType.LimeHarness; - mappings[828] = ItemType.PinkHarness; - mappings[829] = ItemType.GrayHarness; - mappings[830] = ItemType.LightGrayHarness; - mappings[831] = ItemType.CyanHarness; - mappings[832] = ItemType.PurpleHarness; - mappings[833] = ItemType.BlueHarness; - mappings[834] = ItemType.BrownHarness; - mappings[835] = ItemType.GreenHarness; - mappings[836] = ItemType.RedHarness; - mappings[837] = ItemType.BlackHarness; - mappings[838] = ItemType.Minecart; - mappings[839] = ItemType.ChestMinecart; - mappings[840] = ItemType.FurnaceMinecart; - mappings[841] = ItemType.TntMinecart; - mappings[842] = ItemType.HopperMinecart; - mappings[843] = ItemType.CarrotOnAStick; - mappings[844] = ItemType.WarpedFungusOnAStick; - mappings[845] = ItemType.PhantomMembrane; - mappings[846] = ItemType.Elytra; - mappings[847] = ItemType.OakBoat; - mappings[848] = ItemType.OakChestBoat; - mappings[849] = ItemType.SpruceBoat; - mappings[850] = ItemType.SpruceChestBoat; - mappings[851] = ItemType.BirchBoat; - mappings[852] = ItemType.BirchChestBoat; - mappings[853] = ItemType.JungleBoat; - mappings[854] = ItemType.JungleChestBoat; - mappings[855] = ItemType.AcaciaBoat; - mappings[856] = ItemType.AcaciaChestBoat; - mappings[857] = ItemType.CherryBoat; - mappings[858] = ItemType.CherryChestBoat; - mappings[859] = ItemType.DarkOakBoat; - mappings[860] = ItemType.DarkOakChestBoat; - mappings[861] = ItemType.PaleOakBoat; - mappings[862] = ItemType.PaleOakChestBoat; - mappings[863] = ItemType.MangroveBoat; - mappings[864] = ItemType.MangroveChestBoat; - mappings[865] = ItemType.BambooRaft; - mappings[866] = ItemType.BambooChestRaft; - mappings[867] = ItemType.StructureBlock; - mappings[868] = ItemType.Jigsaw; - mappings[869] = ItemType.TestBlock; - mappings[870] = ItemType.TestInstanceBlock; - mappings[871] = ItemType.TurtleHelmet; - mappings[872] = ItemType.TurtleScute; - mappings[873] = ItemType.ArmadilloScute; - mappings[874] = ItemType.WolfArmor; - mappings[875] = ItemType.FlintAndSteel; - mappings[876] = ItemType.Bowl; - mappings[877] = ItemType.Apple; - mappings[878] = ItemType.Bow; - mappings[879] = ItemType.Arrow; - mappings[880] = ItemType.Coal; - mappings[881] = ItemType.Charcoal; - mappings[882] = ItemType.Diamond; - mappings[883] = ItemType.Emerald; - mappings[884] = ItemType.LapisLazuli; - mappings[885] = ItemType.Quartz; - mappings[886] = ItemType.AmethystShard; - mappings[887] = ItemType.RawIron; - mappings[888] = ItemType.IronIngot; - mappings[889] = ItemType.RawCopper; - mappings[890] = ItemType.CopperIngot; - mappings[891] = ItemType.RawGold; - mappings[892] = ItemType.GoldIngot; - mappings[893] = ItemType.NetheriteIngot; - mappings[894] = ItemType.NetheriteScrap; - mappings[895] = ItemType.WoodenSword; - mappings[896] = ItemType.WoodenShovel; - mappings[897] = ItemType.WoodenPickaxe; - mappings[898] = ItemType.WoodenAxe; - mappings[899] = ItemType.WoodenHoe; - mappings[900] = ItemType.CopperSword; - mappings[901] = ItemType.CopperShovel; - mappings[902] = ItemType.CopperPickaxe; - mappings[903] = ItemType.CopperAxe; - mappings[904] = ItemType.CopperHoe; - mappings[905] = ItemType.StoneSword; - mappings[906] = ItemType.StoneShovel; - mappings[907] = ItemType.StonePickaxe; - mappings[908] = ItemType.StoneAxe; - mappings[909] = ItemType.StoneHoe; - mappings[910] = ItemType.GoldenSword; - mappings[911] = ItemType.GoldenShovel; - mappings[912] = ItemType.GoldenPickaxe; - mappings[913] = ItemType.GoldenAxe; - mappings[914] = ItemType.GoldenHoe; - mappings[915] = ItemType.IronSword; - mappings[916] = ItemType.IronShovel; - mappings[917] = ItemType.IronPickaxe; - mappings[918] = ItemType.IronAxe; - mappings[919] = ItemType.IronHoe; - mappings[920] = ItemType.DiamondSword; - mappings[921] = ItemType.DiamondShovel; - mappings[922] = ItemType.DiamondPickaxe; - mappings[923] = ItemType.DiamondAxe; - mappings[924] = ItemType.DiamondHoe; - mappings[925] = ItemType.NetheriteSword; - mappings[926] = ItemType.NetheriteShovel; - mappings[927] = ItemType.NetheritePickaxe; - mappings[928] = ItemType.NetheriteAxe; - mappings[929] = ItemType.NetheriteHoe; - mappings[930] = ItemType.Stick; - mappings[931] = ItemType.MushroomStew; - mappings[932] = ItemType.String; - mappings[933] = ItemType.Feather; - mappings[934] = ItemType.Gunpowder; - mappings[935] = ItemType.WheatSeeds; - mappings[936] = ItemType.Wheat; - mappings[937] = ItemType.Bread; - mappings[938] = ItemType.LeatherHelmet; - mappings[939] = ItemType.LeatherChestplate; - mappings[940] = ItemType.LeatherLeggings; - mappings[941] = ItemType.LeatherBoots; - mappings[942] = ItemType.CopperHelmet; - mappings[943] = ItemType.CopperChestplate; - mappings[944] = ItemType.CopperLeggings; - mappings[945] = ItemType.CopperBoots; - mappings[946] = ItemType.ChainmailHelmet; - mappings[947] = ItemType.ChainmailChestplate; - mappings[948] = ItemType.ChainmailLeggings; - mappings[949] = ItemType.ChainmailBoots; - mappings[950] = ItemType.IronHelmet; - mappings[951] = ItemType.IronChestplate; - mappings[952] = ItemType.IronLeggings; - mappings[953] = ItemType.IronBoots; - mappings[954] = ItemType.DiamondHelmet; - mappings[955] = ItemType.DiamondChestplate; - mappings[956] = ItemType.DiamondLeggings; - mappings[957] = ItemType.DiamondBoots; - mappings[958] = ItemType.GoldenHelmet; - mappings[959] = ItemType.GoldenChestplate; - mappings[960] = ItemType.GoldenLeggings; - mappings[961] = ItemType.GoldenBoots; - mappings[962] = ItemType.NetheriteHelmet; - mappings[963] = ItemType.NetheriteChestplate; - mappings[964] = ItemType.NetheriteLeggings; - mappings[965] = ItemType.NetheriteBoots; - mappings[966] = ItemType.Flint; - mappings[967] = ItemType.Porkchop; - mappings[968] = ItemType.CookedPorkchop; - mappings[969] = ItemType.Painting; - mappings[970] = ItemType.GoldenApple; - mappings[971] = ItemType.EnchantedGoldenApple; - mappings[972] = ItemType.OakSign; - mappings[973] = ItemType.SpruceSign; - mappings[974] = ItemType.BirchSign; - mappings[975] = ItemType.JungleSign; - mappings[976] = ItemType.AcaciaSign; - mappings[977] = ItemType.CherrySign; - mappings[978] = ItemType.DarkOakSign; - mappings[979] = ItemType.PaleOakSign; - mappings[980] = ItemType.MangroveSign; - mappings[981] = ItemType.BambooSign; - mappings[982] = ItemType.CrimsonSign; - mappings[983] = ItemType.WarpedSign; - mappings[984] = ItemType.OakHangingSign; - mappings[985] = ItemType.SpruceHangingSign; - mappings[986] = ItemType.BirchHangingSign; - mappings[987] = ItemType.JungleHangingSign; - mappings[988] = ItemType.AcaciaHangingSign; - mappings[989] = ItemType.CherryHangingSign; - mappings[990] = ItemType.DarkOakHangingSign; - mappings[991] = ItemType.PaleOakHangingSign; - mappings[992] = ItemType.MangroveHangingSign; - mappings[993] = ItemType.BambooHangingSign; - mappings[994] = ItemType.CrimsonHangingSign; - mappings[995] = ItemType.WarpedHangingSign; - mappings[996] = ItemType.Bucket; - mappings[997] = ItemType.WaterBucket; - mappings[998] = ItemType.LavaBucket; - mappings[999] = ItemType.PowderSnowBucket; - mappings[1000] = ItemType.Snowball; - mappings[1001] = ItemType.Leather; - mappings[1002] = ItemType.MilkBucket; - mappings[1003] = ItemType.PufferfishBucket; - mappings[1004] = ItemType.SalmonBucket; - mappings[1005] = ItemType.CodBucket; - mappings[1006] = ItemType.TropicalFishBucket; - mappings[1007] = ItemType.AxolotlBucket; - mappings[1008] = ItemType.TadpoleBucket; - mappings[1009] = ItemType.Brick; - mappings[1010] = ItemType.ClayBall; - mappings[1011] = ItemType.DriedKelpBlock; - mappings[1012] = ItemType.Paper; - mappings[1013] = ItemType.Book; - mappings[1014] = ItemType.SlimeBall; - mappings[1015] = ItemType.Egg; - mappings[1016] = ItemType.BlueEgg; - mappings[1017] = ItemType.BrownEgg; - mappings[1018] = ItemType.Compass; - mappings[1019] = ItemType.RecoveryCompass; - mappings[1020] = ItemType.Bundle; - mappings[1021] = ItemType.WhiteBundle; - mappings[1022] = ItemType.OrangeBundle; - mappings[1023] = ItemType.MagentaBundle; - mappings[1024] = ItemType.LightBlueBundle; - mappings[1025] = ItemType.YellowBundle; - mappings[1026] = ItemType.LimeBundle; - mappings[1027] = ItemType.PinkBundle; - mappings[1028] = ItemType.GrayBundle; - mappings[1029] = ItemType.LightGrayBundle; - mappings[1030] = ItemType.CyanBundle; - mappings[1031] = ItemType.PurpleBundle; - mappings[1032] = ItemType.BlueBundle; - mappings[1033] = ItemType.BrownBundle; - mappings[1034] = ItemType.GreenBundle; - mappings[1035] = ItemType.RedBundle; - mappings[1036] = ItemType.BlackBundle; - mappings[1037] = ItemType.FishingRod; - mappings[1038] = ItemType.Clock; - mappings[1039] = ItemType.Spyglass; - mappings[1040] = ItemType.GlowstoneDust; - mappings[1041] = ItemType.Cod; - mappings[1042] = ItemType.Salmon; - mappings[1043] = ItemType.TropicalFish; - mappings[1044] = ItemType.Pufferfish; - mappings[1045] = ItemType.CookedCod; - mappings[1046] = ItemType.CookedSalmon; - mappings[1047] = ItemType.InkSac; - mappings[1048] = ItemType.GlowInkSac; - mappings[1049] = ItemType.CocoaBeans; - mappings[1050] = ItemType.WhiteDye; - mappings[1051] = ItemType.OrangeDye; - mappings[1052] = ItemType.MagentaDye; - mappings[1053] = ItemType.LightBlueDye; - mappings[1054] = ItemType.YellowDye; - mappings[1055] = ItemType.LimeDye; - mappings[1056] = ItemType.PinkDye; - mappings[1057] = ItemType.GrayDye; - mappings[1058] = ItemType.LightGrayDye; - mappings[1059] = ItemType.CyanDye; - mappings[1060] = ItemType.PurpleDye; - mappings[1061] = ItemType.BlueDye; - mappings[1062] = ItemType.BrownDye; - mappings[1063] = ItemType.GreenDye; - mappings[1064] = ItemType.RedDye; - mappings[1065] = ItemType.BlackDye; - mappings[1066] = ItemType.BoneMeal; - mappings[1067] = ItemType.Bone; - mappings[1068] = ItemType.Sugar; - mappings[1069] = ItemType.Cake; - mappings[1070] = ItemType.WhiteBed; - mappings[1071] = ItemType.OrangeBed; - mappings[1072] = ItemType.MagentaBed; - mappings[1073] = ItemType.LightBlueBed; - mappings[1074] = ItemType.YellowBed; - mappings[1075] = ItemType.LimeBed; - mappings[1076] = ItemType.PinkBed; - mappings[1077] = ItemType.GrayBed; - mappings[1078] = ItemType.LightGrayBed; - mappings[1079] = ItemType.CyanBed; - mappings[1080] = ItemType.PurpleBed; - mappings[1081] = ItemType.BlueBed; - mappings[1082] = ItemType.BrownBed; - mappings[1083] = ItemType.GreenBed; - mappings[1084] = ItemType.RedBed; - mappings[1085] = ItemType.BlackBed; - mappings[1086] = ItemType.Cookie; - mappings[1087] = ItemType.Crafter; - mappings[1088] = ItemType.FilledMap; - mappings[1089] = ItemType.Shears; - mappings[1090] = ItemType.MelonSlice; - mappings[1091] = ItemType.DriedKelp; - mappings[1092] = ItemType.PumpkinSeeds; - mappings[1093] = ItemType.MelonSeeds; - mappings[1094] = ItemType.Beef; - mappings[1095] = ItemType.CookedBeef; - mappings[1096] = ItemType.Chicken; - mappings[1097] = ItemType.CookedChicken; - mappings[1098] = ItemType.RottenFlesh; - mappings[1099] = ItemType.EnderPearl; - mappings[1100] = ItemType.BlazeRod; - mappings[1101] = ItemType.GhastTear; - mappings[1102] = ItemType.GoldNugget; - mappings[1103] = ItemType.NetherWart; - mappings[1104] = ItemType.GlassBottle; - mappings[1105] = ItemType.Potion; - mappings[1106] = ItemType.SpiderEye; - mappings[1107] = ItemType.FermentedSpiderEye; - mappings[1108] = ItemType.BlazePowder; - mappings[1109] = ItemType.MagmaCream; - mappings[1110] = ItemType.BrewingStand; - mappings[1111] = ItemType.Cauldron; - mappings[1112] = ItemType.EnderEye; - mappings[1113] = ItemType.GlisteringMelonSlice; - mappings[1114] = ItemType.ArmadilloSpawnEgg; - mappings[1115] = ItemType.AllaySpawnEgg; - mappings[1116] = ItemType.AxolotlSpawnEgg; - mappings[1117] = ItemType.BatSpawnEgg; - mappings[1118] = ItemType.BeeSpawnEgg; - mappings[1119] = ItemType.BlazeSpawnEgg; - mappings[1120] = ItemType.BoggedSpawnEgg; - mappings[1121] = ItemType.BreezeSpawnEgg; - mappings[1122] = ItemType.CatSpawnEgg; - mappings[1123] = ItemType.CamelSpawnEgg; - mappings[1124] = ItemType.CaveSpiderSpawnEgg; - mappings[1125] = ItemType.ChickenSpawnEgg; - mappings[1126] = ItemType.CodSpawnEgg; - mappings[1127] = ItemType.CopperGolemSpawnEgg; - mappings[1128] = ItemType.CowSpawnEgg; - mappings[1129] = ItemType.CreeperSpawnEgg; - mappings[1130] = ItemType.DolphinSpawnEgg; - mappings[1131] = ItemType.DonkeySpawnEgg; - mappings[1132] = ItemType.DrownedSpawnEgg; - mappings[1133] = ItemType.ElderGuardianSpawnEgg; - mappings[1134] = ItemType.EnderDragonSpawnEgg; - mappings[1135] = ItemType.EndermanSpawnEgg; - mappings[1136] = ItemType.EndermiteSpawnEgg; - mappings[1137] = ItemType.EvokerSpawnEgg; - mappings[1138] = ItemType.FoxSpawnEgg; - mappings[1139] = ItemType.FrogSpawnEgg; - mappings[1140] = ItemType.GhastSpawnEgg; - mappings[1141] = ItemType.HappyGhastSpawnEgg; - mappings[1142] = ItemType.GlowSquidSpawnEgg; - mappings[1143] = ItemType.GoatSpawnEgg; - mappings[1144] = ItemType.GuardianSpawnEgg; - mappings[1145] = ItemType.HoglinSpawnEgg; - mappings[1146] = ItemType.HorseSpawnEgg; - mappings[1147] = ItemType.HuskSpawnEgg; - mappings[1148] = ItemType.IronGolemSpawnEgg; - mappings[1149] = ItemType.LlamaSpawnEgg; - mappings[1150] = ItemType.MagmaCubeSpawnEgg; - mappings[1151] = ItemType.MooshroomSpawnEgg; - mappings[1152] = ItemType.MuleSpawnEgg; - mappings[1153] = ItemType.OcelotSpawnEgg; - mappings[1154] = ItemType.PandaSpawnEgg; - mappings[1155] = ItemType.ParrotSpawnEgg; - mappings[1156] = ItemType.PhantomSpawnEgg; - mappings[1157] = ItemType.PigSpawnEgg; - mappings[1158] = ItemType.PiglinSpawnEgg; - mappings[1159] = ItemType.PiglinBruteSpawnEgg; - mappings[1160] = ItemType.PillagerSpawnEgg; - mappings[1161] = ItemType.PolarBearSpawnEgg; - mappings[1162] = ItemType.PufferfishSpawnEgg; - mappings[1163] = ItemType.RabbitSpawnEgg; - mappings[1164] = ItemType.RavagerSpawnEgg; - mappings[1165] = ItemType.SalmonSpawnEgg; - mappings[1166] = ItemType.SheepSpawnEgg; - mappings[1167] = ItemType.ShulkerSpawnEgg; - mappings[1168] = ItemType.SilverfishSpawnEgg; - mappings[1169] = ItemType.SkeletonSpawnEgg; - mappings[1170] = ItemType.SkeletonHorseSpawnEgg; - mappings[1171] = ItemType.SlimeSpawnEgg; - mappings[1172] = ItemType.SnifferSpawnEgg; - mappings[1173] = ItemType.SnowGolemSpawnEgg; - mappings[1174] = ItemType.SpiderSpawnEgg; - mappings[1175] = ItemType.SquidSpawnEgg; - mappings[1176] = ItemType.StraySpawnEgg; - mappings[1177] = ItemType.StriderSpawnEgg; - mappings[1178] = ItemType.TadpoleSpawnEgg; - mappings[1179] = ItemType.TraderLlamaSpawnEgg; - mappings[1180] = ItemType.TropicalFishSpawnEgg; - mappings[1181] = ItemType.TurtleSpawnEgg; - mappings[1182] = ItemType.VexSpawnEgg; - mappings[1183] = ItemType.VillagerSpawnEgg; - mappings[1184] = ItemType.VindicatorSpawnEgg; - mappings[1185] = ItemType.WanderingTraderSpawnEgg; - mappings[1186] = ItemType.WardenSpawnEgg; - mappings[1187] = ItemType.WitchSpawnEgg; - mappings[1188] = ItemType.WitherSpawnEgg; - mappings[1189] = ItemType.WitherSkeletonSpawnEgg; - mappings[1190] = ItemType.WolfSpawnEgg; - mappings[1191] = ItemType.ZoglinSpawnEgg; - mappings[1192] = ItemType.CreakingSpawnEgg; - mappings[1193] = ItemType.ZombieSpawnEgg; - mappings[1194] = ItemType.ZombieHorseSpawnEgg; - mappings[1195] = ItemType.ZombieVillagerSpawnEgg; - mappings[1196] = ItemType.ZombifiedPiglinSpawnEgg; - mappings[1197] = ItemType.ExperienceBottle; - mappings[1198] = ItemType.FireCharge; - mappings[1199] = ItemType.WindCharge; - mappings[1200] = ItemType.WritableBook; - mappings[1201] = ItemType.WrittenBook; - mappings[1202] = ItemType.BreezeRod; - mappings[1203] = ItemType.Mace; - mappings[1204] = ItemType.ItemFrame; - mappings[1205] = ItemType.GlowItemFrame; - mappings[1206] = ItemType.FlowerPot; - mappings[1207] = ItemType.Carrot; - mappings[1208] = ItemType.Potato; - mappings[1209] = ItemType.BakedPotato; - mappings[1210] = ItemType.PoisonousPotato; - mappings[1211] = ItemType.Map; - mappings[1212] = ItemType.GoldenCarrot; - mappings[1213] = ItemType.SkeletonSkull; - mappings[1214] = ItemType.WitherSkeletonSkull; - mappings[1215] = ItemType.PlayerHead; - mappings[1216] = ItemType.ZombieHead; - mappings[1217] = ItemType.CreeperHead; - mappings[1218] = ItemType.DragonHead; - mappings[1219] = ItemType.PiglinHead; - mappings[1220] = ItemType.NetherStar; - mappings[1221] = ItemType.PumpkinPie; - mappings[1222] = ItemType.FireworkRocket; - mappings[1223] = ItemType.FireworkStar; - mappings[1224] = ItemType.EnchantedBook; - mappings[1225] = ItemType.NetherBrick; - mappings[1226] = ItemType.ResinBrick; - mappings[1227] = ItemType.PrismarineShard; - mappings[1228] = ItemType.PrismarineCrystals; - mappings[1229] = ItemType.Rabbit; - mappings[1230] = ItemType.CookedRabbit; - mappings[1231] = ItemType.RabbitStew; - mappings[1232] = ItemType.RabbitFoot; - mappings[1233] = ItemType.RabbitHide; - mappings[1234] = ItemType.ArmorStand; - mappings[1235] = ItemType.CopperHorseArmor; - mappings[1236] = ItemType.IronHorseArmor; - mappings[1237] = ItemType.GoldenHorseArmor; - mappings[1238] = ItemType.DiamondHorseArmor; - mappings[1239] = ItemType.LeatherHorseArmor; - mappings[1240] = ItemType.Lead; - mappings[1241] = ItemType.NameTag; - mappings[1242] = ItemType.CommandBlockMinecart; - mappings[1243] = ItemType.Mutton; - mappings[1244] = ItemType.CookedMutton; - mappings[1245] = ItemType.WhiteBanner; - mappings[1246] = ItemType.OrangeBanner; - mappings[1247] = ItemType.MagentaBanner; - mappings[1248] = ItemType.LightBlueBanner; - mappings[1249] = ItemType.YellowBanner; - mappings[1250] = ItemType.LimeBanner; - mappings[1251] = ItemType.PinkBanner; - mappings[1252] = ItemType.GrayBanner; - mappings[1253] = ItemType.LightGrayBanner; - mappings[1254] = ItemType.CyanBanner; - mappings[1255] = ItemType.PurpleBanner; - mappings[1256] = ItemType.BlueBanner; - mappings[1257] = ItemType.BrownBanner; - mappings[1258] = ItemType.GreenBanner; - mappings[1259] = ItemType.RedBanner; - mappings[1260] = ItemType.BlackBanner; - mappings[1261] = ItemType.EndCrystal; - mappings[1262] = ItemType.ChorusFruit; - mappings[1263] = ItemType.PoppedChorusFruit; - mappings[1264] = ItemType.TorchflowerSeeds; - mappings[1265] = ItemType.PitcherPod; - mappings[1266] = ItemType.Beetroot; - mappings[1267] = ItemType.BeetrootSeeds; - mappings[1268] = ItemType.BeetrootSoup; - mappings[1269] = ItemType.DragonBreath; - mappings[1270] = ItemType.SplashPotion; - mappings[1271] = ItemType.SpectralArrow; - mappings[1272] = ItemType.TippedArrow; - mappings[1273] = ItemType.LingeringPotion; - mappings[1274] = ItemType.Shield; - mappings[1275] = ItemType.TotemOfUndying; - mappings[1276] = ItemType.ShulkerShell; - mappings[1277] = ItemType.IronNugget; - mappings[1278] = ItemType.CopperNugget; - mappings[1279] = ItemType.KnowledgeBook; - mappings[1280] = ItemType.DebugStick; - mappings[1281] = ItemType.MusicDisc13; - mappings[1282] = ItemType.MusicDiscCat; - mappings[1283] = ItemType.MusicDiscBlocks; - mappings[1284] = ItemType.MusicDiscChirp; - mappings[1285] = ItemType.MusicDiscCreator; - mappings[1286] = ItemType.MusicDiscCreatorMusicBox; - mappings[1287] = ItemType.MusicDiscFar; - mappings[1288] = ItemType.MusicDiscLavaChicken; - mappings[1289] = ItemType.MusicDiscMall; - mappings[1290] = ItemType.MusicDiscMellohi; - mappings[1291] = ItemType.MusicDiscStal; - mappings[1292] = ItemType.MusicDiscStrad; - mappings[1293] = ItemType.MusicDiscWard; - mappings[1294] = ItemType.MusicDisc11; - mappings[1295] = ItemType.MusicDiscWait; - mappings[1296] = ItemType.MusicDiscOtherside; - mappings[1297] = ItemType.MusicDiscRelic; - mappings[1298] = ItemType.MusicDisc5; - mappings[1299] = ItemType.MusicDiscPigstep; - mappings[1300] = ItemType.MusicDiscPrecipice; - mappings[1301] = ItemType.MusicDiscTears; - mappings[1302] = ItemType.DiscFragment5; - mappings[1303] = ItemType.Trident; - mappings[1304] = ItemType.NautilusShell; - mappings[1305] = ItemType.HeartOfTheSea; - mappings[1306] = ItemType.Crossbow; - mappings[1307] = ItemType.SuspiciousStew; - mappings[1308] = ItemType.Loom; - mappings[1309] = ItemType.FlowerBannerPattern; - mappings[1310] = ItemType.CreeperBannerPattern; - mappings[1311] = ItemType.SkullBannerPattern; - mappings[1312] = ItemType.MojangBannerPattern; - mappings[1313] = ItemType.GlobeBannerPattern; - mappings[1314] = ItemType.PiglinBannerPattern; - mappings[1315] = ItemType.FlowBannerPattern; - mappings[1316] = ItemType.GusterBannerPattern; - mappings[1317] = ItemType.FieldMasonedBannerPattern; - mappings[1318] = ItemType.BordureIndentedBannerPattern; - mappings[1319] = ItemType.GoatHorn; - mappings[1320] = ItemType.Composter; - mappings[1321] = ItemType.Barrel; - mappings[1322] = ItemType.Smoker; - mappings[1323] = ItemType.BlastFurnace; - mappings[1324] = ItemType.CartographyTable; - mappings[1325] = ItemType.FletchingTable; - mappings[1326] = ItemType.Grindstone; - mappings[1327] = ItemType.SmithingTable; - mappings[1328] = ItemType.Stonecutter; - mappings[1329] = ItemType.Bell; - mappings[1330] = ItemType.Lantern; - mappings[1331] = ItemType.SoulLantern; - mappings[1332] = ItemType.SweetBerries; - mappings[1333] = ItemType.GlowBerries; - mappings[1334] = ItemType.Campfire; - mappings[1335] = ItemType.SoulCampfire; - mappings[1336] = ItemType.Shroomlight; - mappings[1337] = ItemType.Honeycomb; - mappings[1338] = ItemType.BeeNest; - mappings[1339] = ItemType.Beehive; - mappings[1340] = ItemType.HoneyBottle; - mappings[1341] = ItemType.HoneycombBlock; - mappings[1342] = ItemType.Lodestone; - mappings[1343] = ItemType.CryingObsidian; - mappings[1344] = ItemType.Blackstone; - mappings[1345] = ItemType.BlackstoneSlab; - mappings[1346] = ItemType.BlackstoneStairs; - mappings[1347] = ItemType.GildedBlackstone; - mappings[1348] = ItemType.PolishedBlackstone; - mappings[1349] = ItemType.PolishedBlackstoneSlab; - mappings[1350] = ItemType.PolishedBlackstoneStairs; - mappings[1351] = ItemType.ChiseledPolishedBlackstone; - mappings[1352] = ItemType.PolishedBlackstoneBricks; - mappings[1353] = ItemType.PolishedBlackstoneBrickSlab; - mappings[1354] = ItemType.PolishedBlackstoneBrickStairs; - mappings[1355] = ItemType.CrackedPolishedBlackstoneBricks; - mappings[1356] = ItemType.RespawnAnchor; - mappings[1357] = ItemType.Candle; - mappings[1358] = ItemType.WhiteCandle; - mappings[1359] = ItemType.OrangeCandle; - mappings[1360] = ItemType.MagentaCandle; - mappings[1361] = ItemType.LightBlueCandle; - mappings[1362] = ItemType.YellowCandle; - mappings[1363] = ItemType.LimeCandle; - mappings[1364] = ItemType.PinkCandle; - mappings[1365] = ItemType.GrayCandle; - mappings[1366] = ItemType.LightGrayCandle; - mappings[1367] = ItemType.CyanCandle; - mappings[1368] = ItemType.PurpleCandle; - mappings[1369] = ItemType.BlueCandle; - mappings[1370] = ItemType.BrownCandle; - mappings[1371] = ItemType.GreenCandle; - mappings[1372] = ItemType.RedCandle; - mappings[1373] = ItemType.BlackCandle; - mappings[1374] = ItemType.SmallAmethystBud; - mappings[1375] = ItemType.MediumAmethystBud; - mappings[1376] = ItemType.LargeAmethystBud; - mappings[1377] = ItemType.AmethystCluster; - mappings[1378] = ItemType.PointedDripstone; - mappings[1379] = ItemType.OchreFroglight; - mappings[1380] = ItemType.VerdantFroglight; - mappings[1381] = ItemType.PearlescentFroglight; - mappings[1382] = ItemType.Frogspawn; - mappings[1383] = ItemType.EchoShard; - mappings[1384] = ItemType.Brush; - mappings[1385] = ItemType.NetheriteUpgradeSmithingTemplate; - mappings[1386] = ItemType.SentryArmorTrimSmithingTemplate; - mappings[1387] = ItemType.DuneArmorTrimSmithingTemplate; - mappings[1388] = ItemType.CoastArmorTrimSmithingTemplate; - mappings[1389] = ItemType.WildArmorTrimSmithingTemplate; - mappings[1390] = ItemType.WardArmorTrimSmithingTemplate; - mappings[1391] = ItemType.EyeArmorTrimSmithingTemplate; - mappings[1392] = ItemType.VexArmorTrimSmithingTemplate; - mappings[1393] = ItemType.TideArmorTrimSmithingTemplate; - mappings[1394] = ItemType.SnoutArmorTrimSmithingTemplate; - mappings[1395] = ItemType.RibArmorTrimSmithingTemplate; - mappings[1396] = ItemType.SpireArmorTrimSmithingTemplate; - mappings[1397] = ItemType.WayfinderArmorTrimSmithingTemplate; - mappings[1398] = ItemType.ShaperArmorTrimSmithingTemplate; - mappings[1399] = ItemType.SilenceArmorTrimSmithingTemplate; - mappings[1400] = ItemType.RaiserArmorTrimSmithingTemplate; - mappings[1401] = ItemType.HostArmorTrimSmithingTemplate; - mappings[1402] = ItemType.FlowArmorTrimSmithingTemplate; - mappings[1403] = ItemType.BoltArmorTrimSmithingTemplate; - mappings[1404] = ItemType.AnglerPotterySherd; - mappings[1405] = ItemType.ArcherPotterySherd; - mappings[1406] = ItemType.ArmsUpPotterySherd; - mappings[1407] = ItemType.BladePotterySherd; - mappings[1408] = ItemType.BrewerPotterySherd; - mappings[1409] = ItemType.BurnPotterySherd; - mappings[1410] = ItemType.DangerPotterySherd; - mappings[1411] = ItemType.ExplorerPotterySherd; - mappings[1412] = ItemType.FlowPotterySherd; - mappings[1413] = ItemType.FriendPotterySherd; - mappings[1414] = ItemType.GusterPotterySherd; - mappings[1415] = ItemType.HeartPotterySherd; - mappings[1416] = ItemType.HeartbreakPotterySherd; - mappings[1417] = ItemType.HowlPotterySherd; - mappings[1418] = ItemType.MinerPotterySherd; - mappings[1419] = ItemType.MournerPotterySherd; - mappings[1420] = ItemType.PlentyPotterySherd; - mappings[1421] = ItemType.PrizePotterySherd; - mappings[1422] = ItemType.ScrapePotterySherd; - mappings[1423] = ItemType.SheafPotterySherd; - mappings[1424] = ItemType.ShelterPotterySherd; - mappings[1425] = ItemType.SkullPotterySherd; - mappings[1426] = ItemType.SnortPotterySherd; - mappings[1427] = ItemType.CopperGrate; - mappings[1428] = ItemType.ExposedCopperGrate; - mappings[1429] = ItemType.WeatheredCopperGrate; - mappings[1430] = ItemType.OxidizedCopperGrate; - mappings[1431] = ItemType.WaxedCopperGrate; - mappings[1432] = ItemType.WaxedExposedCopperGrate; - mappings[1433] = ItemType.WaxedWeatheredCopperGrate; - mappings[1434] = ItemType.WaxedOxidizedCopperGrate; - mappings[1435] = ItemType.CopperBulb; - mappings[1436] = ItemType.ExposedCopperBulb; - mappings[1437] = ItemType.WeatheredCopperBulb; - mappings[1438] = ItemType.OxidizedCopperBulb; - mappings[1439] = ItemType.WaxedCopperBulb; - mappings[1440] = ItemType.WaxedExposedCopperBulb; - mappings[1441] = ItemType.WaxedWeatheredCopperBulb; - mappings[1442] = ItemType.WaxedOxidizedCopperBulb; - mappings[1443] = ItemType.CopperChest; - mappings[1444] = ItemType.ExposedCopperChest; - mappings[1445] = ItemType.WeatheredCopperChest; - mappings[1446] = ItemType.OxidizedCopperChest; - mappings[1447] = ItemType.WaxedCopperChest; - mappings[1448] = ItemType.WaxedExposedCopperChest; - mappings[1449] = ItemType.WaxedWeatheredCopperChest; - mappings[1450] = ItemType.WaxedOxidizedCopperChest; - mappings[1451] = ItemType.CopperGolemStatue; - mappings[1452] = ItemType.ExposedCopperGolemStatue; - mappings[1453] = ItemType.WeatheredCopperGolemStatue; - mappings[1454] = ItemType.OxidizedCopperGolemStatue; - mappings[1455] = ItemType.WaxedCopperGolemStatue; - mappings[1456] = ItemType.WaxedExposedCopperGolemStatue; - mappings[1457] = ItemType.WaxedWeatheredCopperGolemStatue; - mappings[1458] = ItemType.WaxedOxidizedCopperGolemStatue; - mappings[1459] = ItemType.TrialSpawner; - mappings[1460] = ItemType.TrialKey; - mappings[1461] = ItemType.OminousTrialKey; - mappings[1462] = ItemType.Vault; - mappings[1463] = ItemType.OminousBottle; + mappings[391] = ItemType.CopperBars; + mappings[392] = ItemType.ExposedCopperBars; + mappings[393] = ItemType.WeatheredCopperBars; + mappings[394] = ItemType.OxidizedCopperBars; + mappings[395] = ItemType.WaxedCopperBars; + mappings[396] = ItemType.WaxedExposedCopperBars; + mappings[397] = ItemType.WaxedWeatheredCopperBars; + mappings[398] = ItemType.WaxedOxidizedCopperBars; + mappings[399] = ItemType.IronChain; + mappings[400] = ItemType.CopperChain; + mappings[401] = ItemType.ExposedCopperChain; + mappings[402] = ItemType.WeatheredCopperChain; + mappings[403] = ItemType.OxidizedCopperChain; + mappings[404] = ItemType.WaxedCopperChain; + mappings[405] = ItemType.WaxedExposedCopperChain; + mappings[406] = ItemType.WaxedWeatheredCopperChain; + mappings[407] = ItemType.WaxedOxidizedCopperChain; + mappings[408] = ItemType.GlassPane; + mappings[409] = ItemType.Melon; + mappings[410] = ItemType.Vine; + mappings[411] = ItemType.GlowLichen; + mappings[412] = ItemType.ResinClump; + mappings[413] = ItemType.ResinBlock; + mappings[414] = ItemType.ResinBricks; + mappings[415] = ItemType.ResinBrickStairs; + mappings[416] = ItemType.ResinBrickSlab; + mappings[417] = ItemType.ResinBrickWall; + mappings[418] = ItemType.ChiseledResinBricks; + mappings[419] = ItemType.BrickStairs; + mappings[420] = ItemType.StoneBrickStairs; + mappings[421] = ItemType.MudBrickStairs; + mappings[422] = ItemType.Mycelium; + mappings[423] = ItemType.LilyPad; + mappings[424] = ItemType.NetherBricks; + mappings[425] = ItemType.CrackedNetherBricks; + mappings[426] = ItemType.ChiseledNetherBricks; + mappings[427] = ItemType.NetherBrickFence; + mappings[428] = ItemType.NetherBrickStairs; + mappings[429] = ItemType.Sculk; + mappings[430] = ItemType.SculkVein; + mappings[431] = ItemType.SculkCatalyst; + mappings[432] = ItemType.SculkShrieker; + mappings[433] = ItemType.EnchantingTable; + mappings[434] = ItemType.EndPortalFrame; + mappings[435] = ItemType.EndStone; + mappings[436] = ItemType.EndStoneBricks; + mappings[437] = ItemType.DragonEgg; + mappings[438] = ItemType.SandstoneStairs; + mappings[439] = ItemType.EnderChest; + mappings[440] = ItemType.EmeraldBlock; + mappings[441] = ItemType.OakStairs; + mappings[442] = ItemType.SpruceStairs; + mappings[443] = ItemType.BirchStairs; + mappings[444] = ItemType.JungleStairs; + mappings[445] = ItemType.AcaciaStairs; + mappings[446] = ItemType.CherryStairs; + mappings[447] = ItemType.DarkOakStairs; + mappings[448] = ItemType.PaleOakStairs; + mappings[449] = ItemType.MangroveStairs; + mappings[450] = ItemType.BambooStairs; + mappings[451] = ItemType.BambooMosaicStairs; + mappings[452] = ItemType.CrimsonStairs; + mappings[453] = ItemType.WarpedStairs; + mappings[454] = ItemType.CommandBlock; + mappings[455] = ItemType.Beacon; + mappings[456] = ItemType.CobblestoneWall; + mappings[457] = ItemType.MossyCobblestoneWall; + mappings[458] = ItemType.BrickWall; + mappings[459] = ItemType.PrismarineWall; + mappings[460] = ItemType.RedSandstoneWall; + mappings[461] = ItemType.MossyStoneBrickWall; + mappings[462] = ItemType.GraniteWall; + mappings[463] = ItemType.StoneBrickWall; + mappings[464] = ItemType.MudBrickWall; + mappings[465] = ItemType.NetherBrickWall; + mappings[466] = ItemType.AndesiteWall; + mappings[467] = ItemType.RedNetherBrickWall; + mappings[468] = ItemType.SandstoneWall; + mappings[469] = ItemType.EndStoneBrickWall; + mappings[470] = ItemType.DioriteWall; + mappings[471] = ItemType.BlackstoneWall; + mappings[472] = ItemType.PolishedBlackstoneWall; + mappings[473] = ItemType.PolishedBlackstoneBrickWall; + mappings[474] = ItemType.CobbledDeepslateWall; + mappings[475] = ItemType.PolishedDeepslateWall; + mappings[476] = ItemType.DeepslateBrickWall; + mappings[477] = ItemType.DeepslateTileWall; + mappings[478] = ItemType.Anvil; + mappings[479] = ItemType.ChippedAnvil; + mappings[480] = ItemType.DamagedAnvil; + mappings[481] = ItemType.ChiseledQuartzBlock; + mappings[482] = ItemType.QuartzBlock; + mappings[483] = ItemType.QuartzBricks; + mappings[484] = ItemType.QuartzPillar; + mappings[485] = ItemType.QuartzStairs; + mappings[486] = ItemType.WhiteTerracotta; + mappings[487] = ItemType.OrangeTerracotta; + mappings[488] = ItemType.MagentaTerracotta; + mappings[489] = ItemType.LightBlueTerracotta; + mappings[490] = ItemType.YellowTerracotta; + mappings[491] = ItemType.LimeTerracotta; + mappings[492] = ItemType.PinkTerracotta; + mappings[493] = ItemType.GrayTerracotta; + mappings[494] = ItemType.LightGrayTerracotta; + mappings[495] = ItemType.CyanTerracotta; + mappings[496] = ItemType.PurpleTerracotta; + mappings[497] = ItemType.BlueTerracotta; + mappings[498] = ItemType.BrownTerracotta; + mappings[499] = ItemType.GreenTerracotta; + mappings[500] = ItemType.RedTerracotta; + mappings[501] = ItemType.BlackTerracotta; + mappings[502] = ItemType.Barrier; + mappings[503] = ItemType.Light; + mappings[504] = ItemType.HayBlock; + mappings[505] = ItemType.WhiteCarpet; + mappings[506] = ItemType.OrangeCarpet; + mappings[507] = ItemType.MagentaCarpet; + mappings[508] = ItemType.LightBlueCarpet; + mappings[509] = ItemType.YellowCarpet; + mappings[510] = ItemType.LimeCarpet; + mappings[511] = ItemType.PinkCarpet; + mappings[512] = ItemType.GrayCarpet; + mappings[513] = ItemType.LightGrayCarpet; + mappings[514] = ItemType.CyanCarpet; + mappings[515] = ItemType.PurpleCarpet; + mappings[516] = ItemType.BlueCarpet; + mappings[517] = ItemType.BrownCarpet; + mappings[518] = ItemType.GreenCarpet; + mappings[519] = ItemType.RedCarpet; + mappings[520] = ItemType.BlackCarpet; + mappings[521] = ItemType.Terracotta; + mappings[522] = ItemType.PackedIce; + mappings[523] = ItemType.DirtPath; + mappings[524] = ItemType.Sunflower; + mappings[525] = ItemType.Lilac; + mappings[526] = ItemType.RoseBush; + mappings[527] = ItemType.Peony; + mappings[528] = ItemType.TallGrass; + mappings[529] = ItemType.LargeFern; + mappings[530] = ItemType.WhiteStainedGlass; + mappings[531] = ItemType.OrangeStainedGlass; + mappings[532] = ItemType.MagentaStainedGlass; + mappings[533] = ItemType.LightBlueStainedGlass; + mappings[534] = ItemType.YellowStainedGlass; + mappings[535] = ItemType.LimeStainedGlass; + mappings[536] = ItemType.PinkStainedGlass; + mappings[537] = ItemType.GrayStainedGlass; + mappings[538] = ItemType.LightGrayStainedGlass; + mappings[539] = ItemType.CyanStainedGlass; + mappings[540] = ItemType.PurpleStainedGlass; + mappings[541] = ItemType.BlueStainedGlass; + mappings[542] = ItemType.BrownStainedGlass; + mappings[543] = ItemType.GreenStainedGlass; + mappings[544] = ItemType.RedStainedGlass; + mappings[545] = ItemType.BlackStainedGlass; + mappings[546] = ItemType.WhiteStainedGlassPane; + mappings[547] = ItemType.OrangeStainedGlassPane; + mappings[548] = ItemType.MagentaStainedGlassPane; + mappings[549] = ItemType.LightBlueStainedGlassPane; + mappings[550] = ItemType.YellowStainedGlassPane; + mappings[551] = ItemType.LimeStainedGlassPane; + mappings[552] = ItemType.PinkStainedGlassPane; + mappings[553] = ItemType.GrayStainedGlassPane; + mappings[554] = ItemType.LightGrayStainedGlassPane; + mappings[555] = ItemType.CyanStainedGlassPane; + mappings[556] = ItemType.PurpleStainedGlassPane; + mappings[557] = ItemType.BlueStainedGlassPane; + mappings[558] = ItemType.BrownStainedGlassPane; + mappings[559] = ItemType.GreenStainedGlassPane; + mappings[560] = ItemType.RedStainedGlassPane; + mappings[561] = ItemType.BlackStainedGlassPane; + mappings[562] = ItemType.Prismarine; + mappings[563] = ItemType.PrismarineBricks; + mappings[564] = ItemType.DarkPrismarine; + mappings[565] = ItemType.PrismarineStairs; + mappings[566] = ItemType.PrismarineBrickStairs; + mappings[567] = ItemType.DarkPrismarineStairs; + mappings[568] = ItemType.SeaLantern; + mappings[569] = ItemType.RedSandstone; + mappings[570] = ItemType.ChiseledRedSandstone; + mappings[571] = ItemType.CutRedSandstone; + mappings[572] = ItemType.RedSandstoneStairs; + mappings[573] = ItemType.RepeatingCommandBlock; + mappings[574] = ItemType.ChainCommandBlock; + mappings[575] = ItemType.MagmaBlock; + mappings[576] = ItemType.NetherWartBlock; + mappings[577] = ItemType.WarpedWartBlock; + mappings[578] = ItemType.RedNetherBricks; + mappings[579] = ItemType.BoneBlock; + mappings[580] = ItemType.StructureVoid; + mappings[581] = ItemType.ShulkerBox; + mappings[582] = ItemType.WhiteShulkerBox; + mappings[583] = ItemType.OrangeShulkerBox; + mappings[584] = ItemType.MagentaShulkerBox; + mappings[585] = ItemType.LightBlueShulkerBox; + mappings[586] = ItemType.YellowShulkerBox; + mappings[587] = ItemType.LimeShulkerBox; + mappings[588] = ItemType.PinkShulkerBox; + mappings[589] = ItemType.GrayShulkerBox; + mappings[590] = ItemType.LightGrayShulkerBox; + mappings[591] = ItemType.CyanShulkerBox; + mappings[592] = ItemType.PurpleShulkerBox; + mappings[593] = ItemType.BlueShulkerBox; + mappings[594] = ItemType.BrownShulkerBox; + mappings[595] = ItemType.GreenShulkerBox; + mappings[596] = ItemType.RedShulkerBox; + mappings[597] = ItemType.BlackShulkerBox; + mappings[598] = ItemType.WhiteGlazedTerracotta; + mappings[599] = ItemType.OrangeGlazedTerracotta; + mappings[600] = ItemType.MagentaGlazedTerracotta; + mappings[601] = ItemType.LightBlueGlazedTerracotta; + mappings[602] = ItemType.YellowGlazedTerracotta; + mappings[603] = ItemType.LimeGlazedTerracotta; + mappings[604] = ItemType.PinkGlazedTerracotta; + mappings[605] = ItemType.GrayGlazedTerracotta; + mappings[606] = ItemType.LightGrayGlazedTerracotta; + mappings[607] = ItemType.CyanGlazedTerracotta; + mappings[608] = ItemType.PurpleGlazedTerracotta; + mappings[609] = ItemType.BlueGlazedTerracotta; + mappings[610] = ItemType.BrownGlazedTerracotta; + mappings[611] = ItemType.GreenGlazedTerracotta; + mappings[612] = ItemType.RedGlazedTerracotta; + mappings[613] = ItemType.BlackGlazedTerracotta; + mappings[614] = ItemType.WhiteConcrete; + mappings[615] = ItemType.OrangeConcrete; + mappings[616] = ItemType.MagentaConcrete; + mappings[617] = ItemType.LightBlueConcrete; + mappings[618] = ItemType.YellowConcrete; + mappings[619] = ItemType.LimeConcrete; + mappings[620] = ItemType.PinkConcrete; + mappings[621] = ItemType.GrayConcrete; + mappings[622] = ItemType.LightGrayConcrete; + mappings[623] = ItemType.CyanConcrete; + mappings[624] = ItemType.PurpleConcrete; + mappings[625] = ItemType.BlueConcrete; + mappings[626] = ItemType.BrownConcrete; + mappings[627] = ItemType.GreenConcrete; + mappings[628] = ItemType.RedConcrete; + mappings[629] = ItemType.BlackConcrete; + mappings[630] = ItemType.WhiteConcretePowder; + mappings[631] = ItemType.OrangeConcretePowder; + mappings[632] = ItemType.MagentaConcretePowder; + mappings[633] = ItemType.LightBlueConcretePowder; + mappings[634] = ItemType.YellowConcretePowder; + mappings[635] = ItemType.LimeConcretePowder; + mappings[636] = ItemType.PinkConcretePowder; + mappings[637] = ItemType.GrayConcretePowder; + mappings[638] = ItemType.LightGrayConcretePowder; + mappings[639] = ItemType.CyanConcretePowder; + mappings[640] = ItemType.PurpleConcretePowder; + mappings[641] = ItemType.BlueConcretePowder; + mappings[642] = ItemType.BrownConcretePowder; + mappings[643] = ItemType.GreenConcretePowder; + mappings[644] = ItemType.RedConcretePowder; + mappings[645] = ItemType.BlackConcretePowder; + mappings[646] = ItemType.TurtleEgg; + mappings[647] = ItemType.SnifferEgg; + mappings[648] = ItemType.DriedGhast; + mappings[649] = ItemType.DeadTubeCoralBlock; + mappings[650] = ItemType.DeadBrainCoralBlock; + mappings[651] = ItemType.DeadBubbleCoralBlock; + mappings[652] = ItemType.DeadFireCoralBlock; + mappings[653] = ItemType.DeadHornCoralBlock; + mappings[654] = ItemType.TubeCoralBlock; + mappings[655] = ItemType.BrainCoralBlock; + mappings[656] = ItemType.BubbleCoralBlock; + mappings[657] = ItemType.FireCoralBlock; + mappings[658] = ItemType.HornCoralBlock; + mappings[659] = ItemType.TubeCoral; + mappings[660] = ItemType.BrainCoral; + mappings[661] = ItemType.BubbleCoral; + mappings[662] = ItemType.FireCoral; + mappings[663] = ItemType.HornCoral; + mappings[664] = ItemType.DeadBrainCoral; + mappings[665] = ItemType.DeadBubbleCoral; + mappings[666] = ItemType.DeadFireCoral; + mappings[667] = ItemType.DeadHornCoral; + mappings[668] = ItemType.DeadTubeCoral; + mappings[669] = ItemType.TubeCoralFan; + mappings[670] = ItemType.BrainCoralFan; + mappings[671] = ItemType.BubbleCoralFan; + mappings[672] = ItemType.FireCoralFan; + mappings[673] = ItemType.HornCoralFan; + mappings[674] = ItemType.DeadTubeCoralFan; + mappings[675] = ItemType.DeadBrainCoralFan; + mappings[676] = ItemType.DeadBubbleCoralFan; + mappings[677] = ItemType.DeadFireCoralFan; + mappings[678] = ItemType.DeadHornCoralFan; + mappings[679] = ItemType.BlueIce; + mappings[680] = ItemType.Conduit; + mappings[681] = ItemType.PolishedGraniteStairs; + mappings[682] = ItemType.SmoothRedSandstoneStairs; + mappings[683] = ItemType.MossyStoneBrickStairs; + mappings[684] = ItemType.PolishedDioriteStairs; + mappings[685] = ItemType.MossyCobblestoneStairs; + mappings[686] = ItemType.EndStoneBrickStairs; + mappings[687] = ItemType.StoneStairs; + mappings[688] = ItemType.SmoothSandstoneStairs; + mappings[689] = ItemType.SmoothQuartzStairs; + mappings[690] = ItemType.GraniteStairs; + mappings[691] = ItemType.AndesiteStairs; + mappings[692] = ItemType.RedNetherBrickStairs; + mappings[693] = ItemType.PolishedAndesiteStairs; + mappings[694] = ItemType.DioriteStairs; + mappings[695] = ItemType.CobbledDeepslateStairs; + mappings[696] = ItemType.PolishedDeepslateStairs; + mappings[697] = ItemType.DeepslateBrickStairs; + mappings[698] = ItemType.DeepslateTileStairs; + mappings[699] = ItemType.PolishedGraniteSlab; + mappings[700] = ItemType.SmoothRedSandstoneSlab; + mappings[701] = ItemType.MossyStoneBrickSlab; + mappings[702] = ItemType.PolishedDioriteSlab; + mappings[703] = ItemType.MossyCobblestoneSlab; + mappings[704] = ItemType.EndStoneBrickSlab; + mappings[705] = ItemType.SmoothSandstoneSlab; + mappings[706] = ItemType.SmoothQuartzSlab; + mappings[707] = ItemType.GraniteSlab; + mappings[708] = ItemType.AndesiteSlab; + mappings[709] = ItemType.RedNetherBrickSlab; + mappings[710] = ItemType.PolishedAndesiteSlab; + mappings[711] = ItemType.DioriteSlab; + mappings[712] = ItemType.CobbledDeepslateSlab; + mappings[713] = ItemType.PolishedDeepslateSlab; + mappings[714] = ItemType.DeepslateBrickSlab; + mappings[715] = ItemType.DeepslateTileSlab; + mappings[716] = ItemType.Scaffolding; + mappings[717] = ItemType.Redstone; + mappings[718] = ItemType.RedstoneTorch; + mappings[719] = ItemType.RedstoneBlock; + mappings[720] = ItemType.Repeater; + mappings[721] = ItemType.Comparator; + mappings[722] = ItemType.Piston; + mappings[723] = ItemType.StickyPiston; + mappings[724] = ItemType.SlimeBlock; + mappings[725] = ItemType.HoneyBlock; + mappings[726] = ItemType.Observer; + mappings[727] = ItemType.Hopper; + mappings[728] = ItemType.Dispenser; + mappings[729] = ItemType.Dropper; + mappings[730] = ItemType.Lectern; + mappings[731] = ItemType.Target; + mappings[732] = ItemType.Lever; + mappings[733] = ItemType.LightningRod; + mappings[734] = ItemType.ExposedLightningRod; + mappings[735] = ItemType.WeatheredLightningRod; + mappings[736] = ItemType.OxidizedLightningRod; + mappings[737] = ItemType.WaxedLightningRod; + mappings[738] = ItemType.WaxedExposedLightningRod; + mappings[739] = ItemType.WaxedWeatheredLightningRod; + mappings[740] = ItemType.WaxedOxidizedLightningRod; + mappings[741] = ItemType.DaylightDetector; + mappings[742] = ItemType.SculkSensor; + mappings[743] = ItemType.CalibratedSculkSensor; + mappings[744] = ItemType.TripwireHook; + mappings[745] = ItemType.TrappedChest; + mappings[746] = ItemType.Tnt; + mappings[747] = ItemType.RedstoneLamp; + mappings[748] = ItemType.NoteBlock; + mappings[749] = ItemType.StoneButton; + mappings[750] = ItemType.PolishedBlackstoneButton; + mappings[751] = ItemType.OakButton; + mappings[752] = ItemType.SpruceButton; + mappings[753] = ItemType.BirchButton; + mappings[754] = ItemType.JungleButton; + mappings[755] = ItemType.AcaciaButton; + mappings[756] = ItemType.CherryButton; + mappings[757] = ItemType.DarkOakButton; + mappings[758] = ItemType.PaleOakButton; + mappings[759] = ItemType.MangroveButton; + mappings[760] = ItemType.BambooButton; + mappings[761] = ItemType.CrimsonButton; + mappings[762] = ItemType.WarpedButton; + mappings[763] = ItemType.StonePressurePlate; + mappings[764] = ItemType.PolishedBlackstonePressurePlate; + mappings[765] = ItemType.LightWeightedPressurePlate; + mappings[766] = ItemType.HeavyWeightedPressurePlate; + mappings[767] = ItemType.OakPressurePlate; + mappings[768] = ItemType.SprucePressurePlate; + mappings[769] = ItemType.BirchPressurePlate; + mappings[770] = ItemType.JunglePressurePlate; + mappings[771] = ItemType.AcaciaPressurePlate; + mappings[772] = ItemType.CherryPressurePlate; + mappings[773] = ItemType.DarkOakPressurePlate; + mappings[774] = ItemType.PaleOakPressurePlate; + mappings[775] = ItemType.MangrovePressurePlate; + mappings[776] = ItemType.BambooPressurePlate; + mappings[777] = ItemType.CrimsonPressurePlate; + mappings[778] = ItemType.WarpedPressurePlate; + mappings[779] = ItemType.IronDoor; + mappings[780] = ItemType.OakDoor; + mappings[781] = ItemType.SpruceDoor; + mappings[782] = ItemType.BirchDoor; + mappings[783] = ItemType.JungleDoor; + mappings[784] = ItemType.AcaciaDoor; + mappings[785] = ItemType.CherryDoor; + mappings[786] = ItemType.DarkOakDoor; + mappings[787] = ItemType.PaleOakDoor; + mappings[788] = ItemType.MangroveDoor; + mappings[789] = ItemType.BambooDoor; + mappings[790] = ItemType.CrimsonDoor; + mappings[791] = ItemType.WarpedDoor; + mappings[792] = ItemType.CopperDoor; + mappings[793] = ItemType.ExposedCopperDoor; + mappings[794] = ItemType.WeatheredCopperDoor; + mappings[795] = ItemType.OxidizedCopperDoor; + mappings[796] = ItemType.WaxedCopperDoor; + mappings[797] = ItemType.WaxedExposedCopperDoor; + mappings[798] = ItemType.WaxedWeatheredCopperDoor; + mappings[799] = ItemType.WaxedOxidizedCopperDoor; + mappings[800] = ItemType.IronTrapdoor; + mappings[801] = ItemType.OakTrapdoor; + mappings[802] = ItemType.SpruceTrapdoor; + mappings[803] = ItemType.BirchTrapdoor; + mappings[804] = ItemType.JungleTrapdoor; + mappings[805] = ItemType.AcaciaTrapdoor; + mappings[806] = ItemType.CherryTrapdoor; + mappings[807] = ItemType.DarkOakTrapdoor; + mappings[808] = ItemType.PaleOakTrapdoor; + mappings[809] = ItemType.MangroveTrapdoor; + mappings[810] = ItemType.BambooTrapdoor; + mappings[811] = ItemType.CrimsonTrapdoor; + mappings[812] = ItemType.WarpedTrapdoor; + mappings[813] = ItemType.CopperTrapdoor; + mappings[814] = ItemType.ExposedCopperTrapdoor; + mappings[815] = ItemType.WeatheredCopperTrapdoor; + mappings[816] = ItemType.OxidizedCopperTrapdoor; + mappings[817] = ItemType.WaxedCopperTrapdoor; + mappings[818] = ItemType.WaxedExposedCopperTrapdoor; + mappings[819] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[820] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[821] = ItemType.OakFenceGate; + mappings[822] = ItemType.SpruceFenceGate; + mappings[823] = ItemType.BirchFenceGate; + mappings[824] = ItemType.JungleFenceGate; + mappings[825] = ItemType.AcaciaFenceGate; + mappings[826] = ItemType.CherryFenceGate; + mappings[827] = ItemType.DarkOakFenceGate; + mappings[828] = ItemType.PaleOakFenceGate; + mappings[829] = ItemType.MangroveFenceGate; + mappings[830] = ItemType.BambooFenceGate; + mappings[831] = ItemType.CrimsonFenceGate; + mappings[832] = ItemType.WarpedFenceGate; + mappings[833] = ItemType.PoweredRail; + mappings[834] = ItemType.DetectorRail; + mappings[835] = ItemType.Rail; + mappings[836] = ItemType.ActivatorRail; + mappings[837] = ItemType.Saddle; + mappings[838] = ItemType.WhiteHarness; + mappings[839] = ItemType.OrangeHarness; + mappings[840] = ItemType.MagentaHarness; + mappings[841] = ItemType.LightBlueHarness; + mappings[842] = ItemType.YellowHarness; + mappings[843] = ItemType.LimeHarness; + mappings[844] = ItemType.PinkHarness; + mappings[845] = ItemType.GrayHarness; + mappings[846] = ItemType.LightGrayHarness; + mappings[847] = ItemType.CyanHarness; + mappings[848] = ItemType.PurpleHarness; + mappings[849] = ItemType.BlueHarness; + mappings[850] = ItemType.BrownHarness; + mappings[851] = ItemType.GreenHarness; + mappings[852] = ItemType.RedHarness; + mappings[853] = ItemType.BlackHarness; + mappings[854] = ItemType.Minecart; + mappings[855] = ItemType.ChestMinecart; + mappings[856] = ItemType.FurnaceMinecart; + mappings[857] = ItemType.TntMinecart; + mappings[858] = ItemType.HopperMinecart; + mappings[859] = ItemType.CarrotOnAStick; + mappings[860] = ItemType.WarpedFungusOnAStick; + mappings[861] = ItemType.PhantomMembrane; + mappings[862] = ItemType.Elytra; + mappings[863] = ItemType.OakBoat; + mappings[864] = ItemType.OakChestBoat; + mappings[865] = ItemType.SpruceBoat; + mappings[866] = ItemType.SpruceChestBoat; + mappings[867] = ItemType.BirchBoat; + mappings[868] = ItemType.BirchChestBoat; + mappings[869] = ItemType.JungleBoat; + mappings[870] = ItemType.JungleChestBoat; + mappings[871] = ItemType.AcaciaBoat; + mappings[872] = ItemType.AcaciaChestBoat; + mappings[873] = ItemType.CherryBoat; + mappings[874] = ItemType.CherryChestBoat; + mappings[875] = ItemType.DarkOakBoat; + mappings[876] = ItemType.DarkOakChestBoat; + mappings[877] = ItemType.PaleOakBoat; + mappings[878] = ItemType.PaleOakChestBoat; + mappings[879] = ItemType.MangroveBoat; + mappings[880] = ItemType.MangroveChestBoat; + mappings[881] = ItemType.BambooRaft; + mappings[882] = ItemType.BambooChestRaft; + mappings[883] = ItemType.StructureBlock; + mappings[884] = ItemType.Jigsaw; + mappings[885] = ItemType.TestBlock; + mappings[886] = ItemType.TestInstanceBlock; + mappings[887] = ItemType.TurtleHelmet; + mappings[888] = ItemType.TurtleScute; + mappings[889] = ItemType.ArmadilloScute; + mappings[890] = ItemType.WolfArmor; + mappings[891] = ItemType.FlintAndSteel; + mappings[892] = ItemType.Bowl; + mappings[893] = ItemType.Apple; + mappings[894] = ItemType.Bow; + mappings[895] = ItemType.Arrow; + mappings[896] = ItemType.Coal; + mappings[897] = ItemType.Charcoal; + mappings[898] = ItemType.Diamond; + mappings[899] = ItemType.Emerald; + mappings[900] = ItemType.LapisLazuli; + mappings[901] = ItemType.Quartz; + mappings[902] = ItemType.AmethystShard; + mappings[903] = ItemType.RawIron; + mappings[904] = ItemType.IronIngot; + mappings[905] = ItemType.RawCopper; + mappings[906] = ItemType.CopperIngot; + mappings[907] = ItemType.RawGold; + mappings[908] = ItemType.GoldIngot; + mappings[909] = ItemType.NetheriteIngot; + mappings[910] = ItemType.NetheriteScrap; + mappings[911] = ItemType.WoodenSword; + mappings[912] = ItemType.WoodenShovel; + mappings[913] = ItemType.WoodenPickaxe; + mappings[914] = ItemType.WoodenAxe; + mappings[915] = ItemType.WoodenHoe; + mappings[916] = ItemType.CopperSword; + mappings[917] = ItemType.CopperShovel; + mappings[918] = ItemType.CopperPickaxe; + mappings[919] = ItemType.CopperAxe; + mappings[920] = ItemType.CopperHoe; + mappings[921] = ItemType.StoneSword; + mappings[922] = ItemType.StoneShovel; + mappings[923] = ItemType.StonePickaxe; + mappings[924] = ItemType.StoneAxe; + mappings[925] = ItemType.StoneHoe; + mappings[926] = ItemType.GoldenSword; + mappings[927] = ItemType.GoldenShovel; + mappings[928] = ItemType.GoldenPickaxe; + mappings[929] = ItemType.GoldenAxe; + mappings[930] = ItemType.GoldenHoe; + mappings[931] = ItemType.IronSword; + mappings[932] = ItemType.IronShovel; + mappings[933] = ItemType.IronPickaxe; + mappings[934] = ItemType.IronAxe; + mappings[935] = ItemType.IronHoe; + mappings[936] = ItemType.DiamondSword; + mappings[937] = ItemType.DiamondShovel; + mappings[938] = ItemType.DiamondPickaxe; + mappings[939] = ItemType.DiamondAxe; + mappings[940] = ItemType.DiamondHoe; + mappings[941] = ItemType.NetheriteSword; + mappings[942] = ItemType.NetheriteShovel; + mappings[943] = ItemType.NetheritePickaxe; + mappings[944] = ItemType.NetheriteAxe; + mappings[945] = ItemType.NetheriteHoe; + mappings[946] = ItemType.Stick; + mappings[947] = ItemType.MushroomStew; + mappings[948] = ItemType.String; + mappings[949] = ItemType.Feather; + mappings[950] = ItemType.Gunpowder; + mappings[951] = ItemType.WheatSeeds; + mappings[952] = ItemType.Wheat; + mappings[953] = ItemType.Bread; + mappings[954] = ItemType.LeatherHelmet; + mappings[955] = ItemType.LeatherChestplate; + mappings[956] = ItemType.LeatherLeggings; + mappings[957] = ItemType.LeatherBoots; + mappings[958] = ItemType.CopperHelmet; + mappings[959] = ItemType.CopperChestplate; + mappings[960] = ItemType.CopperLeggings; + mappings[961] = ItemType.CopperBoots; + mappings[962] = ItemType.ChainmailHelmet; + mappings[963] = ItemType.ChainmailChestplate; + mappings[964] = ItemType.ChainmailLeggings; + mappings[965] = ItemType.ChainmailBoots; + mappings[966] = ItemType.IronHelmet; + mappings[967] = ItemType.IronChestplate; + mappings[968] = ItemType.IronLeggings; + mappings[969] = ItemType.IronBoots; + mappings[970] = ItemType.DiamondHelmet; + mappings[971] = ItemType.DiamondChestplate; + mappings[972] = ItemType.DiamondLeggings; + mappings[973] = ItemType.DiamondBoots; + mappings[974] = ItemType.GoldenHelmet; + mappings[975] = ItemType.GoldenChestplate; + mappings[976] = ItemType.GoldenLeggings; + mappings[977] = ItemType.GoldenBoots; + mappings[978] = ItemType.NetheriteHelmet; + mappings[979] = ItemType.NetheriteChestplate; + mappings[980] = ItemType.NetheriteLeggings; + mappings[981] = ItemType.NetheriteBoots; + mappings[982] = ItemType.Flint; + mappings[983] = ItemType.Porkchop; + mappings[984] = ItemType.CookedPorkchop; + mappings[985] = ItemType.Painting; + mappings[986] = ItemType.GoldenApple; + mappings[987] = ItemType.EnchantedGoldenApple; + mappings[988] = ItemType.OakSign; + mappings[989] = ItemType.SpruceSign; + mappings[990] = ItemType.BirchSign; + mappings[991] = ItemType.JungleSign; + mappings[992] = ItemType.AcaciaSign; + mappings[993] = ItemType.CherrySign; + mappings[994] = ItemType.DarkOakSign; + mappings[995] = ItemType.PaleOakSign; + mappings[996] = ItemType.MangroveSign; + mappings[997] = ItemType.BambooSign; + mappings[998] = ItemType.CrimsonSign; + mappings[999] = ItemType.WarpedSign; + mappings[1000] = ItemType.OakHangingSign; + mappings[1001] = ItemType.SpruceHangingSign; + mappings[1002] = ItemType.BirchHangingSign; + mappings[1003] = ItemType.JungleHangingSign; + mappings[1004] = ItemType.AcaciaHangingSign; + mappings[1005] = ItemType.CherryHangingSign; + mappings[1006] = ItemType.DarkOakHangingSign; + mappings[1007] = ItemType.PaleOakHangingSign; + mappings[1008] = ItemType.MangroveHangingSign; + mappings[1009] = ItemType.BambooHangingSign; + mappings[1010] = ItemType.CrimsonHangingSign; + mappings[1011] = ItemType.WarpedHangingSign; + mappings[1012] = ItemType.Bucket; + mappings[1013] = ItemType.WaterBucket; + mappings[1014] = ItemType.LavaBucket; + mappings[1015] = ItemType.PowderSnowBucket; + mappings[1016] = ItemType.Snowball; + mappings[1017] = ItemType.Leather; + mappings[1018] = ItemType.MilkBucket; + mappings[1019] = ItemType.PufferfishBucket; + mappings[1020] = ItemType.SalmonBucket; + mappings[1021] = ItemType.CodBucket; + mappings[1022] = ItemType.TropicalFishBucket; + mappings[1023] = ItemType.AxolotlBucket; + mappings[1024] = ItemType.TadpoleBucket; + mappings[1025] = ItemType.Brick; + mappings[1026] = ItemType.ClayBall; + mappings[1027] = ItemType.DriedKelpBlock; + mappings[1028] = ItemType.Paper; + mappings[1029] = ItemType.Book; + mappings[1030] = ItemType.SlimeBall; + mappings[1031] = ItemType.Egg; + mappings[1032] = ItemType.BlueEgg; + mappings[1033] = ItemType.BrownEgg; + mappings[1034] = ItemType.Compass; + mappings[1035] = ItemType.RecoveryCompass; + mappings[1036] = ItemType.Bundle; + mappings[1037] = ItemType.WhiteBundle; + mappings[1038] = ItemType.OrangeBundle; + mappings[1039] = ItemType.MagentaBundle; + mappings[1040] = ItemType.LightBlueBundle; + mappings[1041] = ItemType.YellowBundle; + mappings[1042] = ItemType.LimeBundle; + mappings[1043] = ItemType.PinkBundle; + mappings[1044] = ItemType.GrayBundle; + mappings[1045] = ItemType.LightGrayBundle; + mappings[1046] = ItemType.CyanBundle; + mappings[1047] = ItemType.PurpleBundle; + mappings[1048] = ItemType.BlueBundle; + mappings[1049] = ItemType.BrownBundle; + mappings[1050] = ItemType.GreenBundle; + mappings[1051] = ItemType.RedBundle; + mappings[1052] = ItemType.BlackBundle; + mappings[1053] = ItemType.FishingRod; + mappings[1054] = ItemType.Clock; + mappings[1055] = ItemType.Spyglass; + mappings[1056] = ItemType.GlowstoneDust; + mappings[1057] = ItemType.Cod; + mappings[1058] = ItemType.Salmon; + mappings[1059] = ItemType.TropicalFish; + mappings[1060] = ItemType.Pufferfish; + mappings[1061] = ItemType.CookedCod; + mappings[1062] = ItemType.CookedSalmon; + mappings[1063] = ItemType.InkSac; + mappings[1064] = ItemType.GlowInkSac; + mappings[1065] = ItemType.CocoaBeans; + mappings[1066] = ItemType.WhiteDye; + mappings[1067] = ItemType.OrangeDye; + mappings[1068] = ItemType.MagentaDye; + mappings[1069] = ItemType.LightBlueDye; + mappings[1070] = ItemType.YellowDye; + mappings[1071] = ItemType.LimeDye; + mappings[1072] = ItemType.PinkDye; + mappings[1073] = ItemType.GrayDye; + mappings[1074] = ItemType.LightGrayDye; + mappings[1075] = ItemType.CyanDye; + mappings[1076] = ItemType.PurpleDye; + mappings[1077] = ItemType.BlueDye; + mappings[1078] = ItemType.BrownDye; + mappings[1079] = ItemType.GreenDye; + mappings[1080] = ItemType.RedDye; + mappings[1081] = ItemType.BlackDye; + mappings[1082] = ItemType.BoneMeal; + mappings[1083] = ItemType.Bone; + mappings[1084] = ItemType.Sugar; + mappings[1085] = ItemType.Cake; + mappings[1086] = ItemType.WhiteBed; + mappings[1087] = ItemType.OrangeBed; + mappings[1088] = ItemType.MagentaBed; + mappings[1089] = ItemType.LightBlueBed; + mappings[1090] = ItemType.YellowBed; + mappings[1091] = ItemType.LimeBed; + mappings[1092] = ItemType.PinkBed; + mappings[1093] = ItemType.GrayBed; + mappings[1094] = ItemType.LightGrayBed; + mappings[1095] = ItemType.CyanBed; + mappings[1096] = ItemType.PurpleBed; + mappings[1097] = ItemType.BlueBed; + mappings[1098] = ItemType.BrownBed; + mappings[1099] = ItemType.GreenBed; + mappings[1100] = ItemType.RedBed; + mappings[1101] = ItemType.BlackBed; + mappings[1102] = ItemType.Cookie; + mappings[1103] = ItemType.Crafter; + mappings[1104] = ItemType.FilledMap; + mappings[1105] = ItemType.Shears; + mappings[1106] = ItemType.MelonSlice; + mappings[1107] = ItemType.DriedKelp; + mappings[1108] = ItemType.PumpkinSeeds; + mappings[1109] = ItemType.MelonSeeds; + mappings[1110] = ItemType.Beef; + mappings[1111] = ItemType.CookedBeef; + mappings[1112] = ItemType.Chicken; + mappings[1113] = ItemType.CookedChicken; + mappings[1114] = ItemType.RottenFlesh; + mappings[1115] = ItemType.EnderPearl; + mappings[1116] = ItemType.BlazeRod; + mappings[1117] = ItemType.GhastTear; + mappings[1118] = ItemType.GoldNugget; + mappings[1119] = ItemType.NetherWart; + mappings[1120] = ItemType.GlassBottle; + mappings[1121] = ItemType.Potion; + mappings[1122] = ItemType.SpiderEye; + mappings[1123] = ItemType.FermentedSpiderEye; + mappings[1124] = ItemType.BlazePowder; + mappings[1125] = ItemType.MagmaCream; + mappings[1126] = ItemType.BrewingStand; + mappings[1127] = ItemType.Cauldron; + mappings[1128] = ItemType.EnderEye; + mappings[1129] = ItemType.GlisteringMelonSlice; + mappings[1130] = ItemType.ArmadilloSpawnEgg; + mappings[1131] = ItemType.AllaySpawnEgg; + mappings[1132] = ItemType.AxolotlSpawnEgg; + mappings[1133] = ItemType.BatSpawnEgg; + mappings[1134] = ItemType.BeeSpawnEgg; + mappings[1135] = ItemType.BlazeSpawnEgg; + mappings[1136] = ItemType.BoggedSpawnEgg; + mappings[1137] = ItemType.BreezeSpawnEgg; + mappings[1138] = ItemType.CatSpawnEgg; + mappings[1139] = ItemType.CamelSpawnEgg; + mappings[1140] = ItemType.CaveSpiderSpawnEgg; + mappings[1141] = ItemType.ChickenSpawnEgg; + mappings[1142] = ItemType.CodSpawnEgg; + mappings[1143] = ItemType.CopperGolemSpawnEgg; + mappings[1144] = ItemType.CowSpawnEgg; + mappings[1145] = ItemType.CreeperSpawnEgg; + mappings[1146] = ItemType.DolphinSpawnEgg; + mappings[1147] = ItemType.DonkeySpawnEgg; + mappings[1148] = ItemType.DrownedSpawnEgg; + mappings[1149] = ItemType.ElderGuardianSpawnEgg; + mappings[1150] = ItemType.EnderDragonSpawnEgg; + mappings[1151] = ItemType.EndermanSpawnEgg; + mappings[1152] = ItemType.EndermiteSpawnEgg; + mappings[1153] = ItemType.EvokerSpawnEgg; + mappings[1154] = ItemType.FoxSpawnEgg; + mappings[1155] = ItemType.FrogSpawnEgg; + mappings[1156] = ItemType.GhastSpawnEgg; + mappings[1157] = ItemType.HappyGhastSpawnEgg; + mappings[1158] = ItemType.GlowSquidSpawnEgg; + mappings[1159] = ItemType.GoatSpawnEgg; + mappings[1160] = ItemType.GuardianSpawnEgg; + mappings[1161] = ItemType.HoglinSpawnEgg; + mappings[1162] = ItemType.HorseSpawnEgg; + mappings[1163] = ItemType.HuskSpawnEgg; + mappings[1164] = ItemType.IronGolemSpawnEgg; + mappings[1165] = ItemType.LlamaSpawnEgg; + mappings[1166] = ItemType.MagmaCubeSpawnEgg; + mappings[1167] = ItemType.MooshroomSpawnEgg; + mappings[1168] = ItemType.MuleSpawnEgg; + mappings[1169] = ItemType.OcelotSpawnEgg; + mappings[1170] = ItemType.PandaSpawnEgg; + mappings[1171] = ItemType.ParrotSpawnEgg; + mappings[1172] = ItemType.PhantomSpawnEgg; + mappings[1173] = ItemType.PigSpawnEgg; + mappings[1174] = ItemType.PiglinSpawnEgg; + mappings[1175] = ItemType.PiglinBruteSpawnEgg; + mappings[1176] = ItemType.PillagerSpawnEgg; + mappings[1177] = ItemType.PolarBearSpawnEgg; + mappings[1178] = ItemType.PufferfishSpawnEgg; + mappings[1179] = ItemType.RabbitSpawnEgg; + mappings[1180] = ItemType.RavagerSpawnEgg; + mappings[1181] = ItemType.SalmonSpawnEgg; + mappings[1182] = ItemType.SheepSpawnEgg; + mappings[1183] = ItemType.ShulkerSpawnEgg; + mappings[1184] = ItemType.SilverfishSpawnEgg; + mappings[1185] = ItemType.SkeletonSpawnEgg; + mappings[1186] = ItemType.SkeletonHorseSpawnEgg; + mappings[1187] = ItemType.SlimeSpawnEgg; + mappings[1188] = ItemType.SnifferSpawnEgg; + mappings[1189] = ItemType.SnowGolemSpawnEgg; + mappings[1190] = ItemType.SpiderSpawnEgg; + mappings[1191] = ItemType.SquidSpawnEgg; + mappings[1192] = ItemType.StraySpawnEgg; + mappings[1193] = ItemType.StriderSpawnEgg; + mappings[1194] = ItemType.TadpoleSpawnEgg; + mappings[1195] = ItemType.TraderLlamaSpawnEgg; + mappings[1196] = ItemType.TropicalFishSpawnEgg; + mappings[1197] = ItemType.TurtleSpawnEgg; + mappings[1198] = ItemType.VexSpawnEgg; + mappings[1199] = ItemType.VillagerSpawnEgg; + mappings[1200] = ItemType.VindicatorSpawnEgg; + mappings[1201] = ItemType.WanderingTraderSpawnEgg; + mappings[1202] = ItemType.WardenSpawnEgg; + mappings[1203] = ItemType.WitchSpawnEgg; + mappings[1204] = ItemType.WitherSpawnEgg; + mappings[1205] = ItemType.WitherSkeletonSpawnEgg; + mappings[1206] = ItemType.WolfSpawnEgg; + mappings[1207] = ItemType.ZoglinSpawnEgg; + mappings[1208] = ItemType.CreakingSpawnEgg; + mappings[1209] = ItemType.ZombieSpawnEgg; + mappings[1210] = ItemType.ZombieHorseSpawnEgg; + mappings[1211] = ItemType.ZombieVillagerSpawnEgg; + mappings[1212] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1213] = ItemType.ExperienceBottle; + mappings[1214] = ItemType.FireCharge; + mappings[1215] = ItemType.WindCharge; + mappings[1216] = ItemType.WritableBook; + mappings[1217] = ItemType.WrittenBook; + mappings[1218] = ItemType.BreezeRod; + mappings[1219] = ItemType.Mace; + mappings[1220] = ItemType.ItemFrame; + mappings[1221] = ItemType.GlowItemFrame; + mappings[1222] = ItemType.FlowerPot; + mappings[1223] = ItemType.Carrot; + mappings[1224] = ItemType.Potato; + mappings[1225] = ItemType.BakedPotato; + mappings[1226] = ItemType.PoisonousPotato; + mappings[1227] = ItemType.Map; + mappings[1228] = ItemType.GoldenCarrot; + mappings[1229] = ItemType.SkeletonSkull; + mappings[1230] = ItemType.WitherSkeletonSkull; + mappings[1231] = ItemType.PlayerHead; + mappings[1232] = ItemType.ZombieHead; + mappings[1233] = ItemType.CreeperHead; + mappings[1234] = ItemType.DragonHead; + mappings[1235] = ItemType.PiglinHead; + mappings[1236] = ItemType.NetherStar; + mappings[1237] = ItemType.PumpkinPie; + mappings[1238] = ItemType.FireworkRocket; + mappings[1239] = ItemType.FireworkStar; + mappings[1240] = ItemType.EnchantedBook; + mappings[1241] = ItemType.NetherBrick; + mappings[1242] = ItemType.ResinBrick; + mappings[1243] = ItemType.PrismarineShard; + mappings[1244] = ItemType.PrismarineCrystals; + mappings[1245] = ItemType.Rabbit; + mappings[1246] = ItemType.CookedRabbit; + mappings[1247] = ItemType.RabbitStew; + mappings[1248] = ItemType.RabbitFoot; + mappings[1249] = ItemType.RabbitHide; + mappings[1250] = ItemType.ArmorStand; + mappings[1251] = ItemType.CopperHorseArmor; + mappings[1252] = ItemType.IronHorseArmor; + mappings[1253] = ItemType.GoldenHorseArmor; + mappings[1254] = ItemType.DiamondHorseArmor; + mappings[1255] = ItemType.LeatherHorseArmor; + mappings[1256] = ItemType.Lead; + mappings[1257] = ItemType.NameTag; + mappings[1258] = ItemType.CommandBlockMinecart; + mappings[1259] = ItemType.Mutton; + mappings[1260] = ItemType.CookedMutton; + mappings[1261] = ItemType.WhiteBanner; + mappings[1262] = ItemType.OrangeBanner; + mappings[1263] = ItemType.MagentaBanner; + mappings[1264] = ItemType.LightBlueBanner; + mappings[1265] = ItemType.YellowBanner; + mappings[1266] = ItemType.LimeBanner; + mappings[1267] = ItemType.PinkBanner; + mappings[1268] = ItemType.GrayBanner; + mappings[1269] = ItemType.LightGrayBanner; + mappings[1270] = ItemType.CyanBanner; + mappings[1271] = ItemType.PurpleBanner; + mappings[1272] = ItemType.BlueBanner; + mappings[1273] = ItemType.BrownBanner; + mappings[1274] = ItemType.GreenBanner; + mappings[1275] = ItemType.RedBanner; + mappings[1276] = ItemType.BlackBanner; + mappings[1277] = ItemType.EndCrystal; + mappings[1278] = ItemType.ChorusFruit; + mappings[1279] = ItemType.PoppedChorusFruit; + mappings[1280] = ItemType.TorchflowerSeeds; + mappings[1281] = ItemType.PitcherPod; + mappings[1282] = ItemType.Beetroot; + mappings[1283] = ItemType.BeetrootSeeds; + mappings[1284] = ItemType.BeetrootSoup; + mappings[1285] = ItemType.DragonBreath; + mappings[1286] = ItemType.SplashPotion; + mappings[1287] = ItemType.SpectralArrow; + mappings[1288] = ItemType.TippedArrow; + mappings[1289] = ItemType.LingeringPotion; + mappings[1290] = ItemType.Shield; + mappings[1291] = ItemType.TotemOfUndying; + mappings[1292] = ItemType.ShulkerShell; + mappings[1293] = ItemType.IronNugget; + mappings[1294] = ItemType.CopperNugget; + mappings[1295] = ItemType.KnowledgeBook; + mappings[1296] = ItemType.DebugStick; + mappings[1297] = ItemType.MusicDisc13; + mappings[1298] = ItemType.MusicDiscCat; + mappings[1299] = ItemType.MusicDiscBlocks; + mappings[1300] = ItemType.MusicDiscChirp; + mappings[1301] = ItemType.MusicDiscCreator; + mappings[1302] = ItemType.MusicDiscCreatorMusicBox; + mappings[1303] = ItemType.MusicDiscFar; + mappings[1304] = ItemType.MusicDiscLavaChicken; + mappings[1305] = ItemType.MusicDiscMall; + mappings[1306] = ItemType.MusicDiscMellohi; + mappings[1307] = ItemType.MusicDiscStal; + mappings[1308] = ItemType.MusicDiscStrad; + mappings[1309] = ItemType.MusicDiscWard; + mappings[1310] = ItemType.MusicDisc11; + mappings[1311] = ItemType.MusicDiscWait; + mappings[1312] = ItemType.MusicDiscOtherside; + mappings[1313] = ItemType.MusicDiscRelic; + mappings[1314] = ItemType.MusicDisc5; + mappings[1315] = ItemType.MusicDiscPigstep; + mappings[1316] = ItemType.MusicDiscPrecipice; + mappings[1317] = ItemType.MusicDiscTears; + mappings[1318] = ItemType.DiscFragment5; + mappings[1319] = ItemType.Trident; + mappings[1320] = ItemType.NautilusShell; + mappings[1321] = ItemType.HeartOfTheSea; + mappings[1322] = ItemType.Crossbow; + mappings[1323] = ItemType.SuspiciousStew; + mappings[1324] = ItemType.Loom; + mappings[1325] = ItemType.FlowerBannerPattern; + mappings[1326] = ItemType.CreeperBannerPattern; + mappings[1327] = ItemType.SkullBannerPattern; + mappings[1328] = ItemType.MojangBannerPattern; + mappings[1329] = ItemType.GlobeBannerPattern; + mappings[1330] = ItemType.PiglinBannerPattern; + mappings[1331] = ItemType.FlowBannerPattern; + mappings[1332] = ItemType.GusterBannerPattern; + mappings[1333] = ItemType.FieldMasonedBannerPattern; + mappings[1334] = ItemType.BordureIndentedBannerPattern; + mappings[1335] = ItemType.GoatHorn; + mappings[1336] = ItemType.Composter; + mappings[1337] = ItemType.Barrel; + mappings[1338] = ItemType.Smoker; + mappings[1339] = ItemType.BlastFurnace; + mappings[1340] = ItemType.CartographyTable; + mappings[1341] = ItemType.FletchingTable; + mappings[1342] = ItemType.Grindstone; + mappings[1343] = ItemType.SmithingTable; + mappings[1344] = ItemType.Stonecutter; + mappings[1345] = ItemType.Bell; + mappings[1346] = ItemType.Lantern; + mappings[1347] = ItemType.SoulLantern; + mappings[1348] = ItemType.CopperLantern; + mappings[1349] = ItemType.ExposedCopperLantern; + mappings[1350] = ItemType.WeatheredCopperLantern; + mappings[1351] = ItemType.OxidizedCopperLantern; + mappings[1352] = ItemType.WaxedCopperLantern; + mappings[1353] = ItemType.WaxedExposedCopperLantern; + mappings[1354] = ItemType.WaxedWeatheredCopperLantern; + mappings[1355] = ItemType.WaxedOxidizedCopperLantern; + mappings[1356] = ItemType.SweetBerries; + mappings[1357] = ItemType.GlowBerries; + mappings[1358] = ItemType.Campfire; + mappings[1359] = ItemType.SoulCampfire; + mappings[1360] = ItemType.Shroomlight; + mappings[1361] = ItemType.Honeycomb; + mappings[1362] = ItemType.BeeNest; + mappings[1363] = ItemType.Beehive; + mappings[1364] = ItemType.HoneyBottle; + mappings[1365] = ItemType.HoneycombBlock; + mappings[1366] = ItemType.Lodestone; + mappings[1367] = ItemType.CryingObsidian; + mappings[1368] = ItemType.Blackstone; + mappings[1369] = ItemType.BlackstoneSlab; + mappings[1370] = ItemType.BlackstoneStairs; + mappings[1371] = ItemType.GildedBlackstone; + mappings[1372] = ItemType.PolishedBlackstone; + mappings[1373] = ItemType.PolishedBlackstoneSlab; + mappings[1374] = ItemType.PolishedBlackstoneStairs; + mappings[1375] = ItemType.ChiseledPolishedBlackstone; + mappings[1376] = ItemType.PolishedBlackstoneBricks; + mappings[1377] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1378] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1379] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1380] = ItemType.RespawnAnchor; + mappings[1381] = ItemType.Candle; + mappings[1382] = ItemType.WhiteCandle; + mappings[1383] = ItemType.OrangeCandle; + mappings[1384] = ItemType.MagentaCandle; + mappings[1385] = ItemType.LightBlueCandle; + mappings[1386] = ItemType.YellowCandle; + mappings[1387] = ItemType.LimeCandle; + mappings[1388] = ItemType.PinkCandle; + mappings[1389] = ItemType.GrayCandle; + mappings[1390] = ItemType.LightGrayCandle; + mappings[1391] = ItemType.CyanCandle; + mappings[1392] = ItemType.PurpleCandle; + mappings[1393] = ItemType.BlueCandle; + mappings[1394] = ItemType.BrownCandle; + mappings[1395] = ItemType.GreenCandle; + mappings[1396] = ItemType.RedCandle; + mappings[1397] = ItemType.BlackCandle; + mappings[1398] = ItemType.SmallAmethystBud; + mappings[1399] = ItemType.MediumAmethystBud; + mappings[1400] = ItemType.LargeAmethystBud; + mappings[1401] = ItemType.AmethystCluster; + mappings[1402] = ItemType.PointedDripstone; + mappings[1403] = ItemType.OchreFroglight; + mappings[1404] = ItemType.VerdantFroglight; + mappings[1405] = ItemType.PearlescentFroglight; + mappings[1406] = ItemType.Frogspawn; + mappings[1407] = ItemType.EchoShard; + mappings[1408] = ItemType.Brush; + mappings[1409] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1410] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1411] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1412] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1413] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1414] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1415] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1416] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1417] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1418] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1419] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1420] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1421] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1422] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1423] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1424] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1425] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1426] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1427] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1428] = ItemType.AnglerPotterySherd; + mappings[1429] = ItemType.ArcherPotterySherd; + mappings[1430] = ItemType.ArmsUpPotterySherd; + mappings[1431] = ItemType.BladePotterySherd; + mappings[1432] = ItemType.BrewerPotterySherd; + mappings[1433] = ItemType.BurnPotterySherd; + mappings[1434] = ItemType.DangerPotterySherd; + mappings[1435] = ItemType.ExplorerPotterySherd; + mappings[1436] = ItemType.FlowPotterySherd; + mappings[1437] = ItemType.FriendPotterySherd; + mappings[1438] = ItemType.GusterPotterySherd; + mappings[1439] = ItemType.HeartPotterySherd; + mappings[1440] = ItemType.HeartbreakPotterySherd; + mappings[1441] = ItemType.HowlPotterySherd; + mappings[1442] = ItemType.MinerPotterySherd; + mappings[1443] = ItemType.MournerPotterySherd; + mappings[1444] = ItemType.PlentyPotterySherd; + mappings[1445] = ItemType.PrizePotterySherd; + mappings[1446] = ItemType.ScrapePotterySherd; + mappings[1447] = ItemType.SheafPotterySherd; + mappings[1448] = ItemType.ShelterPotterySherd; + mappings[1449] = ItemType.SkullPotterySherd; + mappings[1450] = ItemType.SnortPotterySherd; + mappings[1451] = ItemType.CopperGrate; + mappings[1452] = ItemType.ExposedCopperGrate; + mappings[1453] = ItemType.WeatheredCopperGrate; + mappings[1454] = ItemType.OxidizedCopperGrate; + mappings[1455] = ItemType.WaxedCopperGrate; + mappings[1456] = ItemType.WaxedExposedCopperGrate; + mappings[1457] = ItemType.WaxedWeatheredCopperGrate; + mappings[1458] = ItemType.WaxedOxidizedCopperGrate; + mappings[1459] = ItemType.CopperBulb; + mappings[1460] = ItemType.ExposedCopperBulb; + mappings[1461] = ItemType.WeatheredCopperBulb; + mappings[1462] = ItemType.OxidizedCopperBulb; + mappings[1463] = ItemType.WaxedCopperBulb; + mappings[1464] = ItemType.WaxedExposedCopperBulb; + mappings[1465] = ItemType.WaxedWeatheredCopperBulb; + mappings[1466] = ItemType.WaxedOxidizedCopperBulb; + mappings[1467] = ItemType.CopperChest; + mappings[1468] = ItemType.ExposedCopperChest; + mappings[1469] = ItemType.WeatheredCopperChest; + mappings[1470] = ItemType.OxidizedCopperChest; + mappings[1471] = ItemType.WaxedCopperChest; + mappings[1472] = ItemType.WaxedExposedCopperChest; + mappings[1473] = ItemType.WaxedWeatheredCopperChest; + mappings[1474] = ItemType.WaxedOxidizedCopperChest; + mappings[1475] = ItemType.CopperGolemStatue; + mappings[1476] = ItemType.ExposedCopperGolemStatue; + mappings[1477] = ItemType.WeatheredCopperGolemStatue; + mappings[1478] = ItemType.OxidizedCopperGolemStatue; + mappings[1479] = ItemType.WaxedCopperGolemStatue; + mappings[1480] = ItemType.WaxedExposedCopperGolemStatue; + mappings[1481] = ItemType.WaxedWeatheredCopperGolemStatue; + mappings[1482] = ItemType.WaxedOxidizedCopperGolemStatue; + mappings[1483] = ItemType.TrialSpawner; + mappings[1484] = ItemType.TrialKey; + mappings[1485] = ItemType.OminousTrialKey; + mappings[1486] = ItemType.Vault; + mappings[1487] = ItemType.OminousBottle; } protected override Dictionary GetDict() diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 479c10fa..16859e0c 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -113,19 +113,19 @@ namespace MinecraftClient.Inventory BirchWood, BlackBanner, BlackBed, + BlackBundle, BlackCandle, BlackCarpet, BlackConcrete, BlackConcretePowder, BlackDye, BlackGlazedTerracotta, + BlackHarness, BlackShulkerBox, BlackStainedGlass, BlackStainedGlassPane, BlackTerracotta, BlackWool, - BlackBundle, - BlackHarness, Blackstone, BlackstoneSlab, BlackstoneStairs, @@ -137,13 +137,15 @@ namespace MinecraftClient.Inventory BlazeSpawnEgg, BlueBanner, BlueBed, + BlueBundle, BlueCandle, BlueCarpet, BlueConcrete, BlueConcretePowder, BlueDye, - BlueEgg, // blue egg + BlueEgg, BlueGlazedTerracotta, + BlueHarness, BlueIce, BlueOrchid, BlueShulkerBox, @@ -151,8 +153,6 @@ namespace MinecraftClient.Inventory BlueStainedGlassPane, BlueTerracotta, BlueWool, - BlueBundle, - BlueHarness, BoggedSpawnEgg, BoltArmorTrimSmithingTemplate, Bone, @@ -178,13 +178,15 @@ namespace MinecraftClient.Inventory Bricks, BrownBanner, BrownBed, + BrownBundle, BrownCandle, BrownCarpet, BrownConcrete, BrownConcretePowder, BrownDye, - BrownEgg, // brown egg + BrownEgg, BrownGlazedTerracotta, + BrownHarness, BrownMushroom, BrownMushroomBlock, BrownShulkerBox, @@ -192,8 +194,6 @@ namespace MinecraftClient.Inventory BrownStainedGlassPane, BrownTerracotta, BrownWool, - BrownBundle, - BrownHarness, Brush, BubbleCoral, BubbleCoralBlock, @@ -202,9 +202,9 @@ namespace MinecraftClient.Inventory BuddingAmethyst, Bundle, BurnPotterySherd, - Bush, // bush + Bush, Cactus, - CactusFlower, // cactus flower + CactusFlower, Cake, Calcite, CalibratedSculkSensor, @@ -300,9 +300,11 @@ namespace MinecraftClient.Inventory CookedSalmon, Cookie, CopperAxe, + CopperBars, CopperBlock, CopperBoots, CopperBulb, + CopperChain, CopperChest, CopperChestplate, CopperDoor, @@ -313,6 +315,7 @@ namespace MinecraftClient.Inventory CopperHoe, CopperHorseArmor, CopperIngot, + CopperLantern, CopperLeggings, CopperNugget, CopperOre, @@ -363,19 +366,19 @@ namespace MinecraftClient.Inventory CutSandstoneSlab, CyanBanner, CyanBed, + CyanBundle, CyanCandle, CyanCarpet, CyanConcrete, CyanConcretePowder, CyanDye, CyanGlazedTerracotta, + CyanHarness, CyanShulkerBox, CyanStainedGlass, CyanStainedGlassPane, CyanTerracotta, CyanWool, - CyanBundle, - CyanHarness, DamagedAnvil, Dandelion, DangerPotterySherd, @@ -469,8 +472,8 @@ namespace MinecraftClient.Inventory DripstoneBlock, Dropper, DrownedSpawnEgg, - DryShortGrass, // dry short grass - DryTallGrass, // dry tall grass + DryShortGrass, + DryTallGrass, DuneArmorTrimSmithingTemplate, EchoShard, Egg, @@ -501,11 +504,14 @@ namespace MinecraftClient.Inventory ExplorerPotterySherd, ExposedChiseledCopper, ExposedCopper, + ExposedCopperBars, ExposedCopperBulb, + ExposedCopperChain, ExposedCopperChest, ExposedCopperDoor, ExposedCopperGolemStatue, ExposedCopperGrate, + ExposedCopperLantern, ExposedCopperTrapdoor, ExposedCutCopper, ExposedCutCopperSlab, @@ -522,7 +528,7 @@ namespace MinecraftClient.Inventory FireCoral, FireCoralBlock, FireCoralFan, - FireflyBush, // firefly bush + FireflyBush, FireworkRocket, FireworkStar, FishingRod, @@ -583,34 +589,34 @@ namespace MinecraftClient.Inventory Gravel, GrayBanner, GrayBed, + GrayBundle, GrayCandle, GrayCarpet, GrayConcrete, GrayConcretePowder, GrayDye, GrayGlazedTerracotta, + GrayHarness, GrayShulkerBox, GrayStainedGlass, GrayStainedGlassPane, GrayTerracotta, GrayWool, - GrayBundle, - GrayHarness, GreenBanner, GreenBed, + GreenBundle, GreenCandle, GreenCarpet, GreenConcrete, GreenConcretePowder, GreenDye, GreenGlazedTerracotta, + GreenHarness, GreenShulkerBox, GreenStainedGlass, GreenStainedGlassPane, GreenTerracotta, GreenWool, - GreenBundle, - GreenHarness, Grindstone, GuardianSpawnEgg, Gunpowder, @@ -699,7 +705,7 @@ namespace MinecraftClient.Inventory LargeFern, LavaBucket, Lead, - LeafLitter, // leaf litter + LeafLitter, Leather, LeatherBoots, LeatherChestplate, @@ -711,34 +717,34 @@ namespace MinecraftClient.Inventory Light, LightBlueBanner, LightBlueBed, + LightBlueBundle, LightBlueCandle, LightBlueCarpet, LightBlueConcrete, LightBlueConcretePowder, LightBlueDye, LightBlueGlazedTerracotta, + LightBlueHarness, LightBlueShulkerBox, LightBlueStainedGlass, LightBlueStainedGlassPane, LightBlueTerracotta, LightBlueWool, - LightBlueBundle, - LightBlueHarness, LightGrayBanner, LightGrayBed, + LightGrayBundle, LightGrayCandle, LightGrayCarpet, LightGrayConcrete, LightGrayConcretePowder, LightGrayDye, LightGrayGlazedTerracotta, + LightGrayHarness, LightGrayShulkerBox, LightGrayStainedGlass, LightGrayStainedGlassPane, LightGrayTerracotta, LightGrayWool, - LightGrayBundle, - LightGrayHarness, LightWeightedPressurePlate, LightningRod, Lilac, @@ -746,19 +752,19 @@ namespace MinecraftClient.Inventory LilyPad, LimeBanner, LimeBed, + LimeBundle, LimeCandle, LimeCarpet, LimeConcrete, LimeConcretePowder, LimeDye, LimeGlazedTerracotta, + LimeHarness, LimeShulkerBox, LimeStainedGlass, LimeStainedGlassPane, LimeTerracotta, LimeWool, - LimeBundle, - LimeHarness, LingeringPotion, LlamaSpawnEgg, Lodestone, @@ -766,19 +772,19 @@ namespace MinecraftClient.Inventory Mace, MagentaBanner, MagentaBed, + MagentaBundle, MagentaCandle, MagentaCarpet, MagentaConcrete, MagentaConcretePowder, MagentaDye, MagentaGlazedTerracotta, + MagentaHarness, MagentaShulkerBox, MagentaStainedGlass, MagentaStainedGlassPane, MagentaTerracotta, MagentaWool, - MagentaBundle, - MagentaHarness, MagmaBlock, MagmaCream, MagmaCubeSpawnEgg, @@ -910,28 +916,31 @@ namespace MinecraftClient.Inventory OpenEyeblossom, OrangeBanner, OrangeBed, + OrangeBundle, OrangeCandle, OrangeCarpet, OrangeConcrete, OrangeConcretePowder, OrangeDye, OrangeGlazedTerracotta, + OrangeHarness, OrangeShulkerBox, OrangeStainedGlass, OrangeStainedGlassPane, OrangeTerracotta, OrangeTulip, OrangeWool, - OrangeBundle, - OrangeHarness, OxeyeDaisy, OxidizedChiseledCopper, OxidizedCopper, + OxidizedCopperBars, OxidizedCopperBulb, + OxidizedCopperChain, OxidizedCopperChest, OxidizedCopperDoor, OxidizedCopperGolemStatue, OxidizedCopperGrate, + OxidizedCopperLantern, OxidizedCopperTrapdoor, OxidizedCutCopper, OxidizedCutCopperSlab, @@ -977,12 +986,14 @@ namespace MinecraftClient.Inventory PillagerSpawnEgg, PinkBanner, PinkBed, + PinkBundle, PinkCandle, PinkCarpet, PinkConcrete, PinkConcretePowder, PinkDye, PinkGlazedTerracotta, + PinkHarness, PinkPetals, PinkShulkerBox, PinkStainedGlass, @@ -990,8 +1001,6 @@ namespace MinecraftClient.Inventory PinkTerracotta, PinkTulip, PinkWool, - PinkBundle, - PinkHarness, Piston, PitcherPlant, PitcherPod, @@ -1054,19 +1063,19 @@ namespace MinecraftClient.Inventory PumpkinSeeds, PurpleBanner, PurpleBed, + PurpleBundle, PurpleCandle, PurpleCarpet, PurpleConcrete, PurpleConcretePowder, PurpleDye, PurpleGlazedTerracotta, + PurpleHarness, PurpleShulkerBox, PurpleStainedGlass, PurpleStainedGlassPane, PurpleTerracotta, PurpleWool, - PurpleBundle, - PurpleHarness, PurpurBlock, PurpurPillar, PurpurSlab, @@ -1094,12 +1103,14 @@ namespace MinecraftClient.Inventory RecoveryCompass, RedBanner, RedBed, + RedBundle, RedCandle, RedCarpet, RedConcrete, RedConcretePowder, RedDye, RedGlazedTerracotta, + RedHarness, RedMushroom, RedMushroomBlock, RedNetherBrickSlab, @@ -1117,8 +1128,6 @@ namespace MinecraftClient.Inventory RedTerracotta, RedTulip, RedWool, - RedBundle, - RedHarness, Redstone, RedstoneBlock, RedstoneLamp, @@ -1129,10 +1138,10 @@ namespace MinecraftClient.Inventory RepeatingCommandBlock, ResinBlock, ResinBrick, - ResinBricks, ResinBrickSlab, ResinBrickStairs, ResinBrickWall, + ResinBricks, ResinClump, RespawnAnchor, RibArmorTrimSmithingTemplate, @@ -1165,6 +1174,7 @@ namespace MinecraftClient.Inventory SheepSpawnEgg, ShelterPotterySherd, Shield, + ShortDryGrass, ShortGrass, Shroomlight, ShulkerBox, @@ -1291,11 +1301,12 @@ namespace MinecraftClient.Inventory SweetBerries, TadpoleBucket, TadpoleSpawnEgg, + TallDryGrass, TallGrass, Target, Terracotta, - TestBlock, // test block - TestInstanceBlock, // test instance block + TestBlock, + TestInstanceBlock, TideArmorTrimSmithingTemplate, TintedGlass, TippedArrow, @@ -1361,23 +1372,29 @@ namespace MinecraftClient.Inventory WarpedWartBlock, WaterBucket, WaxedChiseledCopper, + WaxedCopperBars, WaxedCopperBlock, WaxedCopperBulb, + WaxedCopperChain, WaxedCopperChest, WaxedCopperDoor, WaxedCopperGolemStatue, WaxedCopperGrate, + WaxedCopperLantern, WaxedCopperTrapdoor, WaxedCutCopper, WaxedCutCopperSlab, WaxedCutCopperStairs, WaxedExposedChiseledCopper, WaxedExposedCopper, + WaxedExposedCopperBars, WaxedExposedCopperBulb, + WaxedExposedCopperChain, WaxedExposedCopperChest, WaxedExposedCopperDoor, WaxedExposedCopperGolemStatue, WaxedExposedCopperGrate, + WaxedExposedCopperLantern, WaxedExposedCopperTrapdoor, WaxedExposedCutCopper, WaxedExposedCutCopperSlab, @@ -1386,11 +1403,14 @@ namespace MinecraftClient.Inventory WaxedLightningRod, WaxedOxidizedChiseledCopper, WaxedOxidizedCopper, + WaxedOxidizedCopperBars, WaxedOxidizedCopperBulb, + WaxedOxidizedCopperChain, WaxedOxidizedCopperChest, WaxedOxidizedCopperDoor, WaxedOxidizedCopperGolemStatue, WaxedOxidizedCopperGrate, + WaxedOxidizedCopperLantern, WaxedOxidizedCopperTrapdoor, WaxedOxidizedCutCopper, WaxedOxidizedCutCopperSlab, @@ -1398,11 +1418,14 @@ namespace MinecraftClient.Inventory WaxedOxidizedLightningRod, WaxedWeatheredChiseledCopper, WaxedWeatheredCopper, + WaxedWeatheredCopperBars, WaxedWeatheredCopperBulb, + WaxedWeatheredCopperChain, WaxedWeatheredCopperChest, WaxedWeatheredCopperDoor, WaxedWeatheredCopperGolemStatue, WaxedWeatheredCopperGrate, + WaxedWeatheredCopperLantern, WaxedWeatheredCopperTrapdoor, WaxedWeatheredCutCopper, WaxedWeatheredCutCopperSlab, @@ -1411,11 +1434,14 @@ namespace MinecraftClient.Inventory WayfinderArmorTrimSmithingTemplate, WeatheredChiseledCopper, WeatheredCopper, + WeatheredCopperBars, WeatheredCopperBulb, + WeatheredCopperChain, WeatheredCopperChest, WeatheredCopperDoor, WeatheredCopperGolemStatue, WeatheredCopperGrate, + WeatheredCopperLantern, WeatheredCopperTrapdoor, WeatheredCutCopper, WeatheredCutCopperSlab, @@ -1427,22 +1453,22 @@ namespace MinecraftClient.Inventory WheatSeeds, WhiteBanner, WhiteBed, + WhiteBundle, WhiteCandle, WhiteCarpet, WhiteConcrete, WhiteConcretePowder, WhiteDye, WhiteGlazedTerracotta, + WhiteHarness, WhiteShulkerBox, WhiteStainedGlass, WhiteStainedGlassPane, WhiteTerracotta, WhiteTulip, WhiteWool, - WhiteBundle, - WhiteHarness, WildArmorTrimSmithingTemplate, - Wildflowers, // wildflowers + Wildflowers, WindCharge, WitchSpawnEgg, WitherRose, @@ -1460,19 +1486,19 @@ namespace MinecraftClient.Inventory WrittenBook, YellowBanner, YellowBed, + YellowBundle, YellowCandle, YellowCarpet, YellowConcrete, YellowConcretePowder, YellowDye, YellowGlazedTerracotta, + YellowHarness, YellowShulkerBox, YellowStainedGlass, YellowStainedGlassPane, YellowTerracotta, YellowWool, - YellowBundle, - YellowHarness, ZoglinSpawnEgg, ZombieHead, ZombieHorseSpawnEgg, @@ -1480,4 +1506,4 @@ namespace MinecraftClient.Inventory ZombieVillagerSpawnEgg, ZombifiedPiglinSpawnEgg, } -} \ No newline at end of file +} diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs b/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs index 2d94c921..9994f3c3 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1219.cs @@ -8,1949 +8,2338 @@ namespace MinecraftClient.Mapping.BlockPalettes static Palette1219() { - for (int i = 10569; i <= 10592; i++) - materials[i] = Material.AcaciaButton; - for (int i = 14050; i <= 14113; i++) - materials[i] = Material.AcaciaDoor; - for (int i = 13666; i <= 13697; i++) - materials[i] = Material.AcaciaFence; - for (int i = 13378; i <= 13409; i++) - materials[i] = Material.AcaciaFenceGate; - for (int i = 5898; i <= 5961; i++) - materials[i] = Material.AcaciaHangingSign; - for (int i = 364; i <= 391; i++) - materials[i] = Material.AcaciaLeaves; - for (int i = 148; i <= 150; i++) - materials[i] = Material.AcaciaLog; - materials[19] = Material.AcaciaPlanks; - for (int i = 6668; i <= 6669; i++) - materials[i] = Material.AcaciaPressurePlate; - for (int i = 37; i <= 38; i++) - materials[i] = Material.AcaciaSapling; - for (int i = 2399; i <= 2462; i++) - materials[i] = Material.AcaciaShelf; - for (int i = 5230; i <= 5261; i++) - materials[i] = Material.AcaciaSign; - for (int i = 13152; i <= 13157; i++) - materials[i] = Material.AcaciaSlab; - for (int i = 11770; i <= 11849; i++) - materials[i] = Material.AcaciaStairs; - for (int i = 7169; i <= 7232; i++) - materials[i] = Material.AcaciaTrapdoor; - for (int i = 6498; i <= 6505; i++) - materials[i] = Material.AcaciaWallHangingSign; - for (int i = 5650; i <= 5657; i++) - materials[i] = Material.AcaciaWallSign; - for (int i = 213; i <= 215; i++) - materials[i] = Material.AcaciaWood; - for (int i = 11206; i <= 11229; i++) - materials[i] = Material.ActivatorRail; - materials[0] = Material.Air; - materials[2125] = Material.Allium; - materials[23200] = Material.AmethystBlock; - for (int i = 23202; i <= 23213; i++) - materials[i] = Material.AmethystCluster; - materials[21617] = Material.AncientDebris; - materials[6] = Material.Andesite; - for (int i = 16268; i <= 16273; i++) - materials[i] = Material.AndesiteSlab; - for (int i = 15894; i <= 15973; i++) - materials[i] = Material.AndesiteStairs; - for (int i = 18884; i <= 19207; i++) - materials[i] = Material.AndesiteWall; - for (int i = 10993; i <= 10996; i++) - materials[i] = Material.Anvil; - for (int i = 8137; i <= 8140; i++) - materials[i] = Material.AttachedMelonStem; - for (int i = 8133; i <= 8136; i++) - materials[i] = Material.AttachedPumpkinStem; - materials[27609] = Material.Azalea; - for (int i = 504; i <= 531; i++) - materials[i] = Material.AzaleaLeaves; - materials[2126] = Material.AzureBluet; - for (int i = 15077; i <= 15088; i++) - materials[i] = Material.Bamboo; - for (int i = 168; i <= 170; i++) - materials[i] = Material.BambooBlock; - for (int i = 10689; i <= 10712; i++) - materials[i] = Material.BambooButton; - for (int i = 14370; i <= 14433; i++) - materials[i] = Material.BambooDoor; - for (int i = 13826; i <= 13857; i++) - materials[i] = Material.BambooFence; - for (int i = 13538; i <= 13569; i++) - materials[i] = Material.BambooFenceGate; - for (int i = 6410; i <= 6473; i++) - materials[i] = Material.BambooHangingSign; - materials[28] = Material.BambooMosaic; - for (int i = 13188; i <= 13193; i++) - materials[i] = Material.BambooMosaicSlab; - for (int i = 12250; i <= 12329; i++) - materials[i] = Material.BambooMosaicStairs; - materials[27] = Material.BambooPlanks; - for (int i = 6678; i <= 6679; i++) - materials[i] = Material.BambooPressurePlate; - materials[15076] = Material.BambooSapling; - for (int i = 2463; i <= 2526; i++) - materials[i] = Material.BambooShelf; - for (int i = 5422; i <= 5453; i++) - materials[i] = Material.BambooSign; - for (int i = 13182; i <= 13187; i++) - materials[i] = Material.BambooSlab; - for (int i = 12170; i <= 12249; i++) - materials[i] = Material.BambooStairs; - for (int i = 7489; i <= 7552; i++) - materials[i] = Material.BambooTrapdoor; - for (int i = 6562; i <= 6569; i++) - materials[i] = Material.BambooWallHangingSign; - for (int i = 5698; i <= 5705; i++) - materials[i] = Material.BambooWallSign; - for (int i = 20540; i <= 20551; i++) - materials[i] = Material.Barrel; - for (int i = 12331; i <= 12332; i++) - materials[i] = Material.Barrier; - for (int i = 6799; i <= 6801; i++) - materials[i] = Material.Basalt; - materials[9779] = Material.Beacon; - materials[85] = Material.Bedrock; - for (int i = 21566; i <= 21589; i++) - materials[i] = Material.BeeNest; - for (int i = 21590; i <= 21613; i++) - materials[i] = Material.Beehive; - for (int i = 14609; i <= 14612; i++) - materials[i] = Material.Beetroots; - for (int i = 20603; i <= 20634; i++) - materials[i] = Material.Bell; - for (int i = 27661; i <= 27692; i++) - materials[i] = Material.BigDripleaf; - for (int i = 27693; i <= 27700; i++) - materials[i] = Material.BigDripleafStem; - for (int i = 10521; i <= 10544; i++) - materials[i] = Material.BirchButton; - for (int i = 13922; i <= 13985; i++) - materials[i] = Material.BirchDoor; - for (int i = 13602; i <= 13633; i++) - materials[i] = Material.BirchFence; - for (int i = 13314; i <= 13345; i++) - materials[i] = Material.BirchFenceGate; - for (int i = 5834; i <= 5897; i++) - materials[i] = Material.BirchHangingSign; - for (int i = 308; i <= 335; i++) - materials[i] = Material.BirchLeaves; - for (int i = 142; i <= 144; i++) - materials[i] = Material.BirchLog; - materials[17] = Material.BirchPlanks; - for (int i = 6664; i <= 6665; i++) - materials[i] = Material.BirchPressurePlate; - for (int i = 33; i <= 34; i++) - materials[i] = Material.BirchSapling; - for (int i = 2527; i <= 2590; i++) - materials[i] = Material.BirchShelf; - for (int i = 5198; i <= 5229; i++) - materials[i] = Material.BirchSign; - for (int i = 13140; i <= 13145; i++) - materials[i] = Material.BirchSlab; - for (int i = 9607; i <= 9686; i++) - materials[i] = Material.BirchStairs; - for (int i = 7041; i <= 7104; i++) - materials[i] = Material.BirchTrapdoor; - for (int i = 6490; i <= 6497; i++) - materials[i] = Material.BirchWallHangingSign; - for (int i = 5642; i <= 5649; i++) - materials[i] = Material.BirchWallSign; - for (int i = 207; i <= 209; i++) - materials[i] = Material.BirchWood; - for (int i = 12965; i <= 12980; i++) - materials[i] = Material.BlackBanner; - for (int i = 1971; i <= 1986; i++) - materials[i] = Material.BlackBed; - for (int i = 23150; i <= 23165; i++) - materials[i] = Material.BlackCandle; - for (int i = 23198; i <= 23199; i++) - materials[i] = Material.BlackCandleCake; - materials[12709] = Material.BlackCarpet; - materials[14843] = Material.BlackConcrete; - materials[14859] = Material.BlackConcretePowder; - for (int i = 14824; i <= 14827; i++) - materials[i] = Material.BlackGlazedTerracotta; - for (int i = 14758; i <= 14763; i++) - materials[i] = Material.BlackShulkerBox; - materials[6912] = Material.BlackStainedGlass; - for (int i = 11738; i <= 11769; i++) - materials[i] = Material.BlackStainedGlassPane; - materials[11257] = Material.BlackTerracotta; - for (int i = 13041; i <= 13044; i++) - materials[i] = Material.BlackWallBanner; - materials[2108] = Material.BlackWool; - materials[21629] = Material.Blackstone; - for (int i = 22034; i <= 22039; i++) - materials[i] = Material.BlackstoneSlab; - for (int i = 21630; i <= 21709; i++) - materials[i] = Material.BlackstoneStairs; - for (int i = 21710; i <= 22033; i++) - materials[i] = Material.BlackstoneWall; - for (int i = 20560; i <= 20567; i++) - materials[i] = Material.BlastFurnace; - for (int i = 12901; i <= 12916; i++) - materials[i] = Material.BlueBanner; - for (int i = 1907; i <= 1922; i++) - materials[i] = Material.BlueBed; - for (int i = 23086; i <= 23101; i++) - materials[i] = Material.BlueCandle; - for (int i = 23190; i <= 23191; i++) - materials[i] = Material.BlueCandleCake; - materials[12705] = Material.BlueCarpet; - materials[14839] = Material.BlueConcrete; - materials[14855] = Material.BlueConcretePowder; - for (int i = 14808; i <= 14811; i++) - materials[i] = Material.BlueGlazedTerracotta; - materials[15073] = Material.BlueIce; - materials[2124] = Material.BlueOrchid; - for (int i = 14734; i <= 14739; i++) - materials[i] = Material.BlueShulkerBox; - materials[6908] = Material.BlueStainedGlass; - for (int i = 11610; i <= 11641; i++) - materials[i] = Material.BlueStainedGlassPane; - materials[11253] = Material.BlueTerracotta; - for (int i = 13025; i <= 13028; i++) - materials[i] = Material.BlueWallBanner; - materials[2104] = Material.BlueWool; - for (int i = 14646; i <= 14648; i++) - materials[i] = Material.BoneBlock; - materials[2142] = Material.Bookshelf; - for (int i = 14957; i <= 14958; i++) - materials[i] = Material.BrainCoral; - materials[14941] = Material.BrainCoralBlock; - for (int i = 14977; i <= 14978; i++) - materials[i] = Material.BrainCoralFan; - for (int i = 15033; i <= 15040; i++) - materials[i] = Material.BrainCoralWallFan; - for (int i = 9251; i <= 9258; i++) - materials[i] = Material.BrewingStand; - for (int i = 13230; i <= 13235; i++) - materials[i] = Material.BrickSlab; - for (int i = 8477; i <= 8556; i++) - materials[i] = Material.BrickStairs; - for (int i = 16292; i <= 16615; i++) - materials[i] = Material.BrickWall; - materials[2139] = Material.Bricks; - for (int i = 12917; i <= 12932; i++) - materials[i] = Material.BrownBanner; - for (int i = 1923; i <= 1938; i++) - materials[i] = Material.BrownBed; - for (int i = 23102; i <= 23117; i++) - materials[i] = Material.BrownCandle; - for (int i = 23192; i <= 23193; i++) - materials[i] = Material.BrownCandleCake; - materials[12706] = Material.BrownCarpet; - materials[14840] = Material.BrownConcrete; - materials[14856] = Material.BrownConcretePowder; - for (int i = 14812; i <= 14815; i++) - materials[i] = Material.BrownGlazedTerracotta; - materials[2135] = Material.BrownMushroom; - for (int i = 7565; i <= 7628; i++) - materials[i] = Material.BrownMushroomBlock; - for (int i = 14740; i <= 14745; i++) - materials[i] = Material.BrownShulkerBox; - materials[6909] = Material.BrownStainedGlass; - for (int i = 11642; i <= 11673; i++) - materials[i] = Material.BrownStainedGlassPane; - materials[11254] = Material.BrownTerracotta; - for (int i = 13029; i <= 13032; i++) - materials[i] = Material.BrownWallBanner; - materials[2105] = Material.BrownWool; - for (int i = 15092; i <= 15093; i++) - materials[i] = Material.BubbleColumn; - for (int i = 14959; i <= 14960; i++) - materials[i] = Material.BubbleCoral; - materials[14942] = Material.BubbleCoralBlock; - for (int i = 14979; i <= 14980; i++) - materials[i] = Material.BubbleCoralFan; - for (int i = 15041; i <= 15048; i++) - materials[i] = Material.BubbleCoralWallFan; - materials[23201] = Material.BuddingAmethyst; - materials[2051] = Material.Bush; - for (int i = 6728; i <= 6743; i++) - materials[i] = Material.Cactus; - materials[6744] = Material.CactusFlower; - for (int i = 6826; i <= 6832; i++) - materials[i] = Material.Cake; - materials[24485] = Material.Calcite; - for (int i = 24584; i <= 24967; i++) - materials[i] = Material.CalibratedSculkSensor; - for (int i = 20675; i <= 20706; i++) - materials[i] = Material.Campfire; - for (int i = 22894; i <= 22909; i++) - materials[i] = Material.Candle; - for (int i = 23166; i <= 23167; i++) - materials[i] = Material.CandleCake; - for (int i = 10457; i <= 10464; i++) - materials[i] = Material.Carrots; - materials[20568] = Material.CartographyTable; - for (int i = 6818; i <= 6821; i++) - materials[i] = Material.CarvedPumpkin; - materials[9259] = Material.Cauldron; - materials[15091] = Material.CaveAir; - for (int i = 27554; i <= 27605; i++) - materials[i] = Material.CaveVines; - for (int i = 27606; i <= 27607; i++) - materials[i] = Material.CaveVinesPlant; - for (int i = 14627; i <= 14638; i++) - materials[i] = Material.ChainCommandBlock; - for (int i = 10593; i <= 10616; i++) - materials[i] = Material.CherryButton; - for (int i = 14114; i <= 14177; i++) - materials[i] = Material.CherryDoor; - for (int i = 13698; i <= 13729; i++) - materials[i] = Material.CherryFence; - for (int i = 13410; i <= 13441; i++) - materials[i] = Material.CherryFenceGate; - for (int i = 5962; i <= 6025; i++) - materials[i] = Material.CherryHangingSign; - for (int i = 392; i <= 419; i++) - materials[i] = Material.CherryLeaves; - for (int i = 151; i <= 153; i++) - materials[i] = Material.CherryLog; - materials[20] = Material.CherryPlanks; - for (int i = 6670; i <= 6671; i++) - materials[i] = Material.CherryPressurePlate; - for (int i = 39; i <= 40; i++) - materials[i] = Material.CherrySapling; - for (int i = 2591; i <= 2654; i++) - materials[i] = Material.CherryShelf; - for (int i = 5262; i <= 5293; i++) - materials[i] = Material.CherrySign; - for (int i = 13158; i <= 13163; i++) - materials[i] = Material.CherrySlab; - for (int i = 11850; i <= 11929; i++) - materials[i] = Material.CherryStairs; - for (int i = 7233; i <= 7296; i++) - materials[i] = Material.CherryTrapdoor; - for (int i = 6506; i <= 6513; i++) - materials[i] = Material.CherryWallHangingSign; - for (int i = 5658; i <= 5665; i++) - materials[i] = Material.CherryWallSign; - for (int i = 216; i <= 218; i++) - materials[i] = Material.CherryWood; - for (int i = 3786; i <= 3809; i++) - materials[i] = Material.Chest; - for (int i = 10997; i <= 11000; i++) - materials[i] = Material.ChippedAnvil; - for (int i = 2143; i <= 2398; i++) - materials[i] = Material.ChiseledBookshelf; - materials[25120] = Material.ChiseledCopper; - materials[29368] = Material.ChiseledDeepslate; - materials[22891] = Material.ChiseledNetherBricks; - materials[22043] = Material.ChiseledPolishedBlackstone; - materials[11122] = Material.ChiseledQuartzBlock; - materials[13046] = Material.ChiseledRedSandstone; - materials[9132] = Material.ChiseledResinBricks; - materials[579] = Material.ChiseledSandstone; - materials[7556] = Material.ChiseledStoneBricks; - materials[24072] = Material.ChiseledTuff; - materials[24484] = Material.ChiseledTuffBricks; - for (int i = 14504; i <= 14509; i++) - materials[i] = Material.ChorusFlower; - for (int i = 14440; i <= 14503; i++) - materials[i] = Material.ChorusPlant; - materials[6745] = Material.Clay; - materials[29667] = Material.ClosedEyeblossom; - materials[12711] = Material.CoalBlock; - materials[133] = Material.CoalOre; - materials[11] = Material.CoarseDirt; - materials[27724] = Material.CobbledDeepslate; - for (int i = 27805; i <= 27810; i++) - materials[i] = Material.CobbledDeepslateSlab; - for (int i = 27725; i <= 27804; i++) - materials[i] = Material.CobbledDeepslateStairs; - for (int i = 27811; i <= 28134; i++) - materials[i] = Material.CobbledDeepslateWall; - materials[14] = Material.Cobblestone; - for (int i = 13224; i <= 13229; i++) - materials[i] = Material.CobblestoneSlab; - for (int i = 5546; i <= 5625; i++) - materials[i] = Material.CobblestoneStairs; - for (int i = 9780; i <= 10103; i++) - materials[i] = Material.CobblestoneWall; - materials[2047] = Material.Cobweb; - for (int i = 9280; i <= 9291; i++) - materials[i] = Material.Cocoa; - for (int i = 9767; i <= 9778; i++) - materials[i] = Material.CommandBlock; - for (int i = 11061; i <= 11076; i++) - materials[i] = Material.Comparator; - for (int i = 21541; i <= 21549; i++) - materials[i] = Material.Composter; - for (int i = 15074; i <= 15075; i++) - materials[i] = Material.Conduit; - for (int i = 7789; i <= 7820; i++) - materials[i] = Material.CopperBars; - materials[25107] = Material.CopperBlock; - for (int i = 26861; i <= 26864; i++) - materials[i] = Material.CopperBulb; - for (int i = 8051; i <= 8056; i++) - materials[i] = Material.CopperChain; - for (int i = 26893; i <= 26916; i++) - materials[i] = Material.CopperChest; - for (int i = 25821; i <= 25884; i++) - materials[i] = Material.CopperDoor; - for (int i = 27085; i <= 27116; i++) - materials[i] = Material.CopperGolemStatue; - for (int i = 26845; i <= 26846; i++) - materials[i] = Material.CopperGrate; - for (int i = 20643; i <= 20646; i++) - materials[i] = Material.CopperLantern; - materials[25111] = Material.CopperOre; - materials[6810] = Material.CopperTorch; - for (int i = 26333; i <= 26396; i++) - materials[i] = Material.CopperTrapdoor; - for (int i = 6811; i <= 6814; i++) - materials[i] = Material.CopperWallTorch; - materials[2132] = Material.Cornflower; - materials[29369] = Material.CrackedDeepslateBricks; - materials[29370] = Material.CrackedDeepslateTiles; - materials[22892] = Material.CrackedNetherBricks; - materials[22042] = Material.CrackedPolishedBlackstoneBricks; - materials[7555] = Material.CrackedStoneBricks; - for (int i = 29407; i <= 29454; i++) - materials[i] = Material.Crafter; - materials[5109] = Material.CraftingTable; - for (int i = 3688; i <= 3705; i++) - materials[i] = Material.CreakingHeart; - for (int i = 10873; i <= 10904; i++) - materials[i] = Material.CreeperHead; - for (int i = 10905; i <= 10912; i++) - materials[i] = Material.CreeperWallHead; - for (int i = 21264; i <= 21287; i++) - materials[i] = Material.CrimsonButton; - for (int i = 21312; i <= 21375; i++) - materials[i] = Material.CrimsonDoor; - for (int i = 20848; i <= 20879; i++) - materials[i] = Material.CrimsonFence; - for (int i = 21040; i <= 21071; i++) - materials[i] = Material.CrimsonFenceGate; - materials[20773] = Material.CrimsonFungus; - for (int i = 6218; i <= 6281; i++) - materials[i] = Material.CrimsonHangingSign; - for (int i = 20766; i <= 20768; i++) - materials[i] = Material.CrimsonHyphae; - materials[20772] = Material.CrimsonNylium; - materials[20830] = Material.CrimsonPlanks; - for (int i = 20844; i <= 20845; i++) - materials[i] = Material.CrimsonPressurePlate; - materials[20829] = Material.CrimsonRoots; - for (int i = 2655; i <= 2718; i++) - materials[i] = Material.CrimsonShelf; - for (int i = 21440; i <= 21471; i++) - materials[i] = Material.CrimsonSign; - for (int i = 20832; i <= 20837; i++) - materials[i] = Material.CrimsonSlab; - for (int i = 21104; i <= 21183; i++) - materials[i] = Material.CrimsonStairs; - for (int i = 20760; i <= 20762; i++) - materials[i] = Material.CrimsonStem; - for (int i = 20912; i <= 20975; i++) - materials[i] = Material.CrimsonTrapdoor; - for (int i = 6546; i <= 6553; i++) - materials[i] = Material.CrimsonWallHangingSign; - for (int i = 21504; i <= 21511; i++) - materials[i] = Material.CrimsonWallSign; - materials[21618] = Material.CryingObsidian; - materials[25116] = Material.CutCopper; - for (int i = 25463; i <= 25468; i++) - materials[i] = Material.CutCopperSlab; - for (int i = 25365; i <= 25444; i++) - materials[i] = Material.CutCopperStairs; - materials[13047] = Material.CutRedSandstone; - for (int i = 13266; i <= 13271; i++) - materials[i] = Material.CutRedSandstoneSlab; - materials[580] = Material.CutSandstone; - for (int i = 13212; i <= 13217; i++) - materials[i] = Material.CutSandstoneSlab; - for (int i = 12869; i <= 12884; i++) - materials[i] = Material.CyanBanner; - for (int i = 1875; i <= 1890; i++) - materials[i] = Material.CyanBed; - for (int i = 23054; i <= 23069; i++) - materials[i] = Material.CyanCandle; - for (int i = 23186; i <= 23187; i++) - materials[i] = Material.CyanCandleCake; - materials[12703] = Material.CyanCarpet; - materials[14837] = Material.CyanConcrete; - materials[14853] = Material.CyanConcretePowder; - for (int i = 14800; i <= 14803; i++) - materials[i] = Material.CyanGlazedTerracotta; - for (int i = 14722; i <= 14727; i++) - materials[i] = Material.CyanShulkerBox; - materials[6906] = Material.CyanStainedGlass; - for (int i = 11546; i <= 11577; i++) - materials[i] = Material.CyanStainedGlassPane; - materials[11251] = Material.CyanTerracotta; - for (int i = 13017; i <= 13020; i++) - materials[i] = Material.CyanWallBanner; - materials[2102] = Material.CyanWool; - for (int i = 11001; i <= 11004; i++) - materials[i] = Material.DamagedAnvil; - materials[2121] = Material.Dandelion; - for (int i = 10617; i <= 10640; i++) - materials[i] = Material.DarkOakButton; - for (int i = 14178; i <= 14241; i++) - materials[i] = Material.DarkOakDoor; - for (int i = 13730; i <= 13761; i++) - materials[i] = Material.DarkOakFence; - for (int i = 13442; i <= 13473; i++) - materials[i] = Material.DarkOakFenceGate; - for (int i = 6090; i <= 6153; i++) - materials[i] = Material.DarkOakHangingSign; - for (int i = 420; i <= 447; i++) - materials[i] = Material.DarkOakLeaves; - for (int i = 154; i <= 156; i++) - materials[i] = Material.DarkOakLog; - materials[21] = Material.DarkOakPlanks; - for (int i = 6672; i <= 6673; i++) - materials[i] = Material.DarkOakPressurePlate; - for (int i = 41; i <= 42; i++) - materials[i] = Material.DarkOakSapling; - for (int i = 2719; i <= 2782; i++) - materials[i] = Material.DarkOakShelf; - for (int i = 5326; i <= 5357; i++) - materials[i] = Material.DarkOakSign; - for (int i = 13164; i <= 13169; i++) - materials[i] = Material.DarkOakSlab; - for (int i = 11930; i <= 12009; i++) - materials[i] = Material.DarkOakStairs; - for (int i = 7297; i <= 7360; i++) - materials[i] = Material.DarkOakTrapdoor; - for (int i = 6522; i <= 6529; i++) - materials[i] = Material.DarkOakWallHangingSign; - for (int i = 5674; i <= 5681; i++) - materials[i] = Material.DarkOakWallSign; - for (int i = 219; i <= 221; i++) - materials[i] = Material.DarkOakWood; - materials[12431] = Material.DarkPrismarine; - for (int i = 12684; i <= 12689; i++) - materials[i] = Material.DarkPrismarineSlab; - for (int i = 12592; i <= 12671; i++) - materials[i] = Material.DarkPrismarineStairs; - for (int i = 11077; i <= 11108; i++) - materials[i] = Material.DaylightDetector; - for (int i = 14947; i <= 14948; i++) - materials[i] = Material.DeadBrainCoral; - materials[14936] = Material.DeadBrainCoralBlock; - for (int i = 14967; i <= 14968; i++) - materials[i] = Material.DeadBrainCoralFan; - for (int i = 14993; i <= 15000; i++) - materials[i] = Material.DeadBrainCoralWallFan; - for (int i = 14949; i <= 14950; i++) - materials[i] = Material.DeadBubbleCoral; - materials[14937] = Material.DeadBubbleCoralBlock; - for (int i = 14969; i <= 14970; i++) - materials[i] = Material.DeadBubbleCoralFan; - for (int i = 15001; i <= 15008; i++) - materials[i] = Material.DeadBubbleCoralWallFan; - materials[2050] = Material.DeadBush; - for (int i = 14951; i <= 14952; i++) - materials[i] = Material.DeadFireCoral; - materials[14938] = Material.DeadFireCoralBlock; - for (int i = 14971; i <= 14972; i++) - materials[i] = Material.DeadFireCoralFan; - for (int i = 15009; i <= 15016; i++) - materials[i] = Material.DeadFireCoralWallFan; - for (int i = 14953; i <= 14954; i++) - materials[i] = Material.DeadHornCoral; - materials[14939] = Material.DeadHornCoralBlock; - for (int i = 14973; i <= 14974; i++) - materials[i] = Material.DeadHornCoralFan; - for (int i = 15017; i <= 15024; i++) - materials[i] = Material.DeadHornCoralWallFan; - for (int i = 14945; i <= 14946; i++) - materials[i] = Material.DeadTubeCoral; - materials[14935] = Material.DeadTubeCoralBlock; - for (int i = 14965; i <= 14966; i++) - materials[i] = Material.DeadTubeCoralFan; - for (int i = 14985; i <= 14992; i++) - materials[i] = Material.DeadTubeCoralWallFan; - for (int i = 29391; i <= 29406; i++) - materials[i] = Material.DecoratedPot; - for (int i = 27721; i <= 27723; i++) - materials[i] = Material.Deepslate; - for (int i = 29038; i <= 29043; i++) - materials[i] = Material.DeepslateBrickSlab; - for (int i = 28958; i <= 29037; i++) - materials[i] = Material.DeepslateBrickStairs; - for (int i = 29044; i <= 29367; i++) - materials[i] = Material.DeepslateBrickWall; - materials[28957] = Material.DeepslateBricks; - materials[134] = Material.DeepslateCoalOre; - materials[25112] = Material.DeepslateCopperOre; - materials[5107] = Material.DeepslateDiamondOre; - materials[9373] = Material.DeepslateEmeraldOre; - materials[130] = Material.DeepslateGoldOre; - materials[132] = Material.DeepslateIronOre; - materials[564] = Material.DeepslateLapisOre; - for (int i = 6682; i <= 6683; i++) - materials[i] = Material.DeepslateRedstoneOre; - for (int i = 28627; i <= 28632; i++) - materials[i] = Material.DeepslateTileSlab; - for (int i = 28547; i <= 28626; i++) - materials[i] = Material.DeepslateTileStairs; - for (int i = 28633; i <= 28956; i++) - materials[i] = Material.DeepslateTileWall; - materials[28546] = Material.DeepslateTiles; - for (int i = 2011; i <= 2034; i++) - materials[i] = Material.DetectorRail; - materials[5108] = Material.DiamondBlock; - materials[5106] = Material.DiamondOre; - materials[4] = Material.Diorite; - for (int i = 16286; i <= 16291; i++) - materials[i] = Material.DioriteSlab; - for (int i = 16134; i <= 16213; i++) - materials[i] = Material.DioriteStairs; - for (int i = 20180; i <= 20503; i++) - materials[i] = Material.DioriteWall; - materials[10] = Material.Dirt; - materials[14613] = Material.DirtPath; - for (int i = 566; i <= 577; i++) - materials[i] = Material.Dispenser; - materials[9277] = Material.DragonEgg; - for (int i = 10913; i <= 10944; i++) - materials[i] = Material.DragonHead; - for (int i = 10945; i <= 10952; i++) - materials[i] = Material.DragonWallHead; - for (int i = 14903; i <= 14934; i++) - materials[i] = Material.DriedGhast; - materials[14887] = Material.DriedKelpBlock; - materials[27553] = Material.DripstoneBlock; - for (int i = 11230; i <= 11241; i++) - materials[i] = Material.Dropper; - materials[9526] = Material.EmeraldBlock; - materials[9372] = Material.EmeraldOre; - materials[9250] = Material.EnchantingTable; - materials[14614] = Material.EndGateway; - materials[9267] = Material.EndPortal; - for (int i = 9268; i <= 9275; i++) - materials[i] = Material.EndPortalFrame; - for (int i = 14434; i <= 14439; i++) - materials[i] = Material.EndRod; - materials[9276] = Material.EndStone; - for (int i = 16244; i <= 16249; i++) - materials[i] = Material.EndStoneBrickSlab; - for (int i = 15494; i <= 15573; i++) - materials[i] = Material.EndStoneBrickStairs; - for (int i = 19856; i <= 20179; i++) - materials[i] = Material.EndStoneBrickWall; - materials[14594] = Material.EndStoneBricks; - for (int i = 9374; i <= 9381; i++) - materials[i] = Material.EnderChest; - materials[25119] = Material.ExposedChiseledCopper; - materials[25108] = Material.ExposedCopper; - for (int i = 7821; i <= 7852; i++) - materials[i] = Material.ExposedCopperBars; - for (int i = 26865; i <= 26868; i++) - materials[i] = Material.ExposedCopperBulb; - for (int i = 8057; i <= 8062; i++) - materials[i] = Material.ExposedCopperChain; - for (int i = 26917; i <= 26940; i++) - materials[i] = Material.ExposedCopperChest; - for (int i = 25885; i <= 25948; i++) - materials[i] = Material.ExposedCopperDoor; - for (int i = 27117; i <= 27148; i++) - materials[i] = Material.ExposedCopperGolemStatue; - for (int i = 26847; i <= 26848; i++) - materials[i] = Material.ExposedCopperGrate; - for (int i = 20647; i <= 20650; i++) - materials[i] = Material.ExposedCopperLantern; - for (int i = 26397; i <= 26460; i++) - materials[i] = Material.ExposedCopperTrapdoor; - materials[25115] = Material.ExposedCutCopper; - for (int i = 25457; i <= 25462; i++) - materials[i] = Material.ExposedCutCopperSlab; - for (int i = 25285; i <= 25364; i++) - materials[i] = Material.ExposedCutCopperStairs; - for (int i = 27365; i <= 27388; i++) - materials[i] = Material.ExposedLightningRod; - for (int i = 5118; i <= 5125; i++) - materials[i] = Material.Farmland; - materials[2049] = Material.Fern; - for (int i = 3174; i <= 3685; i++) - materials[i] = Material.Fire; - for (int i = 14961; i <= 14962; i++) - materials[i] = Material.FireCoral; - materials[14943] = Material.FireCoralBlock; - for (int i = 14981; i <= 14982; i++) - materials[i] = Material.FireCoralFan; - for (int i = 15049; i <= 15056; i++) - materials[i] = Material.FireCoralWallFan; - materials[29670] = Material.FireflyBush; - materials[20569] = Material.FletchingTable; - materials[10428] = Material.FlowerPot; - materials[27610] = Material.FloweringAzalea; - for (int i = 532; i <= 559; i++) - materials[i] = Material.FloweringAzaleaLeaves; - materials[29389] = Material.Frogspawn; - for (int i = 14639; i <= 14642; i++) - materials[i] = Material.FrostedIce; - for (int i = 5126; i <= 5133; i++) - materials[i] = Material.Furnace; - materials[22454] = Material.GildedBlackstone; - materials[562] = Material.Glass; - for (int i = 8099; i <= 8130; i++) - materials[i] = Material.GlassPane; - for (int i = 8189; i <= 8316; i++) - materials[i] = Material.GlowLichen; - materials[6815] = Material.Glowstone; - materials[2137] = Material.GoldBlock; - materials[129] = Material.GoldOre; - materials[2] = Material.Granite; - for (int i = 16262; i <= 16267; i++) - materials[i] = Material.GraniteSlab; - for (int i = 15814; i <= 15893; i++) - materials[i] = Material.GraniteStairs; - for (int i = 17588; i <= 17911; i++) - materials[i] = Material.GraniteWall; + for (int i = 0; i <= 0; i++) + materials[i] = Material.Air; + for (int i = 1; i <= 1; i++) + materials[i] = Material.Stone; + for (int i = 2; i <= 2; i++) + materials[i] = Material.Granite; + for (int i = 3; i <= 3; i++) + materials[i] = Material.PolishedGranite; + for (int i = 4; i <= 4; i++) + materials[i] = Material.Diorite; + for (int i = 5; i <= 5; i++) + materials[i] = Material.PolishedDiorite; + for (int i = 6; i <= 6; i++) + materials[i] = Material.Andesite; + for (int i = 7; i <= 7; i++) + materials[i] = Material.PolishedAndesite; for (int i = 8; i <= 9; i++) materials[i] = Material.GrassBlock; - materials[124] = Material.Gravel; - for (int i = 12837; i <= 12852; i++) - materials[i] = Material.GrayBanner; - for (int i = 1843; i <= 1858; i++) - materials[i] = Material.GrayBed; - for (int i = 23022; i <= 23037; i++) - materials[i] = Material.GrayCandle; - for (int i = 23182; i <= 23183; i++) - materials[i] = Material.GrayCandleCake; - materials[12701] = Material.GrayCarpet; - materials[14835] = Material.GrayConcrete; - materials[14851] = Material.GrayConcretePowder; - for (int i = 14792; i <= 14795; i++) - materials[i] = Material.GrayGlazedTerracotta; - for (int i = 14710; i <= 14715; i++) - materials[i] = Material.GrayShulkerBox; - materials[6904] = Material.GrayStainedGlass; - for (int i = 11482; i <= 11513; i++) - materials[i] = Material.GrayStainedGlassPane; - materials[11249] = Material.GrayTerracotta; - for (int i = 13009; i <= 13012; i++) - materials[i] = Material.GrayWallBanner; - materials[2100] = Material.GrayWool; - for (int i = 12933; i <= 12948; i++) - materials[i] = Material.GreenBanner; - for (int i = 1939; i <= 1954; i++) - materials[i] = Material.GreenBed; - for (int i = 23118; i <= 23133; i++) - materials[i] = Material.GreenCandle; - for (int i = 23194; i <= 23195; i++) - materials[i] = Material.GreenCandleCake; - materials[12707] = Material.GreenCarpet; - materials[14841] = Material.GreenConcrete; - materials[14857] = Material.GreenConcretePowder; - for (int i = 14816; i <= 14819; i++) - materials[i] = Material.GreenGlazedTerracotta; - for (int i = 14746; i <= 14751; i++) - materials[i] = Material.GreenShulkerBox; - materials[6910] = Material.GreenStainedGlass; - for (int i = 11674; i <= 11705; i++) - materials[i] = Material.GreenStainedGlassPane; - materials[11255] = Material.GreenTerracotta; - for (int i = 13033; i <= 13036; i++) - materials[i] = Material.GreenWallBanner; - materials[2106] = Material.GreenWool; - for (int i = 20570; i <= 20581; i++) - materials[i] = Material.Grindstone; - for (int i = 27717; i <= 27718; i++) - materials[i] = Material.HangingRoots; - for (int i = 12691; i <= 12693; i++) - materials[i] = Material.HayBlock; - for (int i = 29499; i <= 29500; i++) - materials[i] = Material.HeavyCore; - for (int i = 11045; i <= 11060; i++) - materials[i] = Material.HeavyWeightedPressurePlate; - materials[21614] = Material.HoneyBlock; - materials[21615] = Material.HoneycombBlock; - for (int i = 11111; i <= 11120; i++) - materials[i] = Material.Hopper; - for (int i = 14963; i <= 14964; i++) - materials[i] = Material.HornCoral; - materials[14944] = Material.HornCoralBlock; - for (int i = 14983; i <= 14984; i++) - materials[i] = Material.HornCoralFan; - for (int i = 15057; i <= 15064; i++) - materials[i] = Material.HornCoralWallFan; - materials[6726] = Material.Ice; - materials[7564] = Material.InfestedChiseledStoneBricks; - materials[7560] = Material.InfestedCobblestone; - materials[7563] = Material.InfestedCrackedStoneBricks; - for (int i = 29371; i <= 29373; i++) - materials[i] = Material.InfestedDeepslate; - materials[7562] = Material.InfestedMossyStoneBricks; - materials[7559] = Material.InfestedStone; - materials[7561] = Material.InfestedStoneBricks; - for (int i = 7757; i <= 7788; i++) - materials[i] = Material.IronBars; - materials[2138] = Material.IronBlock; - for (int i = 8045; i <= 8050; i++) - materials[i] = Material.IronChain; - for (int i = 6596; i <= 6659; i++) - materials[i] = Material.IronDoor; - materials[131] = Material.IronOre; - for (int i = 12365; i <= 12428; i++) - materials[i] = Material.IronTrapdoor; - for (int i = 6822; i <= 6825; i++) - materials[i] = Material.JackOLantern; - for (int i = 21524; i <= 21535; i++) - materials[i] = Material.Jigsaw; - for (int i = 6762; i <= 6763; i++) - materials[i] = Material.Jukebox; - for (int i = 10545; i <= 10568; i++) - materials[i] = Material.JungleButton; - for (int i = 13986; i <= 14049; i++) - materials[i] = Material.JungleDoor; - for (int i = 13634; i <= 13665; i++) - materials[i] = Material.JungleFence; - for (int i = 13346; i <= 13377; i++) - materials[i] = Material.JungleFenceGate; - for (int i = 6026; i <= 6089; i++) - materials[i] = Material.JungleHangingSign; - for (int i = 336; i <= 363; i++) - materials[i] = Material.JungleLeaves; - for (int i = 145; i <= 147; i++) - materials[i] = Material.JungleLog; - materials[18] = Material.JunglePlanks; - for (int i = 6666; i <= 6667; i++) - materials[i] = Material.JunglePressurePlate; - for (int i = 35; i <= 36; i++) - materials[i] = Material.JungleSapling; - for (int i = 2783; i <= 2846; i++) - materials[i] = Material.JungleShelf; - for (int i = 5294; i <= 5325; i++) - materials[i] = Material.JungleSign; - for (int i = 13146; i <= 13151; i++) - materials[i] = Material.JungleSlab; - for (int i = 9687; i <= 9766; i++) - materials[i] = Material.JungleStairs; - for (int i = 7105; i <= 7168; i++) - materials[i] = Material.JungleTrapdoor; - for (int i = 6514; i <= 6521; i++) - materials[i] = Material.JungleWallHangingSign; - for (int i = 5666; i <= 5673; i++) - materials[i] = Material.JungleWallSign; - for (int i = 210; i <= 212; i++) - materials[i] = Material.JungleWood; - for (int i = 14860; i <= 14885; i++) - materials[i] = Material.Kelp; - materials[14886] = Material.KelpPlant; - for (int i = 5518; i <= 5525; i++) - materials[i] = Material.Ladder; - for (int i = 20635; i <= 20638; i++) - materials[i] = Material.Lantern; - materials[565] = Material.LapisBlock; - materials[563] = Material.LapisOre; - for (int i = 23214; i <= 23225; i++) - materials[i] = Material.LargeAmethystBud; - for (int i = 12723; i <= 12724; i++) - materials[i] = Material.LargeFern; - for (int i = 102; i <= 117; i++) - materials[i] = Material.Lava; - materials[9263] = Material.LavaCauldron; - for (int i = 27644; i <= 27659; i++) - materials[i] = Material.LeafLitter; - for (int i = 20582; i <= 20597; i++) - materials[i] = Material.Lectern; - for (int i = 6570; i <= 6593; i++) - materials[i] = Material.Lever; - for (int i = 12333; i <= 12364; i++) - materials[i] = Material.Light; - for (int i = 12773; i <= 12788; i++) - materials[i] = Material.LightBlueBanner; - for (int i = 1779; i <= 1794; i++) - materials[i] = Material.LightBlueBed; - for (int i = 22958; i <= 22973; i++) - materials[i] = Material.LightBlueCandle; - for (int i = 23174; i <= 23175; i++) - materials[i] = Material.LightBlueCandleCake; - materials[12697] = Material.LightBlueCarpet; - materials[14831] = Material.LightBlueConcrete; - materials[14847] = Material.LightBlueConcretePowder; - for (int i = 14776; i <= 14779; i++) - materials[i] = Material.LightBlueGlazedTerracotta; - for (int i = 14686; i <= 14691; i++) - materials[i] = Material.LightBlueShulkerBox; - materials[6900] = Material.LightBlueStainedGlass; - for (int i = 11354; i <= 11385; i++) - materials[i] = Material.LightBlueStainedGlassPane; - materials[11245] = Material.LightBlueTerracotta; - for (int i = 12993; i <= 12996; i++) - materials[i] = Material.LightBlueWallBanner; - materials[2096] = Material.LightBlueWool; - for (int i = 12853; i <= 12868; i++) - materials[i] = Material.LightGrayBanner; - for (int i = 1859; i <= 1874; i++) - materials[i] = Material.LightGrayBed; - for (int i = 23038; i <= 23053; i++) - materials[i] = Material.LightGrayCandle; - for (int i = 23184; i <= 23185; i++) - materials[i] = Material.LightGrayCandleCake; - materials[12702] = Material.LightGrayCarpet; - materials[14836] = Material.LightGrayConcrete; - materials[14852] = Material.LightGrayConcretePowder; - for (int i = 14796; i <= 14799; i++) - materials[i] = Material.LightGrayGlazedTerracotta; - for (int i = 14716; i <= 14721; i++) - materials[i] = Material.LightGrayShulkerBox; - materials[6905] = Material.LightGrayStainedGlass; - for (int i = 11514; i <= 11545; i++) - materials[i] = Material.LightGrayStainedGlassPane; - materials[11250] = Material.LightGrayTerracotta; - for (int i = 13013; i <= 13016; i++) - materials[i] = Material.LightGrayWallBanner; - materials[2101] = Material.LightGrayWool; - for (int i = 11029; i <= 11044; i++) - materials[i] = Material.LightWeightedPressurePlate; - for (int i = 27341; i <= 27364; i++) - materials[i] = Material.LightningRod; - for (int i = 12715; i <= 12716; i++) - materials[i] = Material.Lilac; - materials[2134] = Material.LilyOfTheValley; - materials[8719] = Material.LilyPad; - for (int i = 12805; i <= 12820; i++) - materials[i] = Material.LimeBanner; - for (int i = 1811; i <= 1826; i++) - materials[i] = Material.LimeBed; - for (int i = 22990; i <= 23005; i++) - materials[i] = Material.LimeCandle; - for (int i = 23178; i <= 23179; i++) - materials[i] = Material.LimeCandleCake; - materials[12699] = Material.LimeCarpet; - materials[14833] = Material.LimeConcrete; - materials[14849] = Material.LimeConcretePowder; - for (int i = 14784; i <= 14787; i++) - materials[i] = Material.LimeGlazedTerracotta; - for (int i = 14698; i <= 14703; i++) - materials[i] = Material.LimeShulkerBox; - materials[6902] = Material.LimeStainedGlass; - for (int i = 11418; i <= 11449; i++) - materials[i] = Material.LimeStainedGlassPane; - materials[11247] = Material.LimeTerracotta; - for (int i = 13001; i <= 13004; i++) - materials[i] = Material.LimeWallBanner; - materials[2098] = Material.LimeWool; - materials[21628] = Material.Lodestone; - for (int i = 20536; i <= 20539; i++) - materials[i] = Material.Loom; - for (int i = 12757; i <= 12772; i++) - materials[i] = Material.MagentaBanner; - for (int i = 1763; i <= 1778; i++) - materials[i] = Material.MagentaBed; - for (int i = 22942; i <= 22957; i++) - materials[i] = Material.MagentaCandle; - for (int i = 23172; i <= 23173; i++) - materials[i] = Material.MagentaCandleCake; - materials[12696] = Material.MagentaCarpet; - materials[14830] = Material.MagentaConcrete; - materials[14846] = Material.MagentaConcretePowder; - for (int i = 14772; i <= 14775; i++) - materials[i] = Material.MagentaGlazedTerracotta; - for (int i = 14680; i <= 14685; i++) - materials[i] = Material.MagentaShulkerBox; - materials[6899] = Material.MagentaStainedGlass; - for (int i = 11322; i <= 11353; i++) - materials[i] = Material.MagentaStainedGlassPane; - materials[11244] = Material.MagentaTerracotta; - for (int i = 12989; i <= 12992; i++) - materials[i] = Material.MagentaWallBanner; - materials[2095] = Material.MagentaWool; - materials[14643] = Material.MagmaBlock; - for (int i = 10665; i <= 10688; i++) - materials[i] = Material.MangroveButton; - for (int i = 14306; i <= 14369; i++) - materials[i] = Material.MangroveDoor; - for (int i = 13794; i <= 13825; i++) - materials[i] = Material.MangroveFence; - for (int i = 13506; i <= 13537; i++) - materials[i] = Material.MangroveFenceGate; - for (int i = 6346; i <= 6409; i++) - materials[i] = Material.MangroveHangingSign; - for (int i = 476; i <= 503; i++) - materials[i] = Material.MangroveLeaves; - for (int i = 160; i <= 162; i++) - materials[i] = Material.MangroveLog; - materials[26] = Material.MangrovePlanks; - for (int i = 6676; i <= 6677; i++) - materials[i] = Material.MangrovePressurePlate; - for (int i = 45; i <= 84; i++) - materials[i] = Material.MangrovePropagule; - for (int i = 163; i <= 164; i++) - materials[i] = Material.MangroveRoots; - for (int i = 2847; i <= 2910; i++) - materials[i] = Material.MangroveShelf; - for (int i = 5390; i <= 5421; i++) - materials[i] = Material.MangroveSign; - for (int i = 13176; i <= 13181; i++) - materials[i] = Material.MangroveSlab; - for (int i = 12090; i <= 12169; i++) - materials[i] = Material.MangroveStairs; - for (int i = 7425; i <= 7488; i++) - materials[i] = Material.MangroveTrapdoor; - for (int i = 6538; i <= 6545; i++) - materials[i] = Material.MangroveWallHangingSign; - for (int i = 5690; i <= 5697; i++) - materials[i] = Material.MangroveWallSign; - for (int i = 222; i <= 224; i++) - materials[i] = Material.MangroveWood; - for (int i = 23226; i <= 23237; i++) - materials[i] = Material.MediumAmethystBud; - materials[8132] = Material.Melon; - for (int i = 8149; i <= 8156; i++) - materials[i] = Material.MelonStem; - materials[27660] = Material.MossBlock; - materials[27611] = Material.MossCarpet; - materials[3167] = Material.MossyCobblestone; - for (int i = 16238; i <= 16243; i++) - materials[i] = Material.MossyCobblestoneSlab; - for (int i = 15414; i <= 15493; i++) - materials[i] = Material.MossyCobblestoneStairs; - for (int i = 10104; i <= 10427; i++) - materials[i] = Material.MossyCobblestoneWall; - for (int i = 16226; i <= 16231; i++) - materials[i] = Material.MossyStoneBrickSlab; - for (int i = 15254; i <= 15333; i++) - materials[i] = Material.MossyStoneBrickStairs; - for (int i = 17264; i <= 17587; i++) - materials[i] = Material.MossyStoneBrickWall; - materials[7554] = Material.MossyStoneBricks; - for (int i = 2109; i <= 2120; i++) - materials[i] = Material.MovingPiston; - materials[27720] = Material.Mud; - for (int i = 13242; i <= 13247; i++) - materials[i] = Material.MudBrickSlab; - for (int i = 8637; i <= 8716; i++) - materials[i] = Material.MudBrickStairs; - for (int i = 18236; i <= 18559; i++) - materials[i] = Material.MudBrickWall; - materials[7558] = Material.MudBricks; - for (int i = 165; i <= 167; i++) - materials[i] = Material.MuddyMangroveRoots; - for (int i = 7693; i <= 7756; i++) - materials[i] = Material.MushroomStem; - for (int i = 8717; i <= 8718; i++) - materials[i] = Material.Mycelium; - for (int i = 9134; i <= 9165; i++) - materials[i] = Material.NetherBrickFence; - for (int i = 13248; i <= 13253; i++) - materials[i] = Material.NetherBrickSlab; - for (int i = 9166; i <= 9245; i++) - materials[i] = Material.NetherBrickStairs; - for (int i = 18560; i <= 18883; i++) - materials[i] = Material.NetherBrickWall; - materials[9133] = Material.NetherBricks; - materials[135] = Material.NetherGoldOre; - for (int i = 6816; i <= 6817; i++) - materials[i] = Material.NetherPortal; - materials[11110] = Material.NetherQuartzOre; - materials[20759] = Material.NetherSprouts; - for (int i = 9246; i <= 9249; i++) - materials[i] = Material.NetherWart; - materials[14644] = Material.NetherWartBlock; - materials[21616] = Material.NetheriteBlock; - materials[6796] = Material.Netherrack; - for (int i = 581; i <= 1730; i++) - materials[i] = Material.NoteBlock; - for (int i = 10473; i <= 10496; i++) - materials[i] = Material.OakButton; - for (int i = 5454; i <= 5517; i++) - materials[i] = Material.OakDoor; - for (int i = 6764; i <= 6795; i++) - materials[i] = Material.OakFence; - for (int i = 8445; i <= 8476; i++) - materials[i] = Material.OakFenceGate; - for (int i = 5706; i <= 5769; i++) - materials[i] = Material.OakHangingSign; - for (int i = 252; i <= 279; i++) - materials[i] = Material.OakLeaves; - for (int i = 136; i <= 138; i++) - materials[i] = Material.OakLog; - materials[15] = Material.OakPlanks; - for (int i = 6660; i <= 6661; i++) - materials[i] = Material.OakPressurePlate; - for (int i = 29; i <= 30; i++) - materials[i] = Material.OakSapling; - for (int i = 2911; i <= 2974; i++) - materials[i] = Material.OakShelf; - for (int i = 5134; i <= 5165; i++) - materials[i] = Material.OakSign; - for (int i = 13128; i <= 13133; i++) - materials[i] = Material.OakSlab; - for (int i = 3706; i <= 3785; i++) - materials[i] = Material.OakStairs; - for (int i = 6913; i <= 6976; i++) - materials[i] = Material.OakTrapdoor; - for (int i = 6474; i <= 6481; i++) - materials[i] = Material.OakWallHangingSign; - for (int i = 5626; i <= 5633; i++) - materials[i] = Material.OakWallSign; - for (int i = 201; i <= 203; i++) - materials[i] = Material.OakWood; - for (int i = 14650; i <= 14661; i++) - materials[i] = Material.Observer; - materials[3168] = Material.Obsidian; - for (int i = 29380; i <= 29382; i++) - materials[i] = Material.OchreFroglight; - materials[29666] = Material.OpenEyeblossom; - for (int i = 12741; i <= 12756; i++) - materials[i] = Material.OrangeBanner; - for (int i = 1747; i <= 1762; i++) - materials[i] = Material.OrangeBed; - for (int i = 22926; i <= 22941; i++) - materials[i] = Material.OrangeCandle; - for (int i = 23170; i <= 23171; i++) - materials[i] = Material.OrangeCandleCake; - materials[12695] = Material.OrangeCarpet; - materials[14829] = Material.OrangeConcrete; - materials[14845] = Material.OrangeConcretePowder; - for (int i = 14768; i <= 14771; i++) - materials[i] = Material.OrangeGlazedTerracotta; - for (int i = 14674; i <= 14679; i++) - materials[i] = Material.OrangeShulkerBox; - materials[6898] = Material.OrangeStainedGlass; - for (int i = 11290; i <= 11321; i++) - materials[i] = Material.OrangeStainedGlassPane; - materials[11243] = Material.OrangeTerracotta; - materials[2128] = Material.OrangeTulip; - for (int i = 12985; i <= 12988; i++) - materials[i] = Material.OrangeWallBanner; - materials[2094] = Material.OrangeWool; - materials[2131] = Material.OxeyeDaisy; - materials[25117] = Material.OxidizedChiseledCopper; - materials[25110] = Material.OxidizedCopper; - for (int i = 7885; i <= 7916; i++) - materials[i] = Material.OxidizedCopperBars; - for (int i = 26873; i <= 26876; i++) - materials[i] = Material.OxidizedCopperBulb; - for (int i = 8069; i <= 8074; i++) - materials[i] = Material.OxidizedCopperChain; - for (int i = 26965; i <= 26988; i++) - materials[i] = Material.OxidizedCopperChest; - for (int i = 25949; i <= 26012; i++) - materials[i] = Material.OxidizedCopperDoor; - for (int i = 27181; i <= 27212; i++) - materials[i] = Material.OxidizedCopperGolemStatue; - for (int i = 26851; i <= 26852; i++) - materials[i] = Material.OxidizedCopperGrate; - for (int i = 20655; i <= 20658; i++) - materials[i] = Material.OxidizedCopperLantern; - for (int i = 26461; i <= 26524; i++) - materials[i] = Material.OxidizedCopperTrapdoor; - materials[25113] = Material.OxidizedCutCopper; - for (int i = 25445; i <= 25450; i++) - materials[i] = Material.OxidizedCutCopperSlab; - for (int i = 25125; i <= 25204; i++) - materials[i] = Material.OxidizedCutCopperStairs; - for (int i = 27413; i <= 27436; i++) - materials[i] = Material.OxidizedLightningRod; - materials[12712] = Material.PackedIce; - materials[7557] = Material.PackedMud; - for (int i = 29664; i <= 29665; i++) - materials[i] = Material.PaleHangingMoss; - materials[29501] = Material.PaleMossBlock; - for (int i = 29502; i <= 29663; i++) - materials[i] = Material.PaleMossCarpet; - for (int i = 10641; i <= 10664; i++) - materials[i] = Material.PaleOakButton; - for (int i = 14242; i <= 14305; i++) - materials[i] = Material.PaleOakDoor; - for (int i = 13762; i <= 13793; i++) - materials[i] = Material.PaleOakFence; - for (int i = 13474; i <= 13505; i++) - materials[i] = Material.PaleOakFenceGate; - for (int i = 6154; i <= 6217; i++) - materials[i] = Material.PaleOakHangingSign; - for (int i = 448; i <= 475; i++) - materials[i] = Material.PaleOakLeaves; - for (int i = 157; i <= 159; i++) - materials[i] = Material.PaleOakLog; - materials[25] = Material.PaleOakPlanks; - for (int i = 6674; i <= 6675; i++) - materials[i] = Material.PaleOakPressurePlate; - for (int i = 43; i <= 44; i++) - materials[i] = Material.PaleOakSapling; - for (int i = 2975; i <= 3038; i++) - materials[i] = Material.PaleOakShelf; - for (int i = 5358; i <= 5389; i++) - materials[i] = Material.PaleOakSign; - for (int i = 13170; i <= 13175; i++) - materials[i] = Material.PaleOakSlab; - for (int i = 12010; i <= 12089; i++) - materials[i] = Material.PaleOakStairs; - for (int i = 7361; i <= 7424; i++) - materials[i] = Material.PaleOakTrapdoor; - for (int i = 6530; i <= 6537; i++) - materials[i] = Material.PaleOakWallHangingSign; - for (int i = 5682; i <= 5689; i++) - materials[i] = Material.PaleOakWallSign; + for (int i = 10; i <= 10; i++) + materials[i] = Material.Dirt; + for (int i = 11; i <= 11; i++) + materials[i] = Material.CoarseDirt; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 14; i <= 14; i++) + materials[i] = Material.Cobblestone; + for (int i = 15; i <= 15; i++) + materials[i] = Material.OakPlanks; + for (int i = 16; i <= 16; i++) + materials[i] = Material.SprucePlanks; + for (int i = 17; i <= 17; i++) + materials[i] = Material.BirchPlanks; + for (int i = 18; i <= 18; i++) + materials[i] = Material.JunglePlanks; + for (int i = 19; i <= 19; i++) + materials[i] = Material.AcaciaPlanks; + for (int i = 20; i <= 20; i++) + materials[i] = Material.CherryPlanks; + for (int i = 21; i <= 21; i++) + materials[i] = Material.DarkOakPlanks; for (int i = 22; i <= 24; i++) materials[i] = Material.PaleOakWood; - for (int i = 29386; i <= 29388; i++) - materials[i] = Material.PearlescentFroglight; - for (int i = 12719; i <= 12720; i++) - materials[i] = Material.Peony; - for (int i = 13218; i <= 13223; i++) - materials[i] = Material.PetrifiedOakSlab; - for (int i = 10953; i <= 10984; i++) - materials[i] = Material.PiglinHead; - for (int i = 10985; i <= 10992; i++) - materials[i] = Material.PiglinWallHead; - for (int i = 12821; i <= 12836; i++) - materials[i] = Material.PinkBanner; + for (int i = 25; i <= 25; i++) + materials[i] = Material.PaleOakPlanks; + for (int i = 26; i <= 26; i++) + materials[i] = Material.MangrovePlanks; + for (int i = 27; i <= 27; i++) + materials[i] = Material.BambooPlanks; + for (int i = 28; i <= 28; i++) + materials[i] = Material.BambooMosaic; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 85; i <= 85; i++) + materials[i] = Material.Bedrock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + for (int i = 118; i <= 118; i++) + materials[i] = Material.Sand; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 123; i <= 123; i++) + materials[i] = Material.RedSand; + for (int i = 124; i <= 124; i++) + materials[i] = Material.Gravel; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 129; i <= 129; i++) + materials[i] = Material.GoldOre; + for (int i = 130; i <= 130; i++) + materials[i] = Material.DeepslateGoldOre; + for (int i = 131; i <= 131; i++) + materials[i] = Material.IronOre; + for (int i = 132; i <= 132; i++) + materials[i] = Material.DeepslateIronOre; + for (int i = 133; i <= 133; i++) + materials[i] = Material.CoalOre; + for (int i = 134; i <= 134; i++) + materials[i] = Material.DeepslateCoalOre; + for (int i = 135; i <= 135; i++) + materials[i] = Material.NetherGoldOre; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + for (int i = 560; i <= 560; i++) + materials[i] = Material.Sponge; + for (int i = 561; i <= 561; i++) + materials[i] = Material.WetSponge; + for (int i = 562; i <= 562; i++) + materials[i] = Material.Glass; + for (int i = 563; i <= 563; i++) + materials[i] = Material.LapisOre; + for (int i = 564; i <= 564; i++) + materials[i] = Material.DeepslateLapisOre; + for (int i = 565; i <= 565; i++) + materials[i] = Material.LapisBlock; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + for (int i = 578; i <= 578; i++) + materials[i] = Material.Sandstone; + for (int i = 579; i <= 579; i++) + materials[i] = Material.ChiseledSandstone; + for (int i = 580; i <= 580; i++) + materials[i] = Material.CutSandstone; + for (int i = 581; i <= 1730; i++) + materials[i] = Material.NoteBlock; + for (int i = 1731; i <= 1746; i++) + materials[i] = Material.WhiteBed; + for (int i = 1747; i <= 1762; i++) + materials[i] = Material.OrangeBed; + for (int i = 1763; i <= 1778; i++) + materials[i] = Material.MagentaBed; + for (int i = 1779; i <= 1794; i++) + materials[i] = Material.LightBlueBed; + for (int i = 1795; i <= 1810; i++) + materials[i] = Material.YellowBed; + for (int i = 1811; i <= 1826; i++) + materials[i] = Material.LimeBed; for (int i = 1827; i <= 1842; i++) materials[i] = Material.PinkBed; - for (int i = 23006; i <= 23021; i++) - materials[i] = Material.PinkCandle; - for (int i = 23180; i <= 23181; i++) - materials[i] = Material.PinkCandleCake; - materials[12700] = Material.PinkCarpet; - materials[14834] = Material.PinkConcrete; - materials[14850] = Material.PinkConcretePowder; - for (int i = 14788; i <= 14791; i++) - materials[i] = Material.PinkGlazedTerracotta; - for (int i = 27612; i <= 27627; i++) - materials[i] = Material.PinkPetals; - for (int i = 14704; i <= 14709; i++) - materials[i] = Material.PinkShulkerBox; - materials[6903] = Material.PinkStainedGlass; - for (int i = 11450; i <= 11481; i++) - materials[i] = Material.PinkStainedGlassPane; - materials[11248] = Material.PinkTerracotta; - materials[2130] = Material.PinkTulip; - for (int i = 13005; i <= 13008; i++) - materials[i] = Material.PinkWallBanner; - materials[2099] = Material.PinkWool; + for (int i = 1843; i <= 1858; i++) + materials[i] = Material.GrayBed; + for (int i = 1859; i <= 1874; i++) + materials[i] = Material.LightGrayBed; + for (int i = 1875; i <= 1890; i++) + materials[i] = Material.CyanBed; + for (int i = 1891; i <= 1906; i++) + materials[i] = Material.PurpleBed; + for (int i = 1907; i <= 1922; i++) + materials[i] = Material.BlueBed; + for (int i = 1923; i <= 1938; i++) + materials[i] = Material.BrownBed; + for (int i = 1939; i <= 1954; i++) + materials[i] = Material.GreenBed; + for (int i = 1955; i <= 1970; i++) + materials[i] = Material.RedBed; + for (int i = 1971; i <= 1986; i++) + materials[i] = Material.BlackBed; + for (int i = 1987; i <= 2010; i++) + materials[i] = Material.PoweredRail; + for (int i = 2011; i <= 2034; i++) + materials[i] = Material.DetectorRail; + for (int i = 2035; i <= 2046; i++) + materials[i] = Material.StickyPiston; + for (int i = 2047; i <= 2047; i++) + materials[i] = Material.Cobweb; + for (int i = 2048; i <= 2048; i++) + materials[i] = Material.ShortGrass; + for (int i = 2049; i <= 2049; i++) + materials[i] = Material.Fern; + for (int i = 2050; i <= 2050; i++) + materials[i] = Material.DeadBush; + for (int i = 2051; i <= 2051; i++) + materials[i] = Material.Bush; + for (int i = 2052; i <= 2052; i++) + materials[i] = Material.ShortDryGrass; + for (int i = 2053; i <= 2053; i++) + materials[i] = Material.TallDryGrass; + for (int i = 2054; i <= 2054; i++) + materials[i] = Material.Seagrass; + for (int i = 2055; i <= 2056; i++) + materials[i] = Material.TallSeagrass; for (int i = 2057; i <= 2068; i++) materials[i] = Material.Piston; for (int i = 2069; i <= 2092; i++) materials[i] = Material.PistonHead; - for (int i = 14597; i <= 14606; i++) - materials[i] = Material.PitcherCrop; - for (int i = 14607; i <= 14608; i++) - materials[i] = Material.PitcherPlant; + for (int i = 2093; i <= 2093; i++) + materials[i] = Material.WhiteWool; + for (int i = 2094; i <= 2094; i++) + materials[i] = Material.OrangeWool; + for (int i = 2095; i <= 2095; i++) + materials[i] = Material.MagentaWool; + for (int i = 2096; i <= 2096; i++) + materials[i] = Material.LightBlueWool; + for (int i = 2097; i <= 2097; i++) + materials[i] = Material.YellowWool; + for (int i = 2098; i <= 2098; i++) + materials[i] = Material.LimeWool; + for (int i = 2099; i <= 2099; i++) + materials[i] = Material.PinkWool; + for (int i = 2100; i <= 2100; i++) + materials[i] = Material.GrayWool; + for (int i = 2101; i <= 2101; i++) + materials[i] = Material.LightGrayWool; + for (int i = 2102; i <= 2102; i++) + materials[i] = Material.CyanWool; + for (int i = 2103; i <= 2103; i++) + materials[i] = Material.PurpleWool; + for (int i = 2104; i <= 2104; i++) + materials[i] = Material.BlueWool; + for (int i = 2105; i <= 2105; i++) + materials[i] = Material.BrownWool; + for (int i = 2106; i <= 2106; i++) + materials[i] = Material.GreenWool; + for (int i = 2107; i <= 2107; i++) + materials[i] = Material.RedWool; + for (int i = 2108; i <= 2108; i++) + materials[i] = Material.BlackWool; + for (int i = 2109; i <= 2120; i++) + materials[i] = Material.MovingPiston; + for (int i = 2121; i <= 2121; i++) + materials[i] = Material.Dandelion; + for (int i = 2122; i <= 2122; i++) + materials[i] = Material.Torchflower; + for (int i = 2123; i <= 2123; i++) + materials[i] = Material.Poppy; + for (int i = 2124; i <= 2124; i++) + materials[i] = Material.BlueOrchid; + for (int i = 2125; i <= 2125; i++) + materials[i] = Material.Allium; + for (int i = 2126; i <= 2126; i++) + materials[i] = Material.AzureBluet; + for (int i = 2127; i <= 2127; i++) + materials[i] = Material.RedTulip; + for (int i = 2128; i <= 2128; i++) + materials[i] = Material.OrangeTulip; + for (int i = 2129; i <= 2129; i++) + materials[i] = Material.WhiteTulip; + for (int i = 2130; i <= 2130; i++) + materials[i] = Material.PinkTulip; + for (int i = 2131; i <= 2131; i++) + materials[i] = Material.OxeyeDaisy; + for (int i = 2132; i <= 2132; i++) + materials[i] = Material.Cornflower; + for (int i = 2133; i <= 2133; i++) + materials[i] = Material.WitherRose; + for (int i = 2134; i <= 2134; i++) + materials[i] = Material.LilyOfTheValley; + for (int i = 2135; i <= 2135; i++) + materials[i] = Material.BrownMushroom; + for (int i = 2136; i <= 2136; i++) + materials[i] = Material.RedMushroom; + for (int i = 2137; i <= 2137; i++) + materials[i] = Material.GoldBlock; + for (int i = 2138; i <= 2138; i++) + materials[i] = Material.IronBlock; + for (int i = 2139; i <= 2139; i++) + materials[i] = Material.Bricks; + for (int i = 2140; i <= 2141; i++) + materials[i] = Material.Tnt; + for (int i = 2142; i <= 2142; i++) + materials[i] = Material.Bookshelf; + for (int i = 2143; i <= 2398; i++) + materials[i] = Material.ChiseledBookshelf; + for (int i = 2399; i <= 2462; i++) + materials[i] = Material.AcaciaShelf; + for (int i = 2463; i <= 2526; i++) + materials[i] = Material.BambooShelf; + for (int i = 2527; i <= 2590; i++) + materials[i] = Material.BirchShelf; + for (int i = 2591; i <= 2654; i++) + materials[i] = Material.CherryShelf; + for (int i = 2655; i <= 2718; i++) + materials[i] = Material.CrimsonShelf; + for (int i = 2719; i <= 2782; i++) + materials[i] = Material.DarkOakShelf; + for (int i = 2783; i <= 2846; i++) + materials[i] = Material.JungleShelf; + for (int i = 2847; i <= 2910; i++) + materials[i] = Material.MangroveShelf; + for (int i = 2911; i <= 2974; i++) + materials[i] = Material.OakShelf; + for (int i = 2975; i <= 3038; i++) + materials[i] = Material.PaleOakShelf; + for (int i = 3039; i <= 3102; i++) + materials[i] = Material.SpruceShelf; + for (int i = 3103; i <= 3166; i++) + materials[i] = Material.WarpedShelf; + for (int i = 3167; i <= 3167; i++) + materials[i] = Material.MossyCobblestone; + for (int i = 3168; i <= 3168; i++) + materials[i] = Material.Obsidian; + for (int i = 3169; i <= 3169; i++) + materials[i] = Material.Torch; + for (int i = 3170; i <= 3173; i++) + materials[i] = Material.WallTorch; + for (int i = 3174; i <= 3685; i++) + materials[i] = Material.Fire; + for (int i = 3686; i <= 3686; i++) + materials[i] = Material.SoulFire; + for (int i = 3687; i <= 3687; i++) + materials[i] = Material.Spawner; + for (int i = 3688; i <= 3705; i++) + materials[i] = Material.CreakingHeart; + for (int i = 3706; i <= 3785; i++) + materials[i] = Material.OakStairs; + for (int i = 3786; i <= 3809; i++) + materials[i] = Material.Chest; + for (int i = 3810; i <= 5105; i++) + materials[i] = Material.RedstoneWire; + for (int i = 5106; i <= 5106; i++) + materials[i] = Material.DiamondOre; + for (int i = 5107; i <= 5107; i++) + materials[i] = Material.DeepslateDiamondOre; + for (int i = 5108; i <= 5108; i++) + materials[i] = Material.DiamondBlock; + for (int i = 5109; i <= 5109; i++) + materials[i] = Material.CraftingTable; + for (int i = 5110; i <= 5117; i++) + materials[i] = Material.Wheat; + for (int i = 5118; i <= 5125; i++) + materials[i] = Material.Farmland; + for (int i = 5126; i <= 5133; i++) + materials[i] = Material.Furnace; + for (int i = 5134; i <= 5165; i++) + materials[i] = Material.OakSign; + for (int i = 5166; i <= 5197; i++) + materials[i] = Material.SpruceSign; + for (int i = 5198; i <= 5229; i++) + materials[i] = Material.BirchSign; + for (int i = 5230; i <= 5261; i++) + materials[i] = Material.AcaciaSign; + for (int i = 5262; i <= 5293; i++) + materials[i] = Material.CherrySign; + for (int i = 5294; i <= 5325; i++) + materials[i] = Material.JungleSign; + for (int i = 5326; i <= 5357; i++) + materials[i] = Material.DarkOakSign; + for (int i = 5358; i <= 5389; i++) + materials[i] = Material.PaleOakSign; + for (int i = 5390; i <= 5421; i++) + materials[i] = Material.MangroveSign; + for (int i = 5422; i <= 5453; i++) + materials[i] = Material.BambooSign; + for (int i = 5454; i <= 5517; i++) + materials[i] = Material.OakDoor; + for (int i = 5518; i <= 5525; i++) + materials[i] = Material.Ladder; + for (int i = 5526; i <= 5545; i++) + materials[i] = Material.Rail; + for (int i = 5546; i <= 5625; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 5626; i <= 5633; i++) + materials[i] = Material.OakWallSign; + for (int i = 5634; i <= 5641; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 5642; i <= 5649; i++) + materials[i] = Material.BirchWallSign; + for (int i = 5650; i <= 5657; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 5658; i <= 5665; i++) + materials[i] = Material.CherryWallSign; + for (int i = 5666; i <= 5673; i++) + materials[i] = Material.JungleWallSign; + for (int i = 5674; i <= 5681; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 5682; i <= 5689; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 5690; i <= 5697; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 5698; i <= 5705; i++) + materials[i] = Material.BambooWallSign; + for (int i = 5706; i <= 5769; i++) + materials[i] = Material.OakHangingSign; + for (int i = 5770; i <= 5833; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 5834; i <= 5897; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 5898; i <= 5961; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 5962; i <= 6025; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 6026; i <= 6089; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 6090; i <= 6153; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 6154; i <= 6217; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 6218; i <= 6281; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 6282; i <= 6345; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 6346; i <= 6409; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 6410; i <= 6473; i++) + materials[i] = Material.BambooHangingSign; + for (int i = 6474; i <= 6481; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 6482; i <= 6489; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 6490; i <= 6497; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 6498; i <= 6505; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 6506; i <= 6513; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 6514; i <= 6521; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 6522; i <= 6529; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 6530; i <= 6537; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 6538; i <= 6545; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 6546; i <= 6553; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 6554; i <= 6561; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 6562; i <= 6569; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 6570; i <= 6593; i++) + materials[i] = Material.Lever; + for (int i = 6594; i <= 6595; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 6596; i <= 6659; i++) + materials[i] = Material.IronDoor; + for (int i = 6660; i <= 6661; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 6662; i <= 6663; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 6664; i <= 6665; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 6666; i <= 6667; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 6668; i <= 6669; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 6670; i <= 6671; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 6672; i <= 6673; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 6674; i <= 6675; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 6676; i <= 6677; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 6678; i <= 6679; i++) + materials[i] = Material.BambooPressurePlate; + for (int i = 6680; i <= 6681; i++) + materials[i] = Material.RedstoneOre; + for (int i = 6682; i <= 6683; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 6684; i <= 6685; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 6686; i <= 6693; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 6694; i <= 6717; i++) + materials[i] = Material.StoneButton; + for (int i = 6718; i <= 6725; i++) + materials[i] = Material.Snow; + for (int i = 6726; i <= 6726; i++) + materials[i] = Material.Ice; + for (int i = 6727; i <= 6727; i++) + materials[i] = Material.SnowBlock; + for (int i = 6728; i <= 6743; i++) + materials[i] = Material.Cactus; + for (int i = 6744; i <= 6744; i++) + materials[i] = Material.CactusFlower; + for (int i = 6745; i <= 6745; i++) + materials[i] = Material.Clay; + for (int i = 6746; i <= 6761; i++) + materials[i] = Material.SugarCane; + for (int i = 6762; i <= 6763; i++) + materials[i] = Material.Jukebox; + for (int i = 6764; i <= 6795; i++) + materials[i] = Material.OakFence; + for (int i = 6796; i <= 6796; i++) + materials[i] = Material.Netherrack; + for (int i = 6797; i <= 6797; i++) + materials[i] = Material.SoulSand; + for (int i = 6798; i <= 6798; i++) + materials[i] = Material.SoulSoil; + for (int i = 6799; i <= 6801; i++) + materials[i] = Material.Basalt; + for (int i = 6802; i <= 6804; i++) + materials[i] = Material.PolishedBasalt; + for (int i = 6805; i <= 6805; i++) + materials[i] = Material.SoulTorch; + for (int i = 6806; i <= 6809; i++) + materials[i] = Material.SoulWallTorch; + for (int i = 6810; i <= 6810; i++) + materials[i] = Material.CopperTorch; + for (int i = 6811; i <= 6814; i++) + materials[i] = Material.CopperWallTorch; + for (int i = 6815; i <= 6815; i++) + materials[i] = Material.Glowstone; + for (int i = 6816; i <= 6817; i++) + materials[i] = Material.NetherPortal; + for (int i = 6818; i <= 6821; i++) + materials[i] = Material.CarvedPumpkin; + for (int i = 6822; i <= 6825; i++) + materials[i] = Material.JackOLantern; + for (int i = 6826; i <= 6832; i++) + materials[i] = Material.Cake; + for (int i = 6833; i <= 6896; i++) + materials[i] = Material.Repeater; + for (int i = 6897; i <= 6897; i++) + materials[i] = Material.WhiteStainedGlass; + for (int i = 6898; i <= 6898; i++) + materials[i] = Material.OrangeStainedGlass; + for (int i = 6899; i <= 6899; i++) + materials[i] = Material.MagentaStainedGlass; + for (int i = 6900; i <= 6900; i++) + materials[i] = Material.LightBlueStainedGlass; + for (int i = 6901; i <= 6901; i++) + materials[i] = Material.YellowStainedGlass; + for (int i = 6902; i <= 6902; i++) + materials[i] = Material.LimeStainedGlass; + for (int i = 6903; i <= 6903; i++) + materials[i] = Material.PinkStainedGlass; + for (int i = 6904; i <= 6904; i++) + materials[i] = Material.GrayStainedGlass; + for (int i = 6905; i <= 6905; i++) + materials[i] = Material.LightGrayStainedGlass; + for (int i = 6906; i <= 6906; i++) + materials[i] = Material.CyanStainedGlass; + for (int i = 6907; i <= 6907; i++) + materials[i] = Material.PurpleStainedGlass; + for (int i = 6908; i <= 6908; i++) + materials[i] = Material.BlueStainedGlass; + for (int i = 6909; i <= 6909; i++) + materials[i] = Material.BrownStainedGlass; + for (int i = 6910; i <= 6910; i++) + materials[i] = Material.GreenStainedGlass; + for (int i = 6911; i <= 6911; i++) + materials[i] = Material.RedStainedGlass; + for (int i = 6912; i <= 6912; i++) + materials[i] = Material.BlackStainedGlass; + for (int i = 6913; i <= 6976; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 6977; i <= 7040; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 7041; i <= 7104; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 7105; i <= 7168; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 7169; i <= 7232; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 7233; i <= 7296; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 7297; i <= 7360; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 7361; i <= 7424; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 7425; i <= 7488; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 7489; i <= 7552; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 7553; i <= 7553; i++) + materials[i] = Material.StoneBricks; + for (int i = 7554; i <= 7554; i++) + materials[i] = Material.MossyStoneBricks; + for (int i = 7555; i <= 7555; i++) + materials[i] = Material.CrackedStoneBricks; + for (int i = 7556; i <= 7556; i++) + materials[i] = Material.ChiseledStoneBricks; + for (int i = 7557; i <= 7557; i++) + materials[i] = Material.PackedMud; + for (int i = 7558; i <= 7558; i++) + materials[i] = Material.MudBricks; + for (int i = 7559; i <= 7559; i++) + materials[i] = Material.InfestedStone; + for (int i = 7560; i <= 7560; i++) + materials[i] = Material.InfestedCobblestone; + for (int i = 7561; i <= 7561; i++) + materials[i] = Material.InfestedStoneBricks; + for (int i = 7562; i <= 7562; i++) + materials[i] = Material.InfestedMossyStoneBricks; + for (int i = 7563; i <= 7563; i++) + materials[i] = Material.InfestedCrackedStoneBricks; + for (int i = 7564; i <= 7564; i++) + materials[i] = Material.InfestedChiseledStoneBricks; + for (int i = 7565; i <= 7628; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 7629; i <= 7692; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 7693; i <= 7756; i++) + materials[i] = Material.MushroomStem; + for (int i = 7757; i <= 7788; i++) + materials[i] = Material.IronBars; + for (int i = 7789; i <= 7820; i++) + materials[i] = Material.CopperBars; + for (int i = 7821; i <= 7852; i++) + materials[i] = Material.ExposedCopperBars; + for (int i = 7853; i <= 7884; i++) + materials[i] = Material.WeatheredCopperBars; + for (int i = 7885; i <= 7916; i++) + materials[i] = Material.OxidizedCopperBars; + for (int i = 7917; i <= 7948; i++) + materials[i] = Material.WaxedCopperBars; + for (int i = 7949; i <= 7980; i++) + materials[i] = Material.WaxedExposedCopperBars; + for (int i = 7981; i <= 8012; i++) + materials[i] = Material.WaxedWeatheredCopperBars; + for (int i = 8013; i <= 8044; i++) + materials[i] = Material.WaxedOxidizedCopperBars; + for (int i = 8045; i <= 8050; i++) + materials[i] = Material.IronChain; + for (int i = 8051; i <= 8056; i++) + materials[i] = Material.CopperChain; + for (int i = 8057; i <= 8062; i++) + materials[i] = Material.ExposedCopperChain; + for (int i = 8063; i <= 8068; i++) + materials[i] = Material.WeatheredCopperChain; + for (int i = 8069; i <= 8074; i++) + materials[i] = Material.OxidizedCopperChain; + for (int i = 8075; i <= 8080; i++) + materials[i] = Material.WaxedCopperChain; + for (int i = 8081; i <= 8086; i++) + materials[i] = Material.WaxedExposedCopperChain; + for (int i = 8087; i <= 8092; i++) + materials[i] = Material.WaxedWeatheredCopperChain; + for (int i = 8093; i <= 8098; i++) + materials[i] = Material.WaxedOxidizedCopperChain; + for (int i = 8099; i <= 8130; i++) + materials[i] = Material.GlassPane; + for (int i = 8131; i <= 8131; i++) + materials[i] = Material.Pumpkin; + for (int i = 8132; i <= 8132; i++) + materials[i] = Material.Melon; + for (int i = 8133; i <= 8136; i++) + materials[i] = Material.AttachedPumpkinStem; + for (int i = 8137; i <= 8140; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 8141; i <= 8148; i++) + materials[i] = Material.PumpkinStem; + for (int i = 8149; i <= 8156; i++) + materials[i] = Material.MelonStem; + for (int i = 8157; i <= 8188; i++) + materials[i] = Material.Vine; + for (int i = 8189; i <= 8316; i++) + materials[i] = Material.GlowLichen; + for (int i = 8317; i <= 8444; i++) + materials[i] = Material.ResinClump; + for (int i = 8445; i <= 8476; i++) + materials[i] = Material.OakFenceGate; + for (int i = 8477; i <= 8556; i++) + materials[i] = Material.BrickStairs; + for (int i = 8557; i <= 8636; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 8637; i <= 8716; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 8717; i <= 8718; i++) + materials[i] = Material.Mycelium; + for (int i = 8719; i <= 8719; i++) + materials[i] = Material.LilyPad; + for (int i = 8720; i <= 8720; i++) + materials[i] = Material.ResinBlock; + for (int i = 8721; i <= 8721; i++) + materials[i] = Material.ResinBricks; + for (int i = 8722; i <= 8801; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 8802; i <= 8807; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 8808; i <= 9131; i++) + materials[i] = Material.ResinBrickWall; + for (int i = 9132; i <= 9132; i++) + materials[i] = Material.ChiseledResinBricks; + for (int i = 9133; i <= 9133; i++) + materials[i] = Material.NetherBricks; + for (int i = 9134; i <= 9165; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 9166; i <= 9245; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 9246; i <= 9249; i++) + materials[i] = Material.NetherWart; + for (int i = 9250; i <= 9250; i++) + materials[i] = Material.EnchantingTable; + for (int i = 9251; i <= 9258; i++) + materials[i] = Material.BrewingStand; + for (int i = 9259; i <= 9259; i++) + materials[i] = Material.Cauldron; + for (int i = 9260; i <= 9262; i++) + materials[i] = Material.WaterCauldron; + for (int i = 9263; i <= 9263; i++) + materials[i] = Material.LavaCauldron; + for (int i = 9264; i <= 9266; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 9267; i <= 9267; i++) + materials[i] = Material.EndPortal; + for (int i = 9268; i <= 9275; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 9276; i <= 9276; i++) + materials[i] = Material.EndStone; + for (int i = 9277; i <= 9277; i++) + materials[i] = Material.DragonEgg; + for (int i = 9278; i <= 9279; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 9280; i <= 9291; i++) + materials[i] = Material.Cocoa; + for (int i = 9292; i <= 9371; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 9372; i <= 9372; i++) + materials[i] = Material.EmeraldOre; + for (int i = 9373; i <= 9373; i++) + materials[i] = Material.DeepslateEmeraldOre; + for (int i = 9374; i <= 9381; i++) + materials[i] = Material.EnderChest; + for (int i = 9382; i <= 9397; i++) + materials[i] = Material.TripwireHook; + for (int i = 9398; i <= 9525; i++) + materials[i] = Material.Tripwire; + for (int i = 9526; i <= 9526; i++) + materials[i] = Material.EmeraldBlock; + for (int i = 9527; i <= 9606; i++) + materials[i] = Material.SpruceStairs; + for (int i = 9607; i <= 9686; i++) + materials[i] = Material.BirchStairs; + for (int i = 9687; i <= 9766; i++) + materials[i] = Material.JungleStairs; + for (int i = 9767; i <= 9778; i++) + materials[i] = Material.CommandBlock; + for (int i = 9779; i <= 9779; i++) + materials[i] = Material.Beacon; + for (int i = 9780; i <= 10103; i++) + materials[i] = Material.CobblestoneWall; + for (int i = 10104; i <= 10427; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 10428; i <= 10428; i++) + materials[i] = Material.FlowerPot; + for (int i = 10429; i <= 10429; i++) + materials[i] = Material.PottedTorchflower; + for (int i = 10430; i <= 10430; i++) + materials[i] = Material.PottedOakSapling; + for (int i = 10431; i <= 10431; i++) + materials[i] = Material.PottedSpruceSapling; + for (int i = 10432; i <= 10432; i++) + materials[i] = Material.PottedBirchSapling; + for (int i = 10433; i <= 10433; i++) + materials[i] = Material.PottedJungleSapling; + for (int i = 10434; i <= 10434; i++) + materials[i] = Material.PottedAcaciaSapling; + for (int i = 10435; i <= 10435; i++) + materials[i] = Material.PottedCherrySapling; + for (int i = 10436; i <= 10436; i++) + materials[i] = Material.PottedDarkOakSapling; + for (int i = 10437; i <= 10437; i++) + materials[i] = Material.PottedPaleOakSapling; + for (int i = 10438; i <= 10438; i++) + materials[i] = Material.PottedMangrovePropagule; + for (int i = 10439; i <= 10439; i++) + materials[i] = Material.PottedFern; + for (int i = 10440; i <= 10440; i++) + materials[i] = Material.PottedDandelion; + for (int i = 10441; i <= 10441; i++) + materials[i] = Material.PottedPoppy; + for (int i = 10442; i <= 10442; i++) + materials[i] = Material.PottedBlueOrchid; + for (int i = 10443; i <= 10443; i++) + materials[i] = Material.PottedAllium; + for (int i = 10444; i <= 10444; i++) + materials[i] = Material.PottedAzureBluet; + for (int i = 10445; i <= 10445; i++) + materials[i] = Material.PottedRedTulip; + for (int i = 10446; i <= 10446; i++) + materials[i] = Material.PottedOrangeTulip; + for (int i = 10447; i <= 10447; i++) + materials[i] = Material.PottedWhiteTulip; + for (int i = 10448; i <= 10448; i++) + materials[i] = Material.PottedPinkTulip; + for (int i = 10449; i <= 10449; i++) + materials[i] = Material.PottedOxeyeDaisy; + for (int i = 10450; i <= 10450; i++) + materials[i] = Material.PottedCornflower; + for (int i = 10451; i <= 10451; i++) + materials[i] = Material.PottedLilyOfTheValley; + for (int i = 10452; i <= 10452; i++) + materials[i] = Material.PottedWitherRose; + for (int i = 10453; i <= 10453; i++) + materials[i] = Material.PottedRedMushroom; + for (int i = 10454; i <= 10454; i++) + materials[i] = Material.PottedBrownMushroom; + for (int i = 10455; i <= 10455; i++) + materials[i] = Material.PottedDeadBush; + for (int i = 10456; i <= 10456; i++) + materials[i] = Material.PottedCactus; + for (int i = 10457; i <= 10464; i++) + materials[i] = Material.Carrots; + for (int i = 10465; i <= 10472; i++) + materials[i] = Material.Potatoes; + for (int i = 10473; i <= 10496; i++) + materials[i] = Material.OakButton; + for (int i = 10497; i <= 10520; i++) + materials[i] = Material.SpruceButton; + for (int i = 10521; i <= 10544; i++) + materials[i] = Material.BirchButton; + for (int i = 10545; i <= 10568; i++) + materials[i] = Material.JungleButton; + for (int i = 10569; i <= 10592; i++) + materials[i] = Material.AcaciaButton; + for (int i = 10593; i <= 10616; i++) + materials[i] = Material.CherryButton; + for (int i = 10617; i <= 10640; i++) + materials[i] = Material.DarkOakButton; + for (int i = 10641; i <= 10664; i++) + materials[i] = Material.PaleOakButton; + for (int i = 10665; i <= 10688; i++) + materials[i] = Material.MangroveButton; + for (int i = 10689; i <= 10712; i++) + materials[i] = Material.BambooButton; + for (int i = 10713; i <= 10744; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 10745; i <= 10752; i++) + materials[i] = Material.SkeletonWallSkull; + for (int i = 10753; i <= 10784; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 10785; i <= 10792; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 10793; i <= 10824; i++) + materials[i] = Material.ZombieHead; + for (int i = 10825; i <= 10832; i++) + materials[i] = Material.ZombieWallHead; for (int i = 10833; i <= 10864; i++) materials[i] = Material.PlayerHead; for (int i = 10865; i <= 10872; i++) materials[i] = Material.PlayerWallHead; - for (int i = 12; i <= 13; i++) - materials[i] = Material.Podzol; - for (int i = 27533; i <= 27552; i++) - materials[i] = Material.PointedDripstone; - materials[7] = Material.PolishedAndesite; - for (int i = 16280; i <= 16285; i++) - materials[i] = Material.PolishedAndesiteSlab; + for (int i = 10873; i <= 10904; i++) + materials[i] = Material.CreeperHead; + for (int i = 10905; i <= 10912; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 10913; i <= 10944; i++) + materials[i] = Material.DragonHead; + for (int i = 10945; i <= 10952; i++) + materials[i] = Material.DragonWallHead; + for (int i = 10953; i <= 10984; i++) + materials[i] = Material.PiglinHead; + for (int i = 10985; i <= 10992; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 10993; i <= 10996; i++) + materials[i] = Material.Anvil; + for (int i = 10997; i <= 11000; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 11001; i <= 11004; i++) + materials[i] = Material.DamagedAnvil; + for (int i = 11005; i <= 11028; i++) + materials[i] = Material.TrappedChest; + for (int i = 11029; i <= 11044; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 11045; i <= 11060; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + for (int i = 11061; i <= 11076; i++) + materials[i] = Material.Comparator; + for (int i = 11077; i <= 11108; i++) + materials[i] = Material.DaylightDetector; + for (int i = 11109; i <= 11109; i++) + materials[i] = Material.RedstoneBlock; + for (int i = 11110; i <= 11110; i++) + materials[i] = Material.NetherQuartzOre; + for (int i = 11111; i <= 11120; i++) + materials[i] = Material.Hopper; + for (int i = 11121; i <= 11121; i++) + materials[i] = Material.QuartzBlock; + for (int i = 11122; i <= 11122; i++) + materials[i] = Material.ChiseledQuartzBlock; + for (int i = 11123; i <= 11125; i++) + materials[i] = Material.QuartzPillar; + for (int i = 11126; i <= 11205; i++) + materials[i] = Material.QuartzStairs; + for (int i = 11206; i <= 11229; i++) + materials[i] = Material.ActivatorRail; + for (int i = 11230; i <= 11241; i++) + materials[i] = Material.Dropper; + for (int i = 11242; i <= 11242; i++) + materials[i] = Material.WhiteTerracotta; + for (int i = 11243; i <= 11243; i++) + materials[i] = Material.OrangeTerracotta; + for (int i = 11244; i <= 11244; i++) + materials[i] = Material.MagentaTerracotta; + for (int i = 11245; i <= 11245; i++) + materials[i] = Material.LightBlueTerracotta; + for (int i = 11246; i <= 11246; i++) + materials[i] = Material.YellowTerracotta; + for (int i = 11247; i <= 11247; i++) + materials[i] = Material.LimeTerracotta; + for (int i = 11248; i <= 11248; i++) + materials[i] = Material.PinkTerracotta; + for (int i = 11249; i <= 11249; i++) + materials[i] = Material.GrayTerracotta; + for (int i = 11250; i <= 11250; i++) + materials[i] = Material.LightGrayTerracotta; + for (int i = 11251; i <= 11251; i++) + materials[i] = Material.CyanTerracotta; + for (int i = 11252; i <= 11252; i++) + materials[i] = Material.PurpleTerracotta; + for (int i = 11253; i <= 11253; i++) + materials[i] = Material.BlueTerracotta; + for (int i = 11254; i <= 11254; i++) + materials[i] = Material.BrownTerracotta; + for (int i = 11255; i <= 11255; i++) + materials[i] = Material.GreenTerracotta; + for (int i = 11256; i <= 11256; i++) + materials[i] = Material.RedTerracotta; + for (int i = 11257; i <= 11257; i++) + materials[i] = Material.BlackTerracotta; + for (int i = 11258; i <= 11289; i++) + materials[i] = Material.WhiteStainedGlassPane; + for (int i = 11290; i <= 11321; i++) + materials[i] = Material.OrangeStainedGlassPane; + for (int i = 11322; i <= 11353; i++) + materials[i] = Material.MagentaStainedGlassPane; + for (int i = 11354; i <= 11385; i++) + materials[i] = Material.LightBlueStainedGlassPane; + for (int i = 11386; i <= 11417; i++) + materials[i] = Material.YellowStainedGlassPane; + for (int i = 11418; i <= 11449; i++) + materials[i] = Material.LimeStainedGlassPane; + for (int i = 11450; i <= 11481; i++) + materials[i] = Material.PinkStainedGlassPane; + for (int i = 11482; i <= 11513; i++) + materials[i] = Material.GrayStainedGlassPane; + for (int i = 11514; i <= 11545; i++) + materials[i] = Material.LightGrayStainedGlassPane; + for (int i = 11546; i <= 11577; i++) + materials[i] = Material.CyanStainedGlassPane; + for (int i = 11578; i <= 11609; i++) + materials[i] = Material.PurpleStainedGlassPane; + for (int i = 11610; i <= 11641; i++) + materials[i] = Material.BlueStainedGlassPane; + for (int i = 11642; i <= 11673; i++) + materials[i] = Material.BrownStainedGlassPane; + for (int i = 11674; i <= 11705; i++) + materials[i] = Material.GreenStainedGlassPane; + for (int i = 11706; i <= 11737; i++) + materials[i] = Material.RedStainedGlassPane; + for (int i = 11738; i <= 11769; i++) + materials[i] = Material.BlackStainedGlassPane; + for (int i = 11770; i <= 11849; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 11850; i <= 11929; i++) + materials[i] = Material.CherryStairs; + for (int i = 11930; i <= 12009; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 12010; i <= 12089; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 12090; i <= 12169; i++) + materials[i] = Material.MangroveStairs; + for (int i = 12170; i <= 12249; i++) + materials[i] = Material.BambooStairs; + for (int i = 12250; i <= 12329; i++) + materials[i] = Material.BambooMosaicStairs; + for (int i = 12330; i <= 12330; i++) + materials[i] = Material.SlimeBlock; + for (int i = 12331; i <= 12332; i++) + materials[i] = Material.Barrier; + for (int i = 12333; i <= 12364; i++) + materials[i] = Material.Light; + for (int i = 12365; i <= 12428; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 12429; i <= 12429; i++) + materials[i] = Material.Prismarine; + for (int i = 12430; i <= 12430; i++) + materials[i] = Material.PrismarineBricks; + for (int i = 12431; i <= 12431; i++) + materials[i] = Material.DarkPrismarine; + for (int i = 12432; i <= 12511; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 12512; i <= 12591; i++) + materials[i] = Material.PrismarineBrickStairs; + for (int i = 12592; i <= 12671; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 12672; i <= 12677; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 12678; i <= 12683; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 12684; i <= 12689; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 12690; i <= 12690; i++) + materials[i] = Material.SeaLantern; + for (int i = 12691; i <= 12693; i++) + materials[i] = Material.HayBlock; + for (int i = 12694; i <= 12694; i++) + materials[i] = Material.WhiteCarpet; + for (int i = 12695; i <= 12695; i++) + materials[i] = Material.OrangeCarpet; + for (int i = 12696; i <= 12696; i++) + materials[i] = Material.MagentaCarpet; + for (int i = 12697; i <= 12697; i++) + materials[i] = Material.LightBlueCarpet; + for (int i = 12698; i <= 12698; i++) + materials[i] = Material.YellowCarpet; + for (int i = 12699; i <= 12699; i++) + materials[i] = Material.LimeCarpet; + for (int i = 12700; i <= 12700; i++) + materials[i] = Material.PinkCarpet; + for (int i = 12701; i <= 12701; i++) + materials[i] = Material.GrayCarpet; + for (int i = 12702; i <= 12702; i++) + materials[i] = Material.LightGrayCarpet; + for (int i = 12703; i <= 12703; i++) + materials[i] = Material.CyanCarpet; + for (int i = 12704; i <= 12704; i++) + materials[i] = Material.PurpleCarpet; + for (int i = 12705; i <= 12705; i++) + materials[i] = Material.BlueCarpet; + for (int i = 12706; i <= 12706; i++) + materials[i] = Material.BrownCarpet; + for (int i = 12707; i <= 12707; i++) + materials[i] = Material.GreenCarpet; + for (int i = 12708; i <= 12708; i++) + materials[i] = Material.RedCarpet; + for (int i = 12709; i <= 12709; i++) + materials[i] = Material.BlackCarpet; + for (int i = 12710; i <= 12710; i++) + materials[i] = Material.Terracotta; + for (int i = 12711; i <= 12711; i++) + materials[i] = Material.CoalBlock; + for (int i = 12712; i <= 12712; i++) + materials[i] = Material.PackedIce; + for (int i = 12713; i <= 12714; i++) + materials[i] = Material.Sunflower; + for (int i = 12715; i <= 12716; i++) + materials[i] = Material.Lilac; + for (int i = 12717; i <= 12718; i++) + materials[i] = Material.RoseBush; + for (int i = 12719; i <= 12720; i++) + materials[i] = Material.Peony; + for (int i = 12721; i <= 12722; i++) + materials[i] = Material.TallGrass; + for (int i = 12723; i <= 12724; i++) + materials[i] = Material.LargeFern; + for (int i = 12725; i <= 12740; i++) + materials[i] = Material.WhiteBanner; + for (int i = 12741; i <= 12756; i++) + materials[i] = Material.OrangeBanner; + for (int i = 12757; i <= 12772; i++) + materials[i] = Material.MagentaBanner; + for (int i = 12773; i <= 12788; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 12789; i <= 12804; i++) + materials[i] = Material.YellowBanner; + for (int i = 12805; i <= 12820; i++) + materials[i] = Material.LimeBanner; + for (int i = 12821; i <= 12836; i++) + materials[i] = Material.PinkBanner; + for (int i = 12837; i <= 12852; i++) + materials[i] = Material.GrayBanner; + for (int i = 12853; i <= 12868; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 12869; i <= 12884; i++) + materials[i] = Material.CyanBanner; + for (int i = 12885; i <= 12900; i++) + materials[i] = Material.PurpleBanner; + for (int i = 12901; i <= 12916; i++) + materials[i] = Material.BlueBanner; + for (int i = 12917; i <= 12932; i++) + materials[i] = Material.BrownBanner; + for (int i = 12933; i <= 12948; i++) + materials[i] = Material.GreenBanner; + for (int i = 12949; i <= 12964; i++) + materials[i] = Material.RedBanner; + for (int i = 12965; i <= 12980; i++) + materials[i] = Material.BlackBanner; + for (int i = 12981; i <= 12984; i++) + materials[i] = Material.WhiteWallBanner; + for (int i = 12985; i <= 12988; i++) + materials[i] = Material.OrangeWallBanner; + for (int i = 12989; i <= 12992; i++) + materials[i] = Material.MagentaWallBanner; + for (int i = 12993; i <= 12996; i++) + materials[i] = Material.LightBlueWallBanner; + for (int i = 12997; i <= 13000; i++) + materials[i] = Material.YellowWallBanner; + for (int i = 13001; i <= 13004; i++) + materials[i] = Material.LimeWallBanner; + for (int i = 13005; i <= 13008; i++) + materials[i] = Material.PinkWallBanner; + for (int i = 13009; i <= 13012; i++) + materials[i] = Material.GrayWallBanner; + for (int i = 13013; i <= 13016; i++) + materials[i] = Material.LightGrayWallBanner; + for (int i = 13017; i <= 13020; i++) + materials[i] = Material.CyanWallBanner; + for (int i = 13021; i <= 13024; i++) + materials[i] = Material.PurpleWallBanner; + for (int i = 13025; i <= 13028; i++) + materials[i] = Material.BlueWallBanner; + for (int i = 13029; i <= 13032; i++) + materials[i] = Material.BrownWallBanner; + for (int i = 13033; i <= 13036; i++) + materials[i] = Material.GreenWallBanner; + for (int i = 13037; i <= 13040; i++) + materials[i] = Material.RedWallBanner; + for (int i = 13041; i <= 13044; i++) + materials[i] = Material.BlackWallBanner; + for (int i = 13045; i <= 13045; i++) + materials[i] = Material.RedSandstone; + for (int i = 13046; i <= 13046; i++) + materials[i] = Material.ChiseledRedSandstone; + for (int i = 13047; i <= 13047; i++) + materials[i] = Material.CutRedSandstone; + for (int i = 13048; i <= 13127; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 13128; i <= 13133; i++) + materials[i] = Material.OakSlab; + for (int i = 13134; i <= 13139; i++) + materials[i] = Material.SpruceSlab; + for (int i = 13140; i <= 13145; i++) + materials[i] = Material.BirchSlab; + for (int i = 13146; i <= 13151; i++) + materials[i] = Material.JungleSlab; + for (int i = 13152; i <= 13157; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 13158; i <= 13163; i++) + materials[i] = Material.CherrySlab; + for (int i = 13164; i <= 13169; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 13170; i <= 13175; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 13176; i <= 13181; i++) + materials[i] = Material.MangroveSlab; + for (int i = 13182; i <= 13187; i++) + materials[i] = Material.BambooSlab; + for (int i = 13188; i <= 13193; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 13194; i <= 13199; i++) + materials[i] = Material.StoneSlab; + for (int i = 13200; i <= 13205; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13206; i <= 13211; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 13212; i <= 13217; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 13218; i <= 13223; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 13224; i <= 13229; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 13230; i <= 13235; i++) + materials[i] = Material.BrickSlab; + for (int i = 13236; i <= 13241; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 13242; i <= 13247; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 13248; i <= 13253; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 13254; i <= 13259; i++) + materials[i] = Material.QuartzSlab; + for (int i = 13260; i <= 13265; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 13266; i <= 13271; i++) + materials[i] = Material.CutRedSandstoneSlab; + for (int i = 13272; i <= 13277; i++) + materials[i] = Material.PurpurSlab; + for (int i = 13278; i <= 13278; i++) + materials[i] = Material.SmoothStone; + for (int i = 13279; i <= 13279; i++) + materials[i] = Material.SmoothSandstone; + for (int i = 13280; i <= 13280; i++) + materials[i] = Material.SmoothQuartz; + for (int i = 13281; i <= 13281; i++) + materials[i] = Material.SmoothRedSandstone; + for (int i = 13282; i <= 13313; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 13314; i <= 13345; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 13346; i <= 13377; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 13378; i <= 13409; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 13410; i <= 13441; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 13442; i <= 13473; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 13474; i <= 13505; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 13506; i <= 13537; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 13538; i <= 13569; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 13570; i <= 13601; i++) + materials[i] = Material.SpruceFence; + for (int i = 13602; i <= 13633; i++) + materials[i] = Material.BirchFence; + for (int i = 13634; i <= 13665; i++) + materials[i] = Material.JungleFence; + for (int i = 13666; i <= 13697; i++) + materials[i] = Material.AcaciaFence; + for (int i = 13698; i <= 13729; i++) + materials[i] = Material.CherryFence; + for (int i = 13730; i <= 13761; i++) + materials[i] = Material.DarkOakFence; + for (int i = 13762; i <= 13793; i++) + materials[i] = Material.PaleOakFence; + for (int i = 13794; i <= 13825; i++) + materials[i] = Material.MangroveFence; + for (int i = 13826; i <= 13857; i++) + materials[i] = Material.BambooFence; + for (int i = 13858; i <= 13921; i++) + materials[i] = Material.SpruceDoor; + for (int i = 13922; i <= 13985; i++) + materials[i] = Material.BirchDoor; + for (int i = 13986; i <= 14049; i++) + materials[i] = Material.JungleDoor; + for (int i = 14050; i <= 14113; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 14114; i <= 14177; i++) + materials[i] = Material.CherryDoor; + for (int i = 14178; i <= 14241; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 14242; i <= 14305; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 14306; i <= 14369; i++) + materials[i] = Material.MangroveDoor; + for (int i = 14370; i <= 14433; i++) + materials[i] = Material.BambooDoor; + for (int i = 14434; i <= 14439; i++) + materials[i] = Material.EndRod; + for (int i = 14440; i <= 14503; i++) + materials[i] = Material.ChorusPlant; + for (int i = 14504; i <= 14509; i++) + materials[i] = Material.ChorusFlower; + for (int i = 14510; i <= 14510; i++) + materials[i] = Material.PurpurBlock; + for (int i = 14511; i <= 14513; i++) + materials[i] = Material.PurpurPillar; + for (int i = 14514; i <= 14593; i++) + materials[i] = Material.PurpurStairs; + for (int i = 14594; i <= 14594; i++) + materials[i] = Material.EndStoneBricks; + for (int i = 14595; i <= 14596; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 14597; i <= 14606; i++) + materials[i] = Material.PitcherCrop; + for (int i = 14607; i <= 14608; i++) + materials[i] = Material.PitcherPlant; + for (int i = 14609; i <= 14612; i++) + materials[i] = Material.Beetroots; + for (int i = 14613; i <= 14613; i++) + materials[i] = Material.DirtPath; + for (int i = 14614; i <= 14614; i++) + materials[i] = Material.EndGateway; + for (int i = 14615; i <= 14626; i++) + materials[i] = Material.RepeatingCommandBlock; + for (int i = 14627; i <= 14638; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 14639; i <= 14642; i++) + materials[i] = Material.FrostedIce; + for (int i = 14643; i <= 14643; i++) + materials[i] = Material.MagmaBlock; + for (int i = 14644; i <= 14644; i++) + materials[i] = Material.NetherWartBlock; + for (int i = 14645; i <= 14645; i++) + materials[i] = Material.RedNetherBricks; + for (int i = 14646; i <= 14648; i++) + materials[i] = Material.BoneBlock; + for (int i = 14649; i <= 14649; i++) + materials[i] = Material.StructureVoid; + for (int i = 14650; i <= 14661; i++) + materials[i] = Material.Observer; + for (int i = 14662; i <= 14667; i++) + materials[i] = Material.ShulkerBox; + for (int i = 14668; i <= 14673; i++) + materials[i] = Material.WhiteShulkerBox; + for (int i = 14674; i <= 14679; i++) + materials[i] = Material.OrangeShulkerBox; + for (int i = 14680; i <= 14685; i++) + materials[i] = Material.MagentaShulkerBox; + for (int i = 14686; i <= 14691; i++) + materials[i] = Material.LightBlueShulkerBox; + for (int i = 14692; i <= 14697; i++) + materials[i] = Material.YellowShulkerBox; + for (int i = 14698; i <= 14703; i++) + materials[i] = Material.LimeShulkerBox; + for (int i = 14704; i <= 14709; i++) + materials[i] = Material.PinkShulkerBox; + for (int i = 14710; i <= 14715; i++) + materials[i] = Material.GrayShulkerBox; + for (int i = 14716; i <= 14721; i++) + materials[i] = Material.LightGrayShulkerBox; + for (int i = 14722; i <= 14727; i++) + materials[i] = Material.CyanShulkerBox; + for (int i = 14728; i <= 14733; i++) + materials[i] = Material.PurpleShulkerBox; + for (int i = 14734; i <= 14739; i++) + materials[i] = Material.BlueShulkerBox; + for (int i = 14740; i <= 14745; i++) + materials[i] = Material.BrownShulkerBox; + for (int i = 14746; i <= 14751; i++) + materials[i] = Material.GreenShulkerBox; + for (int i = 14752; i <= 14757; i++) + materials[i] = Material.RedShulkerBox; + for (int i = 14758; i <= 14763; i++) + materials[i] = Material.BlackShulkerBox; + for (int i = 14764; i <= 14767; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 14768; i <= 14771; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 14772; i <= 14775; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 14776; i <= 14779; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 14780; i <= 14783; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 14784; i <= 14787; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 14788; i <= 14791; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 14792; i <= 14795; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 14796; i <= 14799; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 14800; i <= 14803; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 14804; i <= 14807; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 14808; i <= 14811; i++) + materials[i] = Material.BlueGlazedTerracotta; + for (int i = 14812; i <= 14815; i++) + materials[i] = Material.BrownGlazedTerracotta; + for (int i = 14816; i <= 14819; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 14820; i <= 14823; i++) + materials[i] = Material.RedGlazedTerracotta; + for (int i = 14824; i <= 14827; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 14828; i <= 14828; i++) + materials[i] = Material.WhiteConcrete; + for (int i = 14829; i <= 14829; i++) + materials[i] = Material.OrangeConcrete; + for (int i = 14830; i <= 14830; i++) + materials[i] = Material.MagentaConcrete; + for (int i = 14831; i <= 14831; i++) + materials[i] = Material.LightBlueConcrete; + for (int i = 14832; i <= 14832; i++) + materials[i] = Material.YellowConcrete; + for (int i = 14833; i <= 14833; i++) + materials[i] = Material.LimeConcrete; + for (int i = 14834; i <= 14834; i++) + materials[i] = Material.PinkConcrete; + for (int i = 14835; i <= 14835; i++) + materials[i] = Material.GrayConcrete; + for (int i = 14836; i <= 14836; i++) + materials[i] = Material.LightGrayConcrete; + for (int i = 14837; i <= 14837; i++) + materials[i] = Material.CyanConcrete; + for (int i = 14838; i <= 14838; i++) + materials[i] = Material.PurpleConcrete; + for (int i = 14839; i <= 14839; i++) + materials[i] = Material.BlueConcrete; + for (int i = 14840; i <= 14840; i++) + materials[i] = Material.BrownConcrete; + for (int i = 14841; i <= 14841; i++) + materials[i] = Material.GreenConcrete; + for (int i = 14842; i <= 14842; i++) + materials[i] = Material.RedConcrete; + for (int i = 14843; i <= 14843; i++) + materials[i] = Material.BlackConcrete; + for (int i = 14844; i <= 14844; i++) + materials[i] = Material.WhiteConcretePowder; + for (int i = 14845; i <= 14845; i++) + materials[i] = Material.OrangeConcretePowder; + for (int i = 14846; i <= 14846; i++) + materials[i] = Material.MagentaConcretePowder; + for (int i = 14847; i <= 14847; i++) + materials[i] = Material.LightBlueConcretePowder; + for (int i = 14848; i <= 14848; i++) + materials[i] = Material.YellowConcretePowder; + for (int i = 14849; i <= 14849; i++) + materials[i] = Material.LimeConcretePowder; + for (int i = 14850; i <= 14850; i++) + materials[i] = Material.PinkConcretePowder; + for (int i = 14851; i <= 14851; i++) + materials[i] = Material.GrayConcretePowder; + for (int i = 14852; i <= 14852; i++) + materials[i] = Material.LightGrayConcretePowder; + for (int i = 14853; i <= 14853; i++) + materials[i] = Material.CyanConcretePowder; + for (int i = 14854; i <= 14854; i++) + materials[i] = Material.PurpleConcretePowder; + for (int i = 14855; i <= 14855; i++) + materials[i] = Material.BlueConcretePowder; + for (int i = 14856; i <= 14856; i++) + materials[i] = Material.BrownConcretePowder; + for (int i = 14857; i <= 14857; i++) + materials[i] = Material.GreenConcretePowder; + for (int i = 14858; i <= 14858; i++) + materials[i] = Material.RedConcretePowder; + for (int i = 14859; i <= 14859; i++) + materials[i] = Material.BlackConcretePowder; + for (int i = 14860; i <= 14885; i++) + materials[i] = Material.Kelp; + for (int i = 14886; i <= 14886; i++) + materials[i] = Material.KelpPlant; + for (int i = 14887; i <= 14887; i++) + materials[i] = Material.DriedKelpBlock; + for (int i = 14888; i <= 14899; i++) + materials[i] = Material.TurtleEgg; + for (int i = 14900; i <= 14902; i++) + materials[i] = Material.SnifferEgg; + for (int i = 14903; i <= 14934; i++) + materials[i] = Material.DriedGhast; + for (int i = 14935; i <= 14935; i++) + materials[i] = Material.DeadTubeCoralBlock; + for (int i = 14936; i <= 14936; i++) + materials[i] = Material.DeadBrainCoralBlock; + for (int i = 14937; i <= 14937; i++) + materials[i] = Material.DeadBubbleCoralBlock; + for (int i = 14938; i <= 14938; i++) + materials[i] = Material.DeadFireCoralBlock; + for (int i = 14939; i <= 14939; i++) + materials[i] = Material.DeadHornCoralBlock; + for (int i = 14940; i <= 14940; i++) + materials[i] = Material.TubeCoralBlock; + for (int i = 14941; i <= 14941; i++) + materials[i] = Material.BrainCoralBlock; + for (int i = 14942; i <= 14942; i++) + materials[i] = Material.BubbleCoralBlock; + for (int i = 14943; i <= 14943; i++) + materials[i] = Material.FireCoralBlock; + for (int i = 14944; i <= 14944; i++) + materials[i] = Material.HornCoralBlock; + for (int i = 14945; i <= 14946; i++) + materials[i] = Material.DeadTubeCoral; + for (int i = 14947; i <= 14948; i++) + materials[i] = Material.DeadBrainCoral; + for (int i = 14949; i <= 14950; i++) + materials[i] = Material.DeadBubbleCoral; + for (int i = 14951; i <= 14952; i++) + materials[i] = Material.DeadFireCoral; + for (int i = 14953; i <= 14954; i++) + materials[i] = Material.DeadHornCoral; + for (int i = 14955; i <= 14956; i++) + materials[i] = Material.TubeCoral; + for (int i = 14957; i <= 14958; i++) + materials[i] = Material.BrainCoral; + for (int i = 14959; i <= 14960; i++) + materials[i] = Material.BubbleCoral; + for (int i = 14961; i <= 14962; i++) + materials[i] = Material.FireCoral; + for (int i = 14963; i <= 14964; i++) + materials[i] = Material.HornCoral; + for (int i = 14965; i <= 14966; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 14967; i <= 14968; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 14969; i <= 14970; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 14971; i <= 14972; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 14973; i <= 14974; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 14975; i <= 14976; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 14977; i <= 14978; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 14979; i <= 14980; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 14981; i <= 14982; i++) + materials[i] = Material.FireCoralFan; + for (int i = 14983; i <= 14984; i++) + materials[i] = Material.HornCoralFan; + for (int i = 14985; i <= 14992; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 14993; i <= 15000; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 15001; i <= 15008; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + for (int i = 15009; i <= 15016; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 15017; i <= 15024; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 15025; i <= 15032; i++) + materials[i] = Material.TubeCoralWallFan; + for (int i = 15033; i <= 15040; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 15041; i <= 15048; i++) + materials[i] = Material.BubbleCoralWallFan; + for (int i = 15049; i <= 15056; i++) + materials[i] = Material.FireCoralWallFan; + for (int i = 15057; i <= 15064; i++) + materials[i] = Material.HornCoralWallFan; + for (int i = 15065; i <= 15072; i++) + materials[i] = Material.SeaPickle; + for (int i = 15073; i <= 15073; i++) + materials[i] = Material.BlueIce; + for (int i = 15074; i <= 15075; i++) + materials[i] = Material.Conduit; + for (int i = 15076; i <= 15076; i++) + materials[i] = Material.BambooSapling; + for (int i = 15077; i <= 15088; i++) + materials[i] = Material.Bamboo; + for (int i = 15089; i <= 15089; i++) + materials[i] = Material.PottedBamboo; + for (int i = 15090; i <= 15090; i++) + materials[i] = Material.VoidAir; + for (int i = 15091; i <= 15091; i++) + materials[i] = Material.CaveAir; + for (int i = 15092; i <= 15093; i++) + materials[i] = Material.BubbleColumn; + for (int i = 15094; i <= 15173; i++) + materials[i] = Material.PolishedGraniteStairs; + for (int i = 15174; i <= 15253; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + for (int i = 15254; i <= 15333; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 15334; i <= 15413; i++) + materials[i] = Material.PolishedDioriteStairs; + for (int i = 15414; i <= 15493; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 15494; i <= 15573; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 15574; i <= 15653; i++) + materials[i] = Material.StoneStairs; + for (int i = 15654; i <= 15733; i++) + materials[i] = Material.SmoothSandstoneStairs; + for (int i = 15734; i <= 15813; i++) + materials[i] = Material.SmoothQuartzStairs; + for (int i = 15814; i <= 15893; i++) + materials[i] = Material.GraniteStairs; + for (int i = 15894; i <= 15973; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 15974; i <= 16053; i++) + materials[i] = Material.RedNetherBrickStairs; for (int i = 16054; i <= 16133; i++) materials[i] = Material.PolishedAndesiteStairs; - for (int i = 6802; i <= 6804; i++) - materials[i] = Material.PolishedBasalt; - materials[22040] = Material.PolishedBlackstone; + for (int i = 16134; i <= 16213; i++) + materials[i] = Material.DioriteStairs; + for (int i = 16214; i <= 16219; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 16220; i <= 16225; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 16226; i <= 16231; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 16232; i <= 16237; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 16238; i <= 16243; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 16244; i <= 16249; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 16250; i <= 16255; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 16256; i <= 16261; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 16262; i <= 16267; i++) + materials[i] = Material.GraniteSlab; + for (int i = 16268; i <= 16273; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 16274; i <= 16279; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 16280; i <= 16285; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 16286; i <= 16291; i++) + materials[i] = Material.DioriteSlab; + for (int i = 16292; i <= 16615; i++) + materials[i] = Material.BrickWall; + for (int i = 16616; i <= 16939; i++) + materials[i] = Material.PrismarineWall; + for (int i = 16940; i <= 17263; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 17264; i <= 17587; i++) + materials[i] = Material.MossyStoneBrickWall; + for (int i = 17588; i <= 17911; i++) + materials[i] = Material.GraniteWall; + for (int i = 17912; i <= 18235; i++) + materials[i] = Material.StoneBrickWall; + for (int i = 18236; i <= 18559; i++) + materials[i] = Material.MudBrickWall; + for (int i = 18560; i <= 18883; i++) + materials[i] = Material.NetherBrickWall; + for (int i = 18884; i <= 19207; i++) + materials[i] = Material.AndesiteWall; + for (int i = 19208; i <= 19531; i++) + materials[i] = Material.RedNetherBrickWall; + for (int i = 19532; i <= 19855; i++) + materials[i] = Material.SandstoneWall; + for (int i = 19856; i <= 20179; i++) + materials[i] = Material.EndStoneBrickWall; + for (int i = 20180; i <= 20503; i++) + materials[i] = Material.DioriteWall; + for (int i = 20504; i <= 20535; i++) + materials[i] = Material.Scaffolding; + for (int i = 20536; i <= 20539; i++) + materials[i] = Material.Loom; + for (int i = 20540; i <= 20551; i++) + materials[i] = Material.Barrel; + for (int i = 20552; i <= 20559; i++) + materials[i] = Material.Smoker; + for (int i = 20560; i <= 20567; i++) + materials[i] = Material.BlastFurnace; + for (int i = 20568; i <= 20568; i++) + materials[i] = Material.CartographyTable; + for (int i = 20569; i <= 20569; i++) + materials[i] = Material.FletchingTable; + for (int i = 20570; i <= 20581; i++) + materials[i] = Material.Grindstone; + for (int i = 20582; i <= 20597; i++) + materials[i] = Material.Lectern; + for (int i = 20598; i <= 20598; i++) + materials[i] = Material.SmithingTable; + for (int i = 20599; i <= 20602; i++) + materials[i] = Material.Stonecutter; + for (int i = 20603; i <= 20634; i++) + materials[i] = Material.Bell; + for (int i = 20635; i <= 20638; i++) + materials[i] = Material.Lantern; + for (int i = 20639; i <= 20642; i++) + materials[i] = Material.SoulLantern; + for (int i = 20643; i <= 20646; i++) + materials[i] = Material.CopperLantern; + for (int i = 20647; i <= 20650; i++) + materials[i] = Material.ExposedCopperLantern; + for (int i = 20651; i <= 20654; i++) + materials[i] = Material.WeatheredCopperLantern; + for (int i = 20655; i <= 20658; i++) + materials[i] = Material.OxidizedCopperLantern; + for (int i = 20659; i <= 20662; i++) + materials[i] = Material.WaxedCopperLantern; + for (int i = 20663; i <= 20666; i++) + materials[i] = Material.WaxedExposedCopperLantern; + for (int i = 20667; i <= 20670; i++) + materials[i] = Material.WaxedWeatheredCopperLantern; + for (int i = 20671; i <= 20674; i++) + materials[i] = Material.WaxedOxidizedCopperLantern; + for (int i = 20675; i <= 20706; i++) + materials[i] = Material.Campfire; + for (int i = 20707; i <= 20738; i++) + materials[i] = Material.SoulCampfire; + for (int i = 20739; i <= 20742; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 20743; i <= 20745; i++) + materials[i] = Material.WarpedStem; + for (int i = 20746; i <= 20748; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 20749; i <= 20751; i++) + materials[i] = Material.WarpedHyphae; + for (int i = 20752; i <= 20754; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 20755; i <= 20755; i++) + materials[i] = Material.WarpedNylium; + for (int i = 20756; i <= 20756; i++) + materials[i] = Material.WarpedFungus; + for (int i = 20757; i <= 20757; i++) + materials[i] = Material.WarpedWartBlock; + for (int i = 20758; i <= 20758; i++) + materials[i] = Material.WarpedRoots; + for (int i = 20759; i <= 20759; i++) + materials[i] = Material.NetherSprouts; + for (int i = 20760; i <= 20762; i++) + materials[i] = Material.CrimsonStem; + for (int i = 20763; i <= 20765; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 20766; i <= 20768; i++) + materials[i] = Material.CrimsonHyphae; + for (int i = 20769; i <= 20771; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 20772; i <= 20772; i++) + materials[i] = Material.CrimsonNylium; + for (int i = 20773; i <= 20773; i++) + materials[i] = Material.CrimsonFungus; + for (int i = 20774; i <= 20774; i++) + materials[i] = Material.Shroomlight; + for (int i = 20775; i <= 20800; i++) + materials[i] = Material.WeepingVines; + for (int i = 20801; i <= 20801; i++) + materials[i] = Material.WeepingVinesPlant; + for (int i = 20802; i <= 20827; i++) + materials[i] = Material.TwistingVines; + for (int i = 20828; i <= 20828; i++) + materials[i] = Material.TwistingVinesPlant; + for (int i = 20829; i <= 20829; i++) + materials[i] = Material.CrimsonRoots; + for (int i = 20830; i <= 20830; i++) + materials[i] = Material.CrimsonPlanks; + for (int i = 20831; i <= 20831; i++) + materials[i] = Material.WarpedPlanks; + for (int i = 20832; i <= 20837; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 20838; i <= 20843; i++) + materials[i] = Material.WarpedSlab; + for (int i = 20844; i <= 20845; i++) + materials[i] = Material.CrimsonPressurePlate; + for (int i = 20846; i <= 20847; i++) + materials[i] = Material.WarpedPressurePlate; + for (int i = 20848; i <= 20879; i++) + materials[i] = Material.CrimsonFence; + for (int i = 20880; i <= 20911; i++) + materials[i] = Material.WarpedFence; + for (int i = 20912; i <= 20975; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 20976; i <= 21039; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 21040; i <= 21071; i++) + materials[i] = Material.CrimsonFenceGate; + for (int i = 21072; i <= 21103; i++) + materials[i] = Material.WarpedFenceGate; + for (int i = 21104; i <= 21183; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 21184; i <= 21263; i++) + materials[i] = Material.WarpedStairs; + for (int i = 21264; i <= 21287; i++) + materials[i] = Material.CrimsonButton; + for (int i = 21288; i <= 21311; i++) + materials[i] = Material.WarpedButton; + for (int i = 21312; i <= 21375; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 21376; i <= 21439; i++) + materials[i] = Material.WarpedDoor; + for (int i = 21440; i <= 21471; i++) + materials[i] = Material.CrimsonSign; + for (int i = 21472; i <= 21503; i++) + materials[i] = Material.WarpedSign; + for (int i = 21504; i <= 21511; i++) + materials[i] = Material.CrimsonWallSign; + for (int i = 21512; i <= 21519; i++) + materials[i] = Material.WarpedWallSign; + for (int i = 21520; i <= 21523; i++) + materials[i] = Material.StructureBlock; + for (int i = 21524; i <= 21535; i++) + materials[i] = Material.Jigsaw; + for (int i = 21536; i <= 21539; i++) + materials[i] = Material.TestBlock; + for (int i = 21540; i <= 21540; i++) + materials[i] = Material.TestInstanceBlock; + for (int i = 21541; i <= 21549; i++) + materials[i] = Material.Composter; + for (int i = 21550; i <= 21565; i++) + materials[i] = Material.Target; + for (int i = 21566; i <= 21589; i++) + materials[i] = Material.BeeNest; + for (int i = 21590; i <= 21613; i++) + materials[i] = Material.Beehive; + for (int i = 21614; i <= 21614; i++) + materials[i] = Material.HoneyBlock; + for (int i = 21615; i <= 21615; i++) + materials[i] = Material.HoneycombBlock; + for (int i = 21616; i <= 21616; i++) + materials[i] = Material.NetheriteBlock; + for (int i = 21617; i <= 21617; i++) + materials[i] = Material.AncientDebris; + for (int i = 21618; i <= 21618; i++) + materials[i] = Material.CryingObsidian; + for (int i = 21619; i <= 21623; i++) + materials[i] = Material.RespawnAnchor; + for (int i = 21624; i <= 21624; i++) + materials[i] = Material.PottedCrimsonFungus; + for (int i = 21625; i <= 21625; i++) + materials[i] = Material.PottedWarpedFungus; + for (int i = 21626; i <= 21626; i++) + materials[i] = Material.PottedCrimsonRoots; + for (int i = 21627; i <= 21627; i++) + materials[i] = Material.PottedWarpedRoots; + for (int i = 21628; i <= 21628; i++) + materials[i] = Material.Lodestone; + for (int i = 21629; i <= 21629; i++) + materials[i] = Material.Blackstone; + for (int i = 21630; i <= 21709; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 21710; i <= 22033; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 22034; i <= 22039; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 22040; i <= 22040; i++) + materials[i] = Material.PolishedBlackstone; + for (int i = 22041; i <= 22041; i++) + materials[i] = Material.PolishedBlackstoneBricks; + for (int i = 22042; i <= 22042; i++) + materials[i] = Material.CrackedPolishedBlackstoneBricks; + for (int i = 22043; i <= 22043; i++) + materials[i] = Material.ChiseledPolishedBlackstone; for (int i = 22044; i <= 22049; i++) materials[i] = Material.PolishedBlackstoneBrickSlab; for (int i = 22050; i <= 22129; i++) materials[i] = Material.PolishedBlackstoneBrickStairs; for (int i = 22130; i <= 22453; i++) materials[i] = Material.PolishedBlackstoneBrickWall; - materials[22041] = Material.PolishedBlackstoneBricks; - for (int i = 22543; i <= 22566; i++) - materials[i] = Material.PolishedBlackstoneButton; - for (int i = 22541; i <= 22542; i++) - materials[i] = Material.PolishedBlackstonePressurePlate; - for (int i = 22535; i <= 22540; i++) - materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 22454; i <= 22454; i++) + materials[i] = Material.GildedBlackstone; for (int i = 22455; i <= 22534; i++) materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 22535; i <= 22540; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 22541; i <= 22542; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 22543; i <= 22566; i++) + materials[i] = Material.PolishedBlackstoneButton; for (int i = 22567; i <= 22890; i++) materials[i] = Material.PolishedBlackstoneWall; - materials[28135] = Material.PolishedDeepslate; - for (int i = 28216; i <= 28221; i++) - materials[i] = Material.PolishedDeepslateSlab; - for (int i = 28136; i <= 28215; i++) - materials[i] = Material.PolishedDeepslateStairs; - for (int i = 28222; i <= 28545; i++) - materials[i] = Material.PolishedDeepslateWall; - materials[5] = Material.PolishedDiorite; - for (int i = 16232; i <= 16237; i++) - materials[i] = Material.PolishedDioriteSlab; - for (int i = 15334; i <= 15413; i++) - materials[i] = Material.PolishedDioriteStairs; - materials[3] = Material.PolishedGranite; - for (int i = 16214; i <= 16219; i++) - materials[i] = Material.PolishedGraniteSlab; - for (int i = 15094; i <= 15173; i++) - materials[i] = Material.PolishedGraniteStairs; - materials[23661] = Material.PolishedTuff; - for (int i = 23662; i <= 23667; i++) - materials[i] = Material.PolishedTuffSlab; - for (int i = 23668; i <= 23747; i++) - materials[i] = Material.PolishedTuffStairs; - for (int i = 23748; i <= 24071; i++) - materials[i] = Material.PolishedTuffWall; - materials[2123] = Material.Poppy; - for (int i = 10465; i <= 10472; i++) - materials[i] = Material.Potatoes; - materials[10434] = Material.PottedAcaciaSapling; - materials[10443] = Material.PottedAllium; - materials[29378] = Material.PottedAzaleaBush; - materials[10444] = Material.PottedAzureBluet; - materials[15089] = Material.PottedBamboo; - materials[10432] = Material.PottedBirchSapling; - materials[10442] = Material.PottedBlueOrchid; - materials[10454] = Material.PottedBrownMushroom; - materials[10456] = Material.PottedCactus; - materials[10435] = Material.PottedCherrySapling; - materials[29669] = Material.PottedClosedEyeblossom; - materials[10450] = Material.PottedCornflower; - materials[21624] = Material.PottedCrimsonFungus; - materials[21626] = Material.PottedCrimsonRoots; - materials[10440] = Material.PottedDandelion; - materials[10436] = Material.PottedDarkOakSapling; - materials[10455] = Material.PottedDeadBush; - materials[10439] = Material.PottedFern; - materials[29379] = Material.PottedFloweringAzaleaBush; - materials[10433] = Material.PottedJungleSapling; - materials[10451] = Material.PottedLilyOfTheValley; - materials[10438] = Material.PottedMangrovePropagule; - materials[10430] = Material.PottedOakSapling; - materials[29668] = Material.PottedOpenEyeblossom; - materials[10446] = Material.PottedOrangeTulip; - materials[10449] = Material.PottedOxeyeDaisy; - materials[10437] = Material.PottedPaleOakSapling; - materials[10448] = Material.PottedPinkTulip; - materials[10441] = Material.PottedPoppy; - materials[10453] = Material.PottedRedMushroom; - materials[10445] = Material.PottedRedTulip; - materials[10431] = Material.PottedSpruceSapling; - materials[10429] = Material.PottedTorchflower; - materials[21625] = Material.PottedWarpedFungus; - materials[21627] = Material.PottedWarpedRoots; - materials[10447] = Material.PottedWhiteTulip; - materials[10452] = Material.PottedWitherRose; - materials[24487] = Material.PowderSnow; - for (int i = 9264; i <= 9266; i++) - materials[i] = Material.PowderSnowCauldron; - for (int i = 1987; i <= 2010; i++) - materials[i] = Material.PoweredRail; - materials[12429] = Material.Prismarine; - for (int i = 12678; i <= 12683; i++) - materials[i] = Material.PrismarineBrickSlab; - for (int i = 12512; i <= 12591; i++) - materials[i] = Material.PrismarineBrickStairs; - materials[12430] = Material.PrismarineBricks; - for (int i = 12672; i <= 12677; i++) - materials[i] = Material.PrismarineSlab; - for (int i = 12432; i <= 12511; i++) - materials[i] = Material.PrismarineStairs; - for (int i = 16616; i <= 16939; i++) - materials[i] = Material.PrismarineWall; - materials[8131] = Material.Pumpkin; - for (int i = 8141; i <= 8148; i++) - materials[i] = Material.PumpkinStem; - for (int i = 12885; i <= 12900; i++) - materials[i] = Material.PurpleBanner; - for (int i = 1891; i <= 1906; i++) - materials[i] = Material.PurpleBed; + for (int i = 22891; i <= 22891; i++) + materials[i] = Material.ChiseledNetherBricks; + for (int i = 22892; i <= 22892; i++) + materials[i] = Material.CrackedNetherBricks; + for (int i = 22893; i <= 22893; i++) + materials[i] = Material.QuartzBricks; + for (int i = 22894; i <= 22909; i++) + materials[i] = Material.Candle; + for (int i = 22910; i <= 22925; i++) + materials[i] = Material.WhiteCandle; + for (int i = 22926; i <= 22941; i++) + materials[i] = Material.OrangeCandle; + for (int i = 22942; i <= 22957; i++) + materials[i] = Material.MagentaCandle; + for (int i = 22958; i <= 22973; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 22974; i <= 22989; i++) + materials[i] = Material.YellowCandle; + for (int i = 22990; i <= 23005; i++) + materials[i] = Material.LimeCandle; + for (int i = 23006; i <= 23021; i++) + materials[i] = Material.PinkCandle; + for (int i = 23022; i <= 23037; i++) + materials[i] = Material.GrayCandle; + for (int i = 23038; i <= 23053; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 23054; i <= 23069; i++) + materials[i] = Material.CyanCandle; for (int i = 23070; i <= 23085; i++) materials[i] = Material.PurpleCandle; - for (int i = 23188; i <= 23189; i++) - materials[i] = Material.PurpleCandleCake; - materials[12704] = Material.PurpleCarpet; - materials[14838] = Material.PurpleConcrete; - materials[14854] = Material.PurpleConcretePowder; - for (int i = 14804; i <= 14807; i++) - materials[i] = Material.PurpleGlazedTerracotta; - for (int i = 14728; i <= 14733; i++) - materials[i] = Material.PurpleShulkerBox; - materials[6907] = Material.PurpleStainedGlass; - for (int i = 11578; i <= 11609; i++) - materials[i] = Material.PurpleStainedGlassPane; - materials[11252] = Material.PurpleTerracotta; - for (int i = 13021; i <= 13024; i++) - materials[i] = Material.PurpleWallBanner; - materials[2103] = Material.PurpleWool; - materials[14510] = Material.PurpurBlock; - for (int i = 14511; i <= 14513; i++) - materials[i] = Material.PurpurPillar; - for (int i = 13272; i <= 13277; i++) - materials[i] = Material.PurpurSlab; - for (int i = 14514; i <= 14593; i++) - materials[i] = Material.PurpurStairs; - materials[11121] = Material.QuartzBlock; - materials[22893] = Material.QuartzBricks; - for (int i = 11123; i <= 11125; i++) - materials[i] = Material.QuartzPillar; - for (int i = 13254; i <= 13259; i++) - materials[i] = Material.QuartzSlab; - for (int i = 11126; i <= 11205; i++) - materials[i] = Material.QuartzStairs; - for (int i = 5526; i <= 5545; i++) - materials[i] = Material.Rail; - materials[29376] = Material.RawCopperBlock; - materials[29377] = Material.RawGoldBlock; - materials[29375] = Material.RawIronBlock; - for (int i = 12949; i <= 12964; i++) - materials[i] = Material.RedBanner; - for (int i = 1955; i <= 1970; i++) - materials[i] = Material.RedBed; + for (int i = 23086; i <= 23101; i++) + materials[i] = Material.BlueCandle; + for (int i = 23102; i <= 23117; i++) + materials[i] = Material.BrownCandle; + for (int i = 23118; i <= 23133; i++) + materials[i] = Material.GreenCandle; for (int i = 23134; i <= 23149; i++) materials[i] = Material.RedCandle; + for (int i = 23150; i <= 23165; i++) + materials[i] = Material.BlackCandle; + for (int i = 23166; i <= 23167; i++) + materials[i] = Material.CandleCake; + for (int i = 23168; i <= 23169; i++) + materials[i] = Material.WhiteCandleCake; + for (int i = 23170; i <= 23171; i++) + materials[i] = Material.OrangeCandleCake; + for (int i = 23172; i <= 23173; i++) + materials[i] = Material.MagentaCandleCake; + for (int i = 23174; i <= 23175; i++) + materials[i] = Material.LightBlueCandleCake; + for (int i = 23176; i <= 23177; i++) + materials[i] = Material.YellowCandleCake; + for (int i = 23178; i <= 23179; i++) + materials[i] = Material.LimeCandleCake; + for (int i = 23180; i <= 23181; i++) + materials[i] = Material.PinkCandleCake; + for (int i = 23182; i <= 23183; i++) + materials[i] = Material.GrayCandleCake; + for (int i = 23184; i <= 23185; i++) + materials[i] = Material.LightGrayCandleCake; + for (int i = 23186; i <= 23187; i++) + materials[i] = Material.CyanCandleCake; + for (int i = 23188; i <= 23189; i++) + materials[i] = Material.PurpleCandleCake; + for (int i = 23190; i <= 23191; i++) + materials[i] = Material.BlueCandleCake; + for (int i = 23192; i <= 23193; i++) + materials[i] = Material.BrownCandleCake; + for (int i = 23194; i <= 23195; i++) + materials[i] = Material.GreenCandleCake; for (int i = 23196; i <= 23197; i++) materials[i] = Material.RedCandleCake; - materials[12708] = Material.RedCarpet; - materials[14842] = Material.RedConcrete; - materials[14858] = Material.RedConcretePowder; - for (int i = 14820; i <= 14823; i++) - materials[i] = Material.RedGlazedTerracotta; - materials[2136] = Material.RedMushroom; - for (int i = 7629; i <= 7692; i++) - materials[i] = Material.RedMushroomBlock; - for (int i = 16274; i <= 16279; i++) - materials[i] = Material.RedNetherBrickSlab; - for (int i = 15974; i <= 16053; i++) - materials[i] = Material.RedNetherBrickStairs; - for (int i = 19208; i <= 19531; i++) - materials[i] = Material.RedNetherBrickWall; - materials[14645] = Material.RedNetherBricks; - materials[123] = Material.RedSand; - materials[13045] = Material.RedSandstone; - for (int i = 13260; i <= 13265; i++) - materials[i] = Material.RedSandstoneSlab; - for (int i = 13048; i <= 13127; i++) - materials[i] = Material.RedSandstoneStairs; - for (int i = 16940; i <= 17263; i++) - materials[i] = Material.RedSandstoneWall; - for (int i = 14752; i <= 14757; i++) - materials[i] = Material.RedShulkerBox; - materials[6911] = Material.RedStainedGlass; - for (int i = 11706; i <= 11737; i++) - materials[i] = Material.RedStainedGlassPane; - materials[11256] = Material.RedTerracotta; - materials[2127] = Material.RedTulip; - for (int i = 13037; i <= 13040; i++) - materials[i] = Material.RedWallBanner; - materials[2107] = Material.RedWool; - materials[11109] = Material.RedstoneBlock; - for (int i = 9278; i <= 9279; i++) - materials[i] = Material.RedstoneLamp; - for (int i = 6680; i <= 6681; i++) - materials[i] = Material.RedstoneOre; - for (int i = 6684; i <= 6685; i++) - materials[i] = Material.RedstoneTorch; - for (int i = 6686; i <= 6693; i++) - materials[i] = Material.RedstoneWallTorch; - for (int i = 3810; i <= 5105; i++) - materials[i] = Material.RedstoneWire; - materials[29390] = Material.ReinforcedDeepslate; - for (int i = 6833; i <= 6896; i++) - materials[i] = Material.Repeater; - for (int i = 14615; i <= 14626; i++) - materials[i] = Material.RepeatingCommandBlock; - materials[8720] = Material.ResinBlock; - for (int i = 8802; i <= 8807; i++) - materials[i] = Material.ResinBrickSlab; - for (int i = 8722; i <= 8801; i++) - materials[i] = Material.ResinBrickStairs; - for (int i = 8808; i <= 9131; i++) - materials[i] = Material.ResinBrickWall; - materials[8721] = Material.ResinBricks; - for (int i = 8317; i <= 8444; i++) - materials[i] = Material.ResinClump; - for (int i = 21619; i <= 21623; i++) - materials[i] = Material.RespawnAnchor; - materials[27719] = Material.RootedDirt; - for (int i = 12717; i <= 12718; i++) - materials[i] = Material.RoseBush; - materials[118] = Material.Sand; - materials[578] = Material.Sandstone; - for (int i = 13206; i <= 13211; i++) - materials[i] = Material.SandstoneSlab; - for (int i = 9292; i <= 9371; i++) - materials[i] = Material.SandstoneStairs; - for (int i = 19532; i <= 19855; i++) - materials[i] = Material.SandstoneWall; - for (int i = 20504; i <= 20535; i++) - materials[i] = Material.Scaffolding; - materials[24968] = Material.Sculk; - for (int i = 25097; i <= 25098; i++) - materials[i] = Material.SculkCatalyst; - for (int i = 24488; i <= 24583; i++) - materials[i] = Material.SculkSensor; - for (int i = 25099; i <= 25106; i++) - materials[i] = Material.SculkShrieker; - for (int i = 24969; i <= 25096; i++) - materials[i] = Material.SculkVein; - materials[12690] = Material.SeaLantern; - for (int i = 15065; i <= 15072; i++) - materials[i] = Material.SeaPickle; - materials[2054] = Material.Seagrass; - materials[2052] = Material.ShortDryGrass; - materials[2048] = Material.ShortGrass; - materials[20774] = Material.Shroomlight; - for (int i = 14662; i <= 14667; i++) - materials[i] = Material.ShulkerBox; - for (int i = 10713; i <= 10744; i++) - materials[i] = Material.SkeletonSkull; - for (int i = 10745; i <= 10752; i++) - materials[i] = Material.SkeletonWallSkull; - materials[12330] = Material.SlimeBlock; + for (int i = 23198; i <= 23199; i++) + materials[i] = Material.BlackCandleCake; + for (int i = 23200; i <= 23200; i++) + materials[i] = Material.AmethystBlock; + for (int i = 23201; i <= 23201; i++) + materials[i] = Material.BuddingAmethyst; + for (int i = 23202; i <= 23213; i++) + materials[i] = Material.AmethystCluster; + for (int i = 23214; i <= 23225; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 23226; i <= 23237; i++) + materials[i] = Material.MediumAmethystBud; for (int i = 23238; i <= 23249; i++) materials[i] = Material.SmallAmethystBud; - for (int i = 27701; i <= 27716; i++) - materials[i] = Material.SmallDripleaf; - materials[20598] = Material.SmithingTable; - for (int i = 20552; i <= 20559; i++) - materials[i] = Material.Smoker; - materials[29374] = Material.SmoothBasalt; - materials[13280] = Material.SmoothQuartz; - for (int i = 16256; i <= 16261; i++) - materials[i] = Material.SmoothQuartzSlab; - for (int i = 15734; i <= 15813; i++) - materials[i] = Material.SmoothQuartzStairs; - materials[13281] = Material.SmoothRedSandstone; - for (int i = 16220; i <= 16225; i++) - materials[i] = Material.SmoothRedSandstoneSlab; - for (int i = 15174; i <= 15253; i++) - materials[i] = Material.SmoothRedSandstoneStairs; - materials[13279] = Material.SmoothSandstone; - for (int i = 16250; i <= 16255; i++) - materials[i] = Material.SmoothSandstoneSlab; - for (int i = 15654; i <= 15733; i++) - materials[i] = Material.SmoothSandstoneStairs; - materials[13278] = Material.SmoothStone; - for (int i = 13200; i <= 13205; i++) - materials[i] = Material.SmoothStoneSlab; - for (int i = 14900; i <= 14902; i++) - materials[i] = Material.SnifferEgg; - for (int i = 6718; i <= 6725; i++) - materials[i] = Material.Snow; - materials[6727] = Material.SnowBlock; - for (int i = 20707; i <= 20738; i++) - materials[i] = Material.SoulCampfire; - materials[3686] = Material.SoulFire; - for (int i = 20639; i <= 20642; i++) - materials[i] = Material.SoulLantern; - materials[6797] = Material.SoulSand; - materials[6798] = Material.SoulSoil; - materials[6805] = Material.SoulTorch; - for (int i = 6806; i <= 6809; i++) - materials[i] = Material.SoulWallTorch; - materials[3687] = Material.Spawner; - materials[560] = Material.Sponge; - materials[27608] = Material.SporeBlossom; - for (int i = 10497; i <= 10520; i++) - materials[i] = Material.SpruceButton; - for (int i = 13858; i <= 13921; i++) - materials[i] = Material.SpruceDoor; - for (int i = 13570; i <= 13601; i++) - materials[i] = Material.SpruceFence; - for (int i = 13282; i <= 13313; i++) - materials[i] = Material.SpruceFenceGate; - for (int i = 5770; i <= 5833; i++) - materials[i] = Material.SpruceHangingSign; - for (int i = 280; i <= 307; i++) - materials[i] = Material.SpruceLeaves; - for (int i = 139; i <= 141; i++) - materials[i] = Material.SpruceLog; - materials[16] = Material.SprucePlanks; - for (int i = 6662; i <= 6663; i++) - materials[i] = Material.SprucePressurePlate; - for (int i = 31; i <= 32; i++) - materials[i] = Material.SpruceSapling; - for (int i = 3039; i <= 3102; i++) - materials[i] = Material.SpruceShelf; - for (int i = 5166; i <= 5197; i++) - materials[i] = Material.SpruceSign; - for (int i = 13134; i <= 13139; i++) - materials[i] = Material.SpruceSlab; - for (int i = 9527; i <= 9606; i++) - materials[i] = Material.SpruceStairs; - for (int i = 6977; i <= 7040; i++) - materials[i] = Material.SpruceTrapdoor; - for (int i = 6482; i <= 6489; i++) - materials[i] = Material.SpruceWallHangingSign; - for (int i = 5634; i <= 5641; i++) - materials[i] = Material.SpruceWallSign; - for (int i = 204; i <= 206; i++) - materials[i] = Material.SpruceWood; - for (int i = 2035; i <= 2046; i++) - materials[i] = Material.StickyPiston; - materials[1] = Material.Stone; - for (int i = 13236; i <= 13241; i++) - materials[i] = Material.StoneBrickSlab; - for (int i = 8557; i <= 8636; i++) - materials[i] = Material.StoneBrickStairs; - for (int i = 17912; i <= 18235; i++) - materials[i] = Material.StoneBrickWall; - materials[7553] = Material.StoneBricks; - for (int i = 6694; i <= 6717; i++) - materials[i] = Material.StoneButton; - for (int i = 6594; i <= 6595; i++) - materials[i] = Material.StonePressurePlate; - for (int i = 13194; i <= 13199; i++) - materials[i] = Material.StoneSlab; - for (int i = 15574; i <= 15653; i++) - materials[i] = Material.StoneStairs; - for (int i = 20599; i <= 20602; i++) - materials[i] = Material.Stonecutter; - for (int i = 180; i <= 182; i++) - materials[i] = Material.StrippedAcaciaLog; - for (int i = 237; i <= 239; i++) - materials[i] = Material.StrippedAcaciaWood; - for (int i = 198; i <= 200; i++) - materials[i] = Material.StrippedBambooBlock; - for (int i = 174; i <= 176; i++) - materials[i] = Material.StrippedBirchLog; - for (int i = 231; i <= 233; i++) - materials[i] = Material.StrippedBirchWood; - for (int i = 183; i <= 185; i++) - materials[i] = Material.StrippedCherryLog; - for (int i = 240; i <= 242; i++) - materials[i] = Material.StrippedCherryWood; - for (int i = 20769; i <= 20771; i++) - materials[i] = Material.StrippedCrimsonHyphae; - for (int i = 20763; i <= 20765; i++) - materials[i] = Material.StrippedCrimsonStem; - for (int i = 186; i <= 188; i++) - materials[i] = Material.StrippedDarkOakLog; - for (int i = 243; i <= 245; i++) - materials[i] = Material.StrippedDarkOakWood; - for (int i = 177; i <= 179; i++) - materials[i] = Material.StrippedJungleLog; - for (int i = 234; i <= 236; i++) - materials[i] = Material.StrippedJungleWood; - for (int i = 195; i <= 197; i++) - materials[i] = Material.StrippedMangroveLog; - for (int i = 249; i <= 251; i++) - materials[i] = Material.StrippedMangroveWood; - for (int i = 192; i <= 194; i++) - materials[i] = Material.StrippedOakLog; - for (int i = 225; i <= 227; i++) - materials[i] = Material.StrippedOakWood; - for (int i = 189; i <= 191; i++) - materials[i] = Material.StrippedPaleOakLog; - for (int i = 246; i <= 248; i++) - materials[i] = Material.StrippedPaleOakWood; - for (int i = 171; i <= 173; i++) - materials[i] = Material.StrippedSpruceLog; - for (int i = 228; i <= 230; i++) - materials[i] = Material.StrippedSpruceWood; - for (int i = 20752; i <= 20754; i++) - materials[i] = Material.StrippedWarpedHyphae; - for (int i = 20746; i <= 20748; i++) - materials[i] = Material.StrippedWarpedStem; - for (int i = 21520; i <= 21523; i++) - materials[i] = Material.StructureBlock; - materials[14649] = Material.StructureVoid; - for (int i = 6746; i <= 6761; i++) - materials[i] = Material.SugarCane; - for (int i = 12713; i <= 12714; i++) - materials[i] = Material.Sunflower; - for (int i = 125; i <= 128; i++) - materials[i] = Material.SuspiciousGravel; - for (int i = 119; i <= 122; i++) - materials[i] = Material.SuspiciousSand; - for (int i = 20739; i <= 20742; i++) - materials[i] = Material.SweetBerryBush; - materials[2053] = Material.TallDryGrass; - for (int i = 12721; i <= 12722; i++) - materials[i] = Material.TallGrass; - for (int i = 2055; i <= 2056; i++) - materials[i] = Material.TallSeagrass; - for (int i = 21550; i <= 21565; i++) - materials[i] = Material.Target; - materials[12710] = Material.Terracotta; - for (int i = 21536; i <= 21539; i++) - materials[i] = Material.TestBlock; - materials[21540] = Material.TestInstanceBlock; - materials[24486] = Material.TintedGlass; - for (int i = 2140; i <= 2141; i++) - materials[i] = Material.Tnt; - materials[3169] = Material.Torch; - materials[2122] = Material.Torchflower; - for (int i = 14595; i <= 14596; i++) - materials[i] = Material.TorchflowerCrop; - for (int i = 11005; i <= 11028; i++) - materials[i] = Material.TrappedChest; - for (int i = 29455; i <= 29466; i++) - materials[i] = Material.TrialSpawner; - for (int i = 9398; i <= 9525; i++) - materials[i] = Material.Tripwire; - for (int i = 9382; i <= 9397; i++) - materials[i] = Material.TripwireHook; - for (int i = 14955; i <= 14956; i++) - materials[i] = Material.TubeCoral; - materials[14940] = Material.TubeCoralBlock; - for (int i = 14975; i <= 14976; i++) - materials[i] = Material.TubeCoralFan; - for (int i = 15025; i <= 15032; i++) - materials[i] = Material.TubeCoralWallFan; - materials[23250] = Material.Tuff; - for (int i = 24074; i <= 24079; i++) - materials[i] = Material.TuffBrickSlab; - for (int i = 24080; i <= 24159; i++) - materials[i] = Material.TuffBrickStairs; - for (int i = 24160; i <= 24483; i++) - materials[i] = Material.TuffBrickWall; - materials[24073] = Material.TuffBricks; + for (int i = 23250; i <= 23250; i++) + materials[i] = Material.Tuff; for (int i = 23251; i <= 23256; i++) materials[i] = Material.TuffSlab; for (int i = 23257; i <= 23336; i++) materials[i] = Material.TuffStairs; for (int i = 23337; i <= 23660; i++) materials[i] = Material.TuffWall; - for (int i = 14888; i <= 14899; i++) - materials[i] = Material.TurtleEgg; - for (int i = 20802; i <= 20827; i++) - materials[i] = Material.TwistingVines; - materials[20828] = Material.TwistingVinesPlant; - for (int i = 29467; i <= 29498; i++) - materials[i] = Material.Vault; - for (int i = 29383; i <= 29385; i++) - materials[i] = Material.VerdantFroglight; - for (int i = 8157; i <= 8188; i++) - materials[i] = Material.Vine; - materials[15090] = Material.VoidAir; - for (int i = 3170; i <= 3173; i++) - materials[i] = Material.WallTorch; - for (int i = 21288; i <= 21311; i++) - materials[i] = Material.WarpedButton; - for (int i = 21376; i <= 21439; i++) - materials[i] = Material.WarpedDoor; - for (int i = 20880; i <= 20911; i++) - materials[i] = Material.WarpedFence; - for (int i = 21072; i <= 21103; i++) - materials[i] = Material.WarpedFenceGate; - materials[20756] = Material.WarpedFungus; - for (int i = 6282; i <= 6345; i++) - materials[i] = Material.WarpedHangingSign; - for (int i = 20749; i <= 20751; i++) - materials[i] = Material.WarpedHyphae; - materials[20755] = Material.WarpedNylium; - materials[20831] = Material.WarpedPlanks; - for (int i = 20846; i <= 20847; i++) - materials[i] = Material.WarpedPressurePlate; - materials[20758] = Material.WarpedRoots; - for (int i = 3103; i <= 3166; i++) - materials[i] = Material.WarpedShelf; - for (int i = 21472; i <= 21503; i++) - materials[i] = Material.WarpedSign; - for (int i = 20838; i <= 20843; i++) - materials[i] = Material.WarpedSlab; - for (int i = 21184; i <= 21263; i++) - materials[i] = Material.WarpedStairs; - for (int i = 20743; i <= 20745; i++) - materials[i] = Material.WarpedStem; - for (int i = 20976; i <= 21039; i++) - materials[i] = Material.WarpedTrapdoor; - for (int i = 6554; i <= 6561; i++) - materials[i] = Material.WarpedWallHangingSign; - for (int i = 21512; i <= 21519; i++) - materials[i] = Material.WarpedWallSign; - materials[20757] = Material.WarpedWartBlock; - for (int i = 86; i <= 101; i++) - materials[i] = Material.Water; - for (int i = 9260; i <= 9262; i++) - materials[i] = Material.WaterCauldron; - materials[25124] = Material.WaxedChiseledCopper; - for (int i = 7917; i <= 7948; i++) - materials[i] = Material.WaxedCopperBars; - materials[25469] = Material.WaxedCopperBlock; - for (int i = 26877; i <= 26880; i++) - materials[i] = Material.WaxedCopperBulb; - for (int i = 8075; i <= 8080; i++) - materials[i] = Material.WaxedCopperChain; - for (int i = 26989; i <= 27012; i++) - materials[i] = Material.WaxedCopperChest; - for (int i = 26077; i <= 26140; i++) - materials[i] = Material.WaxedCopperDoor; - for (int i = 27213; i <= 27244; i++) - materials[i] = Material.WaxedCopperGolemStatue; - for (int i = 26853; i <= 26854; i++) - materials[i] = Material.WaxedCopperGrate; - for (int i = 20659; i <= 20662; i++) - materials[i] = Material.WaxedCopperLantern; - for (int i = 26589; i <= 26652; i++) - materials[i] = Material.WaxedCopperTrapdoor; - materials[25476] = Material.WaxedCutCopper; - for (int i = 25815; i <= 25820; i++) - materials[i] = Material.WaxedCutCopperSlab; - for (int i = 25717; i <= 25796; i++) - materials[i] = Material.WaxedCutCopperStairs; - materials[25123] = Material.WaxedExposedChiseledCopper; - materials[25471] = Material.WaxedExposedCopper; - for (int i = 7949; i <= 7980; i++) - materials[i] = Material.WaxedExposedCopperBars; - for (int i = 26881; i <= 26884; i++) - materials[i] = Material.WaxedExposedCopperBulb; - for (int i = 8081; i <= 8086; i++) - materials[i] = Material.WaxedExposedCopperChain; - for (int i = 27013; i <= 27036; i++) - materials[i] = Material.WaxedExposedCopperChest; - for (int i = 26141; i <= 26204; i++) - materials[i] = Material.WaxedExposedCopperDoor; - for (int i = 27245; i <= 27276; i++) - materials[i] = Material.WaxedExposedCopperGolemStatue; - for (int i = 26855; i <= 26856; i++) - materials[i] = Material.WaxedExposedCopperGrate; - for (int i = 20663; i <= 20666; i++) - materials[i] = Material.WaxedExposedCopperLantern; - for (int i = 26653; i <= 26716; i++) - materials[i] = Material.WaxedExposedCopperTrapdoor; - materials[25475] = Material.WaxedExposedCutCopper; - for (int i = 25809; i <= 25814; i++) - materials[i] = Material.WaxedExposedCutCopperSlab; - for (int i = 25637; i <= 25716; i++) - materials[i] = Material.WaxedExposedCutCopperStairs; - for (int i = 27461; i <= 27484; i++) - materials[i] = Material.WaxedExposedLightningRod; - for (int i = 27437; i <= 27460; i++) - materials[i] = Material.WaxedLightningRod; - materials[25121] = Material.WaxedOxidizedChiseledCopper; - materials[25472] = Material.WaxedOxidizedCopper; - for (int i = 8013; i <= 8044; i++) - materials[i] = Material.WaxedOxidizedCopperBars; - for (int i = 26889; i <= 26892; i++) - materials[i] = Material.WaxedOxidizedCopperBulb; - for (int i = 8093; i <= 8098; i++) - materials[i] = Material.WaxedOxidizedCopperChain; - for (int i = 27061; i <= 27084; i++) - materials[i] = Material.WaxedOxidizedCopperChest; - for (int i = 26205; i <= 26268; i++) - materials[i] = Material.WaxedOxidizedCopperDoor; - for (int i = 27309; i <= 27340; i++) - materials[i] = Material.WaxedOxidizedCopperGolemStatue; - for (int i = 26859; i <= 26860; i++) - materials[i] = Material.WaxedOxidizedCopperGrate; - for (int i = 20671; i <= 20674; i++) - materials[i] = Material.WaxedOxidizedCopperLantern; - for (int i = 26717; i <= 26780; i++) - materials[i] = Material.WaxedOxidizedCopperTrapdoor; - materials[25473] = Material.WaxedOxidizedCutCopper; - for (int i = 25797; i <= 25802; i++) - materials[i] = Material.WaxedOxidizedCutCopperSlab; - for (int i = 25477; i <= 25556; i++) - materials[i] = Material.WaxedOxidizedCutCopperStairs; - for (int i = 27509; i <= 27532; i++) - materials[i] = Material.WaxedOxidizedLightningRod; - materials[25122] = Material.WaxedWeatheredChiseledCopper; - materials[25470] = Material.WaxedWeatheredCopper; - for (int i = 7981; i <= 8012; i++) - materials[i] = Material.WaxedWeatheredCopperBars; - for (int i = 26885; i <= 26888; i++) - materials[i] = Material.WaxedWeatheredCopperBulb; - for (int i = 8087; i <= 8092; i++) - materials[i] = Material.WaxedWeatheredCopperChain; - for (int i = 27037; i <= 27060; i++) - materials[i] = Material.WaxedWeatheredCopperChest; - for (int i = 26269; i <= 26332; i++) - materials[i] = Material.WaxedWeatheredCopperDoor; - for (int i = 27277; i <= 27308; i++) - materials[i] = Material.WaxedWeatheredCopperGolemStatue; - for (int i = 26857; i <= 26858; i++) - materials[i] = Material.WaxedWeatheredCopperGrate; - for (int i = 20667; i <= 20670; i++) - materials[i] = Material.WaxedWeatheredCopperLantern; - for (int i = 26781; i <= 26844; i++) - materials[i] = Material.WaxedWeatheredCopperTrapdoor; - materials[25474] = Material.WaxedWeatheredCutCopper; - for (int i = 25803; i <= 25808; i++) - materials[i] = Material.WaxedWeatheredCutCopperSlab; - for (int i = 25557; i <= 25636; i++) - materials[i] = Material.WaxedWeatheredCutCopperStairs; - for (int i = 27485; i <= 27508; i++) - materials[i] = Material.WaxedWeatheredLightningRod; - materials[25118] = Material.WeatheredChiseledCopper; - materials[25109] = Material.WeatheredCopper; - for (int i = 7853; i <= 7884; i++) - materials[i] = Material.WeatheredCopperBars; - for (int i = 26869; i <= 26872; i++) - materials[i] = Material.WeatheredCopperBulb; - for (int i = 8063; i <= 8068; i++) - materials[i] = Material.WeatheredCopperChain; - for (int i = 26941; i <= 26964; i++) - materials[i] = Material.WeatheredCopperChest; - for (int i = 26013; i <= 26076; i++) - materials[i] = Material.WeatheredCopperDoor; - for (int i = 27149; i <= 27180; i++) - materials[i] = Material.WeatheredCopperGolemStatue; - for (int i = 26849; i <= 26850; i++) - materials[i] = Material.WeatheredCopperGrate; - for (int i = 20651; i <= 20654; i++) - materials[i] = Material.WeatheredCopperLantern; - for (int i = 26525; i <= 26588; i++) - materials[i] = Material.WeatheredCopperTrapdoor; - materials[25114] = Material.WeatheredCutCopper; - for (int i = 25451; i <= 25456; i++) - materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 23661; i <= 23661; i++) + materials[i] = Material.PolishedTuff; + for (int i = 23662; i <= 23667; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 23668; i <= 23747; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 23748; i <= 24071; i++) + materials[i] = Material.PolishedTuffWall; + for (int i = 24072; i <= 24072; i++) + materials[i] = Material.ChiseledTuff; + for (int i = 24073; i <= 24073; i++) + materials[i] = Material.TuffBricks; + for (int i = 24074; i <= 24079; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 24080; i <= 24159; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 24160; i <= 24483; i++) + materials[i] = Material.TuffBrickWall; + for (int i = 24484; i <= 24484; i++) + materials[i] = Material.ChiseledTuffBricks; + for (int i = 24485; i <= 24485; i++) + materials[i] = Material.Calcite; + for (int i = 24486; i <= 24486; i++) + materials[i] = Material.TintedGlass; + for (int i = 24487; i <= 24487; i++) + materials[i] = Material.PowderSnow; + for (int i = 24488; i <= 24583; i++) + materials[i] = Material.SculkSensor; + for (int i = 24584; i <= 24967; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 24968; i <= 24968; i++) + materials[i] = Material.Sculk; + for (int i = 24969; i <= 25096; i++) + materials[i] = Material.SculkVein; + for (int i = 25097; i <= 25098; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 25099; i <= 25106; i++) + materials[i] = Material.SculkShrieker; + for (int i = 25107; i <= 25107; i++) + materials[i] = Material.CopperBlock; + for (int i = 25108; i <= 25108; i++) + materials[i] = Material.ExposedCopper; + for (int i = 25109; i <= 25109; i++) + materials[i] = Material.WeatheredCopper; + for (int i = 25110; i <= 25110; i++) + materials[i] = Material.OxidizedCopper; + for (int i = 25111; i <= 25111; i++) + materials[i] = Material.CopperOre; + for (int i = 25112; i <= 25112; i++) + materials[i] = Material.DeepslateCopperOre; + for (int i = 25113; i <= 25113; i++) + materials[i] = Material.OxidizedCutCopper; + for (int i = 25114; i <= 25114; i++) + materials[i] = Material.WeatheredCutCopper; + for (int i = 25115; i <= 25115; i++) + materials[i] = Material.ExposedCutCopper; + for (int i = 25116; i <= 25116; i++) + materials[i] = Material.CutCopper; + for (int i = 25117; i <= 25117; i++) + materials[i] = Material.OxidizedChiseledCopper; + for (int i = 25118; i <= 25118; i++) + materials[i] = Material.WeatheredChiseledCopper; + for (int i = 25119; i <= 25119; i++) + materials[i] = Material.ExposedChiseledCopper; + for (int i = 25120; i <= 25120; i++) + materials[i] = Material.ChiseledCopper; + for (int i = 25121; i <= 25121; i++) + materials[i] = Material.WaxedOxidizedChiseledCopper; + for (int i = 25122; i <= 25122; i++) + materials[i] = Material.WaxedWeatheredChiseledCopper; + for (int i = 25123; i <= 25123; i++) + materials[i] = Material.WaxedExposedChiseledCopper; + for (int i = 25124; i <= 25124; i++) + materials[i] = Material.WaxedChiseledCopper; + for (int i = 25125; i <= 25204; i++) + materials[i] = Material.OxidizedCutCopperStairs; for (int i = 25205; i <= 25284; i++) materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 25285; i <= 25364; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 25365; i <= 25444; i++) + materials[i] = Material.CutCopperStairs; + for (int i = 25445; i <= 25450; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 25451; i <= 25456; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 25457; i <= 25462; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 25463; i <= 25468; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 25469; i <= 25469; i++) + materials[i] = Material.WaxedCopperBlock; + for (int i = 25470; i <= 25470; i++) + materials[i] = Material.WaxedWeatheredCopper; + for (int i = 25471; i <= 25471; i++) + materials[i] = Material.WaxedExposedCopper; + for (int i = 25472; i <= 25472; i++) + materials[i] = Material.WaxedOxidizedCopper; + for (int i = 25473; i <= 25473; i++) + materials[i] = Material.WaxedOxidizedCutCopper; + for (int i = 25474; i <= 25474; i++) + materials[i] = Material.WaxedWeatheredCutCopper; + for (int i = 25475; i <= 25475; i++) + materials[i] = Material.WaxedExposedCutCopper; + for (int i = 25476; i <= 25476; i++) + materials[i] = Material.WaxedCutCopper; + for (int i = 25477; i <= 25556; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + for (int i = 25557; i <= 25636; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + for (int i = 25637; i <= 25716; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + for (int i = 25717; i <= 25796; i++) + materials[i] = Material.WaxedCutCopperStairs; + for (int i = 25797; i <= 25802; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 25803; i <= 25808; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 25809; i <= 25814; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 25815; i <= 25820; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 25821; i <= 25884; i++) + materials[i] = Material.CopperDoor; + for (int i = 25885; i <= 25948; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 25949; i <= 26012; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 26013; i <= 26076; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 26077; i <= 26140; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 26141; i <= 26204; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 26205; i <= 26268; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 26269; i <= 26332; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 26333; i <= 26396; i++) + materials[i] = Material.CopperTrapdoor; + for (int i = 26397; i <= 26460; i++) + materials[i] = Material.ExposedCopperTrapdoor; + for (int i = 26461; i <= 26524; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + for (int i = 26525; i <= 26588; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + for (int i = 26589; i <= 26652; i++) + materials[i] = Material.WaxedCopperTrapdoor; + for (int i = 26653; i <= 26716; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + for (int i = 26717; i <= 26780; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + for (int i = 26781; i <= 26844; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + for (int i = 26845; i <= 26846; i++) + materials[i] = Material.CopperGrate; + for (int i = 26847; i <= 26848; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 26849; i <= 26850; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 26851; i <= 26852; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 26853; i <= 26854; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 26855; i <= 26856; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 26857; i <= 26858; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 26859; i <= 26860; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 26861; i <= 26864; i++) + materials[i] = Material.CopperBulb; + for (int i = 26865; i <= 26868; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 26869; i <= 26872; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 26873; i <= 26876; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 26877; i <= 26880; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 26881; i <= 26884; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 26885; i <= 26888; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 26889; i <= 26892; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 26893; i <= 26916; i++) + materials[i] = Material.CopperChest; + for (int i = 26917; i <= 26940; i++) + materials[i] = Material.ExposedCopperChest; + for (int i = 26941; i <= 26964; i++) + materials[i] = Material.WeatheredCopperChest; + for (int i = 26965; i <= 26988; i++) + materials[i] = Material.OxidizedCopperChest; + for (int i = 26989; i <= 27012; i++) + materials[i] = Material.WaxedCopperChest; + for (int i = 27013; i <= 27036; i++) + materials[i] = Material.WaxedExposedCopperChest; + for (int i = 27037; i <= 27060; i++) + materials[i] = Material.WaxedWeatheredCopperChest; + for (int i = 27061; i <= 27084; i++) + materials[i] = Material.WaxedOxidizedCopperChest; + for (int i = 27085; i <= 27116; i++) + materials[i] = Material.CopperGolemStatue; + for (int i = 27117; i <= 27148; i++) + materials[i] = Material.ExposedCopperGolemStatue; + for (int i = 27149; i <= 27180; i++) + materials[i] = Material.WeatheredCopperGolemStatue; + for (int i = 27181; i <= 27212; i++) + materials[i] = Material.OxidizedCopperGolemStatue; + for (int i = 27213; i <= 27244; i++) + materials[i] = Material.WaxedCopperGolemStatue; + for (int i = 27245; i <= 27276; i++) + materials[i] = Material.WaxedExposedCopperGolemStatue; + for (int i = 27277; i <= 27308; i++) + materials[i] = Material.WaxedWeatheredCopperGolemStatue; + for (int i = 27309; i <= 27340; i++) + materials[i] = Material.WaxedOxidizedCopperGolemStatue; + for (int i = 27341; i <= 27364; i++) + materials[i] = Material.LightningRod; + for (int i = 27365; i <= 27388; i++) + materials[i] = Material.ExposedLightningRod; for (int i = 27389; i <= 27412; i++) materials[i] = Material.WeatheredLightningRod; - for (int i = 20775; i <= 20800; i++) - materials[i] = Material.WeepingVines; - materials[20801] = Material.WeepingVinesPlant; - materials[561] = Material.WetSponge; - for (int i = 5110; i <= 5117; i++) - materials[i] = Material.Wheat; - for (int i = 12725; i <= 12740; i++) - materials[i] = Material.WhiteBanner; - for (int i = 1731; i <= 1746; i++) - materials[i] = Material.WhiteBed; - for (int i = 22910; i <= 22925; i++) - materials[i] = Material.WhiteCandle; - for (int i = 23168; i <= 23169; i++) - materials[i] = Material.WhiteCandleCake; - materials[12694] = Material.WhiteCarpet; - materials[14828] = Material.WhiteConcrete; - materials[14844] = Material.WhiteConcretePowder; - for (int i = 14764; i <= 14767; i++) - materials[i] = Material.WhiteGlazedTerracotta; - for (int i = 14668; i <= 14673; i++) - materials[i] = Material.WhiteShulkerBox; - materials[6897] = Material.WhiteStainedGlass; - for (int i = 11258; i <= 11289; i++) - materials[i] = Material.WhiteStainedGlassPane; - materials[11242] = Material.WhiteTerracotta; - materials[2129] = Material.WhiteTulip; - for (int i = 12981; i <= 12984; i++) - materials[i] = Material.WhiteWallBanner; - materials[2093] = Material.WhiteWool; + for (int i = 27413; i <= 27436; i++) + materials[i] = Material.OxidizedLightningRod; + for (int i = 27437; i <= 27460; i++) + materials[i] = Material.WaxedLightningRod; + for (int i = 27461; i <= 27484; i++) + materials[i] = Material.WaxedExposedLightningRod; + for (int i = 27485; i <= 27508; i++) + materials[i] = Material.WaxedWeatheredLightningRod; + for (int i = 27509; i <= 27532; i++) + materials[i] = Material.WaxedOxidizedLightningRod; + for (int i = 27533; i <= 27552; i++) + materials[i] = Material.PointedDripstone; + for (int i = 27553; i <= 27553; i++) + materials[i] = Material.DripstoneBlock; + for (int i = 27554; i <= 27605; i++) + materials[i] = Material.CaveVines; + for (int i = 27606; i <= 27607; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 27608; i <= 27608; i++) + materials[i] = Material.SporeBlossom; + for (int i = 27609; i <= 27609; i++) + materials[i] = Material.Azalea; + for (int i = 27610; i <= 27610; i++) + materials[i] = Material.FloweringAzalea; + for (int i = 27611; i <= 27611; i++) + materials[i] = Material.MossCarpet; + for (int i = 27612; i <= 27627; i++) + materials[i] = Material.PinkPetals; for (int i = 27628; i <= 27643; i++) materials[i] = Material.Wildflowers; - materials[2133] = Material.WitherRose; - for (int i = 10753; i <= 10784; i++) - materials[i] = Material.WitherSkeletonSkull; - for (int i = 10785; i <= 10792; i++) - materials[i] = Material.WitherSkeletonWallSkull; - for (int i = 12789; i <= 12804; i++) - materials[i] = Material.YellowBanner; - for (int i = 1795; i <= 1810; i++) - materials[i] = Material.YellowBed; - for (int i = 22974; i <= 22989; i++) - materials[i] = Material.YellowCandle; - for (int i = 23176; i <= 23177; i++) - materials[i] = Material.YellowCandleCake; - materials[12698] = Material.YellowCarpet; - materials[14832] = Material.YellowConcrete; - materials[14848] = Material.YellowConcretePowder; - for (int i = 14780; i <= 14783; i++) - materials[i] = Material.YellowGlazedTerracotta; - for (int i = 14692; i <= 14697; i++) - materials[i] = Material.YellowShulkerBox; - materials[6901] = Material.YellowStainedGlass; - for (int i = 11386; i <= 11417; i++) - materials[i] = Material.YellowStainedGlassPane; - materials[11246] = Material.YellowTerracotta; - for (int i = 12997; i <= 13000; i++) - materials[i] = Material.YellowWallBanner; - materials[2097] = Material.YellowWool; - for (int i = 10793; i <= 10824; i++) - materials[i] = Material.ZombieHead; - for (int i = 10825; i <= 10832; i++) - materials[i] = Material.ZombieWallHead; + for (int i = 27644; i <= 27659; i++) + materials[i] = Material.LeafLitter; + for (int i = 27660; i <= 27660; i++) + materials[i] = Material.MossBlock; + for (int i = 27661; i <= 27692; i++) + materials[i] = Material.BigDripleaf; + for (int i = 27693; i <= 27700; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 27701; i <= 27716; i++) + materials[i] = Material.SmallDripleaf; + for (int i = 27717; i <= 27718; i++) + materials[i] = Material.HangingRoots; + for (int i = 27719; i <= 27719; i++) + materials[i] = Material.RootedDirt; + for (int i = 27720; i <= 27720; i++) + materials[i] = Material.Mud; + for (int i = 27721; i <= 27723; i++) + materials[i] = Material.Deepslate; + for (int i = 27724; i <= 27724; i++) + materials[i] = Material.CobbledDeepslate; + for (int i = 27725; i <= 27804; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 27805; i <= 27810; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 27811; i <= 28134; i++) + materials[i] = Material.CobbledDeepslateWall; + for (int i = 28135; i <= 28135; i++) + materials[i] = Material.PolishedDeepslate; + for (int i = 28136; i <= 28215; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 28216; i <= 28221; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 28222; i <= 28545; i++) + materials[i] = Material.PolishedDeepslateWall; + for (int i = 28546; i <= 28546; i++) + materials[i] = Material.DeepslateTiles; + for (int i = 28547; i <= 28626; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 28627; i <= 28632; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 28633; i <= 28956; i++) + materials[i] = Material.DeepslateTileWall; + for (int i = 28957; i <= 28957; i++) + materials[i] = Material.DeepslateBricks; + for (int i = 28958; i <= 29037; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 29038; i <= 29043; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 29044; i <= 29367; i++) + materials[i] = Material.DeepslateBrickWall; + for (int i = 29368; i <= 29368; i++) + materials[i] = Material.ChiseledDeepslate; + for (int i = 29369; i <= 29369; i++) + materials[i] = Material.CrackedDeepslateBricks; + for (int i = 29370; i <= 29370; i++) + materials[i] = Material.CrackedDeepslateTiles; + for (int i = 29371; i <= 29373; i++) + materials[i] = Material.InfestedDeepslate; + for (int i = 29374; i <= 29374; i++) + materials[i] = Material.SmoothBasalt; + for (int i = 29375; i <= 29375; i++) + materials[i] = Material.RawIronBlock; + for (int i = 29376; i <= 29376; i++) + materials[i] = Material.RawCopperBlock; + for (int i = 29377; i <= 29377; i++) + materials[i] = Material.RawGoldBlock; + for (int i = 29378; i <= 29378; i++) + materials[i] = Material.PottedAzaleaBush; + for (int i = 29379; i <= 29379; i++) + materials[i] = Material.PottedFloweringAzaleaBush; + for (int i = 29380; i <= 29382; i++) + materials[i] = Material.OchreFroglight; + for (int i = 29383; i <= 29385; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 29386; i <= 29388; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 29389; i <= 29389; i++) + materials[i] = Material.Frogspawn; + for (int i = 29390; i <= 29390; i++) + materials[i] = Material.ReinforcedDeepslate; + for (int i = 29391; i <= 29406; i++) + materials[i] = Material.DecoratedPot; + for (int i = 29407; i <= 29454; i++) + materials[i] = Material.Crafter; + for (int i = 29455; i <= 29466; i++) + materials[i] = Material.TrialSpawner; + for (int i = 29467; i <= 29498; i++) + materials[i] = Material.Vault; + for (int i = 29499; i <= 29500; i++) + materials[i] = Material.HeavyCore; + for (int i = 29501; i <= 29501; i++) + materials[i] = Material.PaleMossBlock; + for (int i = 29502; i <= 29663; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 29664; i <= 29665; i++) + materials[i] = Material.PaleHangingMoss; + for (int i = 29666; i <= 29666; i++) + materials[i] = Material.OpenEyeblossom; + for (int i = 29667; i <= 29667; i++) + materials[i] = Material.ClosedEyeblossom; + for (int i = 29668; i <= 29668; i++) + materials[i] = Material.PottedOpenEyeblossom; + for (int i = 29669; i <= 29669; i++) + materials[i] = Material.PottedClosedEyeblossom; + for (int i = 29670; i <= 29670; i++) + materials[i] = Material.FireflyBush; } protected override Dictionary GetDict() diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index a34b6d70..35454a6e 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -165,9 +165,9 @@ namespace MinecraftClient.Mapping BubbleCoralFan, BubbleCoralWallFan, BuddingAmethyst, - Bush, // bush + Bush, Cactus, - CactusFlower, // cactus_flower + CactusFlower, Cake, Calcite, CalibratedSculkSensor, @@ -416,7 +416,7 @@ namespace MinecraftClient.Mapping FireCoralBlock, FireCoralFan, FireCoralWallFan, - FireflyBush, // firefly_bush + FireflyBush, FletchingTable, FlowerPot, FloweringAzalea, @@ -522,7 +522,7 @@ namespace MinecraftClient.Mapping LargeFern, Lava, LavaCauldron, - LeafLitter, // leaf_litter + LeafLitter, Lectern, Lever, Light, @@ -914,7 +914,7 @@ namespace MinecraftClient.Mapping SeaLantern, SeaPickle, Seagrass, - ShortDryGrass, // short_dry_grass + ShortDryGrass, ShortGrass, Shroomlight, ShulkerBox, @@ -1009,13 +1009,13 @@ namespace MinecraftClient.Mapping SuspiciousGravel, SuspiciousSand, SweetBerryBush, - TallDryGrass, // tall_dry_grass + TallDryGrass, TallGrass, TallSeagrass, Target, Terracotta, - TestBlock, // test_block - TestInstanceBlock, // test_instance_block + TestBlock, + TestInstanceBlock, TintedGlass, Tnt, Torch, @@ -1161,7 +1161,7 @@ namespace MinecraftClient.Mapping WhiteTulip, WhiteWallBanner, WhiteWool, - Wildflowers, // wildflowers + Wildflowers, WitherRose, WitherSkeletonSkull, WitherSkeletonWallSkull, From 34671fdab2d8332e9aa399788167fb11b06d297d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 21 Mar 2026 15:04:20 +0800 Subject: [PATCH 076/484] feat: enhance palette generation and validation for MC 1.21.9 Updated the SKILL.md documentation to include critical steps for generating server reports and validating decompiled source against server data, emphasizing the importance of using server data since MC 1.21.9. Enhanced the diff_registries.py script to support cross-validation with server registries.json, allowing for accurate palette generation. Added new scripts for generating block and entity palettes from server data, ensuring completeness and correctness of entries. This update improves the workflow for adapting to new Minecraft versions and ensures that palette generation reflects the latest changes in item and block registration. Made-with: Cursor --- .../skills/mcc-version-adaptation/SKILL.md | 142 ++++++++++++++++-- tools/README.md | 95 ++++++++++-- tools/diff_registries.py | 105 +++++++++++-- tools/gen_block_palette.py | 119 +++++++++++++++ tools/gen_entity_palette.py | 111 ++++++++++++++ tools/gen_item_palette.py | 122 +++++++++------ 6 files changed, 614 insertions(+), 80 deletions(-) create mode 100644 tools/gen_block_palette.py create mode 100644 tools/gen_entity_palette.py diff --git a/.cursor/skills/mcc-version-adaptation/SKILL.md b/.cursor/skills/mcc-version-adaptation/SKILL.md index b7f26464..44023b06 100644 --- a/.cursor/skills/mcc-version-adaptation/SKILL.md +++ b/.cursor/skills/mcc-version-adaptation/SKILL.md @@ -16,6 +16,38 @@ Systematic workflow for updating Minecraft Console Client to support a new Minec java -jar MinecraftDecompiler.jar --version --side SERVER \ --decompile --output -remapped.jar --decompiled-output -decompiled ``` +- A test server of the target version in `$MCC_SERVERS/` (see `mcc-dev-workflow` skill) + +## Step 0: Generate Server Reports (CRITICAL since 1.21.9) + +**Before** analyzing decompiled source, generate authoritative registry data from the server jar: + +```bash +cd /tmp && java -DbundlerMainClass=net.minecraft.data.Main \ + -jar $MCC_SERVERS/-Vanilla/server.jar \ + --reports --output /tmp/mc_reports +``` + +This produces `/tmp/mc_reports/reports/` containing: +- `registries.json` — all registries with **actual protocol_id** for each entry +- `blocks.json` — all blocks with **block state IDs** +- `packets.json` — packet protocol definitions + +**Why this matters**: Since MC 1.21.9, some items and blocks are registered outside `Items.java`/`Blocks.java` field declarations (via block registration callbacks or other paths). The decompiled source alone will **miss** these entries. The server data generator is the only authoritative source for protocol IDs. + +### Validation check +Compare server registry counts against decompiled source counts: +```bash +python3 -c " +import json +with open('/tmp/mc_reports/reports/registries.json') as f: + data = json.load(f) +for reg in ['minecraft:item', 'minecraft:entity_type', 'minecraft:block']: + print(f'{reg}: {len(data[reg][\"entries\"])} entries') +" +``` + +If server counts differ from decompiled Java source counts, the palette **must** be generated from server data, not from Java source. ## Step 1: Run Registry Diff @@ -33,18 +65,50 @@ This compares five registries and reports which need palette updates: | DataComponents.java | `StructuredComponents/StructuredComponentsRegistryXXX.cs` | New/reordered components | | EntityDataSerializers.java | `EntityMetadataPalettes/EntityMetadataPaletteXXX.cs` | New/reordered serializer types | +**Important**: diff_registries.py compares decompiled Java source. If Step 0 revealed count mismatches, the diff output may undercount. Always cross-reference with server registries.json. + ## Step 2: Generate Updated Palettes For registries marked "PALETTE UPDATE NEEDED": ### Item Palette + +**Preferred method** (accurate since 1.21.9): +```bash +python3 $MCC_REPO/tools/gen_item_palette.py --from-registry /tmp/mc_reports/reports/registries.json +# e.g., gen_item_palette.py --from-registry /tmp/mc_reports/reports/registries.json 1219 +``` + +**Legacy method** (works for versions where Items.java has all items): ```bash python3 $MCC_REPO/tools/gen_item_palette.py # e.g., gen_item_palette.py 1.21.1 121 ``` + - If new items are reported missing from `ItemType.cs`, add them to the enum in alphabetical order. - The script auto-generates the C# palette file. +### Block Palette + +**Preferred method** (accurate since 1.21.9): +```bash +python3 $MCC_REPO/tools/gen_block_palette.py /tmp/mc_reports/reports/blocks.json +# e.g., gen_block_palette.py /tmp/mc_reports/reports/blocks.json 1219 +``` + +**Legacy method** (manual creation from decompiled Blocks.java): Follow the pattern of existing palette files, using `register("name", ...)` call order from the decompiled source. Only reliable when Blocks.java contains all blocks. + +If new blocks are reported missing from `Material.cs`, add them to the enum in alphabetical order. + +### Entity Palette + +```bash +python3 $MCC_REPO/tools/gen_entity_palette.py /tmp/mc_reports/reports/registries.json +# e.g., gen_entity_palette.py /tmp/mc_reports/reports/registries.json 1219 +``` + +If new entity types are reported missing from `EntityType.cs`, add them to the enum in alphabetical order. + ### Entity Metadata Palette ```bash python3 $MCC_REPO/tools/gen_entity_metadata_palette.py @@ -55,9 +119,6 @@ python3 $MCC_REPO/tools/gen_entity_metadata_palette.py 2. MCC's `EntityMetaDataType.cs` enum 3. `DataTypes.cs` read logic (add a `case` to consume the correct bytes) -### Entity/Block Palettes -No generator script yet — these change rarely. When needed, manually create by following the pattern of existing palette files, using `register("name", ...)` call order from the decompiled source. - ### DataComponents / StructuredComponents Compare `DataComponents.java` registration order. If new components appear, update `StructuredComponentsRegistryXXX.cs`. For new component types, implement corresponding reader in `StructuredComponents/Components/`. @@ -72,10 +133,31 @@ After creating palette files, update version selection logic: | Block | `Protocol18.cs` → `blockPalette` initialization | | EntityMetadata | `EntityMetadataPalette.cs` → `GetPalette()` switch | | DataComponents | `StructuredComponentsRegistry.cs` → factory/routing | +| Packet | `PacketType18Handler.cs` → `GetTypeHandler()` switch | Pattern: add a new `>= MC_X_Y_Z_Version => new XxxPaletteXYZ()` case. -## Step 4: Check Variant Encoding Changes +Also update: +- `Protocol18.cs`: add `MC_X_Y_Z_Version = ` constant +- `Protocol18.cs`: update all `> MC_prev_Version` upper-bound checks to `> MC_X_Y_Z_Version` +- `ProtocolHandler.cs`: add version string → protocol mapping, protocol → version mapping, add to supported list +- `Program.cs`: update `MCHighestVersion` + +## Step 4: Check Packet Changes + +Compare `GameProtocols.java` and `ConfigurationProtocols.java` between versions. + +Common patterns: +- **New clientbound packets inserted mid-list**: All subsequent packet IDs shift. Requires a new `PacketPalette` class. +- **New packets appended at end**: Only need to add new enum values and entries in the palette. +- **Packet renames** (same slot): Update MCC's packet type enum name but no ID change. + +When packet changes are detected: +1. Add new packet type enum values to `PacketTypesIn.cs`, `PacketTypesOut.cs`, `ConfigurationPacketTypesIn.cs`, `ConfigurationPacketTypesOut.cs` +2. Create new `PacketPaletteXXX.cs` based on the previous one, adjusting IDs +3. Update `PacketType18Handler.cs` routing + +## Step 5: Check Variant Encoding Changes For entity types that use variant serializers (Cat, Wolf, Frog, Painting), check if the codec changed between versions by inspecting: @@ -85,18 +167,26 @@ For entity types that use variant serializers (Cat, Wolf, Frog, Painting), check - `ByteBufCodecs.holder()` → wire format: `VarInt(id+1)` for registered, `VarInt(0) + inline_data` for direct - If codec changed, update `DataTypes.cs` entity metadata reading logic accordingly. -## Step 5: Handle New EntityDataSerializer Types +## Step 6: Handle New EntityDataSerializer Types When new serializer types are added (detected in Step 1): 1. Add enum value to `EntityMetaDataType.cs` with XML doc comment 2. Add read logic in `DataTypes.cs` `ReadNextMetadata()`: - Determine byte consumption from the decompiled codec - - Examples: VarInt read, list of particles, etc. + - Simple enum types (like CopperGolemState, WeatheringCopperState): `ReadNextVarInt(cache)` + - Composite types (like ResolvableProfile): analyze the STREAM_CODEC chain in decompiled source 3. Create the new palette file (Step 2) 4. Update palette routing (Step 3) -## Step 6: Compile and Verify +## Step 7: Check SpawnEntity / Other Packet Format Changes + +Compare key packet codec classes between versions. Known changes: +- **1.21.9+**: `SpawnEntity` velocity fields changed from `short / 8000.0` to `LpVec3` format (VarLong-packed fixed-point). Gate reading in `DataTypes.ReadNextEntity()` by version. + +When in doubt, compare the relevant packet class (e.g. `ClientboundAddEntityPacket.java`) between versions. + +## Step 8: Compile and Verify ```bash dotnet build $MCC_REPO/MinecraftClient.sln -c Release @@ -104,27 +194,53 @@ dotnet build $MCC_REPO/MinecraftClient.sln -c Release Then connect to a test server of the target version (see `mcc-dev-workflow` skill) and verify: - Successful connection -- `/give` new items → check inventory -- Summon entities (especially variant types) → no metadata parse errors -- Particle effects → no crashes +- `/give` new items → check inventory for correct identification +- `/give` existing items (diamond_sword, etc.) → verify no ID shift +- Summon new entities → check type and health +- Summon variant entities (wolf, cat, frog) → no metadata parse errors +- Place new blocks → `dig` reports correct block type +- Teleport to distant chunks → terrain loads without errors +- Chat commands work normally + +**Always verify basic existing items first** (e.g. diamond_sword) to catch palette ID shift bugs early. If an existing item shows as the wrong type, the palette is using wrong protocol IDs. ## Key Source Files Reference | Decompiled Java Source | Purpose | |----------------------|---------| -| `world/item/Items.java` | Item registry (field declaration order = ID) | +| `world/item/Items.java` | Item registry (field declaration order ≈ ID, **but not always since 1.21.9**) | | `world/entity/EntityType.java` | Entity type registry (`register()` call order = ID) | -| `world/level/block/Blocks.java` | Block registry (`register()` call order = ID) | +| `world/level/block/Blocks.java` | Block registry (`register()` call order ≈ ID, **but not always since 1.21.9**) | | `core/component/DataComponents.java` | Data component registry | | `network/syncher/EntityDataSerializers.java` | Entity metadata type registry (static block order = ID) | +| `network/protocol/game/GameProtocols.java` | Play packet registration order (= packet IDs) | +| `network/protocol/configuration/ConfigurationProtocols.java` | Config packet registration order | + +| Server Data Generator Output | Purpose | +|-----|---------| +| `registries.json` | **Authoritative** protocol_id for all registries | +| `blocks.json` | **Authoritative** block state IDs | +| `packets.json` | Packet protocol definitions | ## Common Pitfalls -- **ID order matters**: IDs are determined by declaration/registration order, not alphabetical. Always use the decompiled source as ground truth. +- **Source field order ≠ runtime registry ID (since 1.21.9)**: Some items/blocks are registered via callbacks (e.g., block items registered by `Blocks.java` during block registration) rather than in `Items.java` field declarations. Always validate palette counts against server `registries.json`. If counts differ, **use server data generator output instead of decompiled source**. +- **ID order matters**: IDs are determined by registration order, not alphabetical. Always use server data generator as ground truth. - **Cross-version jumps**: When MCC skips versions (e.g., 1.20.4→1.20.6), registries from ALL intermediate versions may have changed. Always diff against the actual last-supported version, not the latest palette. - **EntityMetadata type shifts**: A single new serializer type shifts all subsequent IDs, causing widespread metadata parse failures. Symptoms: entity rendering glitches, disconnections, or silent data corruption. - **CUT_STANDSTONE_SLAB**: This is an intentional typo in Minecraft source (should be SANDSTONE). MCC's `ItemType.cs` uses `CutSandstoneSlab` — the gen script handles this via the OVERRIDES dict. +- **Item/block renames across versions**: Some items/blocks get renamed (e.g., `DRY_SHORT_GRASS` → `SHORT_DRY_GRASS`, `CHAIN` → `IRON_CHAIN`). Keep old enum values for backward compatibility with older palettes, and add new ones for the new version. +- **Packet ID cascading shifts**: Even one inserted mid-list clientbound packet shifts ALL subsequent IDs. Always create a new PacketPalette for protocol changes. +- **Test existing items first**: After palette changes, always verify existing items (diamond_sword, stone, etc.) before testing new ones. If they show as wrong items, the palette has a systemic ID offset bug. ## Reusable Scripts All scripts are in `$MCC_REPO/tools/`. See `tools/README.md` for detailed usage. + +| Script | Purpose | Input | +|--------|---------|-------| +| `diff_registries.py` | Compare registries between versions | Decompiled source | +| `gen_item_palette.py` | Generate ItemPalette C# | Decompiled source OR registries.json | +| `gen_block_palette.py` | Generate BlockPalette C# | blocks.json | +| `gen_entity_palette.py` | Generate EntityPalette C# | registries.json | +| `gen_entity_metadata_palette.py` | Generate EntityMetadataPalette C# | Decompiled source | diff --git a/tools/README.md b/tools/README.md index cce914df..17df9676 100644 --- a/tools/README.md +++ b/tools/README.md @@ -2,46 +2,115 @@ Scripts for analyzing Minecraft version differences and generating MCC palette files. -Requires: Python 3.10+, decompiled MC server source in `MinecraftOfficial/-decompiled/`. +Requires: Python 3.10+ -## Decompiling a new MC version +## Data Sources + +Two types of data can be used as input: + +| Source | How to Get | Authoritative? | +|--------|-----------|---------------| +| Decompiled Java source | `MinecraftDecompiler.jar` → `MinecraftOfficial/-decompiled/` | Mostly (see caveat below) | +| Server data reports | `java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports` | **Yes** | + +**Important since MC 1.21.9**: Some items and blocks are registered outside `Items.java`/`Blocks.java` field declarations (via block registration callbacks). In these cases, the decompiled source undercounts entries. **Always use server data reports** for item and block palettes when available. + +### Decompiling a new MC version ```bash cd MinecraftOfficial -java -jar MinecraftDecompiler.jar --version 1.21.4 --side SERVER \ - --decompile --output 1.21.4-remapped.jar --decompiled-output 1.21.4-decompiled +java -jar MinecraftDecompiler.jar --version 1.21.9 --side SERVER \ + --decompile --output 1.21.9-remapped.jar --decompiled-output 1.21.9-decompiled ``` +### Generating server data reports + +```bash +cd /tmp +java -DbundlerMainClass=net.minecraft.data.Main \ + -jar /path/to/server.jar \ + --reports --output /tmp/mc_reports +``` + +This generates: +- `/tmp/mc_reports/reports/registries.json` — all registries with protocol IDs +- `/tmp/mc_reports/reports/blocks.json` — all blocks with block state IDs +- `/tmp/mc_reports/reports/packets.json` — packet protocol definitions + ## diff_registries.py — Compare registries between versions Compares Items, EntityTypes, Blocks, DataComponents, and EntityDataSerializers between two MC versions. Reports whether each palette needs updating, lists added/removed entries, and shows ID shift statistics. ```bash -python3 tools/diff_registries.py 1.20.6 1.21.1 +# Basic comparison (decompiled source only) +python3 tools/diff_registries.py 1.21.8 1.21.9 + +# With cross-validation against server registries.json (recommended) +python3 tools/diff_registries.py 1.21.8 1.21.9 --registry /tmp/mc_reports/reports/registries.json ``` +The `--registry` flag enables cross-validation: compares the count and set of entries found in decompiled Java source against the server's authoritative registry. Any mismatches indicate that palette generation must use server data instead of Java source. + Output indicates for each registry: - **IDENTICAL** → reuse existing palette - **PALETTE UPDATE NEEDED** → create new palette file + update version routing +- **Count MISMATCH** (with --registry) → server has entries not in Java source ## gen_item_palette.py — Generate ItemPalette C# file -Reads `Items.java` field declaration order to generate a complete `ItemPaletteXXX.cs`. +Two modes: ```bash +# Preferred: from server registries.json (accurate since 1.21.9) +python3 tools/gen_item_palette.py --from-registry /tmp/mc_reports/reports/registries.json 1219 + +# Legacy: from decompiled Items.java python3 tools/gen_item_palette.py 1.21.1 121 -# → MinecraftClient/Inventory/ItemPalettes/ItemPalette121.cs ``` -Also validates each item name against `ItemType.cs` and warns about missing enum values. +Output: `MinecraftClient/Inventory/ItemPalettes/ItemPalette.cs` + +Validates each item name against `ItemType.cs` and warns about missing enum values. Add missing values to `ItemType.cs` in alphabetical order before compiling. + +## gen_block_palette.py — Generate BlockPalette C# file + +```bash +python3 tools/gen_block_palette.py /tmp/mc_reports/reports/blocks.json 1219 +# → MinecraftClient/Mapping/BlockPalettes/Palette1219.cs +``` + +Generates a complete block palette with block state ID ranges from the server's `blocks.json`. Validates against `Material.cs` and warns about missing enum values. + +## gen_entity_palette.py — Generate EntityPalette C# file + +```bash +python3 tools/gen_entity_palette.py /tmp/mc_reports/reports/registries.json 1219 +# → MinecraftClient/Mapping/EntityPalettes/EntityPalette1219.cs +``` + +Generates entity type palette from server's `registries.json`. Validates against `EntityType.cs` and warns about missing enum values. ## gen_entity_metadata_palette.py — Generate EntityMetadataPalette C# file -Reads `EntityDataSerializers.java` static block registration order to generate `EntityMetadataPaletteXXX.cs`. - ```bash -python3 tools/gen_entity_metadata_palette.py 1.20.6 1206 -# → MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1206.cs +python3 tools/gen_entity_metadata_palette.py 1.21.9 1219 +# → MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette1219.cs ``` -The script maps Java field names to MCC's `EntityMetaDataType` enum. If a new serializer type appears that isn't in the mapping table, it will warn you to update both the script's `FIELD_TO_ENUM` dict and MCC's `EntityMetaDataType.cs` enum. +Reads `EntityDataSerializers.java` static block registration order. Maps Java field names to MCC's `EntityMetaDataType` enum. If a new serializer type appears that isn't in the mapping table, it will warn you to update: +1. The script's `FIELD_TO_ENUM` dict +2. MCC's `EntityMetaDataType.cs` enum +3. `DataTypes.cs` ReadNextMetadata() read logic + +## Recommended workflow + +1. Generate server reports (Step 0) +2. Run `diff_registries.py --registry` to identify changes and validate source completeness +3. For each registry needing update: + - Items: `gen_item_palette.py --from-registry` + - Blocks: `gen_block_palette.py` + - Entities: `gen_entity_palette.py` + - Metadata: `gen_entity_metadata_palette.py` +4. Add any missing enum values to `ItemType.cs`, `Material.cs`, `EntityType.cs`, `EntityMetaDataType.cs` +5. Update version routing (see SKILL.md) +6. Build and test diff --git a/tools/diff_registries.py b/tools/diff_registries.py index cc26c31f..aba04dff 100644 --- a/tools/diff_registries.py +++ b/tools/diff_registries.py @@ -6,12 +6,19 @@ Compares Items, EntityTypes, Blocks, DataComponents, and EntityDataSerializers to determine which MCC palettes need updating for a new MC version. Usage: - python3 tools/diff_registries.py + python3 tools/diff_registries.py [--registry ] -Example: +Examples: python3 tools/diff_registries.py 1.20.6 1.21.1 + python3 tools/diff_registries.py 1.21.8 1.21.9 --registry /tmp/mc_reports/reports/registries.json + +The optional --registry flag cross-validates decompiled source counts against +the server's authoritative registries.json (generated via --reports). +Since MC 1.21.9, some items/blocks are registered outside Items.java/Blocks.java, +making this cross-validation essential for detecting hidden entries. """ +import json import re import sys import os @@ -65,7 +72,7 @@ def extract_static_register_order(filepath: Path) -> list[str]: return results -def compare_lists(old: list[str], new: list[str], label: str): +def compare_lists(old: list[str], new: list[str], label: str) -> bool: """Compare two ordered lists and report differences.""" set_old, set_new = set(old), set(new) added = sorted(set_new - set_old) @@ -117,7 +124,46 @@ def compare_lists(old: list[str], new: list[str], label: str): return True -def diff_items(old_dir: Path, new_dir: Path): +def cross_validate(registry_data: dict, java_entries: list[str], registry_key: str, + label: str, convert_fn=None): + """Cross-validate Java source entries against server registries.json.""" + reg = registry_data.get(registry_key, {}).get("entries", {}) + server_names = set() + for key in reg: + name = key.removeprefix("minecraft:") + server_names.add(name) + + if convert_fn: + java_names = set(convert_fn(n) for n in java_entries) + else: + java_names = set(n.lower() for n in java_entries) + + server_count = len(server_names) + java_count = len(java_names) + + print(f"\n --- Cross-validation: {label} ---") + print(f" Java source: {java_count} entries, Server registry: {server_count} entries") + + if server_count == java_count: + print(f" ✓ Counts match — Java source is complete") + else: + diff = server_count - java_count + print(f" ⚠ Count MISMATCH: server has {diff:+d} entries vs Java source") + extra_in_server = server_names - java_names + extra_in_java = java_names - server_names + if extra_in_server: + print(f" In server but NOT in Java source ({len(extra_in_server)}):") + for n in sorted(extra_in_server): + pid = reg[f"minecraft:{n}"]["protocol_id"] + print(f" [{pid}] {n}") + print(f" ⚠ MUST use --from-registry / server data to generate palette!") + if extra_in_java: + print(f" In Java source but NOT in server ({len(extra_in_java)}):") + for n in sorted(extra_in_java): + print(f" {n}") + + +def diff_items(old_dir: Path, new_dir: Path, registry_data: dict | None = None): old_f = find_java_file(old_dir, "net/minecraft/world/item/Items.java") new_f = find_java_file(new_dir, "net/minecraft/world/item/Items.java") if not old_f or not new_f: @@ -128,8 +174,12 @@ def diff_items(old_dir: Path, new_dir: Path): new = extract_field_names(new_f, pattern) compare_lists(old, new, "Items.java (Item registry)") + if registry_data: + cross_validate(registry_data, new, "minecraft:item", "Items", + convert_fn=lambda n: n.lower()) -def diff_entity_types(old_dir: Path, new_dir: Path): + +def diff_entity_types(old_dir: Path, new_dir: Path, registry_data: dict | None = None): old_f = find_java_file(old_dir, "net/minecraft/world/entity/EntityType.java") new_f = find_java_file(new_dir, "net/minecraft/world/entity/EntityType.java") if not old_f or not new_f: @@ -139,8 +189,12 @@ def diff_entity_types(old_dir: Path, new_dir: Path): new = extract_register_multiline(new_f) compare_lists(old, new, "EntityType.java (Entity registry)") + if registry_data: + cross_validate(registry_data, new, "minecraft:entity_type", "EntityType", + convert_fn=lambda n: n) -def diff_blocks(old_dir: Path, new_dir: Path): + +def diff_blocks(old_dir: Path, new_dir: Path, registry_data: dict | None = None): old_f = find_java_file(old_dir, "net/minecraft/world/level/block/Blocks.java") new_f = find_java_file(new_dir, "net/minecraft/world/level/block/Blocks.java") if not old_f or not new_f: @@ -150,6 +204,10 @@ def diff_blocks(old_dir: Path, new_dir: Path): new = extract_register_multiline(new_f) compare_lists(old, new, "Blocks.java (Block registry)") + if registry_data: + cross_validate(registry_data, new, "minecraft:block", "Blocks", + convert_fn=lambda n: n) + def diff_data_components(old_dir: Path, new_dir: Path): old_f = find_java_file(old_dir, "net/minecraft/core/component/DataComponents.java") @@ -183,11 +241,23 @@ def diff_entity_data_serializers(old_dir: Path, new_dir: Path): def main(): - if len(sys.argv) != 3: + # Parse arguments + args = sys.argv[1:] + registry_path = None + + if "--registry" in args: + idx = args.index("--registry") + if idx + 1 >= len(args): + print("Error: --registry requires a path argument") + sys.exit(1) + registry_path = Path(args[idx + 1]) + args = args[:idx] + args[idx + 2:] + + if len(args) != 2: print(__doc__) sys.exit(1) - old_ver, new_ver = sys.argv[1], sys.argv[2] + old_ver, new_ver = args[0], args[1] old_dir = DECOMPILED_ROOT / f"{old_ver}-decompiled" new_dir = DECOMPILED_ROOT / f"{new_ver}-decompiled" @@ -199,13 +269,22 @@ def main(): f"--output {v}-remapped.jar --decompiled-output {v}-decompiled") sys.exit(1) + registry_data = None + if registry_path: + if not registry_path.exists(): + print(f"Error: {registry_path} not found") + sys.exit(1) + with open(registry_path) as f: + registry_data = json.load(f) + print(f"Loaded server registries.json for cross-validation") + print(f"Comparing MC {old_ver} → {new_ver}") print(f"Old: {old_dir}") print(f"New: {new_dir}") - diff_items(old_dir, new_dir) - diff_entity_types(old_dir, new_dir) - diff_blocks(old_dir, new_dir) + diff_items(old_dir, new_dir, registry_data) + diff_entity_types(old_dir, new_dir, registry_data) + diff_blocks(old_dir, new_dir, registry_data) diff_data_components(old_dir, new_dir) diff_entity_data_serializers(old_dir, new_dir) @@ -215,6 +294,10 @@ def main(): print(" Review each section above. For any marked 'PALETTE UPDATE NEEDED',") print(" create a new palette file in MCC and update the version routing.") print(" For 'IDENTICAL' sections, the existing palette can be reused.") + if registry_data: + print("\n Cross-validation was performed against server registries.json.") + print(" If any count mismatches were found, use server data generator output") + print(" (--from-registry) instead of decompiled Java source for palette generation.") if __name__ == "__main__": diff --git a/tools/gen_block_palette.py b/tools/gen_block_palette.py new file mode 100644 index 00000000..03c48eca --- /dev/null +++ b/tools/gen_block_palette.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +""" +Generate an MCC BlockPalette C# file from server-generated blocks.json. + +The blocks.json file is generated by running: + java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports + +Usage: + python3 tools/gen_block_palette.py + +Example: + python3 tools/gen_block_palette.py /tmp/mc_reports/reports/blocks.json 1219 + # Generates Palette1219.cs +""" + +import json +import re +import sys +from pathlib import Path + +OUTPUT_DIR = (Path(__file__).resolve().parent.parent / + "MinecraftClient" / "Mapping" / "BlockPalettes") +MATERIAL_CS = OUTPUT_DIR.parent / "Material.cs" + + +def mc_name_to_csharp(mc_name: str) -> str: + """Convert minecraft:snake_case to PascalCase C# enum name.""" + name = mc_name.removeprefix("minecraft:") + return "".join(word.capitalize() for word in name.split("_")) + + +def load_known_materials() -> set[str]: + known = set() + if MATERIAL_CS.exists(): + with open(MATERIAL_CS) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m: + known.add(m.group(1)) + return known + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + + blocks_json = Path(sys.argv[1]) + class_suffix = sys.argv[2] + + if not blocks_json.exists(): + print(f"Error: {blocks_json} not found") + sys.exit(1) + + with open(blocks_json) as f: + data = json.load(f) + + # Build (min_state, max_state, cs_name) for each block, sorted by min_state + block_ranges = [] + for block_key, block_info in data.items(): + cs_name = mc_name_to_csharp(block_key) + states = block_info.get("states", []) + state_ids = [s["id"] for s in states] + if state_ids: + block_ranges.append((min(state_ids), max(state_ids), cs_name)) + + block_ranges.sort(key=lambda x: x[0]) + print(f"Loaded {len(block_ranges)} blocks from {blocks_json}") + + max_state = max(r[1] for r in block_ranges) + print(f"State ID range: 0 - {max_state}") + + known_materials = load_known_materials() + missing = [cs for _, _, cs in block_ranges if known_materials and cs not in known_materials] + if missing: + print(f"\nWARNING: {len(missing)} blocks not found in Material.cs enum:") + for cs_name in missing: + print(f" {cs_name}") + print("\nYou need to add these to Material.cs before the palette will compile.") + print("Insert them in alphabetical order within the enum.") + + class_name = f"Palette{class_suffix}" + output_path = OUTPUT_DIR / f"{class_name}.cs" + + lines = [ + "using System.Collections.Generic;", + "", + "namespace MinecraftClient.Mapping.BlockPalettes", + "{", + f" public class {class_name} : BlockPalette", + " {", + " private static readonly Dictionary materials = new();", + "", + f" static {class_name}()", + " {", + ] + + for min_s, max_s, cs_name in block_ranges: + lines.append(f" for (int i = {min_s}; i <= {max_s}; i++)") + lines.append(f" materials[i] = Material.{cs_name};") + + lines += [ + " }", + "", + " protected override Dictionary GetDict()", + " {", + " return materials;", + " }", + " }", + "}", + "", + ] + + output_path.write_text("\n".join(lines)) + print(f"Generated {output_path} with {len(block_ranges)} blocks ({max_state + 1} total states)") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_entity_palette.py b/tools/gen_entity_palette.py new file mode 100644 index 00000000..a932d591 --- /dev/null +++ b/tools/gen_entity_palette.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +""" +Generate an MCC EntityPalette C# file from server-generated registries.json. + +The registries.json file is generated by running: + java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports + +Usage: + python3 tools/gen_entity_palette.py + +Example: + python3 tools/gen_entity_palette.py /tmp/mc_reports/reports/registries.json 1219 + # Generates EntityPalette1219.cs +""" + +import json +import re +import sys +from pathlib import Path + +OUTPUT_DIR = (Path(__file__).resolve().parent.parent / + "MinecraftClient" / "Mapping" / "EntityPalettes") +ENTITY_TYPE_CS = OUTPUT_DIR.parent / "EntityType.cs" + + +def mc_name_to_csharp(mc_name: str) -> str: + """Convert minecraft:snake_case to PascalCase C# enum name.""" + name = mc_name.removeprefix("minecraft:") + return "".join(word.capitalize() for word in name.split("_")) + + +def load_known_entity_types() -> set[str]: + known = set() + if ENTITY_TYPE_CS.exists(): + with open(ENTITY_TYPE_CS) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m: + known.add(m.group(1)) + return known + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + + registry_path = Path(sys.argv[1]) + class_suffix = sys.argv[2] + + if not registry_path.exists(): + print(f"Error: {registry_path} not found") + sys.exit(1) + + with open(registry_path) as f: + data = json.load(f) + + entities_reg = data.get("minecraft:entity_type", {}).get("entries", {}) + mappings = [] + for entity_key, info in entities_reg.items(): + pid = info["protocol_id"] + cs_name = mc_name_to_csharp(entity_key) + mappings.append((pid, cs_name)) + + mappings.sort(key=lambda x: x[0]) + print(f"Loaded {len(mappings)} entity types from {registry_path}") + + known = load_known_entity_types() + missing = [cs for _, cs in mappings if known and cs not in known] + if missing: + print(f"\nWARNING: {len(missing)} entity types not found in EntityType.cs enum:") + for cs_name in missing: + print(f" {cs_name}") + print("\nYou need to add these to EntityType.cs before the palette will compile.") + print("Insert them in alphabetical order within the enum.") + + class_name = f"EntityPalette{class_suffix}" + output_path = OUTPUT_DIR / f"{class_name}.cs" + + lines = [ + "using System.Collections.Generic;", + "", + "namespace MinecraftClient.Mapping.EntityPalettes", + "{", + f" public class {class_name} : EntityPalette", + " {", + " private static readonly Dictionary mappings = new();", + "", + f" static {class_name}()", + " {", + ] + for pid, cs_name in mappings: + lines.append(f" mappings[{pid}] = EntityType.{cs_name};") + lines += [ + " }", + "", + " protected override Dictionary GetDict()", + " {", + " return mappings;", + " }", + " }", + "}", + "", + ] + + output_path.write_text("\n".join(lines)) + print(f"Generated {output_path} with {len(mappings)} entity types") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_item_palette.py b/tools/gen_item_palette.py index 92643977..5a85963b 100644 --- a/tools/gen_item_palette.py +++ b/tools/gen_item_palette.py @@ -1,36 +1,43 @@ #!/usr/bin/env python3 """ -Generate an MCC ItemPalette C# file from decompiled Items.java. +Generate an MCC ItemPalette C# file. -Reads public static final Item field declarations (which define item IDs -by declaration order) and generates a complete C# palette class. +Supports two input modes: + 1. Server registry (preferred since 1.21.9): + python3 tools/gen_item_palette.py --from-registry /tmp/mc_reports/reports/registries.json -Usage: - python3 tools/gen_item_palette.py + 2. Decompiled Items.java (legacy): + python3 tools/gen_item_palette.py -Example: - python3 tools/gen_item_palette.py 1.21.1 121 - # Generates ItemPalette121.cs +The --from-registry mode uses the server's authoritative protocol_id assignments, +which is required since MC 1.21.9 where some items are registered outside Items.java. -The determines the class name (ItemPalette) and -should match MCC's naming convention (e.g., 121 for 1.21, 1206 for 1.20.6). +The determines the class name (ItemPalette) and should match MCC's +naming convention (e.g., 121 for 1.21, 1219 for 1.21.9). """ +import json import re import sys from pathlib import Path DECOMPILED_ROOT = Path(__file__).resolve().parent.parent / "MinecraftOfficial" OUTPUT_DIR = Path(__file__).resolve().parent.parent / "MinecraftClient" / "Inventory" / "ItemPalettes" +ITEM_TYPE_CS = OUTPUT_DIR.parent / "ItemType.cs" -# Java field name → C# ItemType enum name -# Most conversions are automatic (SCREAMING_SNAKE → PascalCase). -# Add manual overrides here for irregular names. OVERRIDES = { "CUT_STANDSTONE_SLAB": "CutSandstoneSlab", # Mojang typo in source } +def mc_name_to_csharp(mc_name: str) -> str: + """Convert minecraft:snake_case to PascalCase C# enum name.""" + name = mc_name.removeprefix("minecraft:") + if name.upper() in OVERRIDES: + return OVERRIDES[name.upper()] + return "".join(word.capitalize() for word in name.split("_")) + + def java_to_csharp_name(java_name: str) -> str: """Convert SCREAMING_SNAKE_CASE Java field name to PascalCase C# enum name.""" if java_name in OVERRIDES: @@ -38,52 +45,81 @@ def java_to_csharp_name(java_name: str) -> str: return "".join(word.capitalize() for word in java_name.lower().split("_")) -def main(): - if len(sys.argv) != 3: - print(__doc__) - sys.exit(1) +def load_known_enums() -> set[str]: + known = set() + if ITEM_TYPE_CS.exists(): + with open(ITEM_TYPE_CS) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m and m.group(1) not in ("Null", "Unknown"): + known.add(m.group(1)) + return known - mc_version = sys.argv[1] - class_suffix = sys.argv[2] + +def items_from_registry(registry_path: Path) -> list[tuple[int, str]]: + """Load items from server registries.json, returns sorted (protocol_id, cs_name) pairs.""" + with open(registry_path) as f: + data = json.load(f) + items_reg = data.get("minecraft:item", {}).get("entries", {}) + result = [] + for item_key, info in items_reg.items(): + pid = info["protocol_id"] + cs_name = mc_name_to_csharp(item_key) + result.append((pid, cs_name)) + result.sort(key=lambda x: x[0]) + return result + + +def items_from_java(mc_version: str) -> list[tuple[int, str]]: + """Load items from decompiled Items.java field declaration order.""" version_dir = DECOMPILED_ROOT / f"{mc_version}-decompiled" items_java = version_dir / "net" / "minecraft" / "world" / "item" / "Items.java" - if not items_java.exists(): print(f"Error: {items_java} not found") sys.exit(1) pattern = re.compile(r'\s+public static final Item (\w+)\s*=') - field_names = [] + result = [] with open(items_java) as f: for line in f: m = pattern.match(line) if m: - field_names.append(m.group(1)) + idx = len(result) + cs_name = java_to_csharp_name(m.group(1)) + result.append((idx, cs_name)) + return result - print(f"Found {len(field_names)} items in MC {mc_version}") - # Verify enum name conversion against existing ItemType.cs - item_type_cs = OUTPUT_DIR.parent / "ItemType.cs" - known_enums = set() - if item_type_cs.exists(): - with open(item_type_cs) as f: - for line in f: - m = re.match(r'\s+(\w+),?\s*$', line) - if m and m.group(1) not in ("Null", "Unknown"): - known_enums.add(m.group(1)) +def main(): + if len(sys.argv) < 3: + print(__doc__) + sys.exit(1) - missing = [] - mappings = [] - for i, name in enumerate(field_names): - cs_name = java_to_csharp_name(name) - mappings.append((i, cs_name)) - if known_enums and cs_name not in known_enums: - missing.append((i, name, cs_name)) + from_registry = sys.argv[1] == "--from-registry" + if from_registry: + if len(sys.argv) != 4: + print("Usage: gen_item_palette.py --from-registry ") + sys.exit(1) + registry_path = Path(sys.argv[2]) + class_suffix = sys.argv[3] + if not registry_path.exists(): + print(f"Error: {registry_path} not found") + sys.exit(1) + mappings = items_from_registry(registry_path) + print(f"Loaded {len(mappings)} items from {registry_path}") + else: + mc_version = sys.argv[1] + class_suffix = sys.argv[2] + mappings = items_from_java(mc_version) + print(f"Found {len(mappings)} items in MC {mc_version} Items.java") + + known_enums = load_known_enums() + missing = [(pid, cs) for pid, cs in mappings if known_enums and cs not in known_enums] if missing: print(f"\nWARNING: {len(missing)} items not found in ItemType.cs enum:") - for idx, java_name, cs_name in missing: - print(f" [{idx}] {java_name} -> {cs_name}") + for pid, cs_name in missing: + print(f" [{pid}] {cs_name}") print("\nYou need to add these to ItemType.cs before the palette will compile.") print("Insert them in alphabetical order within the enum.") @@ -102,8 +138,8 @@ def main(): f" static {class_name}()", " {", ] - for idx, cs_name in mappings: - lines.append(f" mappings[{idx}] = ItemType.{cs_name};") + for pid, cs_name in mappings: + lines.append(f" mappings[{pid}] = ItemType.{cs_name};") lines += [ " }", "", From 918f1a560d12f0eff60b0591e016b071f3bd5515 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 14:44:47 +0100 Subject: [PATCH 077/484] Centralized skills to .skills folder. --- .claude/skills | 1 + .codex/skills | 1 + .cursor/skills | 1 + .gitignore | 4 ++- .skills/mcc-dev-workflow/SKILL.md | 28 +++++++++++++++++++ .../mcc-version-adaptation/SKILL.md | 0 6 files changed, 34 insertions(+), 1 deletion(-) create mode 120000 .claude/skills create mode 120000 .codex/skills create mode 120000 .cursor/skills create mode 100644 .skills/mcc-dev-workflow/SKILL.md rename {.cursor/skills => .skills}/mcc-version-adaptation/SKILL.md (100%) diff --git a/.claude/skills b/.claude/skills new file mode 120000 index 00000000..4ca0ec66 --- /dev/null +++ b/.claude/skills @@ -0,0 +1 @@ +../.skills \ No newline at end of file diff --git a/.codex/skills b/.codex/skills new file mode 120000 index 00000000..4ca0ec66 --- /dev/null +++ b/.codex/skills @@ -0,0 +1 @@ +../.skills \ No newline at end of file diff --git a/.cursor/skills b/.cursor/skills new file mode 120000 index 00000000..4ca0ec66 --- /dev/null +++ b/.cursor/skills @@ -0,0 +1 @@ +../.skills \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6a75425a..d50b7434 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ /Other/ /.vs/ SessionCache.ini -.* !/.github /packages @@ -428,3 +427,6 @@ MinecraftOfficial/ /mcc_input.txt /MinecraftClient.ini /MinecraftClient.backup.ini + +# Other +.* diff --git a/.skills/mcc-dev-workflow/SKILL.md b/.skills/mcc-dev-workflow/SKILL.md new file mode 100644 index 00000000..bc721633 --- /dev/null +++ b/.skills/mcc-dev-workflow/SKILL.md @@ -0,0 +1,28 @@ +# MCC Development Workflow + +## Project Overview +- Repo: `~/Minecraft/Minecraft-Console-Client` (env var `$MCC_REPO`) +- Solution: `MinecraftClient.sln` (projects: `MinecraftClient` + `ConsoleInteractive`) +- Build: `dotnet build MinecraftClient.sln -c Release` +- Servers: `~/Minecraft/Servers/` (env var `$MCC_SERVERS`) + +## Typical Debug Workflow +1. `~/Minecraft/Servers/start-server.sh 1.20.6-Vanilla` (background) +2. Wait for "Done" in server output +3. Build: `dotnet build $MCC_REPO/MinecraftClient.sln -c Release` +4. Run MCC: `cd $MCC_REPO && MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release -- CursorBot - localhost 2>&1` +5. RCON: `mc-rcon "op CursorBot"` +6. MCC cmd: `echo "inventory player list" >> $MCC_REPO/mcc_input.txt` +7. Read terminal file to see output +8. Kill MCC → rebuild → repeat + +## Timing Reference +| Operation | Typical Duration | +|-----------|-----------------| +| MCC startup → join server | ~1s | +| FileInput command → response | <500ms | + +## Official Minecraft Server Source (Decompiled) +`$MCC_REPO/MinecraftOfficial/` contains decompiled official server code for protocol reference. +When investigating protocol details (packet structure, field order, NBT format, etc.), +look at the corresponding version's decompiled source as authoritative reference. diff --git a/.cursor/skills/mcc-version-adaptation/SKILL.md b/.skills/mcc-version-adaptation/SKILL.md similarity index 100% rename from .cursor/skills/mcc-version-adaptation/SKILL.md rename to .skills/mcc-version-adaptation/SKILL.md From a1c1dbc182ca70ab5855cfeb978fb453abea5b3b Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 17:34:34 +0100 Subject: [PATCH 078/484] Added bot creation skill --- .gitignore | 14 +- .skills/mcc-chatbot-authoring/SKILL.md | 107 ++++ .../assets/builtin-chatbot-template.cs | 57 ++ .../assets/script-chatbot-template.cs | 37 ++ .../references/authoring-reference.md | 492 ++++++++++++++++++ .../references/pattern-cookbook.md | 330 ++++++++++++ 6 files changed, 1030 insertions(+), 7 deletions(-) create mode 100644 .skills/mcc-chatbot-authoring/SKILL.md create mode 100644 .skills/mcc-chatbot-authoring/assets/builtin-chatbot-template.cs create mode 100644 .skills/mcc-chatbot-authoring/assets/script-chatbot-template.cs create mode 100644 .skills/mcc-chatbot-authoring/references/authoring-reference.md create mode 100644 .skills/mcc-chatbot-authoring/references/pattern-cookbook.md diff --git a/.gitignore b/.gitignore index d50b7434..b00da3f6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,15 @@ /Other/ /.vs/ SessionCache.ini -!/.github /packages +# OS-generated files +.DS_Store +Thumbs.db +desktop.ini +ehthumbs.db +._* + ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## @@ -386,9 +392,6 @@ FodyWeavers.xsd !.vscode/extensions.json *.code-workspace -# Cursor files -!.cursor/ - # Local History for Visual Studio Code .history/ @@ -427,6 +430,3 @@ MinecraftOfficial/ /mcc_input.txt /MinecraftClient.ini /MinecraftClient.backup.ini - -# Other -.* diff --git a/.skills/mcc-chatbot-authoring/SKILL.md b/.skills/mcc-chatbot-authoring/SKILL.md new file mode 100644 index 00000000..3934c268 --- /dev/null +++ b/.skills/mcc-chatbot-authoring/SKILL.md @@ -0,0 +1,107 @@ +--- +name: mcc-chatbot-authoring +description: Create, modify, repair, and wire Minecraft Console Client ChatBots and standalone `/script` bots. Use this whenever the user wants an MCC bot, C# script bot, chat or event handlers, periodic automation, movement logic, inventory logic, plugin-channel handling, or asks to fix or port an existing bot; default to standalone `//MCCScript` bots unless the user explicitly asks for a built-in MCC bot or repo wiring. +--- + +# MCC ChatBot Authoring + +Implement MCC chat bots against the bundled MCC authoring reference. Do not invent methods, lifecycle hooks, or registration steps. + +Always read: +- `references/authoring-reference.md` + +Load only as needed: +- `references/pattern-cookbook.md` for concrete standalone examples +- `assets/script-chatbot-template.cs` for the default standalone `/script` path +- `assets/builtin-chatbot-template.cs` only when the user explicitly requests a built-in bot + +If the current workspace contains an MCC checkout, verify final names and signatures against local sources before editing. The skill should still work without those files. +If there is no MCC checkout available, rely on the bundled reference and cookbook as the full source of truth for authoring patterns. + +## Choose the bot type first + +1. Default to a standalone script bot loaded with `/script`. +2. Only choose a built-in bot when the user explicitly asks for a compiled MCC bot, repo wiring, automatic config loading, or changes under the built-in bot system. +3. If the prompt is ambiguous, infer the likely target from commands, requested output files, or phrasing, state the assumption briefly, and proceed. +4. If a user says only "make a bot", do not create a built-in bot. + +## Source priority + +When the local MCC checkout is available, prefer these sources in this order: +1. `MinecraftClient/Scripting/ChatBot.cs` and current files under `MinecraftClient/ChatBots/` +2. the bundled `references/authoring-reference.md` +3. the bundled `references/pattern-cookbook.md` +4. older `MinecraftClient/config/` sample bots only for ideas, not as the default scaffold + +If an older sample conflicts with the current built-in bots, follow the current built-in bots. +If the local checkout is not available, do not block on missing repo files. Use the bundled references directly. + +## Hard rules + +- Only use lifecycle hooks and helpers documented in the bundled reference or verified in the target codebase. +- Do not send chat from `Initialize()`. Use `AfterGameJoined()` once the session can send messages. +- Prefer the current Brigadier command-registration pattern for built-in bots. Do not introduce `ChatBotCommand` unless the surrounding code already uses it. +- For message parsing, normalize with `GetVerbatim(text)` before `IsChatMessage(...)` or `IsPrivateMessage(...)`. +- Clean up everything you register or start: commands, plugin channels, threads, timers, and movement locks. +- If a built-in bot or long-running automation controls movement, follow a movement-lock pattern and release it on every stop path. Do not add `BotMovementLock` to a simple standalone `/script` bot unless the prompt or surrounding code explicitly needs shared movement coordination. +- For built-in bots, follow the host codebase's localization and config-comment conventions instead of scattering hardcoded user-facing text. +- For new code, prefer `Initialize()` over constructors for prerequisite checks and unload decisions. +- In this repo, built-in bot wiring usually means edits in `MinecraftClient/Settings.cs` and `MinecraftClient/McClient.cs` in addition to the bot class. +- For repair tasks, preserve the existing bot type and file layout unless the user explicitly asks for a conversion or restructure. + +## Standalone script bots + +Use the exact MCC metadata format from the bundled reference. +This is the default path for new work. + +The script should usually: +- keep `Initialize()` for cheap setup only +- use `GetText(...)`, `AfterGameJoined()`, and other event hooks for live behavior +- log with `LogToConsole(...)` +- send server chat or commands with `SendText(...)` +- use `PerformInternalCommand(...)` only for MCC internal commands +- add `//using MinecraftClient.Inventory` in metadata when the script uses inventory types explicitly +- reuse the standalone snippets in `references/pattern-cookbook.md` before inventing new scaffolding +- keep load instructions explicit, usually `/script FileName.cs` + +## Built-in bots + +Built-in bots usually need three pieces: +- the bot class itself +- config wiring in the chat-bot config model +- bot registration in the load flow + +If the codebase exposes commands, follow the built-in command and unload pattern from the bundled reference. If it exposes new settings or status text, follow the codebase's localization and config-comment patterns. + +When working in this checkout, built-in bot delivery usually needs: +- a new file under `MinecraftClient/ChatBots/` +- a config property inside `Settings.ChatBotConfigHealper.ChatBotConfig` +- a `BotLoad(new YourBot())` line inside `McClient.RegisterBots(...)` +- literal code snippets or patch hunks for the `Settings.cs` property and the `McClient.cs` registration line, not only prose notes + +## Repair flow + +When the user asks to fix or debug a bot: +- identify whether it is standalone or built-in and keep that shape unless told otherwise +- remove the broken pattern first, then preserve the intended behavior +- check especially for these regressions: `SendText(...)` in `Initialize()`, raw formatted chat parsing, inventory snapshot mutation, missing command unregister, missing plugin-channel unregister, and unreleased movement locks +- reuse the local repo's modern pattern instead of patching around a legacy helper when the helper is no longer current + +## Delivery checklist + +Before finishing, verify: +- the class inherits `ChatBot` +- the chosen overrides exist in the MCC ChatBot API +- standalone script metadata is exact if this is a `/script` bot +- built-in bots are fully wired into config and registration if needed +- all command registrations, background work, and movement locks are released +- files and namespaces match the surrounding codebase + +## Output + +When you implement or modify a bot: +- state whether it is a standalone script bot or built-in bot +- list the files you changed +- mention any required config keys or the MCC command used to load it +- when built-in wiring is involved, show the exact inserted code lines or patch hunks for `Settings.cs` and `McClient.cs` +- call out assumptions briefly if the user did not specify bot type or trigger behavior diff --git a/.skills/mcc-chatbot-authoring/assets/builtin-chatbot-template.cs b/.skills/mcc-chatbot-authoring/assets/builtin-chatbot-template.cs new file mode 100644 index 00000000..086c89e5 --- /dev/null +++ b/.skills/mcc-chatbot-authoring/assets/builtin-chatbot-template.cs @@ -0,0 +1,57 @@ +// Use this template only when the user explicitly requests a built-in MCC bot. + +using MinecraftClient.Scripting; +using Tomlet.Attributes; + +namespace MinecraftClient.ChatBots +{ + public class ExampleBot : ChatBot + { + private const string BotName = "ExampleBot"; + + public static Configs Config = new(); + + [TomlDoNotInlineObject] + public class Configs + { + public bool Enabled = false; + + public void OnSettingUpdate() + { + } + } + + public override void Initialize() + { + LogToConsole(BotName, "Initialized."); + } + + public override void AfterGameJoined() + { + } + + public override void GetText(string text) + { + text = GetVerbatim(text); + + string message = ""; + string username = ""; + + if (IsPrivateMessage(text, ref message, ref username)) + { + } + else if (IsChatMessage(text, ref message, ref username)) + { + } + } + + public override void OnUnload() + { + } + + public override bool OnDisconnect(DisconnectReason reason, string message) + { + return false; + } + } +} diff --git a/.skills/mcc-chatbot-authoring/assets/script-chatbot-template.cs b/.skills/mcc-chatbot-authoring/assets/script-chatbot-template.cs new file mode 100644 index 00000000..72be0cae --- /dev/null +++ b/.skills/mcc-chatbot-authoring/assets/script-chatbot-template.cs @@ -0,0 +1,37 @@ +//MCCScript 1.0 + +MCC.LoadBot(new ExampleScriptBot()); + +//MCCScript Extensions + +public class ExampleScriptBot : ChatBot +{ + public override void Initialize() + { + LogToConsole("ExampleScriptBot initialized."); + } + + public override void AfterGameJoined() + { + // Safe place for startup chat or commands. + } + + public override void GetText(string text) + { + text = GetVerbatim(text); + + string message = ""; + string username = ""; + + if (IsPrivateMessage(text, ref message, ref username)) + { + LogToConsole("PM from " + username + ": " + message); + return; + } + + if (IsChatMessage(text, ref message, ref username)) + { + LogToConsole("Chat from " + username + ": " + message); + } + } +} diff --git a/.skills/mcc-chatbot-authoring/references/authoring-reference.md b/.skills/mcc-chatbot-authoring/references/authoring-reference.md new file mode 100644 index 00000000..e51495ee --- /dev/null +++ b/.skills/mcc-chatbot-authoring/references/authoring-reference.md @@ -0,0 +1,492 @@ +# MCC ChatBot Reference + +Self-contained authoring notes for Minecraft Console Client chat bots. + +## Bot types + +MCC supports two common authoring paths: +- standalone script bots loaded at runtime with `/script` +- built-in bots compiled into the MCC codebase + +Default to a standalone `/script` bot unless the user explicitly asks for a built-in bot or repo wiring. + +## Embedded current patterns + +This skill is intended to work even without an MCC checkout. The patterns below capture the important behavior that would otherwise be borrowed from current repo examples. + +If the local repo is available, you can verify against files such as `TestBot.cs`, `RemoteControl.cs`, `FollowPlayer.cs`, `ItemsCollector.cs`, and `Farmer.cs`. If it is not available, use the embedded patterns here directly. + +### Minimal chat parsing pattern + +Use this as the baseline for public/private chat handling: + +```csharp +public override void GetText(string text) +{ + string message = ""; + string sender = ""; + text = GetVerbatim(text); + + if (IsPrivateMessage(text, ref message, ref sender)) + { + LogToConsole("PM from " + sender + ": " + message); + } + else if (IsChatMessage(text, ref message, ref sender)) + { + LogToConsole("Chat from " + sender + ": " + message); + } +} +``` + +What matters: +- normalize first with `GetVerbatim(text)` +- handle PMs before public chat if both matter +- keep simple chat bots deterministic and small + +### Owner-gated PM control pattern + +Use this when a bot owner should be able to whisper MCC internal commands: + +```csharp +public override void GetText(string text) +{ + text = GetVerbatim(text).Trim(); + string command = ""; + string sender = ""; + + if (IsPrivateMessage(text, ref command, ref sender) + && Settings.Config.Main.Advanced.BotOwners.Contains(sender.ToLowerInvariant())) + { + CmdResult result = new(); + PerformInternalCommand(command, ref result); + SendPrivateMessage(sender, result.ToString()); + } +} +``` + +What matters: +- `PerformInternalCommand(...)` is for MCC commands, not server chat commands +- owner gating should use `Settings.Config.Main.Advanced.BotOwners` +- if `CmdResult` is used in a standalone script, add `//using MinecraftClient.CommandHandler` + +### Periodic work pattern + +Use `Update()` plus a counter or timestamp for simple repeated work: + +```csharp +private int count = 0; + +public override void Update() +{ + count++; + if (count < Settings.DoubleToTick(60)) + return; + + count = 0; + SendText("/list"); +} +``` + +What matters: +- avoid a worker thread for simple periodic loops +- avoid `Thread.Sleep(...)` inside `Update()` +- if sending chat, do it from a join-safe path like `Update()` or `AfterGameJoined()`, not `Initialize()` + +### Built-in Brigadier command pattern + +Use this for built-in command bots: + +```csharp +public override void Initialize() +{ + McClient.dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CommandName) + .Executes(r => OnCommandHelp(r.Source, string.Empty)) + ) + ); + + McClient.dispatcher.Register(l => l.Literal(CommandName) + .Then(l => l.Literal("stop") + .Executes(r => OnCommandStop(r.Source))) + .Then(l => l.Literal("_help") + .Executes(r => OnCommandHelp(r.Source, string.Empty)) + .Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) + ); +} + +public override void OnUnload() +{ + McClient.dispatcher.Unregister(CommandName); + McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); +} +``` + +What matters: +- register commands in `Initialize()` +- unregister the command tree in `OnUnload()` +- remove the help child you added in `OnUnload()` +- prefer this over legacy command wrappers for new built-in work + +### Built-in config and wiring pattern + +Use this as the default built-in shape: + +```csharp +public class ExampleBot : ChatBot +{ + public static Configs Config = new(); + + [TomlDoNotInlineObject] + public class Configs + { + public bool Enabled = false; + + public void OnSettingUpdate() + { + } + } +} +``` + +Typical host wiring shape: + +```csharp +[TomlPrecedingComment("$ChatBot.ExampleBot$")] +public ChatBots.ExampleBot.Configs ExampleBot +{ + get { return ChatBots.ExampleBot.Config; } + set { ChatBots.ExampleBot.Config = value; ChatBots.ExampleBot.Config.OnSettingUpdate(); } +} +``` + +```csharp +if (Config.ChatBot.ExampleBot.Enabled) { BotLoad(new ExampleBot()); } +``` + +What matters: +- built-in configurable bots default to `Enabled = false` +- `OnSettingUpdate()` is the place to normalize config values +- built-in delivery is incomplete without both config wiring and load registration + +### Movement gating pattern + +Use this shape when a built-in bot owns movement: + +```csharp +public override void Initialize() +{ + if (!GetEntityHandlingEnabled()) + { + LogToConsole("Entity handling is required."); + UnloadBot(); + return; + } + + if (!GetTerrainEnabled()) + { + LogToConsole("Terrain handling is required."); + UnloadBot(); + return; + } +} +``` + +```csharp +var movementLock = BotMovementLock.Instance; +if (movementLock is { IsLocked: true }) + return; + +movementLock?.Lock("Example Bot"); +``` + +```csharp +public override void OnUnload() +{ + BotMovementLock.Instance?.UnLock("Example Bot"); +} +``` + +What matters: +- guard terrain and entity handling before movement logic +- built-in movement bots should use `BotMovementLock` +- release the lock on every stop path, including unload and disconnect-sensitive flows + +### Dropped-item collector pattern + +Use this as the standalone item-search baseline: + +```csharp +private DateTime nextScan = DateTime.MinValue; + +public override void Update() +{ + var now = DateTime.UtcNow; + if (now < nextScan || ClientIsMoving()) + return; + + nextScan = now.AddSeconds(1); + + var here = GetCurrentLocation(); + var target = GetEntities().Values + .Where(entity => entity.Type == EntityType.Item && entity.Location.Distance(here) <= 15) + .OrderBy(entity => entity.Location.Distance(here)) + .FirstOrDefault(); + + if (target != null) + MoveToLocation(target.Location); +} +``` + +What matters: +- simple standalone collectors do not need a worker thread +- simple standalone collectors also do not need `BotMovementLock` by default +- `GetEntities()` plus distance ordering is the core search pattern + +### Inventory selection pattern + +Use this as the default hotbar-switch pattern: + +```csharp +private bool TrySwitchToItem(ItemType itemType) +{ + var inventory = GetPlayerInventory(); + + var hotbarSlots = inventory.SearchItem(itemType) + .Where(slot => slot >= 36 && slot <= 44) + .ToArray(); + + if (hotbarSlots.Length == 0) + return false; + + ChangeSlot((short)(hotbarSlots[0] - 36)); + return true; +} +``` + +What matters: +- guard with `GetInventoryEnabled()` +- search inventory snapshots, but mutate real server state with helpers like `ChangeSlot(...)` +- do not treat local `Container.Items` mutation as real inventory manipulation + +Use the older config examples only for ideas, not as primary scaffolding. + +## Standalone script format + +A standalone script bot has two parts in this order: +1. metadata block +2. one or more C# classes, with the main bot class inheriting `ChatBot` + +Required metadata rules: +- line 1 must be exactly `//MCCScript 1.0` +- metadata must include `MCC.LoadBot(new BotClassName());` +- metadata ends with `//MCCScript Extensions` +- optional metadata directives use `//using Namespace` and `//dll SomeLibrary.dll` +- do not insert a space after `//` in metadata directives + +Typical runtime flow: +- place the script file beside MCC +- connect to a server +- load it with `/script YourBotFile.cs` + +### Namespace linking for inventory code + +If a standalone script uses inventory-specific types such as `Container`, `ItemType`, `WindowActionType`, or `ItemMovingHelper`, add this metadata import: + +```csharp +//using MinecraftClient.Inventory +``` + +For built-in bots, use a normal C# import: + +```csharp +using MinecraftClient.Inventory; +``` + +## Lifecycle summary + +Common lifecycle hooks: +- `Initialize()` + called once when the bot loads; use it for cheap setup only +- `AfterGameJoined()` + called after the server has been joined successfully, and again after reconnecting; use it when chat can be sent +- `Update()` + called roughly every 100 ms +- `OnUnload()` + called when the bot unloads; release resources here +- `OnDisconnect(DisconnectReason reason, string message)` + called on disconnect; stop background work and clean up reconnect-sensitive state here + +Important rule: +- do not send chat from `Initialize()`; use `AfterGameJoined()` instead +- prefer `Initialize()` over constructors for environment checks and resource setup + +## Common event hooks + +Useful event hooks include: +- `GetText(string text)` +- `GetText(string text, string? json)` +- `OnPlayerJoin(Guid uuid, string name)` +- `OnPlayerLeave(Guid uuid, string? name)` +- `OnEntitySpawn(Entity entity)` +- `OnEntityDespawn(Entity entity)` +- `OnEntityMove(Entity entity)` +- `OnHealthUpdate(float health, int food)` +- `OnMapData(...)` +- `OnInventoryUpdate(int inventoryId)` +- `OnPluginMessage(string channel, byte[] data)` +- `OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound)` + +Only override hooks that actually exist in the target MCC ChatBot API. + +## Common helpers + +Text and messaging helpers: +- `GetVerbatim(text)` strips Minecraft formatting codes +- `IsChatMessage(text, ref message, ref sender)` parses public chat +- `IsPrivateMessage(text, ref message, ref sender)` parses private chat +- `IsValidName(username)` validates a Minecraft username +- `SendText(text)` sends chat or server commands +- `SendPrivateMessage(player, message)` sends a private message +- `PerformInternalCommand(command, ...)` runs an internal MCC command, not a server command +- `LogToConsole(text)` writes a bot-prefixed console message + +Lifecycle and threading helpers: +- `InvokeOnMainThread(...)` +- `ScheduleOnMainThread(...)` +- `ReconnectToTheServer(...)` +- `UnloadBot()` +- `BotLoad(chatBot)` +- `RunScript(filename, ...)` + +World and player-state helpers: +- `GetWorld()` +- `GetEntities()` +- `GetCurrentLocation()` +- `ClientIsMoving()` +- `GetOnlinePlayers()` +- `GetOnlinePlayersWithUUID()` +- `GetServerTPS()` +- `GetProtocolVersion()` + +Movement and inventory helpers: +- `MoveToLocation(...)` +- `LookAtLocation(...)` +- `GetInventoryEnabled()` +- `GetPlayerInventory()` +- `GetInventories()` +- `GetItemMovingHelper(...)` +- `WindowAction(...)` +- `ChangeSlot(...)` +- `GetCurrentSlot()` +- `UseItemInHand()` +- `UseItemInLeftHand()` +- `CloseInventory(...)` +- `DigBlock(...)` +- `InteractEntity(...)` + +## Inventory notes + +Inventory handling is optional in MCC. Check `GetInventoryEnabled()` before relying on inventory state or mutation. + +Important behavior: +- `GetPlayerInventory()` returns a snapshot copy of the player's inventory +- `GetInventories()` returns current container snapshots +- writing to those `Container` objects locally does not update the server +- to actually change inventory state, use `ChangeSlot(...)`, `WindowAction(...)`, `GetItemMovingHelper(...)`, `UseItemInHand()`, or related helpers + +Useful practical facts: +- hotbar selection uses `ChangeSlot(0..8)` +- hotbar slots are commonly `36..44` in inventory slot numbering +- the offhand slot is commonly `45` +- `Container.SearchItem(...)` is the normal way to locate items by type + +Good inventory workflow: +1. guard with `GetInventoryEnabled()` +2. read the current container using `GetPlayerInventory()` +3. locate slots with `SearchItem(...)` or `Items` +4. mutate server state using `ChangeSlot(...)`, `WindowAction(...)`, or `ItemMovingHelper` +5. if needed, react to `OnInventoryUpdate(...)`, `OnInventoryOpen(...)`, or `OnInventoryClose(...)` + +Plugins and channels: +- `RegisterPluginChannel(channel)` +- `UnregisterPluginChannel(channel)` +- `SendPluginChannelMessage(channel, data, ...)` + +## Built-in bot pattern + +A built-in bot usually follows this shape: +- a class that inherits `ChatBot` +- an optional static `Config` field +- a nested `[TomlDoNotInlineObject]` `Configs` class for settings +- an `Enabled = false` setting by default +- `OnSettingUpdate()` to normalize or validate config values + +If the bot is configurable, the host codebase usually also needs: +- config wiring in the chat-bot config model +- load registration so enabled bots are instantiated automatically + +In this MCC checkout, the usual built-in wiring points are: +- `MinecraftClient/Settings.cs` inside `Settings.ChatBotConfigHealper.ChatBotConfig` +- `MinecraftClient/McClient.cs` inside `RegisterBots(...)` + +Match the surrounding `[TomlPrecedingComment(...)]`, property-forwarding, and `BotLoad(new YourBot())` style instead of inventing a different config path. +When presenting built-in wiring, prefer literal code snippets or patch hunks for those two edits so the wiring can be checked directly. + +If the bot adds user-facing settings or messages, follow the host codebase's localization and config-comment conventions instead of scattering hardcoded strings. + +## Command pattern + +For standalone script bots, prefer chat or PM handling in `GetText(...)` unless the user explicitly asks for built-in command registration. + +For built-in commands, prefer the current Brigadier dispatcher pattern: +- register commands in `Initialize()` +- add a help entry if the bot exposes commands +- unregister the command tree in `OnUnload()` +- remove any help child added during registration in `OnUnload()` + +Avoid using legacy command wrappers if the current codebase uses direct dispatcher registration. +In this checkout, treat direct `McClient.dispatcher.Register(...)` usage in current built-in bots as the source of truth. + +## Concurrency and cleanup + +If the bot starts background work: +- stop it in `OnUnload()` +- stop it in `OnDisconnect(...)` +- consider resetting state in `AfterGameJoined()` after relog +- prefer `Update()` plus counters or timestamps over unmanaged threads when the task is simple periodic work + +If the bot controls movement: +- use a movement-lock discipline +- release the lock on every stop path +- avoid fighting other movement bots +- `BotMovementLock` is mainly for built-in bots or shared long-running automation; a simple standalone script that just calls `MoveToLocation(...)` does not need it by default + +When interacting with client state from background logic, use the main-thread helpers when required by the codebase. + +## Practical defaults + +For simple chat bots: +- normalize text with `GetVerbatim(text)` +- inspect private chat first if the bot listens for whispers +- then inspect public chat +- keep response logic small and deterministic + +For long-running automation bots: +- guard prerequisites early, such as entity handling or terrain support +- fail fast with a clear log message if prerequisites are missing +- release all ongoing work cleanly on unload and disconnect + +## Common pitfalls + +- Incorrect metadata line 1 will break standalone script loading. +- Missing `MCC.LoadBot(new BotClassName())` will prevent standalone script registration. +- Sending chat in `Initialize()` is too early. +- Doing prerequisite checks or unloading from the constructor is harder to reason about than using `Initialize()`. +- Parsing raw formatted text without `GetVerbatim()` causes brittle chat matching. +- Inventing methods not present in the MCC ChatBot API leads to dead code. +- Built-in bot work is incomplete if config or registration wiring is missing. +- Command bots are incomplete if they register commands but do not unregister them. +- `RegisterChatBotCommand(...)` comes from older samples and is not a reliable current pattern for this checkout. +- `ChatBotCommand` exists, but the current built-in bots use Brigadier directly; do not prefer `ChatBotCommand` for new work. +- Blocking `Thread.Sleep(...)` inside `Update()` is a bad default. Prefer timers, counters, or timestamp-based scheduling. +- Mutating the `Container` returned by `GetPlayerInventory()` does not change the server. Use inventory actions instead. diff --git a/.skills/mcc-chatbot-authoring/references/pattern-cookbook.md b/.skills/mcc-chatbot-authoring/references/pattern-cookbook.md new file mode 100644 index 00000000..4d17c85c --- /dev/null +++ b/.skills/mcc-chatbot-authoring/references/pattern-cookbook.md @@ -0,0 +1,330 @@ +# MCC Pattern Cookbook + +Concrete patterns for standalone MCC `/script` bots. Use these before inventing new scaffolding. + +## Periodic task without threads + +Use `Update()` plus a timestamp or counter. This comes from the old `sample-script-with-task.cs` example and still holds up well. + +```csharp +public class PeriodicTaskBot : ChatBot +{ + private DateTime nextRun = DateTime.MinValue; + + public override void Update() + { + var now = DateTime.UtcNow; + if (now < nextRun) + return; + + nextRun = now.AddSeconds(30); + LogDebugToConsole("Running periodic task"); + SendText("/ping"); + } +} +``` + +Why this pattern is good: +- stays on MCC's normal tick flow +- avoids background threads for simple periodic work +- keeps the bot responsive to unload and disconnect + +## Chat and PM handling + +This combines the useful parts of `TestBot`, `sample-script-pm-forwarder.cs`, and `RemoteControl.cs`. + +```csharp +public override void GetText(string text) +{ + text = GetVerbatim(text); + + string message = ""; + string sender = ""; + + if (IsPrivateMessage(text, ref message, ref sender)) + { + LogToConsole("PM from " + sender + ": " + message); + return; + } + + if (IsChatMessage(text, ref message, ref sender)) + { + LogToConsole("Chat from " + sender + ": " + message); + } +} +``` + +Owner-gated internal command handling: + +Add `//using MinecraftClient.CommandHandler` in the script metadata if you use `CmdResult`. + +```csharp +public override void GetText(string text) +{ + text = GetVerbatim(text).Trim(); + + string command = ""; + string sender = ""; + + if (IsPrivateMessage(text, ref command, ref sender) + && Settings.Config.Main.Advanced.BotOwners.Contains(sender.ToLowerInvariant())) + { + CmdResult result = new(); + PerformInternalCommand(command, ref result); + SendPrivateMessage(sender, result.ToString()); + } +} +``` + +## Movement with prerequisite checks + +Modern movement code should copy the guard style from current built-in bots, not the older constructor-heavy scripts. + +```csharp +public override void Initialize() +{ + if (!GetEntityHandlingEnabled() || !GetTerrainEnabled()) + { + LogToConsole("Entity handling and terrain handling are required."); + UnloadBot(); + } +} +``` + +Simple "look at nearest player" logic adapted from `AutoLook.cs`: + +```csharp +private Entity? trackedPlayer = null; + +public override void OnEntitySpawn(Entity entity) +{ + TryTrack(entity); +} + +public override void OnEntityDespawn(Entity entity) +{ + if (trackedPlayer != null && entity.ID == trackedPlayer.ID) + trackedPlayer = null; +} + +public override void OnEntityMove(Entity entity) +{ + if (!TryTrack(entity)) + return; + + LookAtLocation(entity.Location); +} + +private bool TryTrack(Entity entity) +{ + if (entity.Type != EntityType.Player) + return false; + + if (trackedPlayer == null) + { + trackedPlayer = entity; + return true; + } + + if (GetCurrentLocation().Distance(entity.Location) < GetCurrentLocation().Distance(trackedPlayer.Location)) + trackedPlayer = entity; + + return trackedPlayer.ID == entity.ID; +} +``` + +## Search for dropped items and move to them + +This is the safest pattern to preserve from `ItemsCollector.cs` for standalone scripts. + +```csharp +public class NearbyItemsBot : ChatBot +{ + private DateTime nextScan = DateTime.MinValue; + + public override void Initialize() + { + if (!GetEntityHandlingEnabled() || !GetTerrainEnabled()) + { + LogToConsole("Entity handling and terrain handling are required."); + UnloadBot(); + } + } + + public override void Update() + { + var now = DateTime.UtcNow; + if (now < nextScan || ClientIsMoving()) + return; + + nextScan = now.AddSeconds(1); + + var here = GetCurrentLocation(); + var target = GetEntities().Values + .Where(entity => entity.Type == EntityType.Item && entity.Location.Distance(here) <= 15) + .OrderBy(entity => entity.Location.Distance(here)) + .FirstOrDefault(); + + if (target != null) + MoveToLocation(target.Location); + } +} +``` + +Why this version is better than older farming scripts: +- no unmanaged worker thread +- no busy wait loop around movement +- uses the current `GetEntities()` pattern + +## Search for blocks or crops in the world + +The old sugar cane and mining scripts still contain a useful search idea: use `GetWorld().FindBlock(...)`, then filter and sort. + +```csharp +var targets = GetWorld() + .FindBlock(GetCurrentLocation(), Material.SugarCane, 16) + .Where(block => + GetWorld().GetBlock(new Location(block.X, block.Y - 1, block.Z)).Type == Material.SugarCane) + .OrderBy(block => block.Distance(GetCurrentLocation())) + .ToList(); +``` + +Use this as a search primitive. Then decide separately how to move, dig, or harvest. + +## Inventory access and manipulation + +If a standalone script uses inventory types directly, add this import in the metadata block: + +```csharp +//using MinecraftClient.Inventory +``` + +For built-in bots, add: + +```csharp +using MinecraftClient.Inventory; +``` + +Always guard inventory logic first: + +```csharp +public override void Initialize() +{ + if (!GetInventoryEnabled()) + { + LogToConsole("Inventory handling is required."); + UnloadBot(); + } +} +``` + +Important rule: +- `GetPlayerInventory()` returns a snapshot copy, so editing its `Items` dictionary does not change the server +- actual changes must go through `ChangeSlot(...)`, `WindowAction(...)`, `GetItemMovingHelper(...)`, `UseItemInHand()`, and related helpers + +### Search inventory for an item + +This combines the useful current logic from `Farmer.cs` and `AutoEat.cs`. + +```csharp +private bool TrySwitchToItem(ItemType itemType) +{ + var inventory = GetPlayerInventory(); + + if (inventory.Items.TryGetValue(GetCurrentSlot() - 36, out var held) && held.Type == itemType) + return true; + + var hotbarSlots = inventory.SearchItem(itemType) + .Where(slot => slot >= 36 && slot <= 44) + .ToArray(); + + if (hotbarSlots.Length == 0) + return false; + + ChangeSlot((short)(hotbarSlots[0] - 36)); + return true; +} +``` + +Use this for simple hotbar selection. For deeper inventory reshuffling, built-in bots usually need more helper logic. + +### Move an item into the hotbar + +Use this when the item exists in inventory but is not already on the hotbar. + +```csharp +private bool TryMoveItemToHotbar(ItemType itemType, short targetHotbarSlot = 0) +{ + var inventory = GetPlayerInventory(); + var matches = inventory.SearchItem(itemType); + + if (matches.Length == 0) + return false; + + var targetInventorySlot = 36 + targetHotbarSlot; + + if (matches[0] >= 36 && matches[0] <= 44) + { + ChangeSlot((short)(matches[0] - 36)); + return true; + } + + var movingHelper = GetItemMovingHelper(inventory); + movingHelper.Swap(matches[0], targetInventorySlot); + ChangeSlot(targetHotbarSlot); + return true; +} +``` + +Why this pattern is good: +- it reads the current snapshot first +- it does not pretend local `Container` edits affect the server +- it uses the item-moving helper for real inventory manipulation + +### Drop or click items with window actions + +Use `WindowAction(...)` when the bot needs direct inventory clicks or dropping behavior. + +```csharp +private void DropAllOfType(ItemType itemType) +{ + var inventory = GetPlayerInventory(); + + foreach (int slot in inventory.SearchItem(itemType)) + WindowAction(0, slot, WindowActionType.DropItemStack); +} +``` + +Use this pattern carefully: +- verify the correct inventory ID first +- prefer reacting to `OnInventoryUpdate(...)` for larger inventory workflows +- for crafting or chest workflows, use `GetInventories()` and `CloseInventory(...)` as needed + +## Built-in command bot pattern + +Only use this when the user explicitly asks for a built-in bot. + +```csharp +public override void Initialize() +{ + McClient.dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CommandName) + .Executes(r => OnCommandHelp(r.Source, string.Empty)) + ) + ); + + McClient.dispatcher.Register(l => l.Literal(CommandName) + .Then(l => l.Literal("_help") + .Executes(r => OnCommandHelp(r.Source, string.Empty)) + .Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) + ); +} + +public override void OnUnload() +{ + McClient.dispatcher.Unregister(CommandName); + McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); +} +``` + +Use a built-in bot only when the user explicitly asks for compiled MCC behavior or repo wiring. From 50b4b3c8fe0c3181aadff73411591e18a106a09e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 00:49:33 +0800 Subject: [PATCH 079/484] feat: add palettes and enums for MC 1.21.11 (protocol 774) Add 17 new items (spears, nautilus armor, spawn eggs, netherite horse armor), 4 new entities (CamelHusk, Nautilus, Parched, ZombieNautilus), and 2 new entity metadata serializer types (ZombieNautilusVariant, HumanoidArm). Generated ItemPalette12111 (1505 items), EntityPalette12111 (157 entities), and EntityMetadataPalette12111 (39 serializers) from server reports. Made-with: Cursor --- .../ItemPalettes/ItemPalette12111.cs | 1523 +++++++++++++++++ MinecraftClient/Inventory/ItemType.cs | 17 + MinecraftClient/Mapping/EntityMetaDataType.cs | 10 +- .../EntityMetadataPalette12111.cs | 54 + .../EntityPalettes/EntityPalette12111.cs | 175 ++ MinecraftClient/Mapping/EntityType.cs | 4 + tools/gen_entity_metadata_palette.py | 2 + 7 files changed, 1784 insertions(+), 1 deletion(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette12111.cs create mode 100644 MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette12111.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette12111.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette12111.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette12111.cs new file mode 100644 index 00000000..30de90e8 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette12111.cs @@ -0,0 +1,1523 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette12111 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette12111() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.ShortDryGrass; + mappings[210] = ItemType.TallDryGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.OpenEyeblossom; + mappings[231] = ItemType.ClosedEyeblossom; + mappings[232] = ItemType.Poppy; + mappings[233] = ItemType.BlueOrchid; + mappings[234] = ItemType.Allium; + mappings[235] = ItemType.AzureBluet; + mappings[236] = ItemType.RedTulip; + mappings[237] = ItemType.OrangeTulip; + mappings[238] = ItemType.WhiteTulip; + mappings[239] = ItemType.PinkTulip; + mappings[240] = ItemType.OxeyeDaisy; + mappings[241] = ItemType.Cornflower; + mappings[242] = ItemType.LilyOfTheValley; + mappings[243] = ItemType.WitherRose; + mappings[244] = ItemType.Torchflower; + mappings[245] = ItemType.PitcherPlant; + mappings[246] = ItemType.SporeBlossom; + mappings[247] = ItemType.BrownMushroom; + mappings[248] = ItemType.RedMushroom; + mappings[249] = ItemType.CrimsonFungus; + mappings[250] = ItemType.WarpedFungus; + mappings[251] = ItemType.CrimsonRoots; + mappings[252] = ItemType.WarpedRoots; + mappings[253] = ItemType.NetherSprouts; + mappings[254] = ItemType.WeepingVines; + mappings[255] = ItemType.TwistingVines; + mappings[256] = ItemType.SugarCane; + mappings[257] = ItemType.Kelp; + mappings[258] = ItemType.PinkPetals; + mappings[259] = ItemType.Wildflowers; + mappings[260] = ItemType.LeafLitter; + mappings[261] = ItemType.MossCarpet; + mappings[262] = ItemType.MossBlock; + mappings[263] = ItemType.PaleMossCarpet; + mappings[264] = ItemType.PaleHangingMoss; + mappings[265] = ItemType.PaleMossBlock; + mappings[266] = ItemType.HangingRoots; + mappings[267] = ItemType.BigDripleaf; + mappings[268] = ItemType.SmallDripleaf; + mappings[269] = ItemType.Bamboo; + mappings[270] = ItemType.OakSlab; + mappings[271] = ItemType.SpruceSlab; + mappings[272] = ItemType.BirchSlab; + mappings[273] = ItemType.JungleSlab; + mappings[274] = ItemType.AcaciaSlab; + mappings[275] = ItemType.CherrySlab; + mappings[276] = ItemType.DarkOakSlab; + mappings[277] = ItemType.PaleOakSlab; + mappings[278] = ItemType.MangroveSlab; + mappings[279] = ItemType.BambooSlab; + mappings[280] = ItemType.BambooMosaicSlab; + mappings[281] = ItemType.CrimsonSlab; + mappings[282] = ItemType.WarpedSlab; + mappings[283] = ItemType.StoneSlab; + mappings[284] = ItemType.SmoothStoneSlab; + mappings[285] = ItemType.SandstoneSlab; + mappings[286] = ItemType.CutSandstoneSlab; + mappings[287] = ItemType.PetrifiedOakSlab; + mappings[288] = ItemType.CobblestoneSlab; + mappings[289] = ItemType.BrickSlab; + mappings[290] = ItemType.StoneBrickSlab; + mappings[291] = ItemType.MudBrickSlab; + mappings[292] = ItemType.NetherBrickSlab; + mappings[293] = ItemType.QuartzSlab; + mappings[294] = ItemType.RedSandstoneSlab; + mappings[295] = ItemType.CutRedSandstoneSlab; + mappings[296] = ItemType.PurpurSlab; + mappings[297] = ItemType.PrismarineSlab; + mappings[298] = ItemType.PrismarineBrickSlab; + mappings[299] = ItemType.DarkPrismarineSlab; + mappings[300] = ItemType.SmoothQuartz; + mappings[301] = ItemType.SmoothRedSandstone; + mappings[302] = ItemType.SmoothSandstone; + mappings[303] = ItemType.SmoothStone; + mappings[304] = ItemType.Bricks; + mappings[305] = ItemType.AcaciaShelf; + mappings[306] = ItemType.BambooShelf; + mappings[307] = ItemType.BirchShelf; + mappings[308] = ItemType.CherryShelf; + mappings[309] = ItemType.CrimsonShelf; + mappings[310] = ItemType.DarkOakShelf; + mappings[311] = ItemType.JungleShelf; + mappings[312] = ItemType.MangroveShelf; + mappings[313] = ItemType.OakShelf; + mappings[314] = ItemType.PaleOakShelf; + mappings[315] = ItemType.SpruceShelf; + mappings[316] = ItemType.WarpedShelf; + mappings[317] = ItemType.Bookshelf; + mappings[318] = ItemType.ChiseledBookshelf; + mappings[319] = ItemType.DecoratedPot; + mappings[320] = ItemType.MossyCobblestone; + mappings[321] = ItemType.Obsidian; + mappings[322] = ItemType.Torch; + mappings[323] = ItemType.EndRod; + mappings[324] = ItemType.ChorusPlant; + mappings[325] = ItemType.ChorusFlower; + mappings[326] = ItemType.PurpurBlock; + mappings[327] = ItemType.PurpurPillar; + mappings[328] = ItemType.PurpurStairs; + mappings[329] = ItemType.Spawner; + mappings[330] = ItemType.CreakingHeart; + mappings[331] = ItemType.Chest; + mappings[332] = ItemType.CraftingTable; + mappings[333] = ItemType.Farmland; + mappings[334] = ItemType.Furnace; + mappings[335] = ItemType.Ladder; + mappings[336] = ItemType.CobblestoneStairs; + mappings[337] = ItemType.Snow; + mappings[338] = ItemType.Ice; + mappings[339] = ItemType.SnowBlock; + mappings[340] = ItemType.Cactus; + mappings[341] = ItemType.CactusFlower; + mappings[342] = ItemType.Clay; + mappings[343] = ItemType.Jukebox; + mappings[344] = ItemType.OakFence; + mappings[345] = ItemType.SpruceFence; + mappings[346] = ItemType.BirchFence; + mappings[347] = ItemType.JungleFence; + mappings[348] = ItemType.AcaciaFence; + mappings[349] = ItemType.CherryFence; + mappings[350] = ItemType.DarkOakFence; + mappings[351] = ItemType.PaleOakFence; + mappings[352] = ItemType.MangroveFence; + mappings[353] = ItemType.BambooFence; + mappings[354] = ItemType.CrimsonFence; + mappings[355] = ItemType.WarpedFence; + mappings[356] = ItemType.Pumpkin; + mappings[357] = ItemType.CarvedPumpkin; + mappings[358] = ItemType.JackOLantern; + mappings[359] = ItemType.Netherrack; + mappings[360] = ItemType.SoulSand; + mappings[361] = ItemType.SoulSoil; + mappings[362] = ItemType.Basalt; + mappings[363] = ItemType.PolishedBasalt; + mappings[364] = ItemType.SmoothBasalt; + mappings[365] = ItemType.SoulTorch; + mappings[366] = ItemType.CopperTorch; + mappings[367] = ItemType.Glowstone; + mappings[368] = ItemType.InfestedStone; + mappings[369] = ItemType.InfestedCobblestone; + mappings[370] = ItemType.InfestedStoneBricks; + mappings[371] = ItemType.InfestedMossyStoneBricks; + mappings[372] = ItemType.InfestedCrackedStoneBricks; + mappings[373] = ItemType.InfestedChiseledStoneBricks; + mappings[374] = ItemType.InfestedDeepslate; + mappings[375] = ItemType.StoneBricks; + mappings[376] = ItemType.MossyStoneBricks; + mappings[377] = ItemType.CrackedStoneBricks; + mappings[378] = ItemType.ChiseledStoneBricks; + mappings[379] = ItemType.PackedMud; + mappings[380] = ItemType.MudBricks; + mappings[381] = ItemType.DeepslateBricks; + mappings[382] = ItemType.CrackedDeepslateBricks; + mappings[383] = ItemType.DeepslateTiles; + mappings[384] = ItemType.CrackedDeepslateTiles; + mappings[385] = ItemType.ChiseledDeepslate; + mappings[386] = ItemType.ReinforcedDeepslate; + mappings[387] = ItemType.BrownMushroomBlock; + mappings[388] = ItemType.RedMushroomBlock; + mappings[389] = ItemType.MushroomStem; + mappings[390] = ItemType.IronBars; + mappings[391] = ItemType.CopperBars; + mappings[392] = ItemType.ExposedCopperBars; + mappings[393] = ItemType.WeatheredCopperBars; + mappings[394] = ItemType.OxidizedCopperBars; + mappings[395] = ItemType.WaxedCopperBars; + mappings[396] = ItemType.WaxedExposedCopperBars; + mappings[397] = ItemType.WaxedWeatheredCopperBars; + mappings[398] = ItemType.WaxedOxidizedCopperBars; + mappings[399] = ItemType.IronChain; + mappings[400] = ItemType.CopperChain; + mappings[401] = ItemType.ExposedCopperChain; + mappings[402] = ItemType.WeatheredCopperChain; + mappings[403] = ItemType.OxidizedCopperChain; + mappings[404] = ItemType.WaxedCopperChain; + mappings[405] = ItemType.WaxedExposedCopperChain; + mappings[406] = ItemType.WaxedWeatheredCopperChain; + mappings[407] = ItemType.WaxedOxidizedCopperChain; + mappings[408] = ItemType.GlassPane; + mappings[409] = ItemType.Melon; + mappings[410] = ItemType.Vine; + mappings[411] = ItemType.GlowLichen; + mappings[412] = ItemType.ResinClump; + mappings[413] = ItemType.ResinBlock; + mappings[414] = ItemType.ResinBricks; + mappings[415] = ItemType.ResinBrickStairs; + mappings[416] = ItemType.ResinBrickSlab; + mappings[417] = ItemType.ResinBrickWall; + mappings[418] = ItemType.ChiseledResinBricks; + mappings[419] = ItemType.BrickStairs; + mappings[420] = ItemType.StoneBrickStairs; + mappings[421] = ItemType.MudBrickStairs; + mappings[422] = ItemType.Mycelium; + mappings[423] = ItemType.LilyPad; + mappings[424] = ItemType.NetherBricks; + mappings[425] = ItemType.CrackedNetherBricks; + mappings[426] = ItemType.ChiseledNetherBricks; + mappings[427] = ItemType.NetherBrickFence; + mappings[428] = ItemType.NetherBrickStairs; + mappings[429] = ItemType.Sculk; + mappings[430] = ItemType.SculkVein; + mappings[431] = ItemType.SculkCatalyst; + mappings[432] = ItemType.SculkShrieker; + mappings[433] = ItemType.EnchantingTable; + mappings[434] = ItemType.EndPortalFrame; + mappings[435] = ItemType.EndStone; + mappings[436] = ItemType.EndStoneBricks; + mappings[437] = ItemType.DragonEgg; + mappings[438] = ItemType.SandstoneStairs; + mappings[439] = ItemType.EnderChest; + mappings[440] = ItemType.EmeraldBlock; + mappings[441] = ItemType.OakStairs; + mappings[442] = ItemType.SpruceStairs; + mappings[443] = ItemType.BirchStairs; + mappings[444] = ItemType.JungleStairs; + mappings[445] = ItemType.AcaciaStairs; + mappings[446] = ItemType.CherryStairs; + mappings[447] = ItemType.DarkOakStairs; + mappings[448] = ItemType.PaleOakStairs; + mappings[449] = ItemType.MangroveStairs; + mappings[450] = ItemType.BambooStairs; + mappings[451] = ItemType.BambooMosaicStairs; + mappings[452] = ItemType.CrimsonStairs; + mappings[453] = ItemType.WarpedStairs; + mappings[454] = ItemType.CommandBlock; + mappings[455] = ItemType.Beacon; + mappings[456] = ItemType.CobblestoneWall; + mappings[457] = ItemType.MossyCobblestoneWall; + mappings[458] = ItemType.BrickWall; + mappings[459] = ItemType.PrismarineWall; + mappings[460] = ItemType.RedSandstoneWall; + mappings[461] = ItemType.MossyStoneBrickWall; + mappings[462] = ItemType.GraniteWall; + mappings[463] = ItemType.StoneBrickWall; + mappings[464] = ItemType.MudBrickWall; + mappings[465] = ItemType.NetherBrickWall; + mappings[466] = ItemType.AndesiteWall; + mappings[467] = ItemType.RedNetherBrickWall; + mappings[468] = ItemType.SandstoneWall; + mappings[469] = ItemType.EndStoneBrickWall; + mappings[470] = ItemType.DioriteWall; + mappings[471] = ItemType.BlackstoneWall; + mappings[472] = ItemType.PolishedBlackstoneWall; + mappings[473] = ItemType.PolishedBlackstoneBrickWall; + mappings[474] = ItemType.CobbledDeepslateWall; + mappings[475] = ItemType.PolishedDeepslateWall; + mappings[476] = ItemType.DeepslateBrickWall; + mappings[477] = ItemType.DeepslateTileWall; + mappings[478] = ItemType.Anvil; + mappings[479] = ItemType.ChippedAnvil; + mappings[480] = ItemType.DamagedAnvil; + mappings[481] = ItemType.ChiseledQuartzBlock; + mappings[482] = ItemType.QuartzBlock; + mappings[483] = ItemType.QuartzBricks; + mappings[484] = ItemType.QuartzPillar; + mappings[485] = ItemType.QuartzStairs; + mappings[486] = ItemType.WhiteTerracotta; + mappings[487] = ItemType.OrangeTerracotta; + mappings[488] = ItemType.MagentaTerracotta; + mappings[489] = ItemType.LightBlueTerracotta; + mappings[490] = ItemType.YellowTerracotta; + mappings[491] = ItemType.LimeTerracotta; + mappings[492] = ItemType.PinkTerracotta; + mappings[493] = ItemType.GrayTerracotta; + mappings[494] = ItemType.LightGrayTerracotta; + mappings[495] = ItemType.CyanTerracotta; + mappings[496] = ItemType.PurpleTerracotta; + mappings[497] = ItemType.BlueTerracotta; + mappings[498] = ItemType.BrownTerracotta; + mappings[499] = ItemType.GreenTerracotta; + mappings[500] = ItemType.RedTerracotta; + mappings[501] = ItemType.BlackTerracotta; + mappings[502] = ItemType.Barrier; + mappings[503] = ItemType.Light; + mappings[504] = ItemType.HayBlock; + mappings[505] = ItemType.WhiteCarpet; + mappings[506] = ItemType.OrangeCarpet; + mappings[507] = ItemType.MagentaCarpet; + mappings[508] = ItemType.LightBlueCarpet; + mappings[509] = ItemType.YellowCarpet; + mappings[510] = ItemType.LimeCarpet; + mappings[511] = ItemType.PinkCarpet; + mappings[512] = ItemType.GrayCarpet; + mappings[513] = ItemType.LightGrayCarpet; + mappings[514] = ItemType.CyanCarpet; + mappings[515] = ItemType.PurpleCarpet; + mappings[516] = ItemType.BlueCarpet; + mappings[517] = ItemType.BrownCarpet; + mappings[518] = ItemType.GreenCarpet; + mappings[519] = ItemType.RedCarpet; + mappings[520] = ItemType.BlackCarpet; + mappings[521] = ItemType.Terracotta; + mappings[522] = ItemType.PackedIce; + mappings[523] = ItemType.DirtPath; + mappings[524] = ItemType.Sunflower; + mappings[525] = ItemType.Lilac; + mappings[526] = ItemType.RoseBush; + mappings[527] = ItemType.Peony; + mappings[528] = ItemType.TallGrass; + mappings[529] = ItemType.LargeFern; + mappings[530] = ItemType.WhiteStainedGlass; + mappings[531] = ItemType.OrangeStainedGlass; + mappings[532] = ItemType.MagentaStainedGlass; + mappings[533] = ItemType.LightBlueStainedGlass; + mappings[534] = ItemType.YellowStainedGlass; + mappings[535] = ItemType.LimeStainedGlass; + mappings[536] = ItemType.PinkStainedGlass; + mappings[537] = ItemType.GrayStainedGlass; + mappings[538] = ItemType.LightGrayStainedGlass; + mappings[539] = ItemType.CyanStainedGlass; + mappings[540] = ItemType.PurpleStainedGlass; + mappings[541] = ItemType.BlueStainedGlass; + mappings[542] = ItemType.BrownStainedGlass; + mappings[543] = ItemType.GreenStainedGlass; + mappings[544] = ItemType.RedStainedGlass; + mappings[545] = ItemType.BlackStainedGlass; + mappings[546] = ItemType.WhiteStainedGlassPane; + mappings[547] = ItemType.OrangeStainedGlassPane; + mappings[548] = ItemType.MagentaStainedGlassPane; + mappings[549] = ItemType.LightBlueStainedGlassPane; + mappings[550] = ItemType.YellowStainedGlassPane; + mappings[551] = ItemType.LimeStainedGlassPane; + mappings[552] = ItemType.PinkStainedGlassPane; + mappings[553] = ItemType.GrayStainedGlassPane; + mappings[554] = ItemType.LightGrayStainedGlassPane; + mappings[555] = ItemType.CyanStainedGlassPane; + mappings[556] = ItemType.PurpleStainedGlassPane; + mappings[557] = ItemType.BlueStainedGlassPane; + mappings[558] = ItemType.BrownStainedGlassPane; + mappings[559] = ItemType.GreenStainedGlassPane; + mappings[560] = ItemType.RedStainedGlassPane; + mappings[561] = ItemType.BlackStainedGlassPane; + mappings[562] = ItemType.Prismarine; + mappings[563] = ItemType.PrismarineBricks; + mappings[564] = ItemType.DarkPrismarine; + mappings[565] = ItemType.PrismarineStairs; + mappings[566] = ItemType.PrismarineBrickStairs; + mappings[567] = ItemType.DarkPrismarineStairs; + mappings[568] = ItemType.SeaLantern; + mappings[569] = ItemType.RedSandstone; + mappings[570] = ItemType.ChiseledRedSandstone; + mappings[571] = ItemType.CutRedSandstone; + mappings[572] = ItemType.RedSandstoneStairs; + mappings[573] = ItemType.RepeatingCommandBlock; + mappings[574] = ItemType.ChainCommandBlock; + mappings[575] = ItemType.MagmaBlock; + mappings[576] = ItemType.NetherWartBlock; + mappings[577] = ItemType.WarpedWartBlock; + mappings[578] = ItemType.RedNetherBricks; + mappings[579] = ItemType.BoneBlock; + mappings[580] = ItemType.StructureVoid; + mappings[581] = ItemType.ShulkerBox; + mappings[582] = ItemType.WhiteShulkerBox; + mappings[583] = ItemType.OrangeShulkerBox; + mappings[584] = ItemType.MagentaShulkerBox; + mappings[585] = ItemType.LightBlueShulkerBox; + mappings[586] = ItemType.YellowShulkerBox; + mappings[587] = ItemType.LimeShulkerBox; + mappings[588] = ItemType.PinkShulkerBox; + mappings[589] = ItemType.GrayShulkerBox; + mappings[590] = ItemType.LightGrayShulkerBox; + mappings[591] = ItemType.CyanShulkerBox; + mappings[592] = ItemType.PurpleShulkerBox; + mappings[593] = ItemType.BlueShulkerBox; + mappings[594] = ItemType.BrownShulkerBox; + mappings[595] = ItemType.GreenShulkerBox; + mappings[596] = ItemType.RedShulkerBox; + mappings[597] = ItemType.BlackShulkerBox; + mappings[598] = ItemType.WhiteGlazedTerracotta; + mappings[599] = ItemType.OrangeGlazedTerracotta; + mappings[600] = ItemType.MagentaGlazedTerracotta; + mappings[601] = ItemType.LightBlueGlazedTerracotta; + mappings[602] = ItemType.YellowGlazedTerracotta; + mappings[603] = ItemType.LimeGlazedTerracotta; + mappings[604] = ItemType.PinkGlazedTerracotta; + mappings[605] = ItemType.GrayGlazedTerracotta; + mappings[606] = ItemType.LightGrayGlazedTerracotta; + mappings[607] = ItemType.CyanGlazedTerracotta; + mappings[608] = ItemType.PurpleGlazedTerracotta; + mappings[609] = ItemType.BlueGlazedTerracotta; + mappings[610] = ItemType.BrownGlazedTerracotta; + mappings[611] = ItemType.GreenGlazedTerracotta; + mappings[612] = ItemType.RedGlazedTerracotta; + mappings[613] = ItemType.BlackGlazedTerracotta; + mappings[614] = ItemType.WhiteConcrete; + mappings[615] = ItemType.OrangeConcrete; + mappings[616] = ItemType.MagentaConcrete; + mappings[617] = ItemType.LightBlueConcrete; + mappings[618] = ItemType.YellowConcrete; + mappings[619] = ItemType.LimeConcrete; + mappings[620] = ItemType.PinkConcrete; + mappings[621] = ItemType.GrayConcrete; + mappings[622] = ItemType.LightGrayConcrete; + mappings[623] = ItemType.CyanConcrete; + mappings[624] = ItemType.PurpleConcrete; + mappings[625] = ItemType.BlueConcrete; + mappings[626] = ItemType.BrownConcrete; + mappings[627] = ItemType.GreenConcrete; + mappings[628] = ItemType.RedConcrete; + mappings[629] = ItemType.BlackConcrete; + mappings[630] = ItemType.WhiteConcretePowder; + mappings[631] = ItemType.OrangeConcretePowder; + mappings[632] = ItemType.MagentaConcretePowder; + mappings[633] = ItemType.LightBlueConcretePowder; + mappings[634] = ItemType.YellowConcretePowder; + mappings[635] = ItemType.LimeConcretePowder; + mappings[636] = ItemType.PinkConcretePowder; + mappings[637] = ItemType.GrayConcretePowder; + mappings[638] = ItemType.LightGrayConcretePowder; + mappings[639] = ItemType.CyanConcretePowder; + mappings[640] = ItemType.PurpleConcretePowder; + mappings[641] = ItemType.BlueConcretePowder; + mappings[642] = ItemType.BrownConcretePowder; + mappings[643] = ItemType.GreenConcretePowder; + mappings[644] = ItemType.RedConcretePowder; + mappings[645] = ItemType.BlackConcretePowder; + mappings[646] = ItemType.TurtleEgg; + mappings[647] = ItemType.SnifferEgg; + mappings[648] = ItemType.DriedGhast; + mappings[649] = ItemType.DeadTubeCoralBlock; + mappings[650] = ItemType.DeadBrainCoralBlock; + mappings[651] = ItemType.DeadBubbleCoralBlock; + mappings[652] = ItemType.DeadFireCoralBlock; + mappings[653] = ItemType.DeadHornCoralBlock; + mappings[654] = ItemType.TubeCoralBlock; + mappings[655] = ItemType.BrainCoralBlock; + mappings[656] = ItemType.BubbleCoralBlock; + mappings[657] = ItemType.FireCoralBlock; + mappings[658] = ItemType.HornCoralBlock; + mappings[659] = ItemType.TubeCoral; + mappings[660] = ItemType.BrainCoral; + mappings[661] = ItemType.BubbleCoral; + mappings[662] = ItemType.FireCoral; + mappings[663] = ItemType.HornCoral; + mappings[664] = ItemType.DeadBrainCoral; + mappings[665] = ItemType.DeadBubbleCoral; + mappings[666] = ItemType.DeadFireCoral; + mappings[667] = ItemType.DeadHornCoral; + mappings[668] = ItemType.DeadTubeCoral; + mappings[669] = ItemType.TubeCoralFan; + mappings[670] = ItemType.BrainCoralFan; + mappings[671] = ItemType.BubbleCoralFan; + mappings[672] = ItemType.FireCoralFan; + mappings[673] = ItemType.HornCoralFan; + mappings[674] = ItemType.DeadTubeCoralFan; + mappings[675] = ItemType.DeadBrainCoralFan; + mappings[676] = ItemType.DeadBubbleCoralFan; + mappings[677] = ItemType.DeadFireCoralFan; + mappings[678] = ItemType.DeadHornCoralFan; + mappings[679] = ItemType.BlueIce; + mappings[680] = ItemType.Conduit; + mappings[681] = ItemType.PolishedGraniteStairs; + mappings[682] = ItemType.SmoothRedSandstoneStairs; + mappings[683] = ItemType.MossyStoneBrickStairs; + mappings[684] = ItemType.PolishedDioriteStairs; + mappings[685] = ItemType.MossyCobblestoneStairs; + mappings[686] = ItemType.EndStoneBrickStairs; + mappings[687] = ItemType.StoneStairs; + mappings[688] = ItemType.SmoothSandstoneStairs; + mappings[689] = ItemType.SmoothQuartzStairs; + mappings[690] = ItemType.GraniteStairs; + mappings[691] = ItemType.AndesiteStairs; + mappings[692] = ItemType.RedNetherBrickStairs; + mappings[693] = ItemType.PolishedAndesiteStairs; + mappings[694] = ItemType.DioriteStairs; + mappings[695] = ItemType.CobbledDeepslateStairs; + mappings[696] = ItemType.PolishedDeepslateStairs; + mappings[697] = ItemType.DeepslateBrickStairs; + mappings[698] = ItemType.DeepslateTileStairs; + mappings[699] = ItemType.PolishedGraniteSlab; + mappings[700] = ItemType.SmoothRedSandstoneSlab; + mappings[701] = ItemType.MossyStoneBrickSlab; + mappings[702] = ItemType.PolishedDioriteSlab; + mappings[703] = ItemType.MossyCobblestoneSlab; + mappings[704] = ItemType.EndStoneBrickSlab; + mappings[705] = ItemType.SmoothSandstoneSlab; + mappings[706] = ItemType.SmoothQuartzSlab; + mappings[707] = ItemType.GraniteSlab; + mappings[708] = ItemType.AndesiteSlab; + mappings[709] = ItemType.RedNetherBrickSlab; + mappings[710] = ItemType.PolishedAndesiteSlab; + mappings[711] = ItemType.DioriteSlab; + mappings[712] = ItemType.CobbledDeepslateSlab; + mappings[713] = ItemType.PolishedDeepslateSlab; + mappings[714] = ItemType.DeepslateBrickSlab; + mappings[715] = ItemType.DeepslateTileSlab; + mappings[716] = ItemType.Scaffolding; + mappings[717] = ItemType.Redstone; + mappings[718] = ItemType.RedstoneTorch; + mappings[719] = ItemType.RedstoneBlock; + mappings[720] = ItemType.Repeater; + mappings[721] = ItemType.Comparator; + mappings[722] = ItemType.Piston; + mappings[723] = ItemType.StickyPiston; + mappings[724] = ItemType.SlimeBlock; + mappings[725] = ItemType.HoneyBlock; + mappings[726] = ItemType.Observer; + mappings[727] = ItemType.Hopper; + mappings[728] = ItemType.Dispenser; + mappings[729] = ItemType.Dropper; + mappings[730] = ItemType.Lectern; + mappings[731] = ItemType.Target; + mappings[732] = ItemType.Lever; + mappings[733] = ItemType.LightningRod; + mappings[734] = ItemType.ExposedLightningRod; + mappings[735] = ItemType.WeatheredLightningRod; + mappings[736] = ItemType.OxidizedLightningRod; + mappings[737] = ItemType.WaxedLightningRod; + mappings[738] = ItemType.WaxedExposedLightningRod; + mappings[739] = ItemType.WaxedWeatheredLightningRod; + mappings[740] = ItemType.WaxedOxidizedLightningRod; + mappings[741] = ItemType.DaylightDetector; + mappings[742] = ItemType.SculkSensor; + mappings[743] = ItemType.CalibratedSculkSensor; + mappings[744] = ItemType.TripwireHook; + mappings[745] = ItemType.TrappedChest; + mappings[746] = ItemType.Tnt; + mappings[747] = ItemType.RedstoneLamp; + mappings[748] = ItemType.NoteBlock; + mappings[749] = ItemType.StoneButton; + mappings[750] = ItemType.PolishedBlackstoneButton; + mappings[751] = ItemType.OakButton; + mappings[752] = ItemType.SpruceButton; + mappings[753] = ItemType.BirchButton; + mappings[754] = ItemType.JungleButton; + mappings[755] = ItemType.AcaciaButton; + mappings[756] = ItemType.CherryButton; + mappings[757] = ItemType.DarkOakButton; + mappings[758] = ItemType.PaleOakButton; + mappings[759] = ItemType.MangroveButton; + mappings[760] = ItemType.BambooButton; + mappings[761] = ItemType.CrimsonButton; + mappings[762] = ItemType.WarpedButton; + mappings[763] = ItemType.StonePressurePlate; + mappings[764] = ItemType.PolishedBlackstonePressurePlate; + mappings[765] = ItemType.LightWeightedPressurePlate; + mappings[766] = ItemType.HeavyWeightedPressurePlate; + mappings[767] = ItemType.OakPressurePlate; + mappings[768] = ItemType.SprucePressurePlate; + mappings[769] = ItemType.BirchPressurePlate; + mappings[770] = ItemType.JunglePressurePlate; + mappings[771] = ItemType.AcaciaPressurePlate; + mappings[772] = ItemType.CherryPressurePlate; + mappings[773] = ItemType.DarkOakPressurePlate; + mappings[774] = ItemType.PaleOakPressurePlate; + mappings[775] = ItemType.MangrovePressurePlate; + mappings[776] = ItemType.BambooPressurePlate; + mappings[777] = ItemType.CrimsonPressurePlate; + mappings[778] = ItemType.WarpedPressurePlate; + mappings[779] = ItemType.IronDoor; + mappings[780] = ItemType.OakDoor; + mappings[781] = ItemType.SpruceDoor; + mappings[782] = ItemType.BirchDoor; + mappings[783] = ItemType.JungleDoor; + mappings[784] = ItemType.AcaciaDoor; + mappings[785] = ItemType.CherryDoor; + mappings[786] = ItemType.DarkOakDoor; + mappings[787] = ItemType.PaleOakDoor; + mappings[788] = ItemType.MangroveDoor; + mappings[789] = ItemType.BambooDoor; + mappings[790] = ItemType.CrimsonDoor; + mappings[791] = ItemType.WarpedDoor; + mappings[792] = ItemType.CopperDoor; + mappings[793] = ItemType.ExposedCopperDoor; + mappings[794] = ItemType.WeatheredCopperDoor; + mappings[795] = ItemType.OxidizedCopperDoor; + mappings[796] = ItemType.WaxedCopperDoor; + mappings[797] = ItemType.WaxedExposedCopperDoor; + mappings[798] = ItemType.WaxedWeatheredCopperDoor; + mappings[799] = ItemType.WaxedOxidizedCopperDoor; + mappings[800] = ItemType.IronTrapdoor; + mappings[801] = ItemType.OakTrapdoor; + mappings[802] = ItemType.SpruceTrapdoor; + mappings[803] = ItemType.BirchTrapdoor; + mappings[804] = ItemType.JungleTrapdoor; + mappings[805] = ItemType.AcaciaTrapdoor; + mappings[806] = ItemType.CherryTrapdoor; + mappings[807] = ItemType.DarkOakTrapdoor; + mappings[808] = ItemType.PaleOakTrapdoor; + mappings[809] = ItemType.MangroveTrapdoor; + mappings[810] = ItemType.BambooTrapdoor; + mappings[811] = ItemType.CrimsonTrapdoor; + mappings[812] = ItemType.WarpedTrapdoor; + mappings[813] = ItemType.CopperTrapdoor; + mappings[814] = ItemType.ExposedCopperTrapdoor; + mappings[815] = ItemType.WeatheredCopperTrapdoor; + mappings[816] = ItemType.OxidizedCopperTrapdoor; + mappings[817] = ItemType.WaxedCopperTrapdoor; + mappings[818] = ItemType.WaxedExposedCopperTrapdoor; + mappings[819] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[820] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[821] = ItemType.OakFenceGate; + mappings[822] = ItemType.SpruceFenceGate; + mappings[823] = ItemType.BirchFenceGate; + mappings[824] = ItemType.JungleFenceGate; + mappings[825] = ItemType.AcaciaFenceGate; + mappings[826] = ItemType.CherryFenceGate; + mappings[827] = ItemType.DarkOakFenceGate; + mappings[828] = ItemType.PaleOakFenceGate; + mappings[829] = ItemType.MangroveFenceGate; + mappings[830] = ItemType.BambooFenceGate; + mappings[831] = ItemType.CrimsonFenceGate; + mappings[832] = ItemType.WarpedFenceGate; + mappings[833] = ItemType.PoweredRail; + mappings[834] = ItemType.DetectorRail; + mappings[835] = ItemType.Rail; + mappings[836] = ItemType.ActivatorRail; + mappings[837] = ItemType.Saddle; + mappings[838] = ItemType.WhiteHarness; + mappings[839] = ItemType.OrangeHarness; + mappings[840] = ItemType.MagentaHarness; + mappings[841] = ItemType.LightBlueHarness; + mappings[842] = ItemType.YellowHarness; + mappings[843] = ItemType.LimeHarness; + mappings[844] = ItemType.PinkHarness; + mappings[845] = ItemType.GrayHarness; + mappings[846] = ItemType.LightGrayHarness; + mappings[847] = ItemType.CyanHarness; + mappings[848] = ItemType.PurpleHarness; + mappings[849] = ItemType.BlueHarness; + mappings[850] = ItemType.BrownHarness; + mappings[851] = ItemType.GreenHarness; + mappings[852] = ItemType.RedHarness; + mappings[853] = ItemType.BlackHarness; + mappings[854] = ItemType.Minecart; + mappings[855] = ItemType.ChestMinecart; + mappings[856] = ItemType.FurnaceMinecart; + mappings[857] = ItemType.TntMinecart; + mappings[858] = ItemType.HopperMinecart; + mappings[859] = ItemType.CarrotOnAStick; + mappings[860] = ItemType.WarpedFungusOnAStick; + mappings[861] = ItemType.PhantomMembrane; + mappings[862] = ItemType.Elytra; + mappings[863] = ItemType.OakBoat; + mappings[864] = ItemType.OakChestBoat; + mappings[865] = ItemType.SpruceBoat; + mappings[866] = ItemType.SpruceChestBoat; + mappings[867] = ItemType.BirchBoat; + mappings[868] = ItemType.BirchChestBoat; + mappings[869] = ItemType.JungleBoat; + mappings[870] = ItemType.JungleChestBoat; + mappings[871] = ItemType.AcaciaBoat; + mappings[872] = ItemType.AcaciaChestBoat; + mappings[873] = ItemType.CherryBoat; + mappings[874] = ItemType.CherryChestBoat; + mappings[875] = ItemType.DarkOakBoat; + mappings[876] = ItemType.DarkOakChestBoat; + mappings[877] = ItemType.PaleOakBoat; + mappings[878] = ItemType.PaleOakChestBoat; + mappings[879] = ItemType.MangroveBoat; + mappings[880] = ItemType.MangroveChestBoat; + mappings[881] = ItemType.BambooRaft; + mappings[882] = ItemType.BambooChestRaft; + mappings[883] = ItemType.StructureBlock; + mappings[884] = ItemType.Jigsaw; + mappings[885] = ItemType.TestBlock; + mappings[886] = ItemType.TestInstanceBlock; + mappings[887] = ItemType.TurtleHelmet; + mappings[888] = ItemType.TurtleScute; + mappings[889] = ItemType.ArmadilloScute; + mappings[890] = ItemType.WolfArmor; + mappings[891] = ItemType.FlintAndSteel; + mappings[892] = ItemType.Bowl; + mappings[893] = ItemType.Apple; + mappings[894] = ItemType.Bow; + mappings[895] = ItemType.Arrow; + mappings[896] = ItemType.Coal; + mappings[897] = ItemType.Charcoal; + mappings[898] = ItemType.Diamond; + mappings[899] = ItemType.Emerald; + mappings[900] = ItemType.LapisLazuli; + mappings[901] = ItemType.Quartz; + mappings[902] = ItemType.AmethystShard; + mappings[903] = ItemType.RawIron; + mappings[904] = ItemType.IronIngot; + mappings[905] = ItemType.RawCopper; + mappings[906] = ItemType.CopperIngot; + mappings[907] = ItemType.RawGold; + mappings[908] = ItemType.GoldIngot; + mappings[909] = ItemType.NetheriteIngot; + mappings[910] = ItemType.NetheriteScrap; + mappings[911] = ItemType.WoodenSword; + mappings[912] = ItemType.WoodenShovel; + mappings[913] = ItemType.WoodenPickaxe; + mappings[914] = ItemType.WoodenAxe; + mappings[915] = ItemType.WoodenHoe; + mappings[916] = ItemType.CopperSword; + mappings[917] = ItemType.CopperShovel; + mappings[918] = ItemType.CopperPickaxe; + mappings[919] = ItemType.CopperAxe; + mappings[920] = ItemType.CopperHoe; + mappings[921] = ItemType.StoneSword; + mappings[922] = ItemType.StoneShovel; + mappings[923] = ItemType.StonePickaxe; + mappings[924] = ItemType.StoneAxe; + mappings[925] = ItemType.StoneHoe; + mappings[926] = ItemType.GoldenSword; + mappings[927] = ItemType.GoldenShovel; + mappings[928] = ItemType.GoldenPickaxe; + mappings[929] = ItemType.GoldenAxe; + mappings[930] = ItemType.GoldenHoe; + mappings[931] = ItemType.IronSword; + mappings[932] = ItemType.IronShovel; + mappings[933] = ItemType.IronPickaxe; + mappings[934] = ItemType.IronAxe; + mappings[935] = ItemType.IronHoe; + mappings[936] = ItemType.DiamondSword; + mappings[937] = ItemType.DiamondShovel; + mappings[938] = ItemType.DiamondPickaxe; + mappings[939] = ItemType.DiamondAxe; + mappings[940] = ItemType.DiamondHoe; + mappings[941] = ItemType.NetheriteSword; + mappings[942] = ItemType.NetheriteShovel; + mappings[943] = ItemType.NetheritePickaxe; + mappings[944] = ItemType.NetheriteAxe; + mappings[945] = ItemType.NetheriteHoe; + mappings[946] = ItemType.Stick; + mappings[947] = ItemType.MushroomStew; + mappings[948] = ItemType.String; + mappings[949] = ItemType.Feather; + mappings[950] = ItemType.Gunpowder; + mappings[951] = ItemType.WheatSeeds; + mappings[952] = ItemType.Wheat; + mappings[953] = ItemType.Bread; + mappings[954] = ItemType.LeatherHelmet; + mappings[955] = ItemType.LeatherChestplate; + mappings[956] = ItemType.LeatherLeggings; + mappings[957] = ItemType.LeatherBoots; + mappings[958] = ItemType.CopperHelmet; + mappings[959] = ItemType.CopperChestplate; + mappings[960] = ItemType.CopperLeggings; + mappings[961] = ItemType.CopperBoots; + mappings[962] = ItemType.ChainmailHelmet; + mappings[963] = ItemType.ChainmailChestplate; + mappings[964] = ItemType.ChainmailLeggings; + mappings[965] = ItemType.ChainmailBoots; + mappings[966] = ItemType.IronHelmet; + mappings[967] = ItemType.IronChestplate; + mappings[968] = ItemType.IronLeggings; + mappings[969] = ItemType.IronBoots; + mappings[970] = ItemType.DiamondHelmet; + mappings[971] = ItemType.DiamondChestplate; + mappings[972] = ItemType.DiamondLeggings; + mappings[973] = ItemType.DiamondBoots; + mappings[974] = ItemType.GoldenHelmet; + mappings[975] = ItemType.GoldenChestplate; + mappings[976] = ItemType.GoldenLeggings; + mappings[977] = ItemType.GoldenBoots; + mappings[978] = ItemType.NetheriteHelmet; + mappings[979] = ItemType.NetheriteChestplate; + mappings[980] = ItemType.NetheriteLeggings; + mappings[981] = ItemType.NetheriteBoots; + mappings[982] = ItemType.Flint; + mappings[983] = ItemType.Porkchop; + mappings[984] = ItemType.CookedPorkchop; + mappings[985] = ItemType.Painting; + mappings[986] = ItemType.GoldenApple; + mappings[987] = ItemType.EnchantedGoldenApple; + mappings[988] = ItemType.OakSign; + mappings[989] = ItemType.SpruceSign; + mappings[990] = ItemType.BirchSign; + mappings[991] = ItemType.JungleSign; + mappings[992] = ItemType.AcaciaSign; + mappings[993] = ItemType.CherrySign; + mappings[994] = ItemType.DarkOakSign; + mappings[995] = ItemType.PaleOakSign; + mappings[996] = ItemType.MangroveSign; + mappings[997] = ItemType.BambooSign; + mappings[998] = ItemType.CrimsonSign; + mappings[999] = ItemType.WarpedSign; + mappings[1000] = ItemType.OakHangingSign; + mappings[1001] = ItemType.SpruceHangingSign; + mappings[1002] = ItemType.BirchHangingSign; + mappings[1003] = ItemType.JungleHangingSign; + mappings[1004] = ItemType.AcaciaHangingSign; + mappings[1005] = ItemType.CherryHangingSign; + mappings[1006] = ItemType.DarkOakHangingSign; + mappings[1007] = ItemType.PaleOakHangingSign; + mappings[1008] = ItemType.MangroveHangingSign; + mappings[1009] = ItemType.BambooHangingSign; + mappings[1010] = ItemType.CrimsonHangingSign; + mappings[1011] = ItemType.WarpedHangingSign; + mappings[1012] = ItemType.Bucket; + mappings[1013] = ItemType.WaterBucket; + mappings[1014] = ItemType.LavaBucket; + mappings[1015] = ItemType.PowderSnowBucket; + mappings[1016] = ItemType.Snowball; + mappings[1017] = ItemType.Leather; + mappings[1018] = ItemType.MilkBucket; + mappings[1019] = ItemType.PufferfishBucket; + mappings[1020] = ItemType.SalmonBucket; + mappings[1021] = ItemType.CodBucket; + mappings[1022] = ItemType.TropicalFishBucket; + mappings[1023] = ItemType.AxolotlBucket; + mappings[1024] = ItemType.TadpoleBucket; + mappings[1025] = ItemType.Brick; + mappings[1026] = ItemType.ClayBall; + mappings[1027] = ItemType.DriedKelpBlock; + mappings[1028] = ItemType.Paper; + mappings[1029] = ItemType.Book; + mappings[1030] = ItemType.SlimeBall; + mappings[1031] = ItemType.Egg; + mappings[1032] = ItemType.BlueEgg; + mappings[1033] = ItemType.BrownEgg; + mappings[1034] = ItemType.Compass; + mappings[1035] = ItemType.RecoveryCompass; + mappings[1036] = ItemType.Bundle; + mappings[1037] = ItemType.WhiteBundle; + mappings[1038] = ItemType.OrangeBundle; + mappings[1039] = ItemType.MagentaBundle; + mappings[1040] = ItemType.LightBlueBundle; + mappings[1041] = ItemType.YellowBundle; + mappings[1042] = ItemType.LimeBundle; + mappings[1043] = ItemType.PinkBundle; + mappings[1044] = ItemType.GrayBundle; + mappings[1045] = ItemType.LightGrayBundle; + mappings[1046] = ItemType.CyanBundle; + mappings[1047] = ItemType.PurpleBundle; + mappings[1048] = ItemType.BlueBundle; + mappings[1049] = ItemType.BrownBundle; + mappings[1050] = ItemType.GreenBundle; + mappings[1051] = ItemType.RedBundle; + mappings[1052] = ItemType.BlackBundle; + mappings[1053] = ItemType.FishingRod; + mappings[1054] = ItemType.Clock; + mappings[1055] = ItemType.Spyglass; + mappings[1056] = ItemType.GlowstoneDust; + mappings[1057] = ItemType.Cod; + mappings[1058] = ItemType.Salmon; + mappings[1059] = ItemType.TropicalFish; + mappings[1060] = ItemType.Pufferfish; + mappings[1061] = ItemType.CookedCod; + mappings[1062] = ItemType.CookedSalmon; + mappings[1063] = ItemType.InkSac; + mappings[1064] = ItemType.GlowInkSac; + mappings[1065] = ItemType.CocoaBeans; + mappings[1066] = ItemType.WhiteDye; + mappings[1067] = ItemType.OrangeDye; + mappings[1068] = ItemType.MagentaDye; + mappings[1069] = ItemType.LightBlueDye; + mappings[1070] = ItemType.YellowDye; + mappings[1071] = ItemType.LimeDye; + mappings[1072] = ItemType.PinkDye; + mappings[1073] = ItemType.GrayDye; + mappings[1074] = ItemType.LightGrayDye; + mappings[1075] = ItemType.CyanDye; + mappings[1076] = ItemType.PurpleDye; + mappings[1077] = ItemType.BlueDye; + mappings[1078] = ItemType.BrownDye; + mappings[1079] = ItemType.GreenDye; + mappings[1080] = ItemType.RedDye; + mappings[1081] = ItemType.BlackDye; + mappings[1082] = ItemType.BoneMeal; + mappings[1083] = ItemType.Bone; + mappings[1084] = ItemType.Sugar; + mappings[1085] = ItemType.Cake; + mappings[1086] = ItemType.WhiteBed; + mappings[1087] = ItemType.OrangeBed; + mappings[1088] = ItemType.MagentaBed; + mappings[1089] = ItemType.LightBlueBed; + mappings[1090] = ItemType.YellowBed; + mappings[1091] = ItemType.LimeBed; + mappings[1092] = ItemType.PinkBed; + mappings[1093] = ItemType.GrayBed; + mappings[1094] = ItemType.LightGrayBed; + mappings[1095] = ItemType.CyanBed; + mappings[1096] = ItemType.PurpleBed; + mappings[1097] = ItemType.BlueBed; + mappings[1098] = ItemType.BrownBed; + mappings[1099] = ItemType.GreenBed; + mappings[1100] = ItemType.RedBed; + mappings[1101] = ItemType.BlackBed; + mappings[1102] = ItemType.Cookie; + mappings[1103] = ItemType.Crafter; + mappings[1104] = ItemType.FilledMap; + mappings[1105] = ItemType.Shears; + mappings[1106] = ItemType.MelonSlice; + mappings[1107] = ItemType.DriedKelp; + mappings[1108] = ItemType.PumpkinSeeds; + mappings[1109] = ItemType.MelonSeeds; + mappings[1110] = ItemType.Beef; + mappings[1111] = ItemType.CookedBeef; + mappings[1112] = ItemType.Chicken; + mappings[1113] = ItemType.CookedChicken; + mappings[1114] = ItemType.RottenFlesh; + mappings[1115] = ItemType.EnderPearl; + mappings[1116] = ItemType.BlazeRod; + mappings[1117] = ItemType.GhastTear; + mappings[1118] = ItemType.GoldNugget; + mappings[1119] = ItemType.NetherWart; + mappings[1120] = ItemType.GlassBottle; + mappings[1121] = ItemType.Potion; + mappings[1122] = ItemType.SpiderEye; + mappings[1123] = ItemType.FermentedSpiderEye; + mappings[1124] = ItemType.BlazePowder; + mappings[1125] = ItemType.MagmaCream; + mappings[1126] = ItemType.BrewingStand; + mappings[1127] = ItemType.Cauldron; + mappings[1128] = ItemType.EnderEye; + mappings[1129] = ItemType.GlisteringMelonSlice; + mappings[1130] = ItemType.ChickenSpawnEgg; + mappings[1131] = ItemType.CowSpawnEgg; + mappings[1132] = ItemType.PigSpawnEgg; + mappings[1133] = ItemType.SheepSpawnEgg; + mappings[1134] = ItemType.CamelSpawnEgg; + mappings[1135] = ItemType.DonkeySpawnEgg; + mappings[1136] = ItemType.HorseSpawnEgg; + mappings[1137] = ItemType.MuleSpawnEgg; + mappings[1138] = ItemType.CatSpawnEgg; + mappings[1139] = ItemType.ParrotSpawnEgg; + mappings[1140] = ItemType.WolfSpawnEgg; + mappings[1141] = ItemType.ArmadilloSpawnEgg; + mappings[1142] = ItemType.BatSpawnEgg; + mappings[1143] = ItemType.BeeSpawnEgg; + mappings[1144] = ItemType.FoxSpawnEgg; + mappings[1145] = ItemType.GoatSpawnEgg; + mappings[1146] = ItemType.LlamaSpawnEgg; + mappings[1147] = ItemType.OcelotSpawnEgg; + mappings[1148] = ItemType.PandaSpawnEgg; + mappings[1149] = ItemType.PolarBearSpawnEgg; + mappings[1150] = ItemType.RabbitSpawnEgg; + mappings[1151] = ItemType.AxolotlSpawnEgg; + mappings[1152] = ItemType.CodSpawnEgg; + mappings[1153] = ItemType.DolphinSpawnEgg; + mappings[1154] = ItemType.FrogSpawnEgg; + mappings[1155] = ItemType.GlowSquidSpawnEgg; + mappings[1156] = ItemType.NautilusSpawnEgg; + mappings[1157] = ItemType.PufferfishSpawnEgg; + mappings[1158] = ItemType.SalmonSpawnEgg; + mappings[1159] = ItemType.SquidSpawnEgg; + mappings[1160] = ItemType.TadpoleSpawnEgg; + mappings[1161] = ItemType.TropicalFishSpawnEgg; + mappings[1162] = ItemType.TurtleSpawnEgg; + mappings[1163] = ItemType.AllaySpawnEgg; + mappings[1164] = ItemType.MooshroomSpawnEgg; + mappings[1165] = ItemType.SnifferSpawnEgg; + mappings[1166] = ItemType.CopperGolemSpawnEgg; + mappings[1167] = ItemType.IronGolemSpawnEgg; + mappings[1168] = ItemType.SnowGolemSpawnEgg; + mappings[1169] = ItemType.TraderLlamaSpawnEgg; + mappings[1170] = ItemType.VillagerSpawnEgg; + mappings[1171] = ItemType.WanderingTraderSpawnEgg; + mappings[1172] = ItemType.BoggedSpawnEgg; + mappings[1173] = ItemType.CamelHuskSpawnEgg; + mappings[1174] = ItemType.DrownedSpawnEgg; + mappings[1175] = ItemType.HuskSpawnEgg; + mappings[1176] = ItemType.ParchedSpawnEgg; + mappings[1177] = ItemType.SkeletonSpawnEgg; + mappings[1178] = ItemType.SkeletonHorseSpawnEgg; + mappings[1179] = ItemType.StraySpawnEgg; + mappings[1180] = ItemType.WitherSpawnEgg; + mappings[1181] = ItemType.WitherSkeletonSpawnEgg; + mappings[1182] = ItemType.ZombieSpawnEgg; + mappings[1183] = ItemType.ZombieHorseSpawnEgg; + mappings[1184] = ItemType.ZombieNautilusSpawnEgg; + mappings[1185] = ItemType.ZombieVillagerSpawnEgg; + mappings[1186] = ItemType.CaveSpiderSpawnEgg; + mappings[1187] = ItemType.SpiderSpawnEgg; + mappings[1188] = ItemType.BreezeSpawnEgg; + mappings[1189] = ItemType.CreakingSpawnEgg; + mappings[1190] = ItemType.CreeperSpawnEgg; + mappings[1191] = ItemType.ElderGuardianSpawnEgg; + mappings[1192] = ItemType.GuardianSpawnEgg; + mappings[1193] = ItemType.PhantomSpawnEgg; + mappings[1194] = ItemType.SilverfishSpawnEgg; + mappings[1195] = ItemType.SlimeSpawnEgg; + mappings[1196] = ItemType.WardenSpawnEgg; + mappings[1197] = ItemType.WitchSpawnEgg; + mappings[1198] = ItemType.EvokerSpawnEgg; + mappings[1199] = ItemType.PillagerSpawnEgg; + mappings[1200] = ItemType.RavagerSpawnEgg; + mappings[1201] = ItemType.VindicatorSpawnEgg; + mappings[1202] = ItemType.VexSpawnEgg; + mappings[1203] = ItemType.BlazeSpawnEgg; + mappings[1204] = ItemType.GhastSpawnEgg; + mappings[1205] = ItemType.HappyGhastSpawnEgg; + mappings[1206] = ItemType.HoglinSpawnEgg; + mappings[1207] = ItemType.MagmaCubeSpawnEgg; + mappings[1208] = ItemType.PiglinSpawnEgg; + mappings[1209] = ItemType.PiglinBruteSpawnEgg; + mappings[1210] = ItemType.StriderSpawnEgg; + mappings[1211] = ItemType.ZoglinSpawnEgg; + mappings[1212] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1213] = ItemType.EnderDragonSpawnEgg; + mappings[1214] = ItemType.EndermanSpawnEgg; + mappings[1215] = ItemType.EndermiteSpawnEgg; + mappings[1216] = ItemType.ShulkerSpawnEgg; + mappings[1217] = ItemType.ExperienceBottle; + mappings[1218] = ItemType.FireCharge; + mappings[1219] = ItemType.WindCharge; + mappings[1220] = ItemType.WritableBook; + mappings[1221] = ItemType.WrittenBook; + mappings[1222] = ItemType.BreezeRod; + mappings[1223] = ItemType.Mace; + mappings[1224] = ItemType.ItemFrame; + mappings[1225] = ItemType.GlowItemFrame; + mappings[1226] = ItemType.FlowerPot; + mappings[1227] = ItemType.Carrot; + mappings[1228] = ItemType.Potato; + mappings[1229] = ItemType.BakedPotato; + mappings[1230] = ItemType.PoisonousPotato; + mappings[1231] = ItemType.Map; + mappings[1232] = ItemType.GoldenCarrot; + mappings[1233] = ItemType.SkeletonSkull; + mappings[1234] = ItemType.WitherSkeletonSkull; + mappings[1235] = ItemType.PlayerHead; + mappings[1236] = ItemType.ZombieHead; + mappings[1237] = ItemType.CreeperHead; + mappings[1238] = ItemType.DragonHead; + mappings[1239] = ItemType.PiglinHead; + mappings[1240] = ItemType.NetherStar; + mappings[1241] = ItemType.PumpkinPie; + mappings[1242] = ItemType.FireworkRocket; + mappings[1243] = ItemType.FireworkStar; + mappings[1244] = ItemType.EnchantedBook; + mappings[1245] = ItemType.NetherBrick; + mappings[1246] = ItemType.ResinBrick; + mappings[1247] = ItemType.PrismarineShard; + mappings[1248] = ItemType.PrismarineCrystals; + mappings[1249] = ItemType.Rabbit; + mappings[1250] = ItemType.CookedRabbit; + mappings[1251] = ItemType.RabbitStew; + mappings[1252] = ItemType.RabbitFoot; + mappings[1253] = ItemType.RabbitHide; + mappings[1254] = ItemType.ArmorStand; + mappings[1255] = ItemType.CopperHorseArmor; + mappings[1256] = ItemType.IronHorseArmor; + mappings[1257] = ItemType.GoldenHorseArmor; + mappings[1258] = ItemType.DiamondHorseArmor; + mappings[1259] = ItemType.NetheriteHorseArmor; + mappings[1260] = ItemType.LeatherHorseArmor; + mappings[1261] = ItemType.Lead; + mappings[1262] = ItemType.NameTag; + mappings[1263] = ItemType.CommandBlockMinecart; + mappings[1264] = ItemType.Mutton; + mappings[1265] = ItemType.CookedMutton; + mappings[1266] = ItemType.WhiteBanner; + mappings[1267] = ItemType.OrangeBanner; + mappings[1268] = ItemType.MagentaBanner; + mappings[1269] = ItemType.LightBlueBanner; + mappings[1270] = ItemType.YellowBanner; + mappings[1271] = ItemType.LimeBanner; + mappings[1272] = ItemType.PinkBanner; + mappings[1273] = ItemType.GrayBanner; + mappings[1274] = ItemType.LightGrayBanner; + mappings[1275] = ItemType.CyanBanner; + mappings[1276] = ItemType.PurpleBanner; + mappings[1277] = ItemType.BlueBanner; + mappings[1278] = ItemType.BrownBanner; + mappings[1279] = ItemType.GreenBanner; + mappings[1280] = ItemType.RedBanner; + mappings[1281] = ItemType.BlackBanner; + mappings[1282] = ItemType.EndCrystal; + mappings[1283] = ItemType.ChorusFruit; + mappings[1284] = ItemType.PoppedChorusFruit; + mappings[1285] = ItemType.TorchflowerSeeds; + mappings[1286] = ItemType.PitcherPod; + mappings[1287] = ItemType.Beetroot; + mappings[1288] = ItemType.BeetrootSeeds; + mappings[1289] = ItemType.BeetrootSoup; + mappings[1290] = ItemType.DragonBreath; + mappings[1291] = ItemType.SplashPotion; + mappings[1292] = ItemType.SpectralArrow; + mappings[1293] = ItemType.TippedArrow; + mappings[1294] = ItemType.LingeringPotion; + mappings[1295] = ItemType.Shield; + mappings[1296] = ItemType.WoodenSpear; + mappings[1297] = ItemType.StoneSpear; + mappings[1298] = ItemType.CopperSpear; + mappings[1299] = ItemType.IronSpear; + mappings[1300] = ItemType.GoldenSpear; + mappings[1301] = ItemType.DiamondSpear; + mappings[1302] = ItemType.NetheriteSpear; + mappings[1303] = ItemType.TotemOfUndying; + mappings[1304] = ItemType.ShulkerShell; + mappings[1305] = ItemType.IronNugget; + mappings[1306] = ItemType.CopperNugget; + mappings[1307] = ItemType.KnowledgeBook; + mappings[1308] = ItemType.DebugStick; + mappings[1309] = ItemType.MusicDisc13; + mappings[1310] = ItemType.MusicDiscCat; + mappings[1311] = ItemType.MusicDiscBlocks; + mappings[1312] = ItemType.MusicDiscChirp; + mappings[1313] = ItemType.MusicDiscCreator; + mappings[1314] = ItemType.MusicDiscCreatorMusicBox; + mappings[1315] = ItemType.MusicDiscFar; + mappings[1316] = ItemType.MusicDiscLavaChicken; + mappings[1317] = ItemType.MusicDiscMall; + mappings[1318] = ItemType.MusicDiscMellohi; + mappings[1319] = ItemType.MusicDiscStal; + mappings[1320] = ItemType.MusicDiscStrad; + mappings[1321] = ItemType.MusicDiscWard; + mappings[1322] = ItemType.MusicDisc11; + mappings[1323] = ItemType.MusicDiscWait; + mappings[1324] = ItemType.MusicDiscOtherside; + mappings[1325] = ItemType.MusicDiscRelic; + mappings[1326] = ItemType.MusicDisc5; + mappings[1327] = ItemType.MusicDiscPigstep; + mappings[1328] = ItemType.MusicDiscPrecipice; + mappings[1329] = ItemType.MusicDiscTears; + mappings[1330] = ItemType.DiscFragment5; + mappings[1331] = ItemType.Trident; + mappings[1332] = ItemType.NautilusShell; + mappings[1333] = ItemType.IronNautilusArmor; + mappings[1334] = ItemType.GoldenNautilusArmor; + mappings[1335] = ItemType.DiamondNautilusArmor; + mappings[1336] = ItemType.NetheriteNautilusArmor; + mappings[1337] = ItemType.CopperNautilusArmor; + mappings[1338] = ItemType.HeartOfTheSea; + mappings[1339] = ItemType.Crossbow; + mappings[1340] = ItemType.SuspiciousStew; + mappings[1341] = ItemType.Loom; + mappings[1342] = ItemType.FlowerBannerPattern; + mappings[1343] = ItemType.CreeperBannerPattern; + mappings[1344] = ItemType.SkullBannerPattern; + mappings[1345] = ItemType.MojangBannerPattern; + mappings[1346] = ItemType.GlobeBannerPattern; + mappings[1347] = ItemType.PiglinBannerPattern; + mappings[1348] = ItemType.FlowBannerPattern; + mappings[1349] = ItemType.GusterBannerPattern; + mappings[1350] = ItemType.FieldMasonedBannerPattern; + mappings[1351] = ItemType.BordureIndentedBannerPattern; + mappings[1352] = ItemType.GoatHorn; + mappings[1353] = ItemType.Composter; + mappings[1354] = ItemType.Barrel; + mappings[1355] = ItemType.Smoker; + mappings[1356] = ItemType.BlastFurnace; + mappings[1357] = ItemType.CartographyTable; + mappings[1358] = ItemType.FletchingTable; + mappings[1359] = ItemType.Grindstone; + mappings[1360] = ItemType.SmithingTable; + mappings[1361] = ItemType.Stonecutter; + mappings[1362] = ItemType.Bell; + mappings[1363] = ItemType.Lantern; + mappings[1364] = ItemType.SoulLantern; + mappings[1365] = ItemType.CopperLantern; + mappings[1366] = ItemType.ExposedCopperLantern; + mappings[1367] = ItemType.WeatheredCopperLantern; + mappings[1368] = ItemType.OxidizedCopperLantern; + mappings[1369] = ItemType.WaxedCopperLantern; + mappings[1370] = ItemType.WaxedExposedCopperLantern; + mappings[1371] = ItemType.WaxedWeatheredCopperLantern; + mappings[1372] = ItemType.WaxedOxidizedCopperLantern; + mappings[1373] = ItemType.SweetBerries; + mappings[1374] = ItemType.GlowBerries; + mappings[1375] = ItemType.Campfire; + mappings[1376] = ItemType.SoulCampfire; + mappings[1377] = ItemType.Shroomlight; + mappings[1378] = ItemType.Honeycomb; + mappings[1379] = ItemType.BeeNest; + mappings[1380] = ItemType.Beehive; + mappings[1381] = ItemType.HoneyBottle; + mappings[1382] = ItemType.HoneycombBlock; + mappings[1383] = ItemType.Lodestone; + mappings[1384] = ItemType.CryingObsidian; + mappings[1385] = ItemType.Blackstone; + mappings[1386] = ItemType.BlackstoneSlab; + mappings[1387] = ItemType.BlackstoneStairs; + mappings[1388] = ItemType.GildedBlackstone; + mappings[1389] = ItemType.PolishedBlackstone; + mappings[1390] = ItemType.PolishedBlackstoneSlab; + mappings[1391] = ItemType.PolishedBlackstoneStairs; + mappings[1392] = ItemType.ChiseledPolishedBlackstone; + mappings[1393] = ItemType.PolishedBlackstoneBricks; + mappings[1394] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1395] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1396] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1397] = ItemType.RespawnAnchor; + mappings[1398] = ItemType.Candle; + mappings[1399] = ItemType.WhiteCandle; + mappings[1400] = ItemType.OrangeCandle; + mappings[1401] = ItemType.MagentaCandle; + mappings[1402] = ItemType.LightBlueCandle; + mappings[1403] = ItemType.YellowCandle; + mappings[1404] = ItemType.LimeCandle; + mappings[1405] = ItemType.PinkCandle; + mappings[1406] = ItemType.GrayCandle; + mappings[1407] = ItemType.LightGrayCandle; + mappings[1408] = ItemType.CyanCandle; + mappings[1409] = ItemType.PurpleCandle; + mappings[1410] = ItemType.BlueCandle; + mappings[1411] = ItemType.BrownCandle; + mappings[1412] = ItemType.GreenCandle; + mappings[1413] = ItemType.RedCandle; + mappings[1414] = ItemType.BlackCandle; + mappings[1415] = ItemType.SmallAmethystBud; + mappings[1416] = ItemType.MediumAmethystBud; + mappings[1417] = ItemType.LargeAmethystBud; + mappings[1418] = ItemType.AmethystCluster; + mappings[1419] = ItemType.PointedDripstone; + mappings[1420] = ItemType.OchreFroglight; + mappings[1421] = ItemType.VerdantFroglight; + mappings[1422] = ItemType.PearlescentFroglight; + mappings[1423] = ItemType.Frogspawn; + mappings[1424] = ItemType.EchoShard; + mappings[1425] = ItemType.Brush; + mappings[1426] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1427] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1428] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1429] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1430] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1431] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1432] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1433] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1434] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1435] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1436] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1437] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1438] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1439] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1440] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1441] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1442] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1443] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1444] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1445] = ItemType.AnglerPotterySherd; + mappings[1446] = ItemType.ArcherPotterySherd; + mappings[1447] = ItemType.ArmsUpPotterySherd; + mappings[1448] = ItemType.BladePotterySherd; + mappings[1449] = ItemType.BrewerPotterySherd; + mappings[1450] = ItemType.BurnPotterySherd; + mappings[1451] = ItemType.DangerPotterySherd; + mappings[1452] = ItemType.ExplorerPotterySherd; + mappings[1453] = ItemType.FlowPotterySherd; + mappings[1454] = ItemType.FriendPotterySherd; + mappings[1455] = ItemType.GusterPotterySherd; + mappings[1456] = ItemType.HeartPotterySherd; + mappings[1457] = ItemType.HeartbreakPotterySherd; + mappings[1458] = ItemType.HowlPotterySherd; + mappings[1459] = ItemType.MinerPotterySherd; + mappings[1460] = ItemType.MournerPotterySherd; + mappings[1461] = ItemType.PlentyPotterySherd; + mappings[1462] = ItemType.PrizePotterySherd; + mappings[1463] = ItemType.ScrapePotterySherd; + mappings[1464] = ItemType.SheafPotterySherd; + mappings[1465] = ItemType.ShelterPotterySherd; + mappings[1466] = ItemType.SkullPotterySherd; + mappings[1467] = ItemType.SnortPotterySherd; + mappings[1468] = ItemType.CopperGrate; + mappings[1469] = ItemType.ExposedCopperGrate; + mappings[1470] = ItemType.WeatheredCopperGrate; + mappings[1471] = ItemType.OxidizedCopperGrate; + mappings[1472] = ItemType.WaxedCopperGrate; + mappings[1473] = ItemType.WaxedExposedCopperGrate; + mappings[1474] = ItemType.WaxedWeatheredCopperGrate; + mappings[1475] = ItemType.WaxedOxidizedCopperGrate; + mappings[1476] = ItemType.CopperBulb; + mappings[1477] = ItemType.ExposedCopperBulb; + mappings[1478] = ItemType.WeatheredCopperBulb; + mappings[1479] = ItemType.OxidizedCopperBulb; + mappings[1480] = ItemType.WaxedCopperBulb; + mappings[1481] = ItemType.WaxedExposedCopperBulb; + mappings[1482] = ItemType.WaxedWeatheredCopperBulb; + mappings[1483] = ItemType.WaxedOxidizedCopperBulb; + mappings[1484] = ItemType.CopperChest; + mappings[1485] = ItemType.ExposedCopperChest; + mappings[1486] = ItemType.WeatheredCopperChest; + mappings[1487] = ItemType.OxidizedCopperChest; + mappings[1488] = ItemType.WaxedCopperChest; + mappings[1489] = ItemType.WaxedExposedCopperChest; + mappings[1490] = ItemType.WaxedWeatheredCopperChest; + mappings[1491] = ItemType.WaxedOxidizedCopperChest; + mappings[1492] = ItemType.CopperGolemStatue; + mappings[1493] = ItemType.ExposedCopperGolemStatue; + mappings[1494] = ItemType.WeatheredCopperGolemStatue; + mappings[1495] = ItemType.OxidizedCopperGolemStatue; + mappings[1496] = ItemType.WaxedCopperGolemStatue; + mappings[1497] = ItemType.WaxedExposedCopperGolemStatue; + mappings[1498] = ItemType.WaxedWeatheredCopperGolemStatue; + mappings[1499] = ItemType.WaxedOxidizedCopperGolemStatue; + mappings[1500] = ItemType.TrialSpawner; + mappings[1501] = ItemType.TrialKey; + mappings[1502] = ItemType.OminousTrialKey; + mappings[1503] = ItemType.Vault; + mappings[1504] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 16859e0c..96d629ce 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -208,6 +208,7 @@ namespace MinecraftClient.Inventory Cake, Calcite, CalibratedSculkSensor, + CamelHuskSpawnEgg, CamelSpawnEgg, Campfire, Candle, @@ -318,9 +319,11 @@ namespace MinecraftClient.Inventory CopperLantern, CopperLeggings, CopperNugget, + CopperNautilusArmor, CopperOre, CopperPickaxe, CopperShovel, + CopperSpear, CopperSword, CopperTorch, CopperTrapdoor, @@ -449,8 +452,10 @@ namespace MinecraftClient.Inventory DiamondHoe, DiamondHorseArmor, DiamondLeggings, + DiamondNautilusArmor, DiamondOre, DiamondPickaxe, + DiamondSpear, DiamondShovel, DiamondSword, Diorite, @@ -578,8 +583,10 @@ namespace MinecraftClient.Inventory GoldenHoe, GoldenHorseArmor, GoldenLeggings, + GoldenNautilusArmor, GoldenPickaxe, GoldenShovel, + GoldenSpear, GoldenSword, Granite, GraniteSlab, @@ -666,9 +673,11 @@ namespace MinecraftClient.Inventory IronHorseArmor, IronIngot, IronLeggings, + IronNautilusArmor, IronNugget, IronOre, IronPickaxe, + IronSpear, IronShovel, IronSword, IronTrapdoor, @@ -862,6 +871,7 @@ namespace MinecraftClient.Inventory Mycelium, NameTag, NautilusShell, + NautilusSpawnEgg, NetherBrick, NetherBrickFence, NetherBrickSlab, @@ -880,11 +890,14 @@ namespace MinecraftClient.Inventory NetheriteChestplate, NetheriteHelmet, NetheriteHoe, + NetheriteHorseArmor, NetheriteIngot, NetheriteLeggings, + NetheriteNautilusArmor, NetheritePickaxe, NetheriteScrap, NetheriteShovel, + NetheriteSpear, NetheriteSword, NetheriteUpgradeSmithingTemplate, Netherrack, @@ -972,6 +985,7 @@ namespace MinecraftClient.Inventory PaleOakWood, PandaSpawnEgg, Paper, + ParchedSpawnEgg, ParrotSpawnEgg, PearlescentFroglight, Peony, @@ -1261,6 +1275,7 @@ namespace MinecraftClient.Inventory StonePressurePlate, StoneShovel, StoneSlab, + StoneSpear, StoneStairs, StoneSword, Stonecutter, @@ -1480,6 +1495,7 @@ namespace MinecraftClient.Inventory WoodenAxe, WoodenHoe, WoodenPickaxe, + WoodenSpear, WoodenShovel, WoodenSword, WritableBook, @@ -1503,6 +1519,7 @@ namespace MinecraftClient.Inventory ZombieHead, ZombieHorseSpawnEgg, ZombieSpawnEgg, + ZombieNautilusSpawnEgg, ZombieVillagerSpawnEgg, ZombifiedPiglinSpawnEgg, } diff --git a/MinecraftClient/Mapping/EntityMetaDataType.cs b/MinecraftClient/Mapping/EntityMetaDataType.cs index a9204a8e..f5c70b7b 100644 --- a/MinecraftClient/Mapping/EntityMetaDataType.cs +++ b/MinecraftClient/Mapping/EntityMetaDataType.cs @@ -116,5 +116,13 @@ public enum EntityMetaDataType /// /// Either<GameProfile, Partial> + PlayerSkin.Patch (1.21.9+) /// - ResolvableProfile + ResolvableProfile, + /// + /// VarInt (1.21.11+, holder registry ID) + /// + ZombieNautilusVariant, + /// + /// VarInt (1.21.11+, 0=LEFT, 1=RIGHT) + /// + HumanoidArm } \ No newline at end of file diff --git a/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette12111.cs b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette12111.cs new file mode 100644 index 00000000..cff64189 --- /dev/null +++ b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette12111.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityMetadataPalettes; + +public class EntityMetadataPalette12111 : EntityMetadataPalette +{ + private readonly Dictionary entityMetadataMappings = new() + { + { 0, EntityMetaDataType.Byte }, + { 1, EntityMetaDataType.VarInt }, + { 2, EntityMetaDataType.VarLong }, + { 3, EntityMetaDataType.Float }, + { 4, EntityMetaDataType.String }, + { 5, EntityMetaDataType.Chat }, + { 6, EntityMetaDataType.OptionalChat }, + { 7, EntityMetaDataType.Slot }, + { 8, EntityMetaDataType.Boolean }, + { 9, EntityMetaDataType.Rotation }, + { 10, EntityMetaDataType.Position }, + { 11, EntityMetaDataType.OptionalPosition }, + { 12, EntityMetaDataType.Direction }, + { 13, EntityMetaDataType.OptionalLivingEntityReference }, + { 14, EntityMetaDataType.BlockId }, + { 15, EntityMetaDataType.OptionalBlockId }, + { 16, EntityMetaDataType.Particle }, + { 17, EntityMetaDataType.Particles }, + { 18, EntityMetaDataType.VillagerData }, + { 19, EntityMetaDataType.OptionalVarInt }, + { 20, EntityMetaDataType.Pose }, + { 21, EntityMetaDataType.CatVariant }, + { 22, EntityMetaDataType.CowVariant }, + { 23, EntityMetaDataType.WolfVariant }, + { 24, EntityMetaDataType.WolfSoundVariant }, + { 25, EntityMetaDataType.FrogVariant }, + { 26, EntityMetaDataType.PigVariant }, + { 27, EntityMetaDataType.ChickenVariant }, + { 28, EntityMetaDataType.ZombieNautilusVariant }, + { 29, EntityMetaDataType.OptionalGlobalPosition }, + { 30, EntityMetaDataType.PaintingVariant }, + { 31, EntityMetaDataType.SnifferState }, + { 32, EntityMetaDataType.ArmadilloState }, + { 33, EntityMetaDataType.CopperGolemState }, + { 34, EntityMetaDataType.WeatheringCopperState }, + { 35, EntityMetaDataType.Vector3 }, + { 36, EntityMetaDataType.Quaternion }, + { 37, EntityMetaDataType.ResolvableProfile }, + { 38, EntityMetaDataType.HumanoidArm }, + }; + + public override Dictionary GetEntityMetadataMappingsList() + { + return entityMetadataMappings; + } +} diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette12111.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette12111.cs new file mode 100644 index 00000000..5c3cb5ca --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette12111.cs @@ -0,0 +1,175 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette12111 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette12111() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.CamelHusk; + mappings[21] = EntityType.Cat; + mappings[22] = EntityType.CaveSpider; + mappings[23] = EntityType.CherryBoat; + mappings[24] = EntityType.CherryChestBoat; + mappings[25] = EntityType.ChestMinecart; + mappings[26] = EntityType.Chicken; + mappings[27] = EntityType.Cod; + mappings[28] = EntityType.CopperGolem; + mappings[29] = EntityType.CommandBlockMinecart; + mappings[30] = EntityType.Cow; + mappings[31] = EntityType.Creaking; + mappings[32] = EntityType.Creeper; + mappings[33] = EntityType.DarkOakBoat; + mappings[34] = EntityType.DarkOakChestBoat; + mappings[35] = EntityType.Dolphin; + mappings[36] = EntityType.Donkey; + mappings[37] = EntityType.DragonFireball; + mappings[38] = EntityType.Drowned; + mappings[39] = EntityType.Egg; + mappings[40] = EntityType.ElderGuardian; + mappings[41] = EntityType.Enderman; + mappings[42] = EntityType.Endermite; + mappings[43] = EntityType.EnderDragon; + mappings[44] = EntityType.EnderPearl; + mappings[45] = EntityType.EndCrystal; + mappings[46] = EntityType.Evoker; + mappings[47] = EntityType.EvokerFangs; + mappings[48] = EntityType.ExperienceBottle; + mappings[49] = EntityType.ExperienceOrb; + mappings[50] = EntityType.EyeOfEnder; + mappings[51] = EntityType.FallingBlock; + mappings[52] = EntityType.Fireball; + mappings[53] = EntityType.FireworkRocket; + mappings[54] = EntityType.Fox; + mappings[55] = EntityType.Frog; + mappings[56] = EntityType.FurnaceMinecart; + mappings[57] = EntityType.Ghast; + mappings[58] = EntityType.HappyGhast; + mappings[59] = EntityType.Giant; + mappings[60] = EntityType.GlowItemFrame; + mappings[61] = EntityType.GlowSquid; + mappings[62] = EntityType.Goat; + mappings[63] = EntityType.Guardian; + mappings[64] = EntityType.Hoglin; + mappings[65] = EntityType.HopperMinecart; + mappings[66] = EntityType.Horse; + mappings[67] = EntityType.Husk; + mappings[68] = EntityType.Illusioner; + mappings[69] = EntityType.Interaction; + mappings[70] = EntityType.IronGolem; + mappings[71] = EntityType.Item; + mappings[72] = EntityType.ItemDisplay; + mappings[73] = EntityType.ItemFrame; + mappings[74] = EntityType.JungleBoat; + mappings[75] = EntityType.JungleChestBoat; + mappings[76] = EntityType.LeashKnot; + mappings[77] = EntityType.LightningBolt; + mappings[78] = EntityType.Llama; + mappings[79] = EntityType.LlamaSpit; + mappings[80] = EntityType.MagmaCube; + mappings[81] = EntityType.MangroveBoat; + mappings[82] = EntityType.MangroveChestBoat; + mappings[83] = EntityType.Mannequin; + mappings[84] = EntityType.Marker; + mappings[85] = EntityType.Minecart; + mappings[86] = EntityType.Mooshroom; + mappings[87] = EntityType.Mule; + mappings[88] = EntityType.Nautilus; + mappings[89] = EntityType.OakBoat; + mappings[90] = EntityType.OakChestBoat; + mappings[91] = EntityType.Ocelot; + mappings[92] = EntityType.OminousItemSpawner; + mappings[93] = EntityType.Painting; + mappings[94] = EntityType.PaleOakBoat; + mappings[95] = EntityType.PaleOakChestBoat; + mappings[96] = EntityType.Panda; + mappings[97] = EntityType.Parched; + mappings[98] = EntityType.Parrot; + mappings[99] = EntityType.Phantom; + mappings[100] = EntityType.Pig; + mappings[101] = EntityType.Piglin; + mappings[102] = EntityType.PiglinBrute; + mappings[103] = EntityType.Pillager; + mappings[104] = EntityType.PolarBear; + mappings[105] = EntityType.SplashPotion; + mappings[106] = EntityType.LingeringPotion; + mappings[107] = EntityType.Pufferfish; + mappings[108] = EntityType.Rabbit; + mappings[109] = EntityType.Ravager; + mappings[110] = EntityType.Salmon; + mappings[111] = EntityType.Sheep; + mappings[112] = EntityType.Shulker; + mappings[113] = EntityType.ShulkerBullet; + mappings[114] = EntityType.Silverfish; + mappings[115] = EntityType.Skeleton; + mappings[116] = EntityType.SkeletonHorse; + mappings[117] = EntityType.Slime; + mappings[118] = EntityType.SmallFireball; + mappings[119] = EntityType.Sniffer; + mappings[120] = EntityType.Snowball; + mappings[121] = EntityType.SnowGolem; + mappings[122] = EntityType.SpawnerMinecart; + mappings[123] = EntityType.SpectralArrow; + mappings[124] = EntityType.Spider; + mappings[125] = EntityType.SpruceBoat; + mappings[126] = EntityType.SpruceChestBoat; + mappings[127] = EntityType.Squid; + mappings[128] = EntityType.Stray; + mappings[129] = EntityType.Strider; + mappings[130] = EntityType.Tadpole; + mappings[131] = EntityType.TextDisplay; + mappings[132] = EntityType.Tnt; + mappings[133] = EntityType.TntMinecart; + mappings[134] = EntityType.TraderLlama; + mappings[135] = EntityType.Trident; + mappings[136] = EntityType.TropicalFish; + mappings[137] = EntityType.Turtle; + mappings[138] = EntityType.Vex; + mappings[139] = EntityType.Villager; + mappings[140] = EntityType.Vindicator; + mappings[141] = EntityType.WanderingTrader; + mappings[142] = EntityType.Warden; + mappings[143] = EntityType.WindCharge; + mappings[144] = EntityType.Witch; + mappings[145] = EntityType.Wither; + mappings[146] = EntityType.WitherSkeleton; + mappings[147] = EntityType.WitherSkull; + mappings[148] = EntityType.Wolf; + mappings[149] = EntityType.Zoglin; + mappings[150] = EntityType.Zombie; + mappings[151] = EntityType.ZombieHorse; + mappings[152] = EntityType.ZombieNautilus; + mappings[153] = EntityType.ZombieVillager; + mappings[154] = EntityType.ZombifiedPiglin; + mappings[155] = EntityType.Player; + mappings[156] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 4dca83f7..7c4748fd 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -35,6 +35,7 @@ namespace MinecraftClient.Mapping Breeze, BreezeWindCharge, Camel, + CamelHusk, Cat, CaveSpider, CherryBoat, @@ -105,6 +106,7 @@ namespace MinecraftClient.Mapping Minecart, Mooshroom, Mule, + Nautilus, OakBoat, OakChestBoat, Ocelot, @@ -113,6 +115,7 @@ namespace MinecraftClient.Mapping PaleOakBoat, PaleOakChestBoat, Panda, + Parched, Parrot, Phantom, Pig, @@ -169,6 +172,7 @@ namespace MinecraftClient.Mapping Zoglin, Zombie, ZombieHorse, + ZombieNautilus, ZombieVillager, ZombifiedPiglin, } diff --git a/tools/gen_entity_metadata_palette.py b/tools/gen_entity_metadata_palette.py index 74932bc2..5c54e80c 100644 --- a/tools/gen_entity_metadata_palette.py +++ b/tools/gen_entity_metadata_palette.py @@ -62,6 +62,8 @@ FIELD_TO_ENUM = { "VECTOR3": "Vector3", "QUATERNION": "Quaternion", "RESOLVABLE_PROFILE": "ResolvableProfile", + "ZOMBIE_NAUTILUS_VARIANT": "ZombieNautilusVariant", + "HUMANOID_ARM": "HumanoidArm", } From 6c36dc341aa707fc59794c99dc45f51c6c84bd35 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 00:56:04 +0800 Subject: [PATCH 080/484] feat: add version routing, structured components, and metadata for MC 1.21.11 - Add MC_1_21_11_Version constant (protocol 774) - Create StructuredComponentsRegistry12111 with 104 components (8 new: use_effects, minimum_attack_charge, damage_type, attack_range, piercing_weapon, kinetic_weapon, swing_animation, zombie_nautilus/variant) - Add 6 new component classes for 1.21.11 wire formats - Add RegistryEitherHolderComponent for holderRegistry-backed EitherHolder - Add ZombieNautilusVariant and HumanoidArm cases in DataTypes.ReadNextMetadata - Update all version routing in Protocol18, PacketType18Handler, EntityMetadataPalette, StructuredComponentsHandler, and ProtocolHandler - Bump MCHighestVersion to 1.21.11 Made-with: Cursor --- .../Mapping/EntityMetadataPalette.cs | 1 + MinecraftClient/Program.cs | 2 +- .../Protocol/Handlers/DataTypes.cs | 4 + .../Protocol/Handlers/PacketType18Handler.cs | 4 +- .../Protocol/Handlers/Protocol18.cs | 17 ++- .../1_21_11/AttackRangeComponent.cs | 38 ++++++ .../1_21_11/KineticWeaponComponent.cs | 47 +++++++ .../1_21_11/PiercingWeaponComponent.cs | 37 ++++++ .../1_21_11/RegistryEitherHolderComponent.cs | 38 ++++++ .../1_21_11/SwingAnimationComponent.cs | 26 ++++ .../Components/1_21_11/UseEffectsComponent.cs | 29 +++++ .../StructuredComponentsRegistry12111.cs | 123 ++++++++++++++++++ .../StructuredComponentsHandler.cs | 2 +- MinecraftClient/Protocol/ProtocolHandler.cs | 5 +- 14 files changed, 361 insertions(+), 12 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/AttackRangeComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/KineticWeaponComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/PiercingWeaponComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/RegistryEitherHolderComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/SwingAnimationComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/UseEffectsComponent.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 60acef8c..e4ec35e6 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -26,6 +26,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_21_4_Version => new EntityMetadataPalette1206(), // 1.20.6 - 1.21.4 <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.8 <= Protocol18Handler.MC_1_21_9_Version => new EntityMetadataPalette1219(), // 1.21.9 - 1.21.10 + <= Protocol18Handler.MC_1_21_11_Version => new EntityMetadataPalette12111(), // 1.21.11 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index ee448708..ae518b78 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.21.10"; + public const string MCHighestVersion = "1.21.11"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index d669fc68..4b4f0488 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -932,6 +932,10 @@ namespace MinecraftClient.Protocol.Handlers case EntityMetaDataType.WeatheringCopperState: // Weathering Copper state (1.21.9+) value = ReadNextVarInt(cache); break; + case EntityMetaDataType.ZombieNautilusVariant: // ZombieNautilus Variant (1.21.11+) + case EntityMetaDataType.HumanoidArm: // Humanoid Arm (1.21.11+) + value = ReadNextVarInt(cache); + break; case EntityMetaDataType.ResolvableProfile: // ResolvableProfile (1.21.9+) ReadNextResolvableProfile(cache); break; diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index 6a608dba..d8e56c86 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,9 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_9_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_1_21_11_Version => throw new NotImplementedException(Translations .exception_palette_packet), - <= Protocol18Handler.MC_1_21_9_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(), + <= Protocol18Handler.MC_1_21_11_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(), <= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), <= Protocol18Handler.MC_1_21_4_Version and > Protocol18Handler.MC_1_21_2_Version => new PacketPalette1214(), diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 6d102808..4fe6b857 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -79,6 +79,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_6_Version = 771; internal const int MC_1_21_7_Version = 772; internal const int MC_1_21_9_Version = 773; + internal const int MC_1_21_11_Version = 774; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; @@ -130,21 +131,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_9_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_11_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_9_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_11_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_9_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_11_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -153,7 +154,7 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_9_Version when handler.GetTerrainEnabled() => + > MC_1_21_11_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), >= MC_1_21_9_Version => new Palette1219(), >= MC_1_21_6_Version => new Palette1216(), // 1.21.7/1.21.8 blocks unchanged, reuse 1216 @@ -177,8 +178,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_9_Version when handler.GetEntityHandlingEnabled() => + > MC_1_21_11_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_1_21_11_Version => new EntityPalette12111(), >= MC_1_21_9_Version => new EntityPalette1219(), >= MC_1_21_6_Version => new EntityPalette1216(), // 1.21.7/1.21.8 entities unchanged, reuse 1216 >= MC_1_21_5_Version => new EntityPalette1215(), @@ -205,8 +207,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_9_Version when handler.GetInventoryEnabled() => + > MC_1_21_11_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_1_21_11_Version => new ItemPalette12111(), >= MC_1_21_9_Version => new ItemPalette1219(), >= MC_1_21_7_Version => new ItemPalette1217(), >= MC_1_21_6_Version => new ItemPalette1216(), @@ -2665,7 +2668,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_9_Version => throw new NotImplementedException(Translations + > MC_1_21_11_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/AttackRangeComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/AttackRangeComponent.cs new file mode 100644 index 00000000..d4cc2dde --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/AttackRangeComponent.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +public class AttackRangeComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public float MinRange { get; set; } + public float MaxRange { get; set; } + public float MinCreativeRange { get; set; } + public float MaxCreativeRange { get; set; } + public float HitboxMargin { get; set; } + public float MobFactor { get; set; } + + public override void Parse(Queue data) + { + MinRange = dataTypes.ReadNextFloat(data); + MaxRange = dataTypes.ReadNextFloat(data); + MinCreativeRange = dataTypes.ReadNextFloat(data); + MaxCreativeRange = dataTypes.ReadNextFloat(data); + HitboxMargin = dataTypes.ReadNextFloat(data); + MobFactor = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetFloat(MinRange)); + bytes.AddRange(DataTypes.GetFloat(MaxRange)); + bytes.AddRange(DataTypes.GetFloat(MinCreativeRange)); + bytes.AddRange(DataTypes.GetFloat(MaxCreativeRange)); + bytes.AddRange(DataTypes.GetFloat(HitboxMargin)); + bytes.AddRange(DataTypes.GetFloat(MobFactor)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/KineticWeaponComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/KineticWeaponComponent.cs new file mode 100644 index 00000000..1e1da338 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/KineticWeaponComponent.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +public class KineticWeaponComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + dataTypes.ReadNextVarInt(data); // contactCooldownTicks + dataTypes.ReadNextVarInt(data); // delayTicks + ReadOptionalCondition(data); // dismountConditions + ReadOptionalCondition(data); // knockbackConditions + ReadOptionalCondition(data); // damageConditions + dataTypes.ReadNextFloat(data); // forwardMovement + dataTypes.ReadNextFloat(data); // damageMultiplier + ReadOptionalSoundEventHolder(data); // sound + ReadOptionalSoundEventHolder(data); // hitSound + } + + private void ReadOptionalCondition(Queue data) + { + if (!dataTypes.ReadNextBool(data)) return; + dataTypes.ReadNextVarInt(data); // maxDurationTicks + dataTypes.ReadNextFloat(data); // minSpeed + dataTypes.ReadNextFloat(data); // minRelativeSpeed + } + + private void ReadOptionalSoundEventHolder(Queue data) + { + if (!dataTypes.ReadNextBool(data)) return; + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + dataTypes.ReadNextString(data); + if (dataTypes.ReadNextBool(data)) + dataTypes.ReadNextFloat(data); + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/PiercingWeaponComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/PiercingWeaponComponent.cs new file mode 100644 index 00000000..08646c66 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/PiercingWeaponComponent.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +public class PiercingWeaponComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool DealsKnockback { get; set; } + public bool Dismounts { get; set; } + + public override void Parse(Queue data) + { + DealsKnockback = dataTypes.ReadNextBool(data); + Dismounts = dataTypes.ReadNextBool(data); + ReadOptionalSoundEventHolder(data); + ReadOptionalSoundEventHolder(data); + } + + private void ReadOptionalSoundEventHolder(Queue data) + { + if (!dataTypes.ReadNextBool(data)) return; + var holderId = dataTypes.ReadNextVarInt(data); + if (holderId == 0) + { + dataTypes.ReadNextString(data); + if (dataTypes.ReadNextBool(data)) + dataTypes.ReadNextFloat(data); + } + } + + public override Queue Serialize() + { + return new Queue(); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/RegistryEitherHolderComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/RegistryEitherHolderComponent.cs new file mode 100644 index 00000000..bba3d3c7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/RegistryEitherHolderComponent.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +/// +/// EitherHolder backed by holderRegistry (VarInt = raw registry ID, 0 is valid). +/// Used for DamageType and ZombieNautilusVariant where the holder codec is holderRegistry(), +/// unlike the holder() codec used in SoundEvent (where 0 means inline). +/// +public class RegistryEitherHolderComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool IsHolder { get; set; } + public int HolderId { get; set; } + public string? ResourceKey { get; set; } + + public override void Parse(Queue data) + { + IsHolder = dataTypes.ReadNextBool(data); + if (IsHolder) + HolderId = dataTypes.ReadNextVarInt(data); + else + ResourceKey = dataTypes.ReadNextString(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetBool(IsHolder)); + if (IsHolder) + bytes.AddRange(DataTypes.GetVarInt(HolderId)); + else + bytes.AddRange(DataTypes.GetString(ResourceKey ?? "")); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/SwingAnimationComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/SwingAnimationComponent.cs new file mode 100644 index 00000000..7980f9f6 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/SwingAnimationComponent.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +public class SwingAnimationComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public int AnimationType { get; set; } + public int Duration { get; set; } + + public override void Parse(Queue data) + { + AnimationType = dataTypes.ReadNextVarInt(data); + Duration = dataTypes.ReadNextVarInt(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetVarInt(AnimationType)); + bytes.AddRange(DataTypes.GetVarInt(Duration)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/UseEffectsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/UseEffectsComponent.cs new file mode 100644 index 00000000..053e7d58 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_11/UseEffectsComponent.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; + +public class UseEffectsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public bool CanSprint { get; set; } + public bool InteractVibrations { get; set; } + public float SpeedMultiplier { get; set; } + + public override void Parse(Queue data) + { + CanSprint = dataTypes.ReadNextBool(data); + InteractVibrations = dataTypes.ReadNextBool(data); + SpeedMultiplier = dataTypes.ReadNextFloat(data); + } + + public override Queue Serialize() + { + var bytes = new List(); + bytes.AddRange(DataTypes.GetBool(CanSprint)); + bytes.AddRange(DataTypes.GetBool(InteractVibrations)); + bytes.AddRange(DataTypes.GetFloat(SpeedMultiplier)); + return new Queue(bytes); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs new file mode 100644 index 00000000..ec848fb2 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs @@ -0,0 +1,123 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry12111 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry12111(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) + { + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); + RegisterComponent(5, "minecraft:use_effects"); + RegisterComponent(6, "minecraft:custom_name"); + RegisterComponent(7, "minecraft:minimum_attack_charge"); + RegisterComponent(8, "minecraft:damage_type"); + RegisterComponent(9, "minecraft:item_name"); + RegisterComponent(10, "minecraft:item_model"); + RegisterComponent(11, "minecraft:lore"); + RegisterComponent(12, "minecraft:rarity"); + RegisterComponent(13, "minecraft:enchantments"); + RegisterComponent(14, "minecraft:can_place_on"); + RegisterComponent(15, "minecraft:can_break"); + RegisterComponent(16, "minecraft:attribute_modifiers"); + RegisterComponent(17, "minecraft:custom_model_data"); + RegisterComponent(18, "minecraft:tooltip_display"); + RegisterComponent(19, "minecraft:repair_cost"); + RegisterComponent(20, "minecraft:creative_slot_lock"); + RegisterComponent(21, "minecraft:enchantment_glint_override"); + RegisterComponent(22, "minecraft:intangible_projectile"); + RegisterComponent(23, "minecraft:food"); + RegisterComponent(24, "minecraft:consumable"); + RegisterComponent(25, "minecraft:use_remainder"); + RegisterComponent(26, "minecraft:use_cooldown"); + RegisterComponent(27, "minecraft:damage_resistant"); + RegisterComponent(28, "minecraft:tool"); + RegisterComponent(29, "minecraft:weapon"); + RegisterComponent(30, "minecraft:attack_range"); + RegisterComponent(31, "minecraft:enchantable"); + RegisterComponent(32, "minecraft:equippable"); + RegisterComponent(33, "minecraft:repairable"); + RegisterComponent(34, "minecraft:glider"); + RegisterComponent(35, "minecraft:tooltip_style"); + RegisterComponent(36, "minecraft:death_protection"); + RegisterComponent(37, "minecraft:blocks_attacks"); + RegisterComponent(38, "minecraft:piercing_weapon"); + RegisterComponent(39, "minecraft:kinetic_weapon"); + RegisterComponent(40, "minecraft:swing_animation"); + RegisterComponent(41, "minecraft:stored_enchantments"); + RegisterComponent(42, "minecraft:dyed_color"); + RegisterComponent(43, "minecraft:map_color"); + RegisterComponent(44, "minecraft:map_id"); + RegisterComponent(45, "minecraft:map_decorations"); + RegisterComponent(46, "minecraft:map_post_processing"); + RegisterComponent(47, "minecraft:charged_projectiles"); + RegisterComponent(48, "minecraft:bundle_contents"); + RegisterComponent(49, "minecraft:potion_contents"); + RegisterComponent(50, "minecraft:potion_duration_scale"); + RegisterComponent(51, "minecraft:suspicious_stew_effects"); + RegisterComponent(52, "minecraft:writable_book_content"); + RegisterComponent(53, "minecraft:written_book_content"); + RegisterComponent(54, "minecraft:trim"); + RegisterComponent(55, "minecraft:debug_stick_state"); + RegisterComponent(56, "minecraft:entity_data"); + RegisterComponent(57, "minecraft:bucket_entity_data"); + RegisterComponent(58, "minecraft:block_entity_data"); + RegisterComponent(59, "minecraft:instrument"); + RegisterComponent(60, "minecraft:provides_trim_material"); + RegisterComponent(61, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(62, "minecraft:jukebox_playable"); + RegisterComponent(63, "minecraft:provides_banner_patterns"); + RegisterComponent(64, "minecraft:recipes"); + RegisterComponent(65, "minecraft:lodestone_tracker"); + RegisterComponent(66, "minecraft:firework_explosion"); + RegisterComponent(67, "minecraft:fireworks"); + RegisterComponent(68, "minecraft:profile"); + RegisterComponent(69, "minecraft:note_block_sound"); + RegisterComponent(70, "minecraft:banner_patterns"); + RegisterComponent(71, "minecraft:base_color"); + RegisterComponent(72, "minecraft:pot_decorations"); + RegisterComponent(73, "minecraft:container"); + RegisterComponent(74, "minecraft:block_state"); + RegisterComponent(75, "minecraft:bees"); + RegisterComponent(76, "minecraft:lock"); + RegisterComponent(77, "minecraft:container_loot"); + + RegisterComponent(78, "minecraft:break_sound"); + RegisterComponent(79, "minecraft:villager/variant"); + RegisterComponent(80, "minecraft:wolf/variant"); + RegisterComponent(81, "minecraft:wolf/sound_variant"); + RegisterComponent(82, "minecraft:wolf/collar"); + RegisterComponent(83, "minecraft:fox/variant"); + RegisterComponent(84, "minecraft:salmon/size"); + RegisterComponent(85, "minecraft:parrot/variant"); + RegisterComponent(86, "minecraft:tropical_fish/pattern"); + RegisterComponent(87, "minecraft:tropical_fish/base_color"); + RegisterComponent(88, "minecraft:tropical_fish/pattern_color"); + RegisterComponent(89, "minecraft:mooshroom/variant"); + RegisterComponent(90, "minecraft:rabbit/variant"); + RegisterComponent(91, "minecraft:pig/variant"); + RegisterComponent(92, "minecraft:cow/variant"); + RegisterComponent(93, "minecraft:chicken/variant"); + RegisterComponent(94, "minecraft:zombie_nautilus/variant"); + RegisterComponent(95, "minecraft:frog/variant"); + RegisterComponent(96, "minecraft:horse/variant"); + RegisterComponent(97, "minecraft:painting/variant"); + RegisterComponent(98, "minecraft:llama/variant"); + RegisterComponent(99, "minecraft:axolotl/variant"); + RegisterComponent(100, "minecraft:cat/variant"); + RegisterComponent(101, "minecraft:cat/collar"); + RegisterComponent(102, "minecraft:sheep/color"); + RegisterComponent(103, "minecraft:shulker/color"); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index 7274c319..c8b805c2 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -21,7 +21,6 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(SubComponentRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121), - >= Protocol18Handler.MC_1_21_5_Version => typeof(SubComponentRegistry1212), >= Protocol18Handler.MC_1_21_2_Version => typeof(SubComponentRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for subcomponent registries!") }; @@ -34,6 +33,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), + >= Protocol18Handler.MC_1_21_11_Version => typeof(StructuredComponentsRegistry12111), >= Protocol18Handler.MC_1_21_5_Version => typeof(StructuredComponentsRegistry1215), >= Protocol18Handler.MC_1_21_2_Version => typeof(StructuredComponentsRegistry1212), _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index a71b9122..fa1700cc 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -154,7 +154,7 @@ namespace MinecraftClient.Protocol { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769, 770, 771, 772, 773 + 769, 770, 771, 772, 773, 774 }; if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) @@ -368,6 +368,8 @@ namespace MinecraftClient.Protocol case "1.21.9": case "1.21.10": return 773; + case "1.21.11": + return 774; default: return 0; } @@ -455,6 +457,7 @@ namespace MinecraftClient.Protocol 771 => "1.21.6", 772 => "1.21.7", 773 => "1.21.9", + 774 => "1.21.11", _ => "0.0" }; } From cf5c4f00cb29f5189994dbe24474460bd0fd1135 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 19:12:13 +0100 Subject: [PATCH 081/484] Added AGENTS.md/CLAUDE.md and a C# 12 best practices skill for MCC. --- .skills/csharp-best-practices/SKILL.md | 797 +++++++++++++++++++++++++ .skills/mcc-dev-workflow/SKILL.md | 5 + AGENTS.md | 95 +++ CLAUDE.md | 1 + 4 files changed, 898 insertions(+) create mode 100644 .skills/csharp-best-practices/SKILL.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.skills/csharp-best-practices/SKILL.md b/.skills/csharp-best-practices/SKILL.md new file mode 100644 index 00000000..1d99bf30 --- /dev/null +++ b/.skills/csharp-best-practices/SKILL.md @@ -0,0 +1,797 @@ +--- +name: csharp-best-practices +description: > + C# 12 / .NET 8 coding conventions, idiomatic patterns, and performance best practices + for the Minecraft Console Client codebase. Use when writing, reviewing, or modifying C# code. +version: 0.3.0 +--- + +# C# 12 / .NET 8 Best Practices + +Target: **.NET 8**, **C# 12**, nullable enabled. +Sources: [MS C# Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) · [.NET Runtime Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) · [C# 12 Docs](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12) · [.NET 8 Perf](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/) + +## Naming + +| Element | Style | Example | +|---|---|---| +| Type, method, property, const, enum member | PascalCase | `PacketHandler`, `MaxRetries`, `GameMode.Survival` | +| Interface | `I` + PascalCase | `IChatBot` | +| Private instance field | `_camelCase` | `_handler` | +| Private static field | `s_camelCase` | `s_defaultTimeout` | +| Thread-static field | `t_camelCase` | `t_cachedBuffer` | +| Local, parameter | camelCase | `packetId` | +| Type parameter | `T` + PascalCase | `TResult` | +| Namespace | PascalCase | `MinecraftClient.Protocol` | +| Async methods | Suffix `Async` | `ConnectAsync()`, `ReadPacketAsync()` | + +```csharp +// CORRECT: naming conventions +private readonly Dictionary _entities = new(); +private static readonly TimeSpan s_reconnectDelay = TimeSpan.FromSeconds(5); +public int PacketCount { get; private set; } +public async Task ConnectAsync(CancellationToken ct) { } +``` + +```csharp +// WRONG: naming violations +private Dictionary entities = new(); // missing _ +private static TimeSpan reconnectDelay; // missing s_ +public int packet_count { get; set; } // snake_case +public async Task Connect(CancellationToken ct) { } // missing Async suffix +``` + +## C# 12 Features + +### Primary Constructors + +Use for simple parameter capture. Parameters are `camelCase`, mutable — assign to `readonly` fields when immutability matters. + +```csharp +// CORRECT: primary constructor captures dependencies +public class ChatLogger(string logFilePath, bool appendMode) : ChatBot +{ + private readonly StreamWriter _writer = new(logFilePath, appendMode); + public override void GetText(string text) => _writer.WriteLine(text); +} +``` + +```csharp +// WRONG: verbose constructor boilerplate for simple capture +public class ChatLogger : ChatBot +{ + private readonly StreamWriter _writer; + public ChatLogger(string logFilePath, bool appendMode) + { + _writer = new StreamWriter(logFilePath, appendMode); + } + public override void GetText(string text) => _writer.WriteLine(text); +} +``` + +### Collection Expressions + +Use `[...]` and `..` spread for arrays, lists, spans. + +```csharp +// CORRECT: collection expressions (C# 12) +int[] ids = [1, 2, 3]; +List names = ["Steve", "Alex"]; +ReadOnlySpan header = [0xFE, 0x01]; // no heap alloc +int[] combined = [..firstArray, ..secondArray, 42]; +IReadOnlyList empty = []; +``` + +```csharp +// WRONG: verbose initialization +int[] ids = new int[] { 1, 2, 3 }; +var names = new List { "Steve", "Alex" }; +ReadOnlySpan header = new byte[] { 0xFE, 0x01 }; // allocates +var combined = firstArray.Concat(secondArray).Append(42).ToArray(); +``` + +### Type Aliases + +```csharp +// CORRECT: alias complex types for readability +using Coordinate = (int X, int Y, int Z); +using PacketMap = System.Collections.Generic.Dictionary>; +``` + +### Default Lambda Parameters + +```csharp +// CORRECT: C# 12 +var greet = (string name, string prefix = "Player") => $"{prefix} {name}"; +``` + +## Modern Syntax (C# 10–12) + +### File-Scoped Namespaces + +```csharp +// CORRECT: file-scoped namespace — one per file, less nesting +namespace MinecraftClient.ChatBots; + +public class MyBot : ChatBot { } +``` + +```csharp +// WRONG: block-scoped namespace adds unnecessary nesting +namespace MinecraftClient.ChatBots +{ + public class MyBot : ChatBot { } +} +``` + +### Target-Typed `new` + +Use when the type is obvious from the left-hand side. + +```csharp +// CORRECT: target-typed new +private readonly Dictionary _scores = new(); +List entities = new(capacity: 256); +``` + +```csharp +// WRONG: redundant type name +private readonly Dictionary _scores = new Dictionary(); +``` + +### Pattern Matching + +Prefer patterns over type-casting chains and complex boolean logic. + +```csharp +// CORRECT: is-pattern with declaration and property patterns +if (entity is Player { Health: > 0 } player) + SendMessage($"{player.Name} is alive"); +``` + +```csharp +// WRONG: manual cast and multi-step check +if (entity is Player) +{ + var player = (Player)entity; + if (player.Health > 0) + SendMessage($"{player.Name} is alive"); +} +``` + +```csharp +// CORRECT: switch expression +public string GetStatusLabel(GameMode mode) => mode switch +{ + GameMode.Survival => "Survival", + GameMode.Creative => "Creative", + GameMode.Adventure => "Adventure", + GameMode.Spectator => "Spectator", + _ => throw new ArgumentOutOfRangeException(nameof(mode)) +}; +``` + +```csharp +// WRONG: switch statement with returns +public string GetStatusLabel(GameMode mode) +{ + switch (mode) + { + case GameMode.Survival: return "Survival"; + case GameMode.Creative: return "Creative"; + default: throw new ArgumentOutOfRangeException(nameof(mode)); + } +} +``` + +```csharp +// CORRECT: property patterns for compound conditions +if (response is { StatusCode: >= 200 and < 300, Content.Length: > 0 }) + ProcessResponse(response); +``` + +```csharp +// WRONG: multiple chained conditions +if (response != null && response.StatusCode >= 200 + && response.StatusCode < 300 && response.Content != null + && response.Content.Length > 0) + ProcessResponse(response); +``` + +```csharp +// CORRECT: relational, logical, and list patterns +if (health is > 0 and <= 6) LogToConsole("Low health!"); +if (args is [var command, var target, ..]) ProcessCommand(command, target); +``` + +### Raw String Literals + +Use for JSON, regex, multi-line strings. + +```csharp +// CORRECT: raw string literal +string json = """ + { "username": "Steve", "action": "connect" } + """; +string pattern = """<\w+>"""; +``` + +```csharp +// WRONG: escaped quotes +string json = "{ \"username\": \"Steve\", \"action\": \"connect\" }"; +``` + +### Records + +Use `record` for immutable data carriers and DTOs. Use `record struct` for small value types. + +```csharp +// CORRECT: record for data carrier +public record PlayerInfo(string Name, Guid Uuid, GameMode Mode); +public record struct ChunkCoord(int X, int Z); +var updated = info with { Mode = GameMode.Creative }; +``` + +```csharp +// WRONG: full class for a simple data carrier +public class PlayerInfo +{ + public string Name { get; set; } = string.Empty; + public Guid Uuid { get; set; } + public GameMode Mode { get; set; } +} +``` + +```csharp +// CORRECT: compact constructor for record validation +public record OrderItem(string ProductId, int Quantity, decimal UnitPrice) +{ + public OrderItem + { + ArgumentException.ThrowIfNullOrWhiteSpace(ProductId); + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(Quantity); + ArgumentOutOfRangeException.ThrowIfNegative(UnitPrice); + } +} +``` + +### Required Members + +```csharp +// CORRECT: required + init enforces initialization without constructor boilerplate +public class ServerConfig +{ + public required string Host { get; init; } + public required int Port { get; init; } + public string? Password { get; init; } +} +var config = new ServerConfig { Host = "mc.example.com", Port = 25565 }; +``` + +## Nullable Reference Types + +Project has nullable enabled. Follow these rules: + +```csharp +// CORRECT: guard at API boundaries with .NET 8 throw helpers +public void Connect(string host, IProtocolHandler handler) +{ + ArgumentNullException.ThrowIfNull(handler); + ArgumentException.ThrowIfNullOrEmpty(host); +} +``` + +```csharp +// WRONG: manual null checks +if (handler == null) throw new ArgumentNullException(nameof(handler)); +if (string.IsNullOrWhiteSpace(host)) + throw new ArgumentException("Host is required", nameof(host)); +``` + +```csharp +// CORRECT: 'is not null' pattern +if (currentPlayer is not null) + currentPlayer.Update(); +``` + +```csharp +// WRONG: comparison operator for null check +if (currentPlayer != null) + currentPlayer.Update(); +``` + +```csharp +// CORRECT: explicit nullable handling +public Entity? FindEntity(int id) +{ + return _entities.TryGetValue(id, out var entity) ? entity : null; +} + +// CORRECT: null-coalescing / null-conditional +string name = player?.CustomName ?? player?.Name ?? "Unknown"; + +// CORRECT: null-forgiving only when proven safe (after ThrowIfNull or equivalent) +string val = GetRequiredValue()!; + +// CORRECT: annotate return values +[return: MaybeNull] +public T Find(Predicate match) { } + +[MemberNotNull(nameof(_connection))] +private void EnsureConnected() { } +``` + +```csharp +// WRONG: hiding nullability with null-forgiving +public string GetName(Player? player) +{ + return player!.Name; // hides potential NullReferenceException +} +``` + +## Async / Await + +```csharp +// CORRECT: propagate CancellationToken through every async I/O call +public async Task FetchDataAsync(Uri uri, CancellationToken ct = default) +{ + using var response = await _httpClient.GetAsync(uri, ct); + return await response.Content.ReadAsStringAsync(ct); +} +``` + +```csharp +// WRONG: CancellationToken not passed downstream +public async Task FetchDataAsync(Uri uri) +{ + using var response = await _httpClient.GetAsync(uri, default); + return await response.Content.ReadAsStringAsync(default); +} +``` + +```csharp +// CORRECT: ValueTask when result is often available synchronously +public ValueTask GetCachedCountAsync() +{ + if (_cache.TryGetValue("count", out int count)) + return ValueTask.FromResult(count); + return new ValueTask(LoadCountFromDbAsync()); +} +``` + +```csharp +// WRONG: Task allocates unnecessarily when result is cached +public async Task GetCachedCountAsync() +{ + if (_cache.TryGetValue("count", out int count)) + return count; // allocates a Task + return await LoadCountFromDbAsync(); +} +``` + +```csharp +// CORRECT: async Task for async event handlers +public async Task HandleEventAsync(GameEvent e, CancellationToken ct) +{ + await notificationService.SendAsync(e.PlayerId, ct); +} +``` + +```csharp +// WRONG: async void — exceptions are unobservable, cannot be awaited +public async void HandleEvent(GameEvent e) +{ + await notificationService.SendAsync(e.PlayerId, default); +} +``` + +```csharp +// CORRECT: await the result +var packet = await reader.ReadPacketAsync(ct); +``` + +```csharp +// WRONG: .Result / .Wait() causes deadlocks +var packet = reader.ReadPacketAsync(ct).Result; +var packet2 = reader.ReadPacketAsync(ct).GetAwaiter().GetResult(); +``` + +```csharp +// CORRECT: ConfigureAwait(false) in library code +var data = await stream.ReadAsync(buffer, ct).ConfigureAwait(false); + +// CORRECT: IAsyncEnumerable for streaming +public async IAsyncEnumerable ReadChatStreamAsync( + [EnumeratorCancellation] CancellationToken ct = default) +{ + while (!ct.IsCancellationRequested) + yield return await _reader.ReadNextAsync(ct); +} + +// CORRECT: await using for async disposal +await using var conn = new McConnection(host, port); +``` + +## LINQ + +### Prefer Method Syntax for Most Operations + +```csharp +// CORRECT: method syntax for common operations +var onlinePlayers = players + .Where(p => p.IsOnline) + .OrderBy(p => p.Name) + .Select(p => new PlayerListItem(p.Id, p.Name)) + .ToList(); +``` + +```csharp +// AVOID: query syntax for simple operations +var onlinePlayers = ( + from p in players + where p.IsOnline + orderby p.Name + select new PlayerListItem(p.Id, p.Name) +).ToList(); +``` + +### Use Query Syntax for Joins + +```csharp +// CORRECT: query syntax makes joins readable +var results = + from entity in entities + join player in players on entity.OwnerId equals player.Id + where entity.Health > 0 + select new { entity.Name, player.Name }; +``` + +```csharp +// AVOID: method syntax for complex joins is hard to read +var results = entities + .Join(players, + e => e.OwnerId, + p => p.Id, + (e, p) => new { e, p }) + .Where(x => x.e.Health > 0) + .Select(x => new { x.e.Name, PlayerName = x.p.Name }); +``` + +### Materialize to Avoid Multiple Enumeration + +```csharp +// CORRECT: materialize once, iterate many times +var online = players.Where(p => p.IsOnline).ToList(); +Console.WriteLine(online.Count); +foreach (var p in online) { } +``` + +```csharp +// WRONG: enumerates the query twice +var filtered = players.Where(p => p.IsOnline); +Console.WriteLine(filtered.Count()); // first enumeration +foreach (var p in filtered) { } // second enumeration +``` + +### Use Any() Over Count() > 0 + +```csharp +// CORRECT: short-circuits on first match +if (entities.Any(e => e.IsHostile)) + TriggerAlert(); +``` + +```csharp +// WRONG: counts the entire collection +if (entities.Count(e => e.IsHostile) > 0) + TriggerAlert(); +``` + +### Prefer FirstOrDefault with Null Handling + +```csharp +// CORRECT: explicit null handling +var target = players.FirstOrDefault(p => p.Name == name) + ?? throw new InvalidOperationException($"Player '{name}' not found"); +``` + +### TryGetNonEnumeratedCount + +```csharp +// CORRECT: avoid full enumeration just to get count (.NET 6+) +if (source.TryGetNonEnumeratedCount(out int count)) + buffer = new Entity[count]; +``` + +### Avoid LINQ in Hot Paths + +```csharp +// CORRECT: manual loop with Span in performance-critical code +Span data = stackalloc byte[256]; +int found = 0; +for (int i = 0; i < data.Length; i++) + if (data[i] == target) found++; +``` + +```csharp +// AVOID: LINQ allocates enumerators and delegates on hot paths +int found = data.ToArray().Count(b => b == target); +``` + +## Performance (.NET 8) + +### Span\ / Memory\ + +```csharp +// CORRECT: zero-allocation slicing +ReadOnlySpan command = input.AsSpan()[1..]; // skip '/' + +// CORRECT: stack-allocated parsing +public static int ParseVarInt(ReadOnlySpan data, out int bytesRead) +{ + int result = 0; bytesRead = 0; byte cur; + do { cur = data[bytesRead]; result |= (cur & 0x7F) << (bytesRead * 7); bytesRead++; } + while ((cur & 0x80) != 0); + return result; +} +``` + +### FrozenDictionary / FrozenSet (.NET 8) + +Build once, read many — ~50% faster lookups than Dictionary. + +```csharp +// CORRECT: FrozenDictionary for read-heavy lookup tables (palettes, protocol maps) +using System.Collections.Frozen; +private static readonly FrozenDictionary s_blockNames = + new Dictionary { [0] = "air", [1] = "stone" }.ToFrozenDictionary(); +``` + +### SearchValues\ (.NET 8) + +Hardware-accelerated set search. + +```csharp +// CORRECT: precompute once, scan with SIMD +private static readonly SearchValues s_separators = SearchValues.Create(" \t\n\r,;"); +int idx = input.AsSpan().IndexOfAny(s_separators); +``` + +### CompositeFormat (.NET 8) + +Parse format string once, reuse. + +```csharp +// CORRECT: avoids re-parsing the format string each call +private static readonly CompositeFormat s_logFmt = CompositeFormat.Parse("[{0:HH:mm:ss}] {1}: {2}"); +string msg = string.Format(CultureInfo.InvariantCulture, s_logFmt, DateTime.Now, player, text); +``` + +### ArrayPool / stackalloc + +```csharp +// CORRECT: rent from pool for temporary buffers +byte[] buf = ArrayPool.Shared.Rent(4096); +try { int n = stream.Read(buf.AsSpan(0, 4096)); ProcessPacket(buf.AsSpan(0, n)); } +finally { ArrayPool.Shared.Return(buf); } + +// CORRECT: stackalloc for small, fixed-size buffers (< 512 bytes) +Span header = stackalloc byte[5]; +``` + +## String Handling + +```csharp +// CORRECT: explicit StringComparison — always +bool match = name.Equals("Steve", StringComparison.OrdinalIgnoreCase); +int idx = text.IndexOf("hello", StringComparison.Ordinal); +``` + +```csharp +// WRONG: allocates a lowered copy +bool match = name.ToLower() == "steve"; +``` + +```csharp +// CORRECT: string.Create for perf-critical formatting +string hex = string.Create(data.Length * 2, data, static (span, bytes) => +{ + for (int i = 0; i < bytes.Length; i++) + bytes[i].TryFormat(span[(i * 2)..], out _, "X2"); +}); + +// CORRECT: StringBuilder for loops +var sb = new StringBuilder(256); +foreach (var item in inventory) + sb.Append(item.Name).Append(" x").Append(item.Count).AppendLine(); +``` + +```csharp +// WRONG: O(n²) string concatenation in loop +string combined = ""; +foreach (var s in items) combined += s + ", "; +``` + +## Collections — Choosing the Right Type + +| Scenario | Type | Notes | +|---|---|---| +| General key-value | `Dictionary` | O(1) lookup | +| Build once, read many | `FrozenDictionary` | .NET 8; faster reads | +| Thread-safe | `ConcurrentDictionary` | Lock-free reads | +| Immutable snapshots | `ImmutableDictionary` | Persistent structure | +| Membership test | `HashSet` / `FrozenSet` | FrozenSet for static | +| Priority queue | `PriorityQueue` | .NET 6+ | +| Producer-consumer | `Channel` | Over `BlockingCollection` | +| Temp buffer | `ArrayPool` / `stackalloc` | Zero/low alloc | + +## Error Handling + +```csharp +// CORRECT: Try* pattern for expected failures +if (int.TryParse(input, out int value)) ProcessValue(value); +if (_registry.TryGetValue(packetId, out var handler)) handler.Invoke(data); +``` + +```csharp +// WRONG: using exceptions for control flow +try { return dict[key]; } +catch (KeyNotFoundException) { return null; } // use TryGetValue +``` + +```csharp +// CORRECT: exception filters (catch-when) +try { await ConnectAsync(ct); } +catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionRefused) +{ + LogToConsole("Connection refused, retrying..."); +} +``` + +```csharp +// CORRECT: throw helpers (smaller IL, better inlining) +ArgumentNullException.ThrowIfNull(handler); +ArgumentOutOfRangeException.ThrowIfNegative(timeout); +ArgumentOutOfRangeException.ThrowIfGreaterThan(timeout, MaxTimeout); +ObjectDisposedException.ThrowIf(_disposed, this); +``` + +```csharp +// WRONG: generic exceptions +throw new Exception($"Entity {id} not found"); +``` + +```csharp +// CORRECT: specific, meaningful exception types +throw new EntityNotFoundException(id); +// or use null-coalescing with throw +return await FindEntityAsync(id, ct) + ?? throw new EntityNotFoundException(id); +``` + +```csharp +// AVOID: catching Exception without filtering +try { DoWork(); } +catch (Exception) { /* swallowed */ } +``` + +## Warning Suppression + +```csharp +// CORRECT: fix the warning by handling null properly +public string GetDisplayName(Player? player) +{ + return player?.DisplayName ?? "Unknown"; +} +``` + +```csharp +// WRONG: suppressing nullable warning with pragma +#pragma warning disable CS8602 +public string GetDisplayName(Player? player) +{ + return player.DisplayName; // NullReferenceException at runtime +} +#pragma warning restore CS8602 +``` + +```csharp +// WRONG: suppressing with attribute +[SuppressMessage("Usage", "CA1062:Validate arguments of public methods")] +public void Process(Packet packet) +{ + // missing null check +} +``` + +Project-wide `.editorconfig` is the only acceptable place for warning policy: + +```text +# .editorconfig - project-wide policy decisions only +dotnet_diagnostic.CA2007.severity = none +``` + +## Resource Management + +```csharp +// CORRECT: using declaration — disposed at end of scope +using var stream = new FileStream(path, FileMode.Open); +using var reader = new StreamReader(stream); + +// CORRECT: IAsyncDisposable +await using var conn = await CreateConnectionAsync(); +``` + +```csharp +// CORRECT: Dispose pattern +public class PacketReader : IDisposable +{ + private Stream? _stream; + private bool _disposed; + public void Dispose() + { + if (_disposed) return; + _stream?.Dispose(); _stream = null; _disposed = true; + } +} +``` + +## Security + +```csharp +// CORRECT: secure random for tokens +byte[] token = RandomNumberGenerator.GetBytes(32); + +// CORRECT: constant-time comparison for secrets +bool valid = CryptographicOperations.FixedTimeEquals(expected, actual); + +// CORRECT: validate external input +if (Uri.TryCreate(userInput, UriKind.Absolute, out var uri) + && uri.Scheme is "http" or "https") + await FetchAsync(uri); +``` + +```csharp +// WRONG: predictable random for security-sensitive values +var rng = new Random(); + +// WRONG: timing side-channel on secret comparison +bool eq = secret1.SequenceEqual(secret2); +``` + +## Miscellaneous Idioms + +```csharp +// CORRECT: var when type is obvious from RHS +var entities = new Dictionary(); +var timer = Stopwatch.StartNew(); + +// CORRECT: explicit type when var would be unclear +Stream responseStream = GetResponse(); +int count = items.Count; + +// CORRECT: expression-bodied members for one-liners +public override string ToString() => $"[{X}, {Y}, {Z}]"; +public bool IsAlive => Health > 0; + +// CORRECT: discards for unused values +_ = int.TryParse(s, out int result); +(_, int y, _) = GetCoordinates(); + +// CORRECT: nameof for resilient refactoring +throw new ArgumentException("Invalid value", nameof(packetId)); +LogToConsole($"{nameof(AutoEat)}: eating {item.Name}"); + +// CORRECT: static lambdas prevent accidental closure allocations +list.Sort(static (a, b) => a.Id.CompareTo(b.Id)); + +// CORRECT: index/range operators +var last = items[^1]; +var slice = data[3..^1]; + +// CORRECT: tuple deconstruction +var (x, y, z) = GetPosition(); + +// CORRECT: string interpolation with alignment and format specifiers +LogToConsole($"Health: {health,6:F1} | Hunger: {hunger,6:F1}"); +``` diff --git a/.skills/mcc-dev-workflow/SKILL.md b/.skills/mcc-dev-workflow/SKILL.md index bc721633..f0c3c5b9 100644 --- a/.skills/mcc-dev-workflow/SKILL.md +++ b/.skills/mcc-dev-workflow/SKILL.md @@ -1,3 +1,8 @@ +--- +name: mcc-development-workflow +description: Documentation of the typical development workflow for Minecraft Console Client (MCC), including project structure, build commands, and debugging steps. +--- + # MCC Development Workflow ## Project Overview diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..185fa96d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,95 @@ +# AGENTS.md + +## Project +- Minecraft Console Client (MCC) is a cross-platform text/TUI client for Minecraft Java Edition. +- Primary scope: connect to servers, send chat and commands, receive text, automate gameplay/admin tasks, and extend behavior through built-in bots or runtime C# scripts. +- Secondary scope: protocol/version adaptation tooling, docs site, legacy GUI wrapper, and debug tooling. + +## Build / Run +- Init submodules first: `git submodule update --init --recursive` +- Build: `dotnet build MinecraftClient.sln -c Release` +- Publish (matches CI shape): `dotnet publish MinecraftClient.sln -f net8.0 -r --self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded` +- Run from source: `dotnet run --project MinecraftClient -- --help` +- Docs: `cd docs && npm install && npm run docs:dev` or `npm run docs:build` +- Docker: `cd Docker && docker build -t minecraft-console-client:latest .` +- Tests: no dedicated test project is present in the main solution. +- Current state: the solution builds after submodule init, but `dotnet build` emits many analyzer and NuGet vulnerability warnings; treat them as real. + +## Architecture +- `Program` bootstraps console I/O, TOML config, auth/session state, MC version selection, Forge detection, then creates `McClient`. +- `McClient` is the live session runtime: TCP client, selected protocol handler, Brigadier command dispatcher, loaded bots, world/inventory/entity state, queued chat, movement/pathing, reconnect flow. +- `Protocol/` is the network/auth boundary. `ProtocolHandler` maps Minecraft versions to protocol numbers and selects either `Protocol16Handler` (1.4.6-1.6.4) or `Protocol18Handler` (1.7.2+). +- `Scripting/ChatBot` is the extension boundary. Built-in bots and `/script` C# bots share the same event/tick API. +- Main runtime flow: console input -> internal Brigadier command or server chat; packets -> protocol handler -> `McClient` state update -> bot events; `OnUpdate()` (~10 Hz) drives bot ticks, delayed work, chat cooldowns, movement, and main-thread tasks. + +## Technology Stack +- Main app: C#, .NET 8, nullable enabled. +- Command system: `Brigadier.NET`. +- Config: TOML via `Samboy063.Tomlet`. +- Runtime scripting: Roslyn (`Microsoft.CodeAnalysis.CSharp`) with in-memory compilation. +- Networking/auth: custom Minecraft protocol handlers, DNS SRV lookup (`DnsClient`), Forge/session/profile-key support. +- Integrations: `DSharpPlus`, `Telegram.Bot`, `MessagePack`, `Magick.NET`, `Sentry`. +- Docs site: VuePress 2 (`docs/package.json`). +- Tooling: Docker, GitHub Actions, Python 3.10+ scripts under `tools/` for palette/version generation. +- Legacy UI: `MinecraftClientGUI` is a separate .NET Framework 4.0 WinForms wrapper, not the main runtime. + +## Version Support +Feature columns mean: +- Inventory: `/inventory` plus inventory/container bot APIs +- Movement: terrain handling, `/move`, and movement/pathing bots +- Entity: entity tracking and entity-driven bot events + +| Minecraft | Protocol path | Inventory | Movement | Entity | Notes | +| --- | --- | --- | --- | --- | --- | +| 1.4.6-1.6.4 | `Protocol16Handler` | No | No | No | Core login/chat only | +| 1.7.2-1.7.10 | `Protocol18Handler` | No | Yes | No | Pre-1.8 special case | +| 1.8-1.9.4 | `Protocol18Handler` | Partial / docs conflict | Yes | Yes | Runtime gates allow 1.8+, but docs still warn inventory is unsupported through 1.9 | +| 1.10-1.12.2 | `Protocol18Handler` | Yes | Yes | Yes | Pre-flattening palettes | +| 1.13-1.19.2 | `Protocol18Handler` | Yes | Yes | Yes | Flattened block/item/entity palettes | +| 1.19.3-1.20.4 | `Protocol18Handler` | Yes | Yes | Yes | Newer chat/signing and palette splits | +| 1.20.6-1.21.4 | `Protocol18Handler` | Yes | Yes | Yes | Registry-driven world/attribute handling | +| 1.21.5-1.21.8 | `Protocol18Handler` | Yes | Yes | Yes | 1.21.7/1.21.8 reuse 1.21.6 block/entity palettes in code | +| 1.21.9-1.21.10 | `Protocol18Handler` | Yes | Yes | Yes | Latest coded support; version tools prefer server data reports since 1.21.9 | + +Notes: +- Declared code range is `1.4.6` to `1.21.10`. +- Human docs are stale in places and sometimes stop at older ranges; prefer code when docs and code disagree. +- Movement/pathing limits called out in docs still apply: no swimming, no jumping, no knockback, slab support is partial. + +## Module Map +- `MinecraftClient/`: main `net8.0` runtime project. +- `MinecraftClient/Protocol/`: protocol selection, auth/session flows, packet I/O, Forge/profile-key support. +- `MinecraftClient/Mapping/`: world state, movement/pathfinding, block/entity/material palettes. +- `MinecraftClient/Inventory/`: containers, items, enchantments, inventory helpers, item palettes. +- `MinecraftClient/Commands/` and `MinecraftClient/CommandHandler/`: internal MCC commands plus Brigadier argument types/patches. +- `MinecraftClient/ChatBots/`: built-in automation bots, bridges, script scheduler, replay/map/item helpers. +- `MinecraftClient/Scripting/`: `ChatBot` API, runtime C# compilation, movement lock helpers. +- `MinecraftClient/config/`: sample scripts and example bots; excluded from compilation. +- `ConsoleInteractive/`: required git submodule for richer console input/output. +- `docs/`: VuePress documentation site. +- `tools/`: Python scripts for version adaptation and palette generation. +- `DebugTools/`: packet/proxy debugging utilities. +- `MinecraftClientGUI/`: legacy Windows GUI wrapper around the console app. + +## Engineering Guidance + +### DO +- Keep startup/config/auth logic in `Program` and connection runtime logic in `McClient` or `Protocol/*`. +- Update version support holistically: protocol constants, version mapping, packet palette, block palette, item palette, entity palette, metadata palette, and routing switches. +- Use `tools/` and authoritative server data reports when adapting to new Minecraft versions, especially 1.21.9+. +- Guard optional subsystems with `GetTerrainEnabled()`, `GetInventoryEnabled()`, and `GetEntityHandlingEnabled()` before using them. +- For built-in bots, wire all pieces together: bot class, `Settings.ChatBotConfigHealper`, and `McClient.RegisterBots()`. +- Keep `Initialize()` for setup/prereq checks and `AfterGameJoined()` for sending chat or commands. +- Normalize inbound chat with `GetVerbatim()` before `IsChatMessage()` / `IsPrivateMessage()`. +- Clean up commands, plugin channels, threads, timers, and movement locks in `OnUnload()`. +- Prefer nullable-aware code, pattern matching, `ArgumentNullException.ThrowIfNull`, `Try*` APIs for expected failures, and `InvokeOnMainThread()` for cross-thread state changes. +- Use modern C# only when it fits the current target: the repo builds as `net8.0` with default language version. + +### DON'T +- Don't update only `MCVer2ProtocolVersion()` or only one palette file when adding a new Minecraft version. +- Don't send chat in `Initialize()`. +- Don't mutate inventory snapshots and expect server-side effects; use handler APIs/window actions. +- Don't bypass Brigadier with ad hoc command parsing. +- Don't start background workers when `Update()` or delayed tasks are sufficient; if you must, stop them on unload/disconnect. +- Don't leave movement locks, plugin channels, or dispatcher registrations behind. +- Don't trust older docs over current code for supported versions or feature gates. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..23562a5f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +Read @AGENTS.md \ No newline at end of file From c0c4c078c01cc537e59a9049bf72ef0b79d5cb53 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 02:18:01 +0800 Subject: [PATCH 082/484] fix: use HashedStack for container_click and fix enchantments parsing for 1.21.5+ Two bugs fixed: 1. EnchantmentsComponent was reading a trailing ShowTooltip boolean that was removed from the wire format in MC 1.21.5. Created EnchantmentsComponent1215 and StoredEnchantmentsComponent1215 that omit the boolean. Used by StructuredComponentsRegistry1215 and 12111. 2. MC 1.21.5+ changed ServerboundContainerClickPacket to use HashedStack (item holder id + count + hashed component patch map) instead of full ItemStack for changed slots and carried item. Added GetHashedItemSlot() in DataTypes.cs and gated SendWindowAction in Protocol18.cs to use it for 1.21.5+. Since MCC doesn't track component hashes, an empty HashedPatchMap is sent; the server detects stateId mismatch and resyncs. Tested: AutoFishing bot successfully catches fish on MC 1.21.11 with enchanted fishing rods (Lure III + Luck of the Sea III). Made-with: Cursor --- .../Protocol/Handlers/DataTypes.cs | 27 +++++++++++++ .../Protocol/Handlers/Protocol18.cs | 12 +++++- .../1_21_5/EnchantmentsComponent1215.cs | 39 +++++++++++++++++++ .../1_21_5/StoredEnchantmentsComponent1215.cs | 7 ++++ .../StructuredComponentsRegistry12111.cs | 4 +- .../StructuredComponentsRegistry1215.cs | 4 +- 6 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EnchantmentsComponent1215.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/StoredEnchantmentsComponent1215.cs diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 4b4f0488..bd2c84e4 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1679,6 +1679,33 @@ namespace MinecraftClient.Protocol.Handlers return locationBytes; } + /// + /// Get a byte array representing the given item as a HashedStack (1.21.5+). + /// Used for serverbound container_click where the server expects HashedStack instead of full ItemStack. + /// Wire format: Optional<ActualItem> where ActualItem = holderRegistry(item_id) + VarInt(count) + HashedPatchMap. + /// Since MCC doesn't track component hashes, we send an empty HashedPatchMap (0 added, 0 removed). + /// The server will detect the stateId mismatch and resync. + /// + public byte[] GetHashedItemSlot(Item? item, ItemPalette itemPalette) + { + List slotData = new(); + + if (item == null || item.IsEmpty) + { + slotData.AddRange(GetBool(false)); + } + else + { + slotData.AddRange(GetBool(true)); + slotData.AddRange(GetVarInt(itemPalette.ToId(item.Type))); + slotData.AddRange(GetVarInt(item.Count)); + slotData.AddRange(GetVarInt(0)); // HashedPatchMap: 0 added components + slotData.AddRange(GetVarInt(0)); // HashedPatchMap: 0 removed components + } + + return slotData.ToArray(); + } + /// /// Get a byte array representing the given item as an item slot /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 4fe6b857..ab00dfc6 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -4567,11 +4567,19 @@ namespace MinecraftClient.Protocol.Handlers foreach (var slot in changedSlots) { packet.AddRange(dataTypes.GetShort(slot.Item1)); // slot ID - packet.AddRange(dataTypes.GetItemSlot(slot.Item2, itemPalette)); // slot Data + // 1.21.5+ uses HashedStack instead of ItemStack for container_click + if (protocolVersion >= MC_1_21_5_Version) + packet.AddRange(dataTypes.GetHashedItemSlot(slot.Item2, itemPalette)); + else + packet.AddRange(dataTypes.GetItemSlot(slot.Item2, itemPalette)); } } - packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); // Carried item (Clicked item) + // 1.21.5+ uses HashedStack instead of ItemStack for carried item + if (protocolVersion >= MC_1_21_5_Version) + packet.AddRange(dataTypes.GetHashedItemSlot(item, itemPalette)); + else + packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); SendPacket(PacketTypesOut.ClickWindow, packet); return true; diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EnchantmentsComponent1215.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EnchantmentsComponent1215.cs new file mode 100644 index 00000000..4ade9885 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/EnchantmentsComponent1215.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory; +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +/// +/// 1.21.5+ enchantments: showInTooltip removed from wire format (moved to tooltip_display component). +/// Wire: VarInt count, then (VarInt holder_id + VarInt level) per entry. No trailing boolean. +/// +public class EnchantmentsComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EnchantmentsComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + NumberOfEnchantments = dataTypes.ReadNextVarInt(data); + + for (var i = 0; i < NumberOfEnchantments; i++) + { + var registryId = dataTypes.ReadNextVarInt(data); + var level = dataTypes.ReadNextVarInt(data); + Enchantments.Add(new Enchantment(EnchantmentMapping.GetEnchantmentByRegistryId1206(registryId), level)); + } + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(Enchantments.Count)); + foreach (var enchantment in Enchantments) + { + data.AddRange(DataTypes.GetVarInt(EnchantmentMapping.GetRegistryId1206ByEnchantment(enchantment.Type))); + data.AddRange(DataTypes.GetVarInt(enchantment.Level)); + } + return new Queue(data); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/StoredEnchantmentsComponent1215.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/StoredEnchantmentsComponent1215.cs new file mode 100644 index 00000000..8daf09ea --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_21_5/StoredEnchantmentsComponent1215.cs @@ -0,0 +1,7 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; + +public class StoredEnchantmentsComponent1215(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : EnchantmentsComponent1215(dataTypes, itemPalette, subComponentRegistry); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs index ec848fb2..c7faf6a4 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry12111.cs @@ -27,7 +27,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry RegisterComponent(10, "minecraft:item_model"); RegisterComponent(11, "minecraft:lore"); RegisterComponent(12, "minecraft:rarity"); - RegisterComponent(13, "minecraft:enchantments"); + RegisterComponent(13, "minecraft:enchantments"); RegisterComponent(14, "minecraft:can_place_on"); RegisterComponent(15, "minecraft:can_break"); RegisterComponent(16, "minecraft:attribute_modifiers"); @@ -55,7 +55,7 @@ public class StructuredComponentsRegistry12111 : StructuredComponentRegistry RegisterComponent(38, "minecraft:piercing_weapon"); RegisterComponent(39, "minecraft:kinetic_weapon"); RegisterComponent(40, "minecraft:swing_animation"); - RegisterComponent(41, "minecraft:stored_enchantments"); + RegisterComponent(41, "minecraft:stored_enchantments"); RegisterComponent(42, "minecraft:dyed_color"); RegisterComponent(43, "minecraft:map_color"); RegisterComponent(44, "minecraft:map_id"); diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs index 26b3b27e..a0b8a4c7 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1215.cs @@ -23,7 +23,7 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry RegisterComponent(7, "minecraft:item_model"); RegisterComponent(8, "minecraft:lore"); RegisterComponent(9, "minecraft:rarity"); - RegisterComponent(10, "minecraft:enchantments"); + RegisterComponent(10, "minecraft:enchantments"); RegisterComponent(11, "minecraft:can_place_on"); RegisterComponent(12, "minecraft:can_break"); RegisterComponent(13, "minecraft:attribute_modifiers"); @@ -48,7 +48,7 @@ public class StructuredComponentsRegistry1215 : StructuredComponentRegistry RegisterComponent(31, "minecraft:tooltip_style"); RegisterComponent(32, "minecraft:death_protection"); RegisterComponent(33, "minecraft:blocks_attacks"); // NEW - RegisterComponent(34, "minecraft:stored_enchantments"); + RegisterComponent(34, "minecraft:stored_enchantments"); RegisterComponent(35, "minecraft:dyed_color"); RegisterComponent(36, "minecraft:map_color"); RegisterComponent(37, "minecraft:map_id"); From bf0414116721f2eaa5f3fc48baee55ac4560e196 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 19:20:35 +0100 Subject: [PATCH 083/484] Improved AGENTS.md --- AGENTS.md | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 185fa96d..b8fbcd39 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -57,19 +57,34 @@ Notes: - Movement/pathing limits called out in docs still apply: no swimming, no jumping, no knockback, slab support is partial. ## Module Map -- `MinecraftClient/`: main `net8.0` runtime project. -- `MinecraftClient/Protocol/`: protocol selection, auth/session flows, packet I/O, Forge/profile-key support. -- `MinecraftClient/Mapping/`: world state, movement/pathfinding, block/entity/material palettes. -- `MinecraftClient/Inventory/`: containers, items, enchantments, inventory helpers, item palettes. -- `MinecraftClient/Commands/` and `MinecraftClient/CommandHandler/`: internal MCC commands plus Brigadier argument types/patches. -- `MinecraftClient/ChatBots/`: built-in automation bots, bridges, script scheduler, replay/map/item helpers. -- `MinecraftClient/Scripting/`: `ChatBot` API, runtime C# compilation, movement lock helpers. -- `MinecraftClient/config/`: sample scripts and example bots; excluded from compilation. -- `ConsoleInteractive/`: required git submodule for richer console input/output. -- `docs/`: VuePress documentation site. -- `tools/`: Python scripts for version adaptation and palette generation. -- `DebugTools/`: packet/proxy debugging utilities. -- `MinecraftClientGUI/`: legacy Windows GUI wrapper around the console app. +### Core Runtime + +| Module | What It Owns | Important Files | +| --- | --- | --- | +| `MinecraftClient/` | Main `net8.0` runtime assembly and the best starting point. `Program.cs` owns startup, config load/writeback, CLI handling, auth/version selection, update/data-generation entrypoints, and restart/failure flow. `McClient.cs` owns the live session runtime: protocol handler ownership, command dispatch, bot lifecycle, world/inventory/entity state, queued chat, movement ticks, reconnect/disconnect logic, and the main-thread invoke queue. `Settings.cs` defines the TOML schema and runtime/internal overrides used across the app. | `Program.cs`, `McClient.cs`, `Settings.cs`, `ConsoleIO.cs`, `Command.cs`, `UpgradeHelper.cs`, `AutoTimeout.cs` | +| `MinecraftClient/Protocol/` | Network/auth/session boundary. `ProtocolHandler.cs` does DNS SRV lookup, server ping/version detection, MC-version to protocol mapping, and handler selection. `Protocol16.cs` and `Protocol18.cs` implement the packet flow for legacy and modern versions. `Protocol18Terrain.cs` decodes chunk sections/biomes into `World`. `DataTypes.cs` is the low-level reader/writer layer for VarInts, metadata, NBT-like structures, and packet fields. `Message/`, `ProfileKey/`, `Session/`, `Handlers/Forge/`, `Handlers/PacketPalettes/`, and `Handlers/StructuredComponents/` cover chat/signing, cached auth, Forge, packet IDs, and 1.20.6+ item components. | `Protocol/ProtocolHandler.cs`, `Protocol/Handlers/Protocol16.cs`, `Protocol/Handlers/Protocol18.cs`, `Protocol/Handlers/Protocol18Terrain.cs`, `Protocol/Handlers/DataTypes.cs`, `Protocol/Message/ChatParser.cs`, `Protocol/MicrosoftAuthentication.cs`, `Protocol/MojangAPI.cs` | +| `MinecraftClient/Mapping/` | World model, terrain storage, movement logic, and versioned block/entity metadata. `World.cs` stores chunk columns, dimension data, and 1.20.6+ registry-derived dimension/attribute mappings. `Chunk*`, `Block.cs`, and `Location.cs` are the terrain primitives. `Movement.cs` contains step generation, gravity/on-ground checks, and path execution support. `Material.cs` plus `BlockPalettes/*.cs` map block-state IDs to MCC materials. `Entity.cs`, `EntityType.cs`, `EntityPalettes/*.cs`, `EntityMetadataPalette.cs`, and `EntityMetadataPalettes/*.cs` do the same for entities and metadata serializers. | `Mapping/World.cs`, `Mapping/ChunkColumn.cs`, `Mapping/Chunk.cs`, `Mapping/Block.cs`, `Mapping/Location.cs`, `Mapping/Movement.cs`, `Mapping/RaycastHelper.cs`, `Mapping/Material.cs`, `Mapping/Entity.cs`, `Mapping/EntityType.cs` | +| `MinecraftClient/Inventory/` | Inventory/container snapshots, item decoding, and versioned item registries. `Container.cs` models player inventories and server windows, including slot contents and container properties. `Item.cs` bridges older NBT-based items with 1.20.6+ structured components. `ItemType.cs` plus `ItemPalettes/*.cs` provide version-specific item ID mapping. Enchantment, effects, and villager-trade files add higher-level semantics on top of raw inventory data. | `Inventory/Container.cs`, `Inventory/ContainerType.cs`, `Inventory/Item.cs`, `Inventory/ItemMovingHelper.cs`, `Inventory/ItemType.cs`, `Inventory/ItemPalettes/*.cs`, `Inventory/EnchantmentMapping.cs`, `Inventory/VillagerTrade.cs` | + +### Commands And Extensions + +| Module | What It Owns | Important Files | +| --- | --- | --- | +| `MinecraftClient/Commands/` and `MinecraftClient/CommandHandler/` | Internal MCC command system built on Brigadier. Commands are discovered by reflection from `MinecraftClient.Commands` in `McClient.LoadCommands()`. Each file in `Commands/` registers one internal command. `ArgumentType/*.cs` provides typed Brigadier arguments and completion sources for accounts, bots, items, locations, scripts, inventories, and more. `Patch/*.cs` carries MCC-specific Brigadier extensions, and `CmdResult.cs` is the command execution result object. | `Command.cs`, `Commands/*.cs`, `CommandHandler/MccArguments.cs`, `CommandHandler/CmdResult.cs`, `CommandHandler/ArgumentType/*.cs`, `CommandHandler/Patch/*.cs` | +| `MinecraftClient/ChatBots/` | Built-in bots and bridges loaded from config through `McClient.RegisterBots()`. The folder mixes gameplay automation (`AutoAttack`, `AutoDig`, `AutoEat`, `AutoFishing`, `Farmer`), utility/logging bots (`ChatLog`, `PlayerListLogger`, `Alerts`), bridges (`DiscordBridge`, `TelegramBridge`, `RemoteControl`), and tooling like `ScriptScheduler`, `Map`, and `ReplayCapture`. | `ChatBots/AutoRelog.cs`, `ChatBots/Farmer.cs`, `ChatBots/FollowPlayer.cs`, `ChatBots/ItemsCollector.cs`, `ChatBots/Map.cs`, `ChatBots/RemoteControl.cs`, `ChatBots/ScriptScheduler.cs`, `ChatBots/DiscordBridge.cs`, `ChatBots/TelegramBridge.cs`, `ChatBots/ReplayCapture.cs` | +| `MinecraftClient/Scripting/` | Shared extension boundary for compiled bots and runtime C# scripts. `ChatBot.cs` is the main bot API and lifecycle surface. Built-in bots and `/script` bots use the same event model. `CSharpRunner.cs` parses `//MCCScript` files, compiles them with Roslyn, caches assemblies, and executes them through `CSharpAPI`. `DynamicRun/Builder/*` handles in-memory compilation/load-context plumbing, while `BotMovementLock.cs` coordinates movement ownership between automation pieces. | `Scripting/ChatBot.cs`, `Scripting/CSharpRunner.cs`, `Scripting/BotMovementLock.cs`, `Scripting/AssemblyResolver.cs`, `Scripting/DynamicRun/Builder/Compiler.cs`, `Scripting/DynamicRun/Builder/CompileRunner.cs` | +| `MinecraftClient/config/` | Sample runtime assets excluded from compilation. This is the examples/staging area for end-user scripts and standalone bots. `sample-script*.cs` shows supported `/script` patterns, while `config/ChatBots/*.cs` are copy/adapt examples rather than built-in bots. | `config/README.md`, `config/sample-script.cs`, `config/sample-script-with-chatbot.cs`, `config/sample-script-with-world-access.cs`, `config/ChatBots/*.cs` | +| `ConsoleInteractive/` | Required git submodule for richer line editing and console UI. MCC uses the submodule's `ConsoleReader`, `ConsoleWriter`, and suggestion UI from `ConsoleIO.cs` and `McClient.cs` when `BasicIO` is not enabled. | `ConsoleInteractive/README.md`, `ConsoleInteractive/ConsoleInteractive/ConsoleInteractive.sln` | + +### Support And Tooling + +| Module | What It Owns | Important Files | +| --- | --- | --- | +| `MinecraftClient/Logger/`, `MinecraftClient/Proxy/`, `MinecraftClient/Crypto/`, `MinecraftClient/Resources/`, `MinecraftClient/WinAPI/` | Support subsystems under the main app. Logging supports console/file output plus regex filtering. `ProxyHandler.cs` routes update/login/in-game traffic through HTTP or SOCKS proxies. `Crypto/` implements the stream ciphers needed for online-mode protocol encryption. `Resources/` contains UI strings, generated translation accessors, config help text, icons, and embedded Minecraft asset data. `WinAPI/` contains small Windows-only console helpers. | `Logger/FilteredLogger.cs`, `Logger/FileLogLogger.cs`, `Proxy/ProxyHandler.cs`, `Crypto/CryptoHandler.cs`, `Crypto/AesCfb8Stream.cs`, `Resources/Translations/Translations.resx`, `Resources/ConfigComments/ConfigComments.resx`, `Resources/en_us.json`, `WinAPI/ConsoleIcon.cs` | +| `docs/` | VuePress documentation site. `.vuepress/config.ts` sets bundler, theme, plugins, and redirects. `.vuepress/configs/**` holds locale and nav wiring. `guide/*.md` contains the user-facing install, usage, bot, and scripting docs. | `docs/.vuepress/config.ts`, `docs/.vuepress/configs/**`, `docs/guide/README.md`, `docs/guide/configuration.md`, `docs/guide/chat-bots.md`, `docs/guide/creating-text-script.md` | +| `tools/` | Python helpers for Minecraft version adaptation and palette generation. `README.md` is the authoritative workflow. `diff_registries.py` compares versions and validates decompiled data against server reports. The `gen_*` scripts emit the versioned palette source files consumed by `Protocol/`, `Mapping/`, and `Inventory/`. | `tools/README.md`, `tools/diff_registries.py`, `tools/gen_block_palette.py`, `tools/gen_item_palette.py`, `tools/gen_entity_palette.py`, `tools/gen_entity_metadata_palette.py` | +| `DebugTools/` | Standalone packet/proxy debugging utilities for inspecting traffic and compression behavior outside the main client runtime. | `DebugTools/MinecraftClientProxy/Program.cs`, `DebugTools/MinecraftClientProxy/PacketProxy.cs`, `DebugTools/MinecraftClientProxy/ZlibUtils.cs` | +| `MinecraftClientGUI/` | Legacy Windows GUI wrapper around the console app. WinForms shell that launches and communicates with the console executable; not part of the main `net8.0` runtime path. | `MinecraftClientGUI/Program.cs`, `MinecraftClientGUI/Form1.cs`, `MinecraftClientGUI/Form1.Designer.cs`, `MinecraftClientGUI/MinecraftClient.cs` | ## Engineering Guidance @@ -90,6 +105,7 @@ Notes: - Don't send chat in `Initialize()`. - Don't mutate inventory snapshots and expect server-side effects; use handler APIs/window actions. - Don't bypass Brigadier with ad hoc command parsing. +- Never modify `ConsoleInteractive/`; treat it as an external required submodule. - Don't start background workers when `Update()` or delayed tasks are sufficient; if you must, stop them on unload/disconnect. - Don't leave movement locks, plugin channels, or dispatcher registrations behind. - Don't trust older docs over current code for supported versions or feature gates. From 3f431f11046542fa4867a38f046a6c49599cef28 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 19:26:52 +0100 Subject: [PATCH 084/484] Added skill-creator skill from Anthropic --- .skills/skill-creator/LICENSE.txt | 202 +++ .skills/skill-creator/SKILL.md | 479 ++++++ .skills/skill-creator/agents/analyzer.md | 274 ++++ .skills/skill-creator/agents/comparator.md | 202 +++ .skills/skill-creator/agents/grader.md | 223 +++ .skills/skill-creator/assets/eval_review.html | 146 ++ .../eval-viewer/generate_review.py | 471 ++++++ .skills/skill-creator/eval-viewer/viewer.html | 1325 +++++++++++++++++ .skills/skill-creator/references/schemas.md | 430 ++++++ .skills/skill-creator/scripts/__init__.py | 0 .../scripts/aggregate_benchmark.py | 401 +++++ .../skill-creator/scripts/generate_report.py | 326 ++++ .../scripts/improve_description.py | 248 +++ .../skill-creator/scripts/package_skill.py | 136 ++ .../skill-creator/scripts/quick_validate.py | 103 ++ .skills/skill-creator/scripts/run_eval.py | 310 ++++ .skills/skill-creator/scripts/run_loop.py | 332 +++++ .skills/skill-creator/scripts/utils.py | 47 + 18 files changed, 5655 insertions(+) create mode 100644 .skills/skill-creator/LICENSE.txt create mode 100644 .skills/skill-creator/SKILL.md create mode 100644 .skills/skill-creator/agents/analyzer.md create mode 100644 .skills/skill-creator/agents/comparator.md create mode 100644 .skills/skill-creator/agents/grader.md create mode 100644 .skills/skill-creator/assets/eval_review.html create mode 100644 .skills/skill-creator/eval-viewer/generate_review.py create mode 100644 .skills/skill-creator/eval-viewer/viewer.html create mode 100644 .skills/skill-creator/references/schemas.md create mode 100644 .skills/skill-creator/scripts/__init__.py create mode 100644 .skills/skill-creator/scripts/aggregate_benchmark.py create mode 100644 .skills/skill-creator/scripts/generate_report.py create mode 100644 .skills/skill-creator/scripts/improve_description.py create mode 100644 .skills/skill-creator/scripts/package_skill.py create mode 100644 .skills/skill-creator/scripts/quick_validate.py create mode 100644 .skills/skill-creator/scripts/run_eval.py create mode 100644 .skills/skill-creator/scripts/run_loop.py create mode 100644 .skills/skill-creator/scripts/utils.py diff --git a/.skills/skill-creator/LICENSE.txt b/.skills/skill-creator/LICENSE.txt new file mode 100644 index 00000000..7a4a3ea2 --- /dev/null +++ b/.skills/skill-creator/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/.skills/skill-creator/SKILL.md b/.skills/skill-creator/SKILL.md new file mode 100644 index 00000000..942bfe89 --- /dev/null +++ b/.skills/skill-creator/SKILL.md @@ -0,0 +1,479 @@ +--- +name: skill-creator +description: Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy. +--- + +# Skill Creator + +A skill for creating new skills and iteratively improving them. + +At a high level, the process of creating a skill goes like this: + +- Decide what you want the skill to do and roughly how it should do it +- Write a draft of the skill +- Create a few test prompts and run claude-with-access-to-the-skill on them +- Help the user evaluate the results both qualitatively and quantitatively + - While the runs happen in the background, draft some quantitative evals if there aren't any (if there are some, you can either use as is or modify if you feel something needs to change about them). Then explain them to the user (or if they already existed, explain the ones that already exist) + - Use the `eval-viewer/generate_review.py` script to show the user the results for them to look at, and also let them look at the quantitative metrics +- Rewrite the skill based on feedback from the user's evaluation of the results (and also if there are any glaring flaws that become apparent from the quantitative benchmarks) +- Repeat until you're satisfied +- Expand the test set and try again at larger scale + +Your job when using this skill is to figure out where the user is in this process and then jump in and help them progress through these stages. So for instance, maybe they're like "I want to make a skill for X". You can help narrow down what they mean, write a draft, write the test cases, figure out how they want to evaluate, run all the prompts, and repeat. + +On the other hand, maybe they already have a draft of the skill. In this case you can go straight to the eval/iterate part of the loop. + +Of course, you should always be flexible and if the user is like "I don't need to run a bunch of evaluations, just vibe with me", you can do that instead. + +Then after the skill is done (but again, the order is flexible), you can also run the skill description improver, which we have a whole separate script for, to optimize the triggering of the skill. + +Cool? Cool. + +## Communicating with the user + +The skill creator is liable to be used by people across a wide range of familiarity with coding jargon. If you haven't heard (and how could you, it's only very recently that it started), there's a trend now where the power of Claude is inspiring plumbers to open up their terminals, parents and grandparents to google "how to install npm". On the other hand, the bulk of users are probably fairly computer-literate. + +So please pay attention to context cues to understand how to phrase your communication! In the default case, just to give you some idea: + +- "evaluation" and "benchmark" are borderline, but OK +- for "JSON" and "assertion" you want to see serious cues from the user that they know what those things are before using them without explaining them + +It's OK to briefly explain terms if you're in doubt, and feel free to clarify terms with a short definition if you're unsure if the user will get it. + +--- + +## Creating a skill + +### Capture Intent + +Start by understanding the user's intent. The current conversation might already contain a workflow the user wants to capture (e.g., they say "turn this into a skill"). If so, extract answers from the conversation history first — the tools used, the sequence of steps, corrections the user made, input/output formats observed. The user may need to fill the gaps, and should confirm before proceeding to the next step. + +1. What should this skill enable Claude to do? +2. When should this skill trigger? (what user phrases/contexts) +3. What's the expected output format? +4. Should we set up test cases to verify the skill works? Skills with objectively verifiable outputs (file transforms, data extraction, code generation, fixed workflow steps) benefit from test cases. Skills with subjective outputs (writing style, art) often don't need them. Suggest the appropriate default based on the skill type, but let the user decide. + +### Interview and Research + +Proactively ask questions about edge cases, input/output formats, example files, success criteria, and dependencies. Wait to write test prompts until you've got this part ironed out. + +Check available MCPs - if useful for research (searching docs, finding similar skills, looking up best practices), research in parallel via subagents if available, otherwise inline. Come prepared with context to reduce burden on the user. + +### Write the SKILL.md + +Based on the user interview, fill in these components: + +- **name**: Skill identifier +- **description**: When to trigger, what it does. This is the primary triggering mechanism - include both what the skill does AND specific contexts for when to use it. All "when to use" info goes here, not in the body. Note: currently Claude has a tendency to "undertrigger" skills -- to not use them when they'd be useful. To combat this, please make the skill descriptions a little bit "pushy". So for instance, instead of "How to build a simple fast dashboard to display internal Anthropic data.", you might write "How to build a simple fast dashboard to display internal Anthropic data. Make sure to use this skill whenever the user mentions dashboards, data visualization, internal metrics, or wants to display any kind of company data, even if they don't explicitly ask for a 'dashboard.'" +- **compatibility**: Required tools, dependencies (optional, rarely needed) +- **the rest of the skill :)** + +### Skill Writing Guide + +#### Anatomy of a Skill + +``` +skill-name/ +├── SKILL.md (required) +│ ├── YAML frontmatter (name, description required) +│ └── Markdown instructions +└── Bundled Resources (optional) + ├── scripts/ - Executable code for deterministic/repetitive tasks + ├── references/ - Docs loaded into context as needed + └── assets/ - Files used in output (templates, icons, fonts) +``` + +#### Progressive Disclosure + +Skills use a three-level loading system: +1. **Metadata** (name + description) - Always in context (~100 words) +2. **SKILL.md body** - In context whenever skill triggers (<500 lines ideal) +3. **Bundled resources** - As needed (unlimited, scripts can execute without loading) + +These word counts are approximate and you can feel free to go longer if needed. + +**Key patterns:** +- Keep SKILL.md under 500 lines; if you're approaching this limit, add an additional layer of hierarchy along with clear pointers about where the model using the skill should go next to follow up. +- Reference files clearly from SKILL.md with guidance on when to read them +- For large reference files (>300 lines), include a table of contents + +**Domain organization**: When a skill supports multiple domains/frameworks, organize by variant: +``` +cloud-deploy/ +├── SKILL.md (workflow + selection) +└── references/ + ├── aws.md + ├── gcp.md + └── azure.md +``` +Claude reads only the relevant reference file. + +#### Principle of Lack of Surprise + +This goes without saying, but skills must not contain malware, exploit code, or any content that could compromise system security. A skill's contents should not surprise the user in their intent if described. Don't go along with requests to create misleading skills or skills designed to facilitate unauthorized access, data exfiltration, or other malicious activities. Things like a "roleplay as an XYZ" are OK though. + +#### Writing Patterns + +Prefer using the imperative form in instructions. + +**Defining output formats** - You can do it like this: +```markdown +## Report structure +ALWAYS use this exact template: +# [Title] +## Executive summary +## Key findings +## Recommendations +``` + +**Examples pattern** - It's useful to include examples. You can format them like this (but if "Input" and "Output" are in the examples you might want to deviate a little): +```markdown +## Commit message format +**Example 1:** +Input: Added user authentication with JWT tokens +Output: feat(auth): implement JWT-based authentication +``` + +### Writing Style + +Try to explain to the model why things are important in lieu of heavy-handed musty MUSTs. Use theory of mind and try to make the skill general and not super-narrow to specific examples. Start by writing a draft and then look at it with fresh eyes and improve it. + +### Test Cases + +After writing the skill draft, come up with 2-3 realistic test prompts — the kind of thing a real user would actually say. Share them with the user: [you don't have to use this exact language] "Here are a few test cases I'd like to try. Do these look right, or do you want to add more?" Then run them. + +Save test cases to `evals/evals.json`. Don't write assertions yet — just the prompts. You'll draft assertions in the next step while the runs are in progress. + +```json +{ + "skill_name": "example-skill", + "evals": [ + { + "id": 1, + "prompt": "User's task prompt", + "expected_output": "Description of expected result", + "files": [] + } + ] +} +``` + +See `references/schemas.md` for the full schema (including the `assertions` field, which you'll add later). + +## Running and evaluating test cases + +This section is one continuous sequence — don't stop partway through. Do NOT use `/skill-test` or any other testing skill. + +Put results in `-workspace/` as a sibling to the skill directory. Within the workspace, organize results by iteration (`iteration-1/`, `iteration-2/`, etc.) and within that, each test case gets a directory (`eval-0/`, `eval-1/`, etc.). Don't create all of this upfront — just create directories as you go. + +### Step 1: Spawn all runs (with-skill AND baseline) in the same turn + +For each test case, spawn two subagents in the same turn — one with the skill, one without. This is important: don't spawn the with-skill runs first and then come back for baselines later. Launch everything at once so it all finishes around the same time. + +**With-skill run:** + +``` +Execute this task: +- Skill path: +- Task: +- Input files: +- Save outputs to: /iteration-/eval-/with_skill/outputs/ +- Outputs to save: +``` + +**Baseline run** (same prompt, but the baseline depends on context): +- **Creating a new skill**: no skill at all. Same prompt, no skill path, save to `without_skill/outputs/`. +- **Improving an existing skill**: the old version. Before editing, snapshot the skill (`cp -r /skill-snapshot/`), then point the baseline subagent at the snapshot. Save to `old_skill/outputs/`. + +Write an `eval_metadata.json` for each test case (assertions can be empty for now). Give each eval a descriptive name based on what it's testing — not just "eval-0". Use this name for the directory too. If this iteration uses new or modified eval prompts, create these files for each new eval directory — don't assume they carry over from previous iterations. + +```json +{ + "eval_id": 0, + "eval_name": "descriptive-name-here", + "prompt": "The user's task prompt", + "assertions": [] +} +``` + +### Step 2: While runs are in progress, draft assertions + +Don't just wait for the runs to finish — you can use this time productively. Draft quantitative assertions for each test case and explain them to the user. If assertions already exist in `evals/evals.json`, review them and explain what they check. + +Good assertions are objectively verifiable and have descriptive names — they should read clearly in the benchmark viewer so someone glancing at the results immediately understands what each one checks. Subjective skills (writing style, design quality) are better evaluated qualitatively — don't force assertions onto things that need human judgment. + +Update the `eval_metadata.json` files and `evals/evals.json` with the assertions once drafted. Also explain to the user what they'll see in the viewer — both the qualitative outputs and the quantitative benchmark. + +### Step 3: As runs complete, capture timing data + +When each subagent task completes, you receive a notification containing `total_tokens` and `duration_ms`. Save this data immediately to `timing.json` in the run directory: + +```json +{ + "total_tokens": 84852, + "duration_ms": 23332, + "total_duration_seconds": 23.3 +} +``` + +This is the only opportunity to capture this data — it comes through the task notification and isn't persisted elsewhere. Process each notification as it arrives rather than trying to batch them. + +### Step 4: Grade, aggregate, and launch the viewer + +Once all runs are done: + +1. **Grade each run** — spawn a grader subagent (or grade inline) that reads `agents/grader.md` and evaluates each assertion against the outputs. Save results to `grading.json` in each run directory. The grading.json expectations array must use the fields `text`, `passed`, and `evidence` (not `name`/`met`/`details` or other variants) — the viewer depends on these exact field names. For assertions that can be checked programmatically, write and run a script rather than eyeballing it — scripts are faster, more reliable, and can be reused across iterations. + +2. **Aggregate into benchmark** — run the aggregation script from the skill-creator directory: + ```bash + python -m scripts.aggregate_benchmark /iteration-N --skill-name + ``` + This produces `benchmark.json` and `benchmark.md` with pass_rate, time, and tokens for each configuration, with mean ± stddev and the delta. If generating benchmark.json manually, see `references/schemas.md` for the exact schema the viewer expects. +Put each with_skill version before its baseline counterpart. + +3. **Do an analyst pass** — read the benchmark data and surface patterns the aggregate stats might hide. See `agents/analyzer.md` (the "Analyzing Benchmark Results" section) for what to look for — things like assertions that always pass regardless of skill (non-discriminating), high-variance evals (possibly flaky), and time/token tradeoffs. + +4. **Launch the viewer** with both qualitative outputs and quantitative data: + ```bash + nohup python /eval-viewer/generate_review.py \ + /iteration-N \ + --skill-name "my-skill" \ + --benchmark /iteration-N/benchmark.json \ + > /dev/null 2>&1 & + VIEWER_PID=$! + ``` + For iteration 2+, also pass `--previous-workspace /iteration-`. + + **Cowork / headless environments:** If `webbrowser.open()` is not available or the environment has no display, use `--static ` to write a standalone HTML file instead of starting a server. Feedback will be downloaded as a `feedback.json` file when the user clicks "Submit All Reviews". After download, copy `feedback.json` into the workspace directory for the next iteration to pick up. + +Note: please use generate_review.py to create the viewer; there's no need to write custom HTML. + +5. **Tell the user** something like: "I've opened the results in your browser. There are two tabs — 'Outputs' lets you click through each test case and leave feedback, 'Benchmark' shows the quantitative comparison. When you're done, come back here and let me know." + +### What the user sees in the viewer + +The "Outputs" tab shows one test case at a time: +- **Prompt**: the task that was given +- **Output**: the files the skill produced, rendered inline where possible +- **Previous Output** (iteration 2+): collapsed section showing last iteration's output +- **Formal Grades** (if grading was run): collapsed section showing assertion pass/fail +- **Feedback**: a textbox that auto-saves as they type +- **Previous Feedback** (iteration 2+): their comments from last time, shown below the textbox + +The "Benchmark" tab shows the stats summary: pass rates, timing, and token usage for each configuration, with per-eval breakdowns and analyst observations. + +Navigation is via prev/next buttons or arrow keys. When done, they click "Submit All Reviews" which saves all feedback to `feedback.json`. + +### Step 5: Read the feedback + +When the user tells you they're done, read `feedback.json`: + +```json +{ + "reviews": [ + {"run_id": "eval-0-with_skill", "feedback": "the chart is missing axis labels", "timestamp": "..."}, + {"run_id": "eval-1-with_skill", "feedback": "", "timestamp": "..."}, + {"run_id": "eval-2-with_skill", "feedback": "perfect, love this", "timestamp": "..."} + ], + "status": "complete" +} +``` + +Empty feedback means the user thought it was fine. Focus your improvements on the test cases where the user had specific complaints. + +Kill the viewer server when you're done with it: + +```bash +kill $VIEWER_PID 2>/dev/null +``` + +--- + +## Improving the skill + +This is the heart of the loop. You've run the test cases, the user has reviewed the results, and now you need to make the skill better based on their feedback. + +### How to think about improvements + +1. **Generalize from the feedback.** The big picture thing that's happening here is that we're trying to create skills that can be used a million times (maybe literally, maybe even more who knows) across many different prompts. Here you and the user are iterating on only a few examples over and over again because it helps move faster. The user knows these examples in and out and it's quick for them to assess new outputs. But if the skill you and the user are codeveloping works only for those examples, it's useless. Rather than put in fiddly overfitty changes, or oppressively constrictive MUSTs, if there's some stubborn issue, you might try branching out and using different metaphors, or recommending different patterns of working. It's relatively cheap to try and maybe you'll land on something great. + +2. **Keep the prompt lean.** Remove things that aren't pulling their weight. Make sure to read the transcripts, not just the final outputs — if it looks like the skill is making the model waste a bunch of time doing things that are unproductive, you can try getting rid of the parts of the skill that are making it do that and seeing what happens. + +3. **Explain the why.** Try hard to explain the **why** behind everything you're asking the model to do. Today's LLMs are *smart*. They have good theory of mind and when given a good harness can go beyond rote instructions and really make things happen. Even if the feedback from the user is terse or frustrated, try to actually understand the task and why the user is writing what they wrote, and what they actually wrote, and then transmit this understanding into the instructions. If you find yourself writing ALWAYS or NEVER in all caps, or using super rigid structures, that's a yellow flag — if possible, reframe and explain the reasoning so that the model understands why the thing you're asking for is important. That's a more humane, powerful, and effective approach. + +4. **Look for repeated work across test cases.** Read the transcripts from the test runs and notice if the subagents all independently wrote similar helper scripts or took the same multi-step approach to something. If all 3 test cases resulted in the subagent writing a `create_docx.py` or a `build_chart.py`, that's a strong signal the skill should bundle that script. Write it once, put it in `scripts/`, and tell the skill to use it. This saves every future invocation from reinventing the wheel. + +This task is pretty important (we are trying to create billions a year in economic value here!) and your thinking time is not the blocker; take your time and really mull things over. I'd suggest writing a draft revision and then looking at it anew and making improvements. Really do your best to get into the head of the user and understand what they want and need. + +### The iteration loop + +After improving the skill: + +1. Apply your improvements to the skill +2. Rerun all test cases into a new `iteration-/` directory, including baseline runs. If you're creating a new skill, the baseline is always `without_skill` (no skill) — that stays the same across iterations. If you're improving an existing skill, use your judgment on what makes sense as the baseline: the original version the user came in with, or the previous iteration. +3. Launch the reviewer with `--previous-workspace` pointing at the previous iteration +4. Wait for the user to review and tell you they're done +5. Read the new feedback, improve again, repeat + +Keep going until: +- The user says they're happy +- The feedback is all empty (everything looks good) +- You're not making meaningful progress + +--- + +## Advanced: Blind comparison + +For situations where you want a more rigorous comparison between two versions of a skill (e.g., the user asks "is the new version actually better?"), there's a blind comparison system. Read `agents/comparator.md` and `agents/analyzer.md` for the details. The basic idea is: give two outputs to an independent agent without telling it which is which, and let it judge quality. Then analyze why the winner won. + +This is optional, requires subagents, and most users won't need it. The human review loop is usually sufficient. + +--- + +## Description Optimization + +The description field in SKILL.md frontmatter is the primary mechanism that determines whether Claude invokes a skill. After creating or improving a skill, offer to optimize the description for better triggering accuracy. + +### Step 1: Generate trigger eval queries + +Create 20 eval queries — a mix of should-trigger and should-not-trigger. Save as JSON: + +```json +[ + {"query": "the user prompt", "should_trigger": true}, + {"query": "another prompt", "should_trigger": false} +] +``` + +The queries must be realistic and something a Claude Code or Claude.ai user would actually type. Not abstract requests, but requests that are concrete and specific and have a good amount of detail. For instance, file paths, personal context about the user's job or situation, column names and values, company names, URLs. A little bit of backstory. Some might be in lowercase or contain abbreviations or typos or casual speech. Use a mix of different lengths, and focus on edge cases rather than making them clear-cut (the user will get a chance to sign off on them). + +Bad: `"Format this data"`, `"Extract text from PDF"`, `"Create a chart"` + +Good: `"ok so my boss just sent me this xlsx file (its in my downloads, called something like 'Q4 sales final FINAL v2.xlsx') and she wants me to add a column that shows the profit margin as a percentage. The revenue is in column C and costs are in column D i think"` + +For the **should-trigger** queries (8-10), think about coverage. You want different phrasings of the same intent — some formal, some casual. Include cases where the user doesn't explicitly name the skill or file type but clearly needs it. Throw in some uncommon use cases and cases where this skill competes with another but should win. + +For the **should-not-trigger** queries (8-10), the most valuable ones are the near-misses — queries that share keywords or concepts with the skill but actually need something different. Think adjacent domains, ambiguous phrasing where a naive keyword match would trigger but shouldn't, and cases where the query touches on something the skill does but in a context where another tool is more appropriate. + +The key thing to avoid: don't make should-not-trigger queries obviously irrelevant. "Write a fibonacci function" as a negative test for a PDF skill is too easy — it doesn't test anything. The negative cases should be genuinely tricky. + +### Step 2: Review with user + +Present the eval set to the user for review using the HTML template: + +1. Read the template from `assets/eval_review.html` +2. Replace the placeholders: + - `__EVAL_DATA_PLACEHOLDER__` → the JSON array of eval items (no quotes around it — it's a JS variable assignment) + - `__SKILL_NAME_PLACEHOLDER__` → the skill's name + - `__SKILL_DESCRIPTION_PLACEHOLDER__` → the skill's current description +3. Write to a temp file (e.g., `/tmp/eval_review_.html`) and open it: `open /tmp/eval_review_.html` +4. The user can edit queries, toggle should-trigger, add/remove entries, then click "Export Eval Set" +5. The file downloads to `~/Downloads/eval_set.json` — check the Downloads folder for the most recent version in case there are multiple (e.g., `eval_set (1).json`) + +This step matters — bad eval queries lead to bad descriptions. + +### Step 3: Run the optimization loop + +Tell the user: "This will take some time — I'll run the optimization loop in the background and check on it periodically." + +Save the eval set to the workspace, then run in the background: + +```bash +python -m scripts.run_loop \ + --eval-set \ + --skill-path \ + --model \ + --max-iterations 5 \ + --verbose +``` + +Use the model ID from your system prompt (the one powering the current session) so the triggering test matches what the user actually experiences. + +While it runs, periodically tail the output to give the user updates on which iteration it's on and what the scores look like. + +This handles the full optimization loop automatically. It splits the eval set into 60% train and 40% held-out test, evaluates the current description (running each query 3 times to get a reliable trigger rate), then calls Claude with extended thinking to propose improvements based on what failed. It re-evaluates each new description on both train and test, iterating up to 5 times. When it's done, it opens an HTML report in the browser showing the results per iteration and returns JSON with `best_description` — selected by test score rather than train score to avoid overfitting. + +### How skill triggering works + +Understanding the triggering mechanism helps design better eval queries. Skills appear in Claude's `available_skills` list with their name + description, and Claude decides whether to consult a skill based on that description. The important thing to know is that Claude only consults skills for tasks it can't easily handle on its own — simple, one-step queries like "read this PDF" may not trigger a skill even if the description matches perfectly, because Claude can handle them directly with basic tools. Complex, multi-step, or specialized queries reliably trigger skills when the description matches. + +This means your eval queries should be substantive enough that Claude would actually benefit from consulting a skill. Simple queries like "read file X" are poor test cases — they won't trigger skills regardless of description quality. + +### Step 4: Apply the result + +Take `best_description` from the JSON output and update the skill's SKILL.md frontmatter. Show the user before/after and report the scores. + +--- + +### Package and Present (only if `present_files` tool is available) + +Check whether you have access to the `present_files` tool. If you don't, skip this step. If you do, package the skill and present the .skill file to the user: + +```bash +python -m scripts.package_skill +``` + +After packaging, direct the user to the resulting `.skill` file path so they can install it. + +--- + +## Claude.ai-specific instructions + +In Claude.ai, the core workflow is the same (draft → test → review → improve → repeat), but because Claude.ai doesn't have subagents, some mechanics change. Here's what to adapt: + +**Running test cases**: No subagents means no parallel execution. For each test case, read the skill's SKILL.md, then follow its instructions to accomplish the test prompt yourself. Do them one at a time. This is less rigorous than independent subagents (you wrote the skill and you're also running it, so you have full context), but it's a useful sanity check — and the human review step compensates. Skip the baseline runs — just use the skill to complete the task as requested. + +**Reviewing results**: If you can't open a browser (e.g., Claude.ai's VM has no display, or you're on a remote server), skip the browser reviewer entirely. Instead, present results directly in the conversation. For each test case, show the prompt and the output. If the output is a file the user needs to see (like a .docx or .xlsx), save it to the filesystem and tell them where it is so they can download and inspect it. Ask for feedback inline: "How does this look? Anything you'd change?" + +**Benchmarking**: Skip the quantitative benchmarking — it relies on baseline comparisons which aren't meaningful without subagents. Focus on qualitative feedback from the user. + +**The iteration loop**: Same as before — improve the skill, rerun the test cases, ask for feedback — just without the browser reviewer in the middle. You can still organize results into iteration directories on the filesystem if you have one. + +**Description optimization**: This section requires the `claude` CLI tool (specifically `claude -p`) which is only available in Claude Code. Skip it if you're on Claude.ai. + +**Blind comparison**: Requires subagents. Skip it. + +**Packaging**: The `package_skill.py` script works anywhere with Python and a filesystem. On Claude.ai, you can run it and the user can download the resulting `.skill` file. + +--- + +## Cowork-Specific Instructions + +If you're in Cowork, the main things to know are: + +- You have subagents, so the main workflow (spawn test cases in parallel, run baselines, grade, etc.) all works. (However, if you run into severe problems with timeouts, it's OK to run the test prompts in series rather than parallel.) +- You don't have a browser or display, so when generating the eval viewer, use `--static ` to write a standalone HTML file instead of starting a server. Then proffer a link that the user can click to open the HTML in their browser. +- For whatever reason, the Cowork setup seems to disincline Claude from generating the eval viewer after running the tests, so just to reiterate: whether you're in Cowork or in Claude Code, after running tests, you should always generate the eval viewer for the human to look at examples before revising the skill yourself and trying to make corrections, using `generate_review.py` (not writing your own boutique html code). Sorry in advance but I'm gonna go all caps here: GENERATE THE EVAL VIEWER *BEFORE* evaluating inputs yourself. You want to get them in front of the human ASAP! +- Feedback works differently: since there's no running server, the viewer's "Submit All Reviews" button will download `feedback.json` as a file. You can then read it from there (you may have to request access first). +- Packaging works — `package_skill.py` just needs Python and a filesystem. +- Description optimization (`run_loop.py` / `run_eval.py`) should work in Cowork just fine since it uses `claude -p` via subprocess, not a browser, but please save it until you've fully finished making the skill and the user agrees it's in good shape. + +--- + +## Reference files + +The agents/ directory contains instructions for specialized subagents. Read them when you need to spawn the relevant subagent. + +- `agents/grader.md` — How to evaluate assertions against outputs +- `agents/comparator.md` — How to do blind A/B comparison between two outputs +- `agents/analyzer.md` — How to analyze why one version beat another + +The references/ directory has additional documentation: +- `references/schemas.md` — JSON structures for evals.json, grading.json, etc. + +--- + +Repeating one more time the core loop here for emphasis: + +- Figure out what the skill is about +- Draft or edit the skill +- Run claude-with-access-to-the-skill on test prompts +- With the user, evaluate the outputs: + - Create benchmark.json and run `eval-viewer/generate_review.py` to help the user review them + - Run quantitative evals +- Repeat until you and the user are satisfied +- Package the final skill and return it to the user. + +Please add steps to your TodoList, if you have such a thing, to make sure you don't forget. If you're in Cowork, please specifically put "Create evals JSON and run `eval-viewer/generate_review.py` so human can review test cases" in your TodoList to make sure it happens. + +Good luck! diff --git a/.skills/skill-creator/agents/analyzer.md b/.skills/skill-creator/agents/analyzer.md new file mode 100644 index 00000000..14e41d60 --- /dev/null +++ b/.skills/skill-creator/agents/analyzer.md @@ -0,0 +1,274 @@ +# Post-hoc Analyzer Agent + +Analyze blind comparison results to understand WHY the winner won and generate improvement suggestions. + +## Role + +After the blind comparator determines a winner, the Post-hoc Analyzer "unblids" the results by examining the skills and transcripts. The goal is to extract actionable insights: what made the winner better, and how can the loser be improved? + +## Inputs + +You receive these parameters in your prompt: + +- **winner**: "A" or "B" (from blind comparison) +- **winner_skill_path**: Path to the skill that produced the winning output +- **winner_transcript_path**: Path to the execution transcript for the winner +- **loser_skill_path**: Path to the skill that produced the losing output +- **loser_transcript_path**: Path to the execution transcript for the loser +- **comparison_result_path**: Path to the blind comparator's output JSON +- **output_path**: Where to save the analysis results + +## Process + +### Step 1: Read Comparison Result + +1. Read the blind comparator's output at comparison_result_path +2. Note the winning side (A or B), the reasoning, and any scores +3. Understand what the comparator valued in the winning output + +### Step 2: Read Both Skills + +1. Read the winner skill's SKILL.md and key referenced files +2. Read the loser skill's SKILL.md and key referenced files +3. Identify structural differences: + - Instructions clarity and specificity + - Script/tool usage patterns + - Example coverage + - Edge case handling + +### Step 3: Read Both Transcripts + +1. Read the winner's transcript +2. Read the loser's transcript +3. Compare execution patterns: + - How closely did each follow their skill's instructions? + - What tools were used differently? + - Where did the loser diverge from optimal behavior? + - Did either encounter errors or make recovery attempts? + +### Step 4: Analyze Instruction Following + +For each transcript, evaluate: +- Did the agent follow the skill's explicit instructions? +- Did the agent use the skill's provided tools/scripts? +- Were there missed opportunities to leverage skill content? +- Did the agent add unnecessary steps not in the skill? + +Score instruction following 1-10 and note specific issues. + +### Step 5: Identify Winner Strengths + +Determine what made the winner better: +- Clearer instructions that led to better behavior? +- Better scripts/tools that produced better output? +- More comprehensive examples that guided edge cases? +- Better error handling guidance? + +Be specific. Quote from skills/transcripts where relevant. + +### Step 6: Identify Loser Weaknesses + +Determine what held the loser back: +- Ambiguous instructions that led to suboptimal choices? +- Missing tools/scripts that forced workarounds? +- Gaps in edge case coverage? +- Poor error handling that caused failures? + +### Step 7: Generate Improvement Suggestions + +Based on the analysis, produce actionable suggestions for improving the loser skill: +- Specific instruction changes to make +- Tools/scripts to add or modify +- Examples to include +- Edge cases to address + +Prioritize by impact. Focus on changes that would have changed the outcome. + +### Step 8: Write Analysis Results + +Save structured analysis to `{output_path}`. + +## Output Format + +Write a JSON file with this structure: + +```json +{ + "comparison_summary": { + "winner": "A", + "winner_skill": "path/to/winner/skill", + "loser_skill": "path/to/loser/skill", + "comparator_reasoning": "Brief summary of why comparator chose winner" + }, + "winner_strengths": [ + "Clear step-by-step instructions for handling multi-page documents", + "Included validation script that caught formatting errors", + "Explicit guidance on fallback behavior when OCR fails" + ], + "loser_weaknesses": [ + "Vague instruction 'process the document appropriately' led to inconsistent behavior", + "No script for validation, agent had to improvise and made errors", + "No guidance on OCR failure, agent gave up instead of trying alternatives" + ], + "instruction_following": { + "winner": { + "score": 9, + "issues": [ + "Minor: skipped optional logging step" + ] + }, + "loser": { + "score": 6, + "issues": [ + "Did not use the skill's formatting template", + "Invented own approach instead of following step 3", + "Missed the 'always validate output' instruction" + ] + } + }, + "improvement_suggestions": [ + { + "priority": "high", + "category": "instructions", + "suggestion": "Replace 'process the document appropriately' with explicit steps: 1) Extract text, 2) Identify sections, 3) Format per template", + "expected_impact": "Would eliminate ambiguity that caused inconsistent behavior" + }, + { + "priority": "high", + "category": "tools", + "suggestion": "Add validate_output.py script similar to winner skill's validation approach", + "expected_impact": "Would catch formatting errors before final output" + }, + { + "priority": "medium", + "category": "error_handling", + "suggestion": "Add fallback instructions: 'If OCR fails, try: 1) different resolution, 2) image preprocessing, 3) manual extraction'", + "expected_impact": "Would prevent early failure on difficult documents" + } + ], + "transcript_insights": { + "winner_execution_pattern": "Read skill -> Followed 5-step process -> Used validation script -> Fixed 2 issues -> Produced output", + "loser_execution_pattern": "Read skill -> Unclear on approach -> Tried 3 different methods -> No validation -> Output had errors" + } +} +``` + +## Guidelines + +- **Be specific**: Quote from skills and transcripts, don't just say "instructions were unclear" +- **Be actionable**: Suggestions should be concrete changes, not vague advice +- **Focus on skill improvements**: The goal is to improve the losing skill, not critique the agent +- **Prioritize by impact**: Which changes would most likely have changed the outcome? +- **Consider causation**: Did the skill weakness actually cause the worse output, or is it incidental? +- **Stay objective**: Analyze what happened, don't editorialize +- **Think about generalization**: Would this improvement help on other evals too? + +## Categories for Suggestions + +Use these categories to organize improvement suggestions: + +| Category | Description | +|----------|-------------| +| `instructions` | Changes to the skill's prose instructions | +| `tools` | Scripts, templates, or utilities to add/modify | +| `examples` | Example inputs/outputs to include | +| `error_handling` | Guidance for handling failures | +| `structure` | Reorganization of skill content | +| `references` | External docs or resources to add | + +## Priority Levels + +- **high**: Would likely change the outcome of this comparison +- **medium**: Would improve quality but may not change win/loss +- **low**: Nice to have, marginal improvement + +--- + +# Analyzing Benchmark Results + +When analyzing benchmark results, the analyzer's purpose is to **surface patterns and anomalies** across multiple runs, not suggest skill improvements. + +## Role + +Review all benchmark run results and generate freeform notes that help the user understand skill performance. Focus on patterns that wouldn't be visible from aggregate metrics alone. + +## Inputs + +You receive these parameters in your prompt: + +- **benchmark_data_path**: Path to the in-progress benchmark.json with all run results +- **skill_path**: Path to the skill being benchmarked +- **output_path**: Where to save the notes (as JSON array of strings) + +## Process + +### Step 1: Read Benchmark Data + +1. Read the benchmark.json containing all run results +2. Note the configurations tested (with_skill, without_skill) +3. Understand the run_summary aggregates already calculated + +### Step 2: Analyze Per-Assertion Patterns + +For each expectation across all runs: +- Does it **always pass** in both configurations? (may not differentiate skill value) +- Does it **always fail** in both configurations? (may be broken or beyond capability) +- Does it **always pass with skill but fail without**? (skill clearly adds value here) +- Does it **always fail with skill but pass without**? (skill may be hurting) +- Is it **highly variable**? (flaky expectation or non-deterministic behavior) + +### Step 3: Analyze Cross-Eval Patterns + +Look for patterns across evals: +- Are certain eval types consistently harder/easier? +- Do some evals show high variance while others are stable? +- Are there surprising results that contradict expectations? + +### Step 4: Analyze Metrics Patterns + +Look at time_seconds, tokens, tool_calls: +- Does the skill significantly increase execution time? +- Is there high variance in resource usage? +- Are there outlier runs that skew the aggregates? + +### Step 5: Generate Notes + +Write freeform observations as a list of strings. Each note should: +- State a specific observation +- Be grounded in the data (not speculation) +- Help the user understand something the aggregate metrics don't show + +Examples: +- "Assertion 'Output is a PDF file' passes 100% in both configurations - may not differentiate skill value" +- "Eval 3 shows high variance (50% ± 40%) - run 2 had an unusual failure that may be flaky" +- "Without-skill runs consistently fail on table extraction expectations (0% pass rate)" +- "Skill adds 13s average execution time but improves pass rate by 50%" +- "Token usage is 80% higher with skill, primarily due to script output parsing" +- "All 3 without-skill runs for eval 1 produced empty output" + +### Step 6: Write Notes + +Save notes to `{output_path}` as a JSON array of strings: + +```json +[ + "Assertion 'Output is a PDF file' passes 100% in both configurations - may not differentiate skill value", + "Eval 3 shows high variance (50% ± 40%) - run 2 had an unusual failure", + "Without-skill runs consistently fail on table extraction expectations", + "Skill adds 13s average execution time but improves pass rate by 50%" +] +``` + +## Guidelines + +**DO:** +- Report what you observe in the data +- Be specific about which evals, expectations, or runs you're referring to +- Note patterns that aggregate metrics would hide +- Provide context that helps interpret the numbers + +**DO NOT:** +- Suggest improvements to the skill (that's for the improvement step, not benchmarking) +- Make subjective quality judgments ("the output was good/bad") +- Speculate about causes without evidence +- Repeat information already in the run_summary aggregates diff --git a/.skills/skill-creator/agents/comparator.md b/.skills/skill-creator/agents/comparator.md new file mode 100644 index 00000000..80e00eb4 --- /dev/null +++ b/.skills/skill-creator/agents/comparator.md @@ -0,0 +1,202 @@ +# Blind Comparator Agent + +Compare two outputs WITHOUT knowing which skill produced them. + +## Role + +The Blind Comparator judges which output better accomplishes the eval task. You receive two outputs labeled A and B, but you do NOT know which skill produced which. This prevents bias toward a particular skill or approach. + +Your judgment is based purely on output quality and task completion. + +## Inputs + +You receive these parameters in your prompt: + +- **output_a_path**: Path to the first output file or directory +- **output_b_path**: Path to the second output file or directory +- **eval_prompt**: The original task/prompt that was executed +- **expectations**: List of expectations to check (optional - may be empty) + +## Process + +### Step 1: Read Both Outputs + +1. Examine output A (file or directory) +2. Examine output B (file or directory) +3. Note the type, structure, and content of each +4. If outputs are directories, examine all relevant files inside + +### Step 2: Understand the Task + +1. Read the eval_prompt carefully +2. Identify what the task requires: + - What should be produced? + - What qualities matter (accuracy, completeness, format)? + - What would distinguish a good output from a poor one? + +### Step 3: Generate Evaluation Rubric + +Based on the task, generate a rubric with two dimensions: + +**Content Rubric** (what the output contains): +| Criterion | 1 (Poor) | 3 (Acceptable) | 5 (Excellent) | +|-----------|----------|----------------|---------------| +| Correctness | Major errors | Minor errors | Fully correct | +| Completeness | Missing key elements | Mostly complete | All elements present | +| Accuracy | Significant inaccuracies | Minor inaccuracies | Accurate throughout | + +**Structure Rubric** (how the output is organized): +| Criterion | 1 (Poor) | 3 (Acceptable) | 5 (Excellent) | +|-----------|----------|----------------|---------------| +| Organization | Disorganized | Reasonably organized | Clear, logical structure | +| Formatting | Inconsistent/broken | Mostly consistent | Professional, polished | +| Usability | Difficult to use | Usable with effort | Easy to use | + +Adapt criteria to the specific task. For example: +- PDF form → "Field alignment", "Text readability", "Data placement" +- Document → "Section structure", "Heading hierarchy", "Paragraph flow" +- Data output → "Schema correctness", "Data types", "Completeness" + +### Step 4: Evaluate Each Output Against the Rubric + +For each output (A and B): + +1. **Score each criterion** on the rubric (1-5 scale) +2. **Calculate dimension totals**: Content score, Structure score +3. **Calculate overall score**: Average of dimension scores, scaled to 1-10 + +### Step 5: Check Assertions (if provided) + +If expectations are provided: + +1. Check each expectation against output A +2. Check each expectation against output B +3. Count pass rates for each output +4. Use expectation scores as secondary evidence (not the primary decision factor) + +### Step 6: Determine the Winner + +Compare A and B based on (in priority order): + +1. **Primary**: Overall rubric score (content + structure) +2. **Secondary**: Assertion pass rates (if applicable) +3. **Tiebreaker**: If truly equal, declare a TIE + +Be decisive - ties should be rare. One output is usually better, even if marginally. + +### Step 7: Write Comparison Results + +Save results to a JSON file at the path specified (or `comparison.json` if not specified). + +## Output Format + +Write a JSON file with this structure: + +```json +{ + "winner": "A", + "reasoning": "Output A provides a complete solution with proper formatting and all required fields. Output B is missing the date field and has formatting inconsistencies.", + "rubric": { + "A": { + "content": { + "correctness": 5, + "completeness": 5, + "accuracy": 4 + }, + "structure": { + "organization": 4, + "formatting": 5, + "usability": 4 + }, + "content_score": 4.7, + "structure_score": 4.3, + "overall_score": 9.0 + }, + "B": { + "content": { + "correctness": 3, + "completeness": 2, + "accuracy": 3 + }, + "structure": { + "organization": 3, + "formatting": 2, + "usability": 3 + }, + "content_score": 2.7, + "structure_score": 2.7, + "overall_score": 5.4 + } + }, + "output_quality": { + "A": { + "score": 9, + "strengths": ["Complete solution", "Well-formatted", "All fields present"], + "weaknesses": ["Minor style inconsistency in header"] + }, + "B": { + "score": 5, + "strengths": ["Readable output", "Correct basic structure"], + "weaknesses": ["Missing date field", "Formatting inconsistencies", "Partial data extraction"] + } + }, + "expectation_results": { + "A": { + "passed": 4, + "total": 5, + "pass_rate": 0.80, + "details": [ + {"text": "Output includes name", "passed": true}, + {"text": "Output includes date", "passed": true}, + {"text": "Format is PDF", "passed": true}, + {"text": "Contains signature", "passed": false}, + {"text": "Readable text", "passed": true} + ] + }, + "B": { + "passed": 3, + "total": 5, + "pass_rate": 0.60, + "details": [ + {"text": "Output includes name", "passed": true}, + {"text": "Output includes date", "passed": false}, + {"text": "Format is PDF", "passed": true}, + {"text": "Contains signature", "passed": false}, + {"text": "Readable text", "passed": true} + ] + } + } +} +``` + +If no expectations were provided, omit the `expectation_results` field entirely. + +## Field Descriptions + +- **winner**: "A", "B", or "TIE" +- **reasoning**: Clear explanation of why the winner was chosen (or why it's a tie) +- **rubric**: Structured rubric evaluation for each output + - **content**: Scores for content criteria (correctness, completeness, accuracy) + - **structure**: Scores for structure criteria (organization, formatting, usability) + - **content_score**: Average of content criteria (1-5) + - **structure_score**: Average of structure criteria (1-5) + - **overall_score**: Combined score scaled to 1-10 +- **output_quality**: Summary quality assessment + - **score**: 1-10 rating (should match rubric overall_score) + - **strengths**: List of positive aspects + - **weaknesses**: List of issues or shortcomings +- **expectation_results**: (Only if expectations provided) + - **passed**: Number of expectations that passed + - **total**: Total number of expectations + - **pass_rate**: Fraction passed (0.0 to 1.0) + - **details**: Individual expectation results + +## Guidelines + +- **Stay blind**: DO NOT try to infer which skill produced which output. Judge purely on output quality. +- **Be specific**: Cite specific examples when explaining strengths and weaknesses. +- **Be decisive**: Choose a winner unless outputs are genuinely equivalent. +- **Output quality first**: Assertion scores are secondary to overall task completion. +- **Be objective**: Don't favor outputs based on style preferences; focus on correctness and completeness. +- **Explain your reasoning**: The reasoning field should make it clear why you chose the winner. +- **Handle edge cases**: If both outputs fail, pick the one that fails less badly. If both are excellent, pick the one that's marginally better. diff --git a/.skills/skill-creator/agents/grader.md b/.skills/skill-creator/agents/grader.md new file mode 100644 index 00000000..558ab05c --- /dev/null +++ b/.skills/skill-creator/agents/grader.md @@ -0,0 +1,223 @@ +# Grader Agent + +Evaluate expectations against an execution transcript and outputs. + +## Role + +The Grader reviews a transcript and output files, then determines whether each expectation passes or fails. Provide clear evidence for each judgment. + +You have two jobs: grade the outputs, and critique the evals themselves. A passing grade on a weak assertion is worse than useless — it creates false confidence. When you notice an assertion that's trivially satisfied, or an important outcome that no assertion checks, say so. + +## Inputs + +You receive these parameters in your prompt: + +- **expectations**: List of expectations to evaluate (strings) +- **transcript_path**: Path to the execution transcript (markdown file) +- **outputs_dir**: Directory containing output files from execution + +## Process + +### Step 1: Read the Transcript + +1. Read the transcript file completely +2. Note the eval prompt, execution steps, and final result +3. Identify any issues or errors documented + +### Step 2: Examine Output Files + +1. List files in outputs_dir +2. Read/examine each file relevant to the expectations. If outputs aren't plain text, use the inspection tools provided in your prompt — don't rely solely on what the transcript says the executor produced. +3. Note contents, structure, and quality + +### Step 3: Evaluate Each Assertion + +For each expectation: + +1. **Search for evidence** in the transcript and outputs +2. **Determine verdict**: + - **PASS**: Clear evidence the expectation is true AND the evidence reflects genuine task completion, not just surface-level compliance + - **FAIL**: No evidence, or evidence contradicts the expectation, or the evidence is superficial (e.g., correct filename but empty/wrong content) +3. **Cite the evidence**: Quote the specific text or describe what you found + +### Step 4: Extract and Verify Claims + +Beyond the predefined expectations, extract implicit claims from the outputs and verify them: + +1. **Extract claims** from the transcript and outputs: + - Factual statements ("The form has 12 fields") + - Process claims ("Used pypdf to fill the form") + - Quality claims ("All fields were filled correctly") + +2. **Verify each claim**: + - **Factual claims**: Can be checked against the outputs or external sources + - **Process claims**: Can be verified from the transcript + - **Quality claims**: Evaluate whether the claim is justified + +3. **Flag unverifiable claims**: Note claims that cannot be verified with available information + +This catches issues that predefined expectations might miss. + +### Step 5: Read User Notes + +If `{outputs_dir}/user_notes.md` exists: +1. Read it and note any uncertainties or issues flagged by the executor +2. Include relevant concerns in the grading output +3. These may reveal problems even when expectations pass + +### Step 6: Critique the Evals + +After grading, consider whether the evals themselves could be improved. Only surface suggestions when there's a clear gap. + +Good suggestions test meaningful outcomes — assertions that are hard to satisfy without actually doing the work correctly. Think about what makes an assertion *discriminating*: it passes when the skill genuinely succeeds and fails when it doesn't. + +Suggestions worth raising: +- An assertion that passed but would also pass for a clearly wrong output (e.g., checking filename existence but not file content) +- An important outcome you observed — good or bad — that no assertion covers at all +- An assertion that can't actually be verified from the available outputs + +Keep the bar high. The goal is to flag things the eval author would say "good catch" about, not to nitpick every assertion. + +### Step 7: Write Grading Results + +Save results to `{outputs_dir}/../grading.json` (sibling to outputs_dir). + +## Grading Criteria + +**PASS when**: +- The transcript or outputs clearly demonstrate the expectation is true +- Specific evidence can be cited +- The evidence reflects genuine substance, not just surface compliance (e.g., a file exists AND contains correct content, not just the right filename) + +**FAIL when**: +- No evidence found for the expectation +- Evidence contradicts the expectation +- The expectation cannot be verified from available information +- The evidence is superficial — the assertion is technically satisfied but the underlying task outcome is wrong or incomplete +- The output appears to meet the assertion by coincidence rather than by actually doing the work + +**When uncertain**: The burden of proof to pass is on the expectation. + +### Step 8: Read Executor Metrics and Timing + +1. If `{outputs_dir}/metrics.json` exists, read it and include in grading output +2. If `{outputs_dir}/../timing.json` exists, read it and include timing data + +## Output Format + +Write a JSON file with this structure: + +```json +{ + "expectations": [ + { + "text": "The output includes the name 'John Smith'", + "passed": true, + "evidence": "Found in transcript Step 3: 'Extracted names: John Smith, Sarah Johnson'" + }, + { + "text": "The spreadsheet has a SUM formula in cell B10", + "passed": false, + "evidence": "No spreadsheet was created. The output was a text file." + }, + { + "text": "The assistant used the skill's OCR script", + "passed": true, + "evidence": "Transcript Step 2 shows: 'Tool: Bash - python ocr_script.py image.png'" + } + ], + "summary": { + "passed": 2, + "failed": 1, + "total": 3, + "pass_rate": 0.67 + }, + "execution_metrics": { + "tool_calls": { + "Read": 5, + "Write": 2, + "Bash": 8 + }, + "total_tool_calls": 15, + "total_steps": 6, + "errors_encountered": 0, + "output_chars": 12450, + "transcript_chars": 3200 + }, + "timing": { + "executor_duration_seconds": 165.0, + "grader_duration_seconds": 26.0, + "total_duration_seconds": 191.0 + }, + "claims": [ + { + "claim": "The form has 12 fillable fields", + "type": "factual", + "verified": true, + "evidence": "Counted 12 fields in field_info.json" + }, + { + "claim": "All required fields were populated", + "type": "quality", + "verified": false, + "evidence": "Reference section was left blank despite data being available" + } + ], + "user_notes_summary": { + "uncertainties": ["Used 2023 data, may be stale"], + "needs_review": [], + "workarounds": ["Fell back to text overlay for non-fillable fields"] + }, + "eval_feedback": { + "suggestions": [ + { + "assertion": "The output includes the name 'John Smith'", + "reason": "A hallucinated document that mentions the name would also pass — consider checking it appears as the primary contact with matching phone and email from the input" + }, + { + "reason": "No assertion checks whether the extracted phone numbers match the input — I observed incorrect numbers in the output that went uncaught" + } + ], + "overall": "Assertions check presence but not correctness. Consider adding content verification." + } +} +``` + +## Field Descriptions + +- **expectations**: Array of graded expectations + - **text**: The original expectation text + - **passed**: Boolean - true if expectation passes + - **evidence**: Specific quote or description supporting the verdict +- **summary**: Aggregate statistics + - **passed**: Count of passed expectations + - **failed**: Count of failed expectations + - **total**: Total expectations evaluated + - **pass_rate**: Fraction passed (0.0 to 1.0) +- **execution_metrics**: Copied from executor's metrics.json (if available) + - **output_chars**: Total character count of output files (proxy for tokens) + - **transcript_chars**: Character count of transcript +- **timing**: Wall clock timing from timing.json (if available) + - **executor_duration_seconds**: Time spent in executor subagent + - **total_duration_seconds**: Total elapsed time for the run +- **claims**: Extracted and verified claims from the output + - **claim**: The statement being verified + - **type**: "factual", "process", or "quality" + - **verified**: Boolean - whether the claim holds + - **evidence**: Supporting or contradicting evidence +- **user_notes_summary**: Issues flagged by the executor + - **uncertainties**: Things the executor wasn't sure about + - **needs_review**: Items requiring human attention + - **workarounds**: Places where the skill didn't work as expected +- **eval_feedback**: Improvement suggestions for the evals (only when warranted) + - **suggestions**: List of concrete suggestions, each with a `reason` and optionally an `assertion` it relates to + - **overall**: Brief assessment — can be "No suggestions, evals look solid" if nothing to flag + +## Guidelines + +- **Be objective**: Base verdicts on evidence, not assumptions +- **Be specific**: Quote the exact text that supports your verdict +- **Be thorough**: Check both transcript and output files +- **Be consistent**: Apply the same standard to each expectation +- **Explain failures**: Make it clear why evidence was insufficient +- **No partial credit**: Each expectation is pass or fail, not partial diff --git a/.skills/skill-creator/assets/eval_review.html b/.skills/skill-creator/assets/eval_review.html new file mode 100644 index 00000000..938ff32a --- /dev/null +++ b/.skills/skill-creator/assets/eval_review.html @@ -0,0 +1,146 @@ + + + + + + Eval Set Review - __SKILL_NAME_PLACEHOLDER__ + + + + + + +

Eval Set Review: __SKILL_NAME_PLACEHOLDER__

+

Current description: __SKILL_DESCRIPTION_PLACEHOLDER__

+ +
+ + +
+ + + + + + + + + + +
QueryShould TriggerActions
+ +

+ + + + diff --git a/.skills/skill-creator/eval-viewer/generate_review.py b/.skills/skill-creator/eval-viewer/generate_review.py new file mode 100644 index 00000000..7fa59786 --- /dev/null +++ b/.skills/skill-creator/eval-viewer/generate_review.py @@ -0,0 +1,471 @@ +#!/usr/bin/env python3 +"""Generate and serve a review page for eval results. + +Reads the workspace directory, discovers runs (directories with outputs/), +embeds all output data into a self-contained HTML page, and serves it via +a tiny HTTP server. Feedback auto-saves to feedback.json in the workspace. + +Usage: + python generate_review.py [--port PORT] [--skill-name NAME] + python generate_review.py --previous-feedback /path/to/old/feedback.json + +No dependencies beyond the Python stdlib are required. +""" + +import argparse +import base64 +import json +import mimetypes +import os +import re +import signal +import subprocess +import sys +import time +import webbrowser +from functools import partial +from http.server import HTTPServer, BaseHTTPRequestHandler +from pathlib import Path + +# Files to exclude from output listings +METADATA_FILES = {"transcript.md", "user_notes.md", "metrics.json"} + +# Extensions we render as inline text +TEXT_EXTENSIONS = { + ".txt", ".md", ".json", ".csv", ".py", ".js", ".ts", ".tsx", ".jsx", + ".yaml", ".yml", ".xml", ".html", ".css", ".sh", ".rb", ".go", ".rs", + ".java", ".c", ".cpp", ".h", ".hpp", ".sql", ".r", ".toml", +} + +# Extensions we render as inline images +IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp"} + +# MIME type overrides for common types +MIME_OVERRIDES = { + ".svg": "image/svg+xml", + ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", +} + + +def get_mime_type(path: Path) -> str: + ext = path.suffix.lower() + if ext in MIME_OVERRIDES: + return MIME_OVERRIDES[ext] + mime, _ = mimetypes.guess_type(str(path)) + return mime or "application/octet-stream" + + +def find_runs(workspace: Path) -> list[dict]: + """Recursively find directories that contain an outputs/ subdirectory.""" + runs: list[dict] = [] + _find_runs_recursive(workspace, workspace, runs) + runs.sort(key=lambda r: (r.get("eval_id", float("inf")), r["id"])) + return runs + + +def _find_runs_recursive(root: Path, current: Path, runs: list[dict]) -> None: + if not current.is_dir(): + return + + outputs_dir = current / "outputs" + if outputs_dir.is_dir(): + run = build_run(root, current) + if run: + runs.append(run) + return + + skip = {"node_modules", ".git", "__pycache__", "skill", "inputs"} + for child in sorted(current.iterdir()): + if child.is_dir() and child.name not in skip: + _find_runs_recursive(root, child, runs) + + +def build_run(root: Path, run_dir: Path) -> dict | None: + """Build a run dict with prompt, outputs, and grading data.""" + prompt = "" + eval_id = None + + # Try eval_metadata.json + for candidate in [run_dir / "eval_metadata.json", run_dir.parent / "eval_metadata.json"]: + if candidate.exists(): + try: + metadata = json.loads(candidate.read_text()) + prompt = metadata.get("prompt", "") + eval_id = metadata.get("eval_id") + except (json.JSONDecodeError, OSError): + pass + if prompt: + break + + # Fall back to transcript.md + if not prompt: + for candidate in [run_dir / "transcript.md", run_dir / "outputs" / "transcript.md"]: + if candidate.exists(): + try: + text = candidate.read_text() + match = re.search(r"## Eval Prompt\n\n([\s\S]*?)(?=\n##|$)", text) + if match: + prompt = match.group(1).strip() + except OSError: + pass + if prompt: + break + + if not prompt: + prompt = "(No prompt found)" + + run_id = str(run_dir.relative_to(root)).replace("/", "-").replace("\\", "-") + + # Collect output files + outputs_dir = run_dir / "outputs" + output_files: list[dict] = [] + if outputs_dir.is_dir(): + for f in sorted(outputs_dir.iterdir()): + if f.is_file() and f.name not in METADATA_FILES: + output_files.append(embed_file(f)) + + # Load grading if present + grading = None + for candidate in [run_dir / "grading.json", run_dir.parent / "grading.json"]: + if candidate.exists(): + try: + grading = json.loads(candidate.read_text()) + except (json.JSONDecodeError, OSError): + pass + if grading: + break + + return { + "id": run_id, + "prompt": prompt, + "eval_id": eval_id, + "outputs": output_files, + "grading": grading, + } + + +def embed_file(path: Path) -> dict: + """Read a file and return an embedded representation.""" + ext = path.suffix.lower() + mime = get_mime_type(path) + + if ext in TEXT_EXTENSIONS: + try: + content = path.read_text(errors="replace") + except OSError: + content = "(Error reading file)" + return { + "name": path.name, + "type": "text", + "content": content, + } + elif ext in IMAGE_EXTENSIONS: + try: + raw = path.read_bytes() + b64 = base64.b64encode(raw).decode("ascii") + except OSError: + return {"name": path.name, "type": "error", "content": "(Error reading file)"} + return { + "name": path.name, + "type": "image", + "mime": mime, + "data_uri": f"data:{mime};base64,{b64}", + } + elif ext == ".pdf": + try: + raw = path.read_bytes() + b64 = base64.b64encode(raw).decode("ascii") + except OSError: + return {"name": path.name, "type": "error", "content": "(Error reading file)"} + return { + "name": path.name, + "type": "pdf", + "data_uri": f"data:{mime};base64,{b64}", + } + elif ext == ".xlsx": + try: + raw = path.read_bytes() + b64 = base64.b64encode(raw).decode("ascii") + except OSError: + return {"name": path.name, "type": "error", "content": "(Error reading file)"} + return { + "name": path.name, + "type": "xlsx", + "data_b64": b64, + } + else: + # Binary / unknown — base64 download link + try: + raw = path.read_bytes() + b64 = base64.b64encode(raw).decode("ascii") + except OSError: + return {"name": path.name, "type": "error", "content": "(Error reading file)"} + return { + "name": path.name, + "type": "binary", + "mime": mime, + "data_uri": f"data:{mime};base64,{b64}", + } + + +def load_previous_iteration(workspace: Path) -> dict[str, dict]: + """Load previous iteration's feedback and outputs. + + Returns a map of run_id -> {"feedback": str, "outputs": list[dict]}. + """ + result: dict[str, dict] = {} + + # Load feedback + feedback_map: dict[str, str] = {} + feedback_path = workspace / "feedback.json" + if feedback_path.exists(): + try: + data = json.loads(feedback_path.read_text()) + feedback_map = { + r["run_id"]: r["feedback"] + for r in data.get("reviews", []) + if r.get("feedback", "").strip() + } + except (json.JSONDecodeError, OSError, KeyError): + pass + + # Load runs (to get outputs) + prev_runs = find_runs(workspace) + for run in prev_runs: + result[run["id"]] = { + "feedback": feedback_map.get(run["id"], ""), + "outputs": run.get("outputs", []), + } + + # Also add feedback for run_ids that had feedback but no matching run + for run_id, fb in feedback_map.items(): + if run_id not in result: + result[run_id] = {"feedback": fb, "outputs": []} + + return result + + +def generate_html( + runs: list[dict], + skill_name: str, + previous: dict[str, dict] | None = None, + benchmark: dict | None = None, +) -> str: + """Generate the complete standalone HTML page with embedded data.""" + template_path = Path(__file__).parent / "viewer.html" + template = template_path.read_text() + + # Build previous_feedback and previous_outputs maps for the template + previous_feedback: dict[str, str] = {} + previous_outputs: dict[str, list[dict]] = {} + if previous: + for run_id, data in previous.items(): + if data.get("feedback"): + previous_feedback[run_id] = data["feedback"] + if data.get("outputs"): + previous_outputs[run_id] = data["outputs"] + + embedded = { + "skill_name": skill_name, + "runs": runs, + "previous_feedback": previous_feedback, + "previous_outputs": previous_outputs, + } + if benchmark: + embedded["benchmark"] = benchmark + + data_json = json.dumps(embedded) + + return template.replace("/*__EMBEDDED_DATA__*/", f"const EMBEDDED_DATA = {data_json};") + + +# --------------------------------------------------------------------------- +# HTTP server (stdlib only, zero dependencies) +# --------------------------------------------------------------------------- + +def _kill_port(port: int) -> None: + """Kill any process listening on the given port.""" + try: + result = subprocess.run( + ["lsof", "-ti", f":{port}"], + capture_output=True, text=True, timeout=5, + ) + for pid_str in result.stdout.strip().split("\n"): + if pid_str.strip(): + try: + os.kill(int(pid_str.strip()), signal.SIGTERM) + except (ProcessLookupError, ValueError): + pass + if result.stdout.strip(): + time.sleep(0.5) + except subprocess.TimeoutExpired: + pass + except FileNotFoundError: + print("Note: lsof not found, cannot check if port is in use", file=sys.stderr) + +class ReviewHandler(BaseHTTPRequestHandler): + """Serves the review HTML and handles feedback saves. + + Regenerates the HTML on each page load so that refreshing the browser + picks up new eval outputs without restarting the server. + """ + + def __init__( + self, + workspace: Path, + skill_name: str, + feedback_path: Path, + previous: dict[str, dict], + benchmark_path: Path | None, + *args, + **kwargs, + ): + self.workspace = workspace + self.skill_name = skill_name + self.feedback_path = feedback_path + self.previous = previous + self.benchmark_path = benchmark_path + super().__init__(*args, **kwargs) + + def do_GET(self) -> None: + if self.path == "/" or self.path == "/index.html": + # Regenerate HTML on each request (re-scans workspace for new outputs) + runs = find_runs(self.workspace) + benchmark = None + if self.benchmark_path and self.benchmark_path.exists(): + try: + benchmark = json.loads(self.benchmark_path.read_text()) + except (json.JSONDecodeError, OSError): + pass + html = generate_html(runs, self.skill_name, self.previous, benchmark) + content = html.encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Content-Length", str(len(content))) + self.end_headers() + self.wfile.write(content) + elif self.path == "/api/feedback": + data = b"{}" + if self.feedback_path.exists(): + data = self.feedback_path.read_bytes() + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(data))) + self.end_headers() + self.wfile.write(data) + else: + self.send_error(404) + + def do_POST(self) -> None: + if self.path == "/api/feedback": + length = int(self.headers.get("Content-Length", 0)) + body = self.rfile.read(length) + try: + data = json.loads(body) + if not isinstance(data, dict) or "reviews" not in data: + raise ValueError("Expected JSON object with 'reviews' key") + self.feedback_path.write_text(json.dumps(data, indent=2) + "\n") + resp = b'{"ok":true}' + self.send_response(200) + except (json.JSONDecodeError, OSError, ValueError) as e: + resp = json.dumps({"error": str(e)}).encode() + self.send_response(500) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(resp))) + self.end_headers() + self.wfile.write(resp) + else: + self.send_error(404) + + def log_message(self, format: str, *args: object) -> None: + # Suppress request logging to keep terminal clean + pass + + +def main() -> None: + parser = argparse.ArgumentParser(description="Generate and serve eval review") + parser.add_argument("workspace", type=Path, help="Path to workspace directory") + parser.add_argument("--port", "-p", type=int, default=3117, help="Server port (default: 3117)") + parser.add_argument("--skill-name", "-n", type=str, default=None, help="Skill name for header") + parser.add_argument( + "--previous-workspace", type=Path, default=None, + help="Path to previous iteration's workspace (shows old outputs and feedback as context)", + ) + parser.add_argument( + "--benchmark", type=Path, default=None, + help="Path to benchmark.json to show in the Benchmark tab", + ) + parser.add_argument( + "--static", "-s", type=Path, default=None, + help="Write standalone HTML to this path instead of starting a server", + ) + args = parser.parse_args() + + workspace = args.workspace.resolve() + if not workspace.is_dir(): + print(f"Error: {workspace} is not a directory", file=sys.stderr) + sys.exit(1) + + runs = find_runs(workspace) + if not runs: + print(f"No runs found in {workspace}", file=sys.stderr) + sys.exit(1) + + skill_name = args.skill_name or workspace.name.replace("-workspace", "") + feedback_path = workspace / "feedback.json" + + previous: dict[str, dict] = {} + if args.previous_workspace: + previous = load_previous_iteration(args.previous_workspace.resolve()) + + benchmark_path = args.benchmark.resolve() if args.benchmark else None + benchmark = None + if benchmark_path and benchmark_path.exists(): + try: + benchmark = json.loads(benchmark_path.read_text()) + except (json.JSONDecodeError, OSError): + pass + + if args.static: + html = generate_html(runs, skill_name, previous, benchmark) + args.static.parent.mkdir(parents=True, exist_ok=True) + args.static.write_text(html) + print(f"\n Static viewer written to: {args.static}\n") + sys.exit(0) + + # Kill any existing process on the target port + port = args.port + _kill_port(port) + handler = partial(ReviewHandler, workspace, skill_name, feedback_path, previous, benchmark_path) + try: + server = HTTPServer(("127.0.0.1", port), handler) + except OSError: + # Port still in use after kill attempt — find a free one + server = HTTPServer(("127.0.0.1", 0), handler) + port = server.server_address[1] + + url = f"http://localhost:{port}" + print(f"\n Eval Viewer") + print(f" ─────────────────────────────────") + print(f" URL: {url}") + print(f" Workspace: {workspace}") + print(f" Feedback: {feedback_path}") + if previous: + print(f" Previous: {args.previous_workspace} ({len(previous)} runs)") + if benchmark_path: + print(f" Benchmark: {benchmark_path}") + print(f"\n Press Ctrl+C to stop.\n") + + webbrowser.open(url) + + try: + server.serve_forever() + except KeyboardInterrupt: + print("\nStopped.") + server.server_close() + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/eval-viewer/viewer.html b/.skills/skill-creator/eval-viewer/viewer.html new file mode 100644 index 00000000..6d8e9634 --- /dev/null +++ b/.skills/skill-creator/eval-viewer/viewer.html @@ -0,0 +1,1325 @@ + + + + + + Eval Review + + + + + + + +
+
+
+

Eval Review:

+
Review each output and leave feedback below. Navigate with arrow keys or buttons. When done, copy feedback and paste into Claude Code.
+
+
+
+ + + + + +
+
+ +
+
Prompt
+
+
+
+
+ + +
+
Output
+
+
No output files found
+
+
+ + + + + + + + +
+
Your Feedback
+
+ + + +
+
+
+ + +
+ + +
+
+
No benchmark data available. Run a benchmark to see quantitative results here.
+
+
+
+ + +
+
+

Review Complete

+

Your feedback has been saved. Go back to your Claude Code session and tell Claude you're done reviewing.

+
+ +
+
+
+ + +
+ + + + diff --git a/.skills/skill-creator/references/schemas.md b/.skills/skill-creator/references/schemas.md new file mode 100644 index 00000000..b6eeaa2d --- /dev/null +++ b/.skills/skill-creator/references/schemas.md @@ -0,0 +1,430 @@ +# JSON Schemas + +This document defines the JSON schemas used by skill-creator. + +--- + +## evals.json + +Defines the evals for a skill. Located at `evals/evals.json` within the skill directory. + +```json +{ + "skill_name": "example-skill", + "evals": [ + { + "id": 1, + "prompt": "User's example prompt", + "expected_output": "Description of expected result", + "files": ["evals/files/sample1.pdf"], + "expectations": [ + "The output includes X", + "The skill used script Y" + ] + } + ] +} +``` + +**Fields:** +- `skill_name`: Name matching the skill's frontmatter +- `evals[].id`: Unique integer identifier +- `evals[].prompt`: The task to execute +- `evals[].expected_output`: Human-readable description of success +- `evals[].files`: Optional list of input file paths (relative to skill root) +- `evals[].expectations`: List of verifiable statements + +--- + +## history.json + +Tracks version progression in Improve mode. Located at workspace root. + +```json +{ + "started_at": "2026-01-15T10:30:00Z", + "skill_name": "pdf", + "current_best": "v2", + "iterations": [ + { + "version": "v0", + "parent": null, + "expectation_pass_rate": 0.65, + "grading_result": "baseline", + "is_current_best": false + }, + { + "version": "v1", + "parent": "v0", + "expectation_pass_rate": 0.75, + "grading_result": "won", + "is_current_best": false + }, + { + "version": "v2", + "parent": "v1", + "expectation_pass_rate": 0.85, + "grading_result": "won", + "is_current_best": true + } + ] +} +``` + +**Fields:** +- `started_at`: ISO timestamp of when improvement started +- `skill_name`: Name of the skill being improved +- `current_best`: Version identifier of the best performer +- `iterations[].version`: Version identifier (v0, v1, ...) +- `iterations[].parent`: Parent version this was derived from +- `iterations[].expectation_pass_rate`: Pass rate from grading +- `iterations[].grading_result`: "baseline", "won", "lost", or "tie" +- `iterations[].is_current_best`: Whether this is the current best version + +--- + +## grading.json + +Output from the grader agent. Located at `/grading.json`. + +```json +{ + "expectations": [ + { + "text": "The output includes the name 'John Smith'", + "passed": true, + "evidence": "Found in transcript Step 3: 'Extracted names: John Smith, Sarah Johnson'" + }, + { + "text": "The spreadsheet has a SUM formula in cell B10", + "passed": false, + "evidence": "No spreadsheet was created. The output was a text file." + } + ], + "summary": { + "passed": 2, + "failed": 1, + "total": 3, + "pass_rate": 0.67 + }, + "execution_metrics": { + "tool_calls": { + "Read": 5, + "Write": 2, + "Bash": 8 + }, + "total_tool_calls": 15, + "total_steps": 6, + "errors_encountered": 0, + "output_chars": 12450, + "transcript_chars": 3200 + }, + "timing": { + "executor_duration_seconds": 165.0, + "grader_duration_seconds": 26.0, + "total_duration_seconds": 191.0 + }, + "claims": [ + { + "claim": "The form has 12 fillable fields", + "type": "factual", + "verified": true, + "evidence": "Counted 12 fields in field_info.json" + } + ], + "user_notes_summary": { + "uncertainties": ["Used 2023 data, may be stale"], + "needs_review": [], + "workarounds": ["Fell back to text overlay for non-fillable fields"] + }, + "eval_feedback": { + "suggestions": [ + { + "assertion": "The output includes the name 'John Smith'", + "reason": "A hallucinated document that mentions the name would also pass" + } + ], + "overall": "Assertions check presence but not correctness." + } +} +``` + +**Fields:** +- `expectations[]`: Graded expectations with evidence +- `summary`: Aggregate pass/fail counts +- `execution_metrics`: Tool usage and output size (from executor's metrics.json) +- `timing`: Wall clock timing (from timing.json) +- `claims`: Extracted and verified claims from the output +- `user_notes_summary`: Issues flagged by the executor +- `eval_feedback`: (optional) Improvement suggestions for the evals, only present when the grader identifies issues worth raising + +--- + +## metrics.json + +Output from the executor agent. Located at `/outputs/metrics.json`. + +```json +{ + "tool_calls": { + "Read": 5, + "Write": 2, + "Bash": 8, + "Edit": 1, + "Glob": 2, + "Grep": 0 + }, + "total_tool_calls": 18, + "total_steps": 6, + "files_created": ["filled_form.pdf", "field_values.json"], + "errors_encountered": 0, + "output_chars": 12450, + "transcript_chars": 3200 +} +``` + +**Fields:** +- `tool_calls`: Count per tool type +- `total_tool_calls`: Sum of all tool calls +- `total_steps`: Number of major execution steps +- `files_created`: List of output files created +- `errors_encountered`: Number of errors during execution +- `output_chars`: Total character count of output files +- `transcript_chars`: Character count of transcript + +--- + +## timing.json + +Wall clock timing for a run. Located at `/timing.json`. + +**How to capture:** When a subagent task completes, the task notification includes `total_tokens` and `duration_ms`. Save these immediately — they are not persisted anywhere else and cannot be recovered after the fact. + +```json +{ + "total_tokens": 84852, + "duration_ms": 23332, + "total_duration_seconds": 23.3, + "executor_start": "2026-01-15T10:30:00Z", + "executor_end": "2026-01-15T10:32:45Z", + "executor_duration_seconds": 165.0, + "grader_start": "2026-01-15T10:32:46Z", + "grader_end": "2026-01-15T10:33:12Z", + "grader_duration_seconds": 26.0 +} +``` + +--- + +## benchmark.json + +Output from Benchmark mode. Located at `benchmarks//benchmark.json`. + +```json +{ + "metadata": { + "skill_name": "pdf", + "skill_path": "/path/to/pdf", + "executor_model": "claude-sonnet-4-20250514", + "analyzer_model": "most-capable-model", + "timestamp": "2026-01-15T10:30:00Z", + "evals_run": [1, 2, 3], + "runs_per_configuration": 3 + }, + + "runs": [ + { + "eval_id": 1, + "eval_name": "Ocean", + "configuration": "with_skill", + "run_number": 1, + "result": { + "pass_rate": 0.85, + "passed": 6, + "failed": 1, + "total": 7, + "time_seconds": 42.5, + "tokens": 3800, + "tool_calls": 18, + "errors": 0 + }, + "expectations": [ + {"text": "...", "passed": true, "evidence": "..."} + ], + "notes": [ + "Used 2023 data, may be stale", + "Fell back to text overlay for non-fillable fields" + ] + } + ], + + "run_summary": { + "with_skill": { + "pass_rate": {"mean": 0.85, "stddev": 0.05, "min": 0.80, "max": 0.90}, + "time_seconds": {"mean": 45.0, "stddev": 12.0, "min": 32.0, "max": 58.0}, + "tokens": {"mean": 3800, "stddev": 400, "min": 3200, "max": 4100} + }, + "without_skill": { + "pass_rate": {"mean": 0.35, "stddev": 0.08, "min": 0.28, "max": 0.45}, + "time_seconds": {"mean": 32.0, "stddev": 8.0, "min": 24.0, "max": 42.0}, + "tokens": {"mean": 2100, "stddev": 300, "min": 1800, "max": 2500} + }, + "delta": { + "pass_rate": "+0.50", + "time_seconds": "+13.0", + "tokens": "+1700" + } + }, + + "notes": [ + "Assertion 'Output is a PDF file' passes 100% in both configurations - may not differentiate skill value", + "Eval 3 shows high variance (50% ± 40%) - may be flaky or model-dependent", + "Without-skill runs consistently fail on table extraction expectations", + "Skill adds 13s average execution time but improves pass rate by 50%" + ] +} +``` + +**Fields:** +- `metadata`: Information about the benchmark run + - `skill_name`: Name of the skill + - `timestamp`: When the benchmark was run + - `evals_run`: List of eval names or IDs + - `runs_per_configuration`: Number of runs per config (e.g. 3) +- `runs[]`: Individual run results + - `eval_id`: Numeric eval identifier + - `eval_name`: Human-readable eval name (used as section header in the viewer) + - `configuration`: Must be `"with_skill"` or `"without_skill"` (the viewer uses this exact string for grouping and color coding) + - `run_number`: Integer run number (1, 2, 3...) + - `result`: Nested object with `pass_rate`, `passed`, `total`, `time_seconds`, `tokens`, `errors` +- `run_summary`: Statistical aggregates per configuration + - `with_skill` / `without_skill`: Each contains `pass_rate`, `time_seconds`, `tokens` objects with `mean` and `stddev` fields + - `delta`: Difference strings like `"+0.50"`, `"+13.0"`, `"+1700"` +- `notes`: Freeform observations from the analyzer + +**Important:** The viewer reads these field names exactly. Using `config` instead of `configuration`, or putting `pass_rate` at the top level of a run instead of nested under `result`, will cause the viewer to show empty/zero values. Always reference this schema when generating benchmark.json manually. + +--- + +## comparison.json + +Output from blind comparator. Located at `/comparison-N.json`. + +```json +{ + "winner": "A", + "reasoning": "Output A provides a complete solution with proper formatting and all required fields. Output B is missing the date field and has formatting inconsistencies.", + "rubric": { + "A": { + "content": { + "correctness": 5, + "completeness": 5, + "accuracy": 4 + }, + "structure": { + "organization": 4, + "formatting": 5, + "usability": 4 + }, + "content_score": 4.7, + "structure_score": 4.3, + "overall_score": 9.0 + }, + "B": { + "content": { + "correctness": 3, + "completeness": 2, + "accuracy": 3 + }, + "structure": { + "organization": 3, + "formatting": 2, + "usability": 3 + }, + "content_score": 2.7, + "structure_score": 2.7, + "overall_score": 5.4 + } + }, + "output_quality": { + "A": { + "score": 9, + "strengths": ["Complete solution", "Well-formatted", "All fields present"], + "weaknesses": ["Minor style inconsistency in header"] + }, + "B": { + "score": 5, + "strengths": ["Readable output", "Correct basic structure"], + "weaknesses": ["Missing date field", "Formatting inconsistencies", "Partial data extraction"] + } + }, + "expectation_results": { + "A": { + "passed": 4, + "total": 5, + "pass_rate": 0.80, + "details": [ + {"text": "Output includes name", "passed": true} + ] + }, + "B": { + "passed": 3, + "total": 5, + "pass_rate": 0.60, + "details": [ + {"text": "Output includes name", "passed": true} + ] + } + } +} +``` + +--- + +## analysis.json + +Output from post-hoc analyzer. Located at `/analysis.json`. + +```json +{ + "comparison_summary": { + "winner": "A", + "winner_skill": "path/to/winner/skill", + "loser_skill": "path/to/loser/skill", + "comparator_reasoning": "Brief summary of why comparator chose winner" + }, + "winner_strengths": [ + "Clear step-by-step instructions for handling multi-page documents", + "Included validation script that caught formatting errors" + ], + "loser_weaknesses": [ + "Vague instruction 'process the document appropriately' led to inconsistent behavior", + "No script for validation, agent had to improvise" + ], + "instruction_following": { + "winner": { + "score": 9, + "issues": ["Minor: skipped optional logging step"] + }, + "loser": { + "score": 6, + "issues": [ + "Did not use the skill's formatting template", + "Invented own approach instead of following step 3" + ] + } + }, + "improvement_suggestions": [ + { + "priority": "high", + "category": "instructions", + "suggestion": "Replace 'process the document appropriately' with explicit steps", + "expected_impact": "Would eliminate ambiguity that caused inconsistent behavior" + } + ], + "transcript_insights": { + "winner_execution_pattern": "Read skill -> Followed 5-step process -> Used validation script", + "loser_execution_pattern": "Read skill -> Unclear on approach -> Tried 3 different methods" + } +} +``` diff --git a/.skills/skill-creator/scripts/__init__.py b/.skills/skill-creator/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.skills/skill-creator/scripts/aggregate_benchmark.py b/.skills/skill-creator/scripts/aggregate_benchmark.py new file mode 100644 index 00000000..3e66e8c1 --- /dev/null +++ b/.skills/skill-creator/scripts/aggregate_benchmark.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python3 +""" +Aggregate individual run results into benchmark summary statistics. + +Reads grading.json files from run directories and produces: +- run_summary with mean, stddev, min, max for each metric +- delta between with_skill and without_skill configurations + +Usage: + python aggregate_benchmark.py + +Example: + python aggregate_benchmark.py benchmarks/2026-01-15T10-30-00/ + +The script supports two directory layouts: + + Workspace layout (from skill-creator iterations): + / + └── eval-N/ + ├── with_skill/ + │ ├── run-1/grading.json + │ └── run-2/grading.json + └── without_skill/ + ├── run-1/grading.json + └── run-2/grading.json + + Legacy layout (with runs/ subdirectory): + / + └── runs/ + └── eval-N/ + ├── with_skill/ + │ └── run-1/grading.json + └── without_skill/ + └── run-1/grading.json +""" + +import argparse +import json +import math +import sys +from datetime import datetime, timezone +from pathlib import Path + + +def calculate_stats(values: list[float]) -> dict: + """Calculate mean, stddev, min, max for a list of values.""" + if not values: + return {"mean": 0.0, "stddev": 0.0, "min": 0.0, "max": 0.0} + + n = len(values) + mean = sum(values) / n + + if n > 1: + variance = sum((x - mean) ** 2 for x in values) / (n - 1) + stddev = math.sqrt(variance) + else: + stddev = 0.0 + + return { + "mean": round(mean, 4), + "stddev": round(stddev, 4), + "min": round(min(values), 4), + "max": round(max(values), 4) + } + + +def load_run_results(benchmark_dir: Path) -> dict: + """ + Load all run results from a benchmark directory. + + Returns dict keyed by config name (e.g. "with_skill"/"without_skill", + or "new_skill"/"old_skill"), each containing a list of run results. + """ + # Support both layouts: eval dirs directly under benchmark_dir, or under runs/ + runs_dir = benchmark_dir / "runs" + if runs_dir.exists(): + search_dir = runs_dir + elif list(benchmark_dir.glob("eval-*")): + search_dir = benchmark_dir + else: + print(f"No eval directories found in {benchmark_dir} or {benchmark_dir / 'runs'}") + return {} + + results: dict[str, list] = {} + + for eval_idx, eval_dir in enumerate(sorted(search_dir.glob("eval-*"))): + metadata_path = eval_dir / "eval_metadata.json" + if metadata_path.exists(): + try: + with open(metadata_path) as mf: + eval_id = json.load(mf).get("eval_id", eval_idx) + except (json.JSONDecodeError, OSError): + eval_id = eval_idx + else: + try: + eval_id = int(eval_dir.name.split("-")[1]) + except ValueError: + eval_id = eval_idx + + # Discover config directories dynamically rather than hardcoding names + for config_dir in sorted(eval_dir.iterdir()): + if not config_dir.is_dir(): + continue + # Skip non-config directories (inputs, outputs, etc.) + if not list(config_dir.glob("run-*")): + continue + config = config_dir.name + if config not in results: + results[config] = [] + + for run_dir in sorted(config_dir.glob("run-*")): + run_number = int(run_dir.name.split("-")[1]) + grading_file = run_dir / "grading.json" + + if not grading_file.exists(): + print(f"Warning: grading.json not found in {run_dir}") + continue + + try: + with open(grading_file) as f: + grading = json.load(f) + except json.JSONDecodeError as e: + print(f"Warning: Invalid JSON in {grading_file}: {e}") + continue + + # Extract metrics + result = { + "eval_id": eval_id, + "run_number": run_number, + "pass_rate": grading.get("summary", {}).get("pass_rate", 0.0), + "passed": grading.get("summary", {}).get("passed", 0), + "failed": grading.get("summary", {}).get("failed", 0), + "total": grading.get("summary", {}).get("total", 0), + } + + # Extract timing — check grading.json first, then sibling timing.json + timing = grading.get("timing", {}) + result["time_seconds"] = timing.get("total_duration_seconds", 0.0) + timing_file = run_dir / "timing.json" + if result["time_seconds"] == 0.0 and timing_file.exists(): + try: + with open(timing_file) as tf: + timing_data = json.load(tf) + result["time_seconds"] = timing_data.get("total_duration_seconds", 0.0) + result["tokens"] = timing_data.get("total_tokens", 0) + except json.JSONDecodeError: + pass + + # Extract metrics if available + metrics = grading.get("execution_metrics", {}) + result["tool_calls"] = metrics.get("total_tool_calls", 0) + if not result.get("tokens"): + result["tokens"] = metrics.get("output_chars", 0) + result["errors"] = metrics.get("errors_encountered", 0) + + # Extract expectations — viewer requires fields: text, passed, evidence + raw_expectations = grading.get("expectations", []) + for exp in raw_expectations: + if "text" not in exp or "passed" not in exp: + print(f"Warning: expectation in {grading_file} missing required fields (text, passed, evidence): {exp}") + result["expectations"] = raw_expectations + + # Extract notes from user_notes_summary + notes_summary = grading.get("user_notes_summary", {}) + notes = [] + notes.extend(notes_summary.get("uncertainties", [])) + notes.extend(notes_summary.get("needs_review", [])) + notes.extend(notes_summary.get("workarounds", [])) + result["notes"] = notes + + results[config].append(result) + + return results + + +def aggregate_results(results: dict) -> dict: + """ + Aggregate run results into summary statistics. + + Returns run_summary with stats for each configuration and delta. + """ + run_summary = {} + configs = list(results.keys()) + + for config in configs: + runs = results.get(config, []) + + if not runs: + run_summary[config] = { + "pass_rate": {"mean": 0.0, "stddev": 0.0, "min": 0.0, "max": 0.0}, + "time_seconds": {"mean": 0.0, "stddev": 0.0, "min": 0.0, "max": 0.0}, + "tokens": {"mean": 0, "stddev": 0, "min": 0, "max": 0} + } + continue + + pass_rates = [r["pass_rate"] for r in runs] + times = [r["time_seconds"] for r in runs] + tokens = [r.get("tokens", 0) for r in runs] + + run_summary[config] = { + "pass_rate": calculate_stats(pass_rates), + "time_seconds": calculate_stats(times), + "tokens": calculate_stats(tokens) + } + + # Calculate delta between the first two configs (if two exist) + if len(configs) >= 2: + primary = run_summary.get(configs[0], {}) + baseline = run_summary.get(configs[1], {}) + else: + primary = run_summary.get(configs[0], {}) if configs else {} + baseline = {} + + delta_pass_rate = primary.get("pass_rate", {}).get("mean", 0) - baseline.get("pass_rate", {}).get("mean", 0) + delta_time = primary.get("time_seconds", {}).get("mean", 0) - baseline.get("time_seconds", {}).get("mean", 0) + delta_tokens = primary.get("tokens", {}).get("mean", 0) - baseline.get("tokens", {}).get("mean", 0) + + run_summary["delta"] = { + "pass_rate": f"{delta_pass_rate:+.2f}", + "time_seconds": f"{delta_time:+.1f}", + "tokens": f"{delta_tokens:+.0f}" + } + + return run_summary + + +def generate_benchmark(benchmark_dir: Path, skill_name: str = "", skill_path: str = "") -> dict: + """ + Generate complete benchmark.json from run results. + """ + results = load_run_results(benchmark_dir) + run_summary = aggregate_results(results) + + # Build runs array for benchmark.json + runs = [] + for config in results: + for result in results[config]: + runs.append({ + "eval_id": result["eval_id"], + "configuration": config, + "run_number": result["run_number"], + "result": { + "pass_rate": result["pass_rate"], + "passed": result["passed"], + "failed": result["failed"], + "total": result["total"], + "time_seconds": result["time_seconds"], + "tokens": result.get("tokens", 0), + "tool_calls": result.get("tool_calls", 0), + "errors": result.get("errors", 0) + }, + "expectations": result["expectations"], + "notes": result["notes"] + }) + + # Determine eval IDs from results + eval_ids = sorted(set( + r["eval_id"] + for config in results.values() + for r in config + )) + + benchmark = { + "metadata": { + "skill_name": skill_name or "", + "skill_path": skill_path or "", + "executor_model": "", + "analyzer_model": "", + "timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "evals_run": eval_ids, + "runs_per_configuration": 3 + }, + "runs": runs, + "run_summary": run_summary, + "notes": [] # To be filled by analyzer + } + + return benchmark + + +def generate_markdown(benchmark: dict) -> str: + """Generate human-readable benchmark.md from benchmark data.""" + metadata = benchmark["metadata"] + run_summary = benchmark["run_summary"] + + # Determine config names (excluding "delta") + configs = [k for k in run_summary if k != "delta"] + config_a = configs[0] if len(configs) >= 1 else "config_a" + config_b = configs[1] if len(configs) >= 2 else "config_b" + label_a = config_a.replace("_", " ").title() + label_b = config_b.replace("_", " ").title() + + lines = [ + f"# Skill Benchmark: {metadata['skill_name']}", + "", + f"**Model**: {metadata['executor_model']}", + f"**Date**: {metadata['timestamp']}", + f"**Evals**: {', '.join(map(str, metadata['evals_run']))} ({metadata['runs_per_configuration']} runs each per configuration)", + "", + "## Summary", + "", + f"| Metric | {label_a} | {label_b} | Delta |", + "|--------|------------|---------------|-------|", + ] + + a_summary = run_summary.get(config_a, {}) + b_summary = run_summary.get(config_b, {}) + delta = run_summary.get("delta", {}) + + # Format pass rate + a_pr = a_summary.get("pass_rate", {}) + b_pr = b_summary.get("pass_rate", {}) + lines.append(f"| Pass Rate | {a_pr.get('mean', 0)*100:.0f}% ± {a_pr.get('stddev', 0)*100:.0f}% | {b_pr.get('mean', 0)*100:.0f}% ± {b_pr.get('stddev', 0)*100:.0f}% | {delta.get('pass_rate', '—')} |") + + # Format time + a_time = a_summary.get("time_seconds", {}) + b_time = b_summary.get("time_seconds", {}) + lines.append(f"| Time | {a_time.get('mean', 0):.1f}s ± {a_time.get('stddev', 0):.1f}s | {b_time.get('mean', 0):.1f}s ± {b_time.get('stddev', 0):.1f}s | {delta.get('time_seconds', '—')}s |") + + # Format tokens + a_tokens = a_summary.get("tokens", {}) + b_tokens = b_summary.get("tokens", {}) + lines.append(f"| Tokens | {a_tokens.get('mean', 0):.0f} ± {a_tokens.get('stddev', 0):.0f} | {b_tokens.get('mean', 0):.0f} ± {b_tokens.get('stddev', 0):.0f} | {delta.get('tokens', '—')} |") + + # Notes section + if benchmark.get("notes"): + lines.extend([ + "", + "## Notes", + "" + ]) + for note in benchmark["notes"]: + lines.append(f"- {note}") + + return "\n".join(lines) + + +def main(): + parser = argparse.ArgumentParser( + description="Aggregate benchmark run results into summary statistics" + ) + parser.add_argument( + "benchmark_dir", + type=Path, + help="Path to the benchmark directory" + ) + parser.add_argument( + "--skill-name", + default="", + help="Name of the skill being benchmarked" + ) + parser.add_argument( + "--skill-path", + default="", + help="Path to the skill being benchmarked" + ) + parser.add_argument( + "--output", "-o", + type=Path, + help="Output path for benchmark.json (default: /benchmark.json)" + ) + + args = parser.parse_args() + + if not args.benchmark_dir.exists(): + print(f"Directory not found: {args.benchmark_dir}") + sys.exit(1) + + # Generate benchmark + benchmark = generate_benchmark(args.benchmark_dir, args.skill_name, args.skill_path) + + # Determine output paths + output_json = args.output or (args.benchmark_dir / "benchmark.json") + output_md = output_json.with_suffix(".md") + + # Write benchmark.json + with open(output_json, "w") as f: + json.dump(benchmark, f, indent=2) + print(f"Generated: {output_json}") + + # Write benchmark.md + markdown = generate_markdown(benchmark) + with open(output_md, "w") as f: + f.write(markdown) + print(f"Generated: {output_md}") + + # Print summary + run_summary = benchmark["run_summary"] + configs = [k for k in run_summary if k != "delta"] + delta = run_summary.get("delta", {}) + + print(f"\nSummary:") + for config in configs: + pr = run_summary[config]["pass_rate"]["mean"] + label = config.replace("_", " ").title() + print(f" {label}: {pr*100:.1f}% pass rate") + print(f" Delta: {delta.get('pass_rate', '—')}") + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/generate_report.py b/.skills/skill-creator/scripts/generate_report.py new file mode 100644 index 00000000..959e30a0 --- /dev/null +++ b/.skills/skill-creator/scripts/generate_report.py @@ -0,0 +1,326 @@ +#!/usr/bin/env python3 +"""Generate an HTML report from run_loop.py output. + +Takes the JSON output from run_loop.py and generates a visual HTML report +showing each description attempt with check/x for each test case. +Distinguishes between train and test queries. +""" + +import argparse +import html +import json +import sys +from pathlib import Path + + +def generate_html(data: dict, auto_refresh: bool = False, skill_name: str = "") -> str: + """Generate HTML report from loop output data. If auto_refresh is True, adds a meta refresh tag.""" + history = data.get("history", []) + holdout = data.get("holdout", 0) + title_prefix = html.escape(skill_name + " \u2014 ") if skill_name else "" + + # Get all unique queries from train and test sets, with should_trigger info + train_queries: list[dict] = [] + test_queries: list[dict] = [] + if history: + for r in history[0].get("train_results", history[0].get("results", [])): + train_queries.append({"query": r["query"], "should_trigger": r.get("should_trigger", True)}) + if history[0].get("test_results"): + for r in history[0].get("test_results", []): + test_queries.append({"query": r["query"], "should_trigger": r.get("should_trigger", True)}) + + refresh_tag = ' \n' if auto_refresh else "" + + html_parts = [""" + + + +""" + refresh_tag + """ """ + title_prefix + """Skill Description Optimization + + + + + + +

""" + title_prefix + """Skill Description Optimization

+
+ Optimizing your skill's description. This page updates automatically as Claude tests different versions of your skill's description. Each row is an iteration — a new description attempt. The columns show test queries: green checkmarks mean the skill triggered correctly (or correctly didn't trigger), red crosses mean it got it wrong. The "Train" score shows performance on queries used to improve the description; the "Test" score shows performance on held-out queries the optimizer hasn't seen. When it's done, Claude will apply the best-performing description to your skill. +
+"""] + + # Summary section + best_test_score = data.get('best_test_score') + best_train_score = data.get('best_train_score') + html_parts.append(f""" +
+

Original: {html.escape(data.get('original_description', 'N/A'))}

+

Best: {html.escape(data.get('best_description', 'N/A'))}

+

Best Score: {data.get('best_score', 'N/A')} {'(test)' if best_test_score else '(train)'}

+

Iterations: {data.get('iterations_run', 0)} | Train: {data.get('train_size', '?')} | Test: {data.get('test_size', '?')}

+
+""") + + # Legend + html_parts.append(""" +
+ Query columns: + Should trigger + Should NOT trigger + Train + Test +
+""") + + # Table header + html_parts.append(""" +
+ + + + + + + +""") + + # Add column headers for train queries + for qinfo in train_queries: + polarity = "positive-col" if qinfo["should_trigger"] else "negative-col" + html_parts.append(f' \n') + + # Add column headers for test queries (different color) + for qinfo in test_queries: + polarity = "positive-col" if qinfo["should_trigger"] else "negative-col" + html_parts.append(f' \n') + + html_parts.append(""" + + +""") + + # Find best iteration for highlighting + if test_queries: + best_iter = max(history, key=lambda h: h.get("test_passed") or 0).get("iteration") + else: + best_iter = max(history, key=lambda h: h.get("train_passed", h.get("passed", 0))).get("iteration") + + # Add rows for each iteration + for h in history: + iteration = h.get("iteration", "?") + train_passed = h.get("train_passed", h.get("passed", 0)) + train_total = h.get("train_total", h.get("total", 0)) + test_passed = h.get("test_passed") + test_total = h.get("test_total") + description = h.get("description", "") + train_results = h.get("train_results", h.get("results", [])) + test_results = h.get("test_results", []) + + # Create lookups for results by query + train_by_query = {r["query"]: r for r in train_results} + test_by_query = {r["query"]: r for r in test_results} if test_results else {} + + # Compute aggregate correct/total runs across all retries + def aggregate_runs(results: list[dict]) -> tuple[int, int]: + correct = 0 + total = 0 + for r in results: + runs = r.get("runs", 0) + triggers = r.get("triggers", 0) + total += runs + if r.get("should_trigger", True): + correct += triggers + else: + correct += runs - triggers + return correct, total + + train_correct, train_runs = aggregate_runs(train_results) + test_correct, test_runs = aggregate_runs(test_results) + + # Determine score classes + def score_class(correct: int, total: int) -> str: + if total > 0: + ratio = correct / total + if ratio >= 0.8: + return "score-good" + elif ratio >= 0.5: + return "score-ok" + return "score-bad" + + train_class = score_class(train_correct, train_runs) + test_class = score_class(test_correct, test_runs) + + row_class = "best-row" if iteration == best_iter else "" + + html_parts.append(f""" + + + + +""") + + # Add result for each train query + for qinfo in train_queries: + r = train_by_query.get(qinfo["query"], {}) + did_pass = r.get("pass", False) + triggers = r.get("triggers", 0) + runs = r.get("runs", 0) + + icon = "✓" if did_pass else "✗" + css_class = "pass" if did_pass else "fail" + + html_parts.append(f' \n') + + # Add result for each test query (with different background) + for qinfo in test_queries: + r = test_by_query.get(qinfo["query"], {}) + did_pass = r.get("pass", False) + triggers = r.get("triggers", 0) + runs = r.get("runs", 0) + + icon = "✓" if did_pass else "✗" + css_class = "pass" if did_pass else "fail" + + html_parts.append(f' \n') + + html_parts.append(" \n") + + html_parts.append(""" +
IterTrainTestDescription{html.escape(qinfo["query"])}{html.escape(qinfo["query"])}
{iteration}{train_correct}/{train_runs}{test_correct}/{test_runs}{html.escape(description)}{icon}{triggers}/{runs}{icon}{triggers}/{runs}
+
+""") + + html_parts.append(""" + + +""") + + return "".join(html_parts) + + +def main(): + parser = argparse.ArgumentParser(description="Generate HTML report from run_loop output") + parser.add_argument("input", help="Path to JSON output from run_loop.py (or - for stdin)") + parser.add_argument("-o", "--output", default=None, help="Output HTML file (default: stdout)") + parser.add_argument("--skill-name", default="", help="Skill name to include in the report title") + args = parser.parse_args() + + if args.input == "-": + data = json.load(sys.stdin) + else: + data = json.loads(Path(args.input).read_text()) + + html_output = generate_html(data, skill_name=args.skill_name) + + if args.output: + Path(args.output).write_text(html_output) + print(f"Report written to {args.output}", file=sys.stderr) + else: + print(html_output) + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/improve_description.py b/.skills/skill-creator/scripts/improve_description.py new file mode 100644 index 00000000..a270777b --- /dev/null +++ b/.skills/skill-creator/scripts/improve_description.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 +"""Improve a skill description based on eval results. + +Takes eval results (from run_eval.py) and generates an improved description +using Claude with extended thinking. +""" + +import argparse +import json +import re +import sys +from pathlib import Path + +import anthropic + +from scripts.utils import parse_skill_md + + +def improve_description( + client: anthropic.Anthropic, + skill_name: str, + skill_content: str, + current_description: str, + eval_results: dict, + history: list[dict], + model: str, + test_results: dict | None = None, + log_dir: Path | None = None, + iteration: int | None = None, +) -> str: + """Call Claude to improve the description based on eval results.""" + failed_triggers = [ + r for r in eval_results["results"] + if r["should_trigger"] and not r["pass"] + ] + false_triggers = [ + r for r in eval_results["results"] + if not r["should_trigger"] and not r["pass"] + ] + + # Build scores summary + train_score = f"{eval_results['summary']['passed']}/{eval_results['summary']['total']}" + if test_results: + test_score = f"{test_results['summary']['passed']}/{test_results['summary']['total']}" + scores_summary = f"Train: {train_score}, Test: {test_score}" + else: + scores_summary = f"Train: {train_score}" + + prompt = f"""You are optimizing a skill description for a Claude Code skill called "{skill_name}". A "skill" is sort of like a prompt, but with progressive disclosure -- there's a title and description that Claude sees when deciding whether to use the skill, and then if it does use the skill, it reads the .md file which has lots more details and potentially links to other resources in the skill folder like helper files and scripts and additional documentation or examples. + +The description appears in Claude's "available_skills" list. When a user sends a query, Claude decides whether to invoke the skill based solely on the title and on this description. Your goal is to write a description that triggers for relevant queries, and doesn't trigger for irrelevant ones. + +Here's the current description: + +"{current_description}" + + +Current scores ({scores_summary}): + +""" + if failed_triggers: + prompt += "FAILED TO TRIGGER (should have triggered but didn't):\n" + for r in failed_triggers: + prompt += f' - "{r["query"]}" (triggered {r["triggers"]}/{r["runs"]} times)\n' + prompt += "\n" + + if false_triggers: + prompt += "FALSE TRIGGERS (triggered but shouldn't have):\n" + for r in false_triggers: + prompt += f' - "{r["query"]}" (triggered {r["triggers"]}/{r["runs"]} times)\n' + prompt += "\n" + + if history: + prompt += "PREVIOUS ATTEMPTS (do NOT repeat these — try something structurally different):\n\n" + for h in history: + train_s = f"{h.get('train_passed', h.get('passed', 0))}/{h.get('train_total', h.get('total', 0))}" + test_s = f"{h.get('test_passed', '?')}/{h.get('test_total', '?')}" if h.get('test_passed') is not None else None + score_str = f"train={train_s}" + (f", test={test_s}" if test_s else "") + prompt += f'\n' + prompt += f'Description: "{h["description"]}"\n' + if "results" in h: + prompt += "Train results:\n" + for r in h["results"]: + status = "PASS" if r["pass"] else "FAIL" + prompt += f' [{status}] "{r["query"][:80]}" (triggered {r["triggers"]}/{r["runs"]})\n' + if h.get("note"): + prompt += f'Note: {h["note"]}\n' + prompt += "\n\n" + + prompt += f""" + +Skill content (for context on what the skill does): + +{skill_content} + + +Based on the failures, write a new and improved description that is more likely to trigger correctly. When I say "based on the failures", it's a bit of a tricky line to walk because we don't want to overfit to the specific cases you're seeing. So what I DON'T want you to do is produce an ever-expanding list of specific queries that this skill should or shouldn't trigger for. Instead, try to generalize from the failures to broader categories of user intent and situations where this skill would be useful or not useful. The reason for this is twofold: + +1. Avoid overfitting +2. The list might get loooong and it's injected into ALL queries and there might be a lot of skills, so we don't want to blow too much space on any given description. + +Concretely, your description should not be more than about 100-200 words, even if that comes at the cost of accuracy. + +Here are some tips that we've found to work well in writing these descriptions: +- The skill should be phrased in the imperative -- "Use this skill for" rather than "this skill does" +- The skill description should focus on the user's intent, what they are trying to achieve, vs. the implementation details of how the skill works. +- The description competes with other skills for Claude's attention — make it distinctive and immediately recognizable. +- If you're getting lots of failures after repeated attempts, change things up. Try different sentence structures or wordings. + +I'd encourage you to be creative and mix up the style in different iterations since you'll have multiple opportunities to try different approaches and we'll just grab the highest-scoring one at the end. + +Please respond with only the new description text in tags, nothing else.""" + + response = client.messages.create( + model=model, + max_tokens=16000, + thinking={ + "type": "enabled", + "budget_tokens": 10000, + }, + messages=[{"role": "user", "content": prompt}], + ) + + # Extract thinking and text from response + thinking_text = "" + text = "" + for block in response.content: + if block.type == "thinking": + thinking_text = block.thinking + elif block.type == "text": + text = block.text + + # Parse out the tags + match = re.search(r"(.*?)", text, re.DOTALL) + description = match.group(1).strip().strip('"') if match else text.strip().strip('"') + + # Log the transcript + transcript: dict = { + "iteration": iteration, + "prompt": prompt, + "thinking": thinking_text, + "response": text, + "parsed_description": description, + "char_count": len(description), + "over_limit": len(description) > 1024, + } + + # If over 1024 chars, ask the model to shorten it + if len(description) > 1024: + shorten_prompt = f"Your description is {len(description)} characters, which exceeds the hard 1024 character limit. Please rewrite it to be under 1024 characters while preserving the most important trigger words and intent coverage. Respond with only the new description in tags." + shorten_response = client.messages.create( + model=model, + max_tokens=16000, + thinking={ + "type": "enabled", + "budget_tokens": 10000, + }, + messages=[ + {"role": "user", "content": prompt}, + {"role": "assistant", "content": text}, + {"role": "user", "content": shorten_prompt}, + ], + ) + + shorten_thinking = "" + shorten_text = "" + for block in shorten_response.content: + if block.type == "thinking": + shorten_thinking = block.thinking + elif block.type == "text": + shorten_text = block.text + + match = re.search(r"(.*?)", shorten_text, re.DOTALL) + shortened = match.group(1).strip().strip('"') if match else shorten_text.strip().strip('"') + + transcript["rewrite_prompt"] = shorten_prompt + transcript["rewrite_thinking"] = shorten_thinking + transcript["rewrite_response"] = shorten_text + transcript["rewrite_description"] = shortened + transcript["rewrite_char_count"] = len(shortened) + description = shortened + + transcript["final_description"] = description + + if log_dir: + log_dir.mkdir(parents=True, exist_ok=True) + log_file = log_dir / f"improve_iter_{iteration or 'unknown'}.json" + log_file.write_text(json.dumps(transcript, indent=2)) + + return description + + +def main(): + parser = argparse.ArgumentParser(description="Improve a skill description based on eval results") + parser.add_argument("--eval-results", required=True, help="Path to eval results JSON (from run_eval.py)") + parser.add_argument("--skill-path", required=True, help="Path to skill directory") + parser.add_argument("--history", default=None, help="Path to history JSON (previous attempts)") + parser.add_argument("--model", required=True, help="Model for improvement") + parser.add_argument("--verbose", action="store_true", help="Print thinking to stderr") + args = parser.parse_args() + + skill_path = Path(args.skill_path) + if not (skill_path / "SKILL.md").exists(): + print(f"Error: No SKILL.md found at {skill_path}", file=sys.stderr) + sys.exit(1) + + eval_results = json.loads(Path(args.eval_results).read_text()) + history = [] + if args.history: + history = json.loads(Path(args.history).read_text()) + + name, _, content = parse_skill_md(skill_path) + current_description = eval_results["description"] + + if args.verbose: + print(f"Current: {current_description}", file=sys.stderr) + print(f"Score: {eval_results['summary']['passed']}/{eval_results['summary']['total']}", file=sys.stderr) + + client = anthropic.Anthropic() + new_description = improve_description( + client=client, + skill_name=name, + skill_content=content, + current_description=current_description, + eval_results=eval_results, + history=history, + model=args.model, + ) + + if args.verbose: + print(f"Improved: {new_description}", file=sys.stderr) + + # Output as JSON with both the new description and updated history + output = { + "description": new_description, + "history": history + [{ + "description": current_description, + "passed": eval_results["summary"]["passed"], + "failed": eval_results["summary"]["failed"], + "total": eval_results["summary"]["total"], + "results": eval_results["results"], + }], + } + print(json.dumps(output, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/package_skill.py b/.skills/skill-creator/scripts/package_skill.py new file mode 100644 index 00000000..f48eac44 --- /dev/null +++ b/.skills/skill-creator/scripts/package_skill.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +""" +Skill Packager - Creates a distributable .skill file of a skill folder + +Usage: + python utils/package_skill.py [output-directory] + +Example: + python utils/package_skill.py skills/public/my-skill + python utils/package_skill.py skills/public/my-skill ./dist +""" + +import fnmatch +import sys +import zipfile +from pathlib import Path +from scripts.quick_validate import validate_skill + +# Patterns to exclude when packaging skills. +EXCLUDE_DIRS = {"__pycache__", "node_modules"} +EXCLUDE_GLOBS = {"*.pyc"} +EXCLUDE_FILES = {".DS_Store"} +# Directories excluded only at the skill root (not when nested deeper). +ROOT_EXCLUDE_DIRS = {"evals"} + + +def should_exclude(rel_path: Path) -> bool: + """Check if a path should be excluded from packaging.""" + parts = rel_path.parts + if any(part in EXCLUDE_DIRS for part in parts): + return True + # rel_path is relative to skill_path.parent, so parts[0] is the skill + # folder name and parts[1] (if present) is the first subdir. + if len(parts) > 1 and parts[1] in ROOT_EXCLUDE_DIRS: + return True + name = rel_path.name + if name in EXCLUDE_FILES: + return True + return any(fnmatch.fnmatch(name, pat) for pat in EXCLUDE_GLOBS) + + +def package_skill(skill_path, output_dir=None): + """ + Package a skill folder into a .skill file. + + Args: + skill_path: Path to the skill folder + output_dir: Optional output directory for the .skill file (defaults to current directory) + + Returns: + Path to the created .skill file, or None if error + """ + skill_path = Path(skill_path).resolve() + + # Validate skill folder exists + if not skill_path.exists(): + print(f"❌ Error: Skill folder not found: {skill_path}") + return None + + if not skill_path.is_dir(): + print(f"❌ Error: Path is not a directory: {skill_path}") + return None + + # Validate SKILL.md exists + skill_md = skill_path / "SKILL.md" + if not skill_md.exists(): + print(f"❌ Error: SKILL.md not found in {skill_path}") + return None + + # Run validation before packaging + print("🔍 Validating skill...") + valid, message = validate_skill(skill_path) + if not valid: + print(f"❌ Validation failed: {message}") + print(" Please fix the validation errors before packaging.") + return None + print(f"✅ {message}\n") + + # Determine output location + skill_name = skill_path.name + if output_dir: + output_path = Path(output_dir).resolve() + output_path.mkdir(parents=True, exist_ok=True) + else: + output_path = Path.cwd() + + skill_filename = output_path / f"{skill_name}.skill" + + # Create the .skill file (zip format) + try: + with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: + # Walk through the skill directory, excluding build artifacts + for file_path in skill_path.rglob('*'): + if not file_path.is_file(): + continue + arcname = file_path.relative_to(skill_path.parent) + if should_exclude(arcname): + print(f" Skipped: {arcname}") + continue + zipf.write(file_path, arcname) + print(f" Added: {arcname}") + + print(f"\n✅ Successfully packaged skill to: {skill_filename}") + return skill_filename + + except Exception as e: + print(f"❌ Error creating .skill file: {e}") + return None + + +def main(): + if len(sys.argv) < 2: + print("Usage: python utils/package_skill.py [output-directory]") + print("\nExample:") + print(" python utils/package_skill.py skills/public/my-skill") + print(" python utils/package_skill.py skills/public/my-skill ./dist") + sys.exit(1) + + skill_path = sys.argv[1] + output_dir = sys.argv[2] if len(sys.argv) > 2 else None + + print(f"📦 Packaging skill: {skill_path}") + if output_dir: + print(f" Output directory: {output_dir}") + print() + + result = package_skill(skill_path, output_dir) + + if result: + sys.exit(0) + else: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/quick_validate.py b/.skills/skill-creator/scripts/quick_validate.py new file mode 100644 index 00000000..ed8e1ddd --- /dev/null +++ b/.skills/skill-creator/scripts/quick_validate.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +""" +Quick validation script for skills - minimal version +""" + +import sys +import os +import re +import yaml +from pathlib import Path + +def validate_skill(skill_path): + """Basic validation of a skill""" + skill_path = Path(skill_path) + + # Check SKILL.md exists + skill_md = skill_path / 'SKILL.md' + if not skill_md.exists(): + return False, "SKILL.md not found" + + # Read and validate frontmatter + content = skill_md.read_text() + if not content.startswith('---'): + return False, "No YAML frontmatter found" + + # Extract frontmatter + match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL) + if not match: + return False, "Invalid frontmatter format" + + frontmatter_text = match.group(1) + + # Parse YAML frontmatter + try: + frontmatter = yaml.safe_load(frontmatter_text) + if not isinstance(frontmatter, dict): + return False, "Frontmatter must be a YAML dictionary" + except yaml.YAMLError as e: + return False, f"Invalid YAML in frontmatter: {e}" + + # Define allowed properties + ALLOWED_PROPERTIES = {'name', 'description', 'license', 'allowed-tools', 'metadata', 'compatibility'} + + # Check for unexpected properties (excluding nested keys under metadata) + unexpected_keys = set(frontmatter.keys()) - ALLOWED_PROPERTIES + if unexpected_keys: + return False, ( + f"Unexpected key(s) in SKILL.md frontmatter: {', '.join(sorted(unexpected_keys))}. " + f"Allowed properties are: {', '.join(sorted(ALLOWED_PROPERTIES))}" + ) + + # Check required fields + if 'name' not in frontmatter: + return False, "Missing 'name' in frontmatter" + if 'description' not in frontmatter: + return False, "Missing 'description' in frontmatter" + + # Extract name for validation + name = frontmatter.get('name', '') + if not isinstance(name, str): + return False, f"Name must be a string, got {type(name).__name__}" + name = name.strip() + if name: + # Check naming convention (kebab-case: lowercase with hyphens) + if not re.match(r'^[a-z0-9-]+$', name): + return False, f"Name '{name}' should be kebab-case (lowercase letters, digits, and hyphens only)" + if name.startswith('-') or name.endswith('-') or '--' in name: + return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens" + # Check name length (max 64 characters per spec) + if len(name) > 64: + return False, f"Name is too long ({len(name)} characters). Maximum is 64 characters." + + # Extract and validate description + description = frontmatter.get('description', '') + if not isinstance(description, str): + return False, f"Description must be a string, got {type(description).__name__}" + description = description.strip() + if description: + # Check for angle brackets + if '<' in description or '>' in description: + return False, "Description cannot contain angle brackets (< or >)" + # Check description length (max 1024 characters per spec) + if len(description) > 1024: + return False, f"Description is too long ({len(description)} characters). Maximum is 1024 characters." + + # Validate compatibility field if present (optional) + compatibility = frontmatter.get('compatibility', '') + if compatibility: + if not isinstance(compatibility, str): + return False, f"Compatibility must be a string, got {type(compatibility).__name__}" + if len(compatibility) > 500: + return False, f"Compatibility is too long ({len(compatibility)} characters). Maximum is 500 characters." + + return True, "Skill is valid!" + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python quick_validate.py ") + sys.exit(1) + + valid, message = validate_skill(sys.argv[1]) + print(message) + sys.exit(0 if valid else 1) \ No newline at end of file diff --git a/.skills/skill-creator/scripts/run_eval.py b/.skills/skill-creator/scripts/run_eval.py new file mode 100644 index 00000000..e58c70be --- /dev/null +++ b/.skills/skill-creator/scripts/run_eval.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python3 +"""Run trigger evaluation for a skill description. + +Tests whether a skill's description causes Claude to trigger (read the skill) +for a set of queries. Outputs results as JSON. +""" + +import argparse +import json +import os +import select +import subprocess +import sys +import time +import uuid +from concurrent.futures import ProcessPoolExecutor, as_completed +from pathlib import Path + +from scripts.utils import parse_skill_md + + +def find_project_root() -> Path: + """Find the project root by walking up from cwd looking for .claude/. + + Mimics how Claude Code discovers its project root, so the command file + we create ends up where claude -p will look for it. + """ + current = Path.cwd() + for parent in [current, *current.parents]: + if (parent / ".claude").is_dir(): + return parent + return current + + +def run_single_query( + query: str, + skill_name: str, + skill_description: str, + timeout: int, + project_root: str, + model: str | None = None, +) -> bool: + """Run a single query and return whether the skill was triggered. + + Creates a command file in .claude/commands/ so it appears in Claude's + available_skills list, then runs `claude -p` with the raw query. + Uses --include-partial-messages to detect triggering early from + stream events (content_block_start) rather than waiting for the + full assistant message, which only arrives after tool execution. + """ + unique_id = uuid.uuid4().hex[:8] + clean_name = f"{skill_name}-skill-{unique_id}" + project_commands_dir = Path(project_root) / ".claude" / "commands" + command_file = project_commands_dir / f"{clean_name}.md" + + try: + project_commands_dir.mkdir(parents=True, exist_ok=True) + # Use YAML block scalar to avoid breaking on quotes in description + indented_desc = "\n ".join(skill_description.split("\n")) + command_content = ( + f"---\n" + f"description: |\n" + f" {indented_desc}\n" + f"---\n\n" + f"# {skill_name}\n\n" + f"This skill handles: {skill_description}\n" + ) + command_file.write_text(command_content) + + cmd = [ + "claude", + "-p", query, + "--output-format", "stream-json", + "--verbose", + "--include-partial-messages", + ] + if model: + cmd.extend(["--model", model]) + + # Remove CLAUDECODE env var to allow nesting claude -p inside a + # Claude Code session. The guard is for interactive terminal conflicts; + # programmatic subprocess usage is safe. + env = {k: v for k, v in os.environ.items() if k != "CLAUDECODE"} + + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + cwd=project_root, + env=env, + ) + + triggered = False + start_time = time.time() + buffer = "" + # Track state for stream event detection + pending_tool_name = None + accumulated_json = "" + + try: + while time.time() - start_time < timeout: + if process.poll() is not None: + remaining = process.stdout.read() + if remaining: + buffer += remaining.decode("utf-8", errors="replace") + break + + ready, _, _ = select.select([process.stdout], [], [], 1.0) + if not ready: + continue + + chunk = os.read(process.stdout.fileno(), 8192) + if not chunk: + break + buffer += chunk.decode("utf-8", errors="replace") + + while "\n" in buffer: + line, buffer = buffer.split("\n", 1) + line = line.strip() + if not line: + continue + + try: + event = json.loads(line) + except json.JSONDecodeError: + continue + + # Early detection via stream events + if event.get("type") == "stream_event": + se = event.get("event", {}) + se_type = se.get("type", "") + + if se_type == "content_block_start": + cb = se.get("content_block", {}) + if cb.get("type") == "tool_use": + tool_name = cb.get("name", "") + if tool_name in ("Skill", "Read"): + pending_tool_name = tool_name + accumulated_json = "" + else: + return False + + elif se_type == "content_block_delta" and pending_tool_name: + delta = se.get("delta", {}) + if delta.get("type") == "input_json_delta": + accumulated_json += delta.get("partial_json", "") + if clean_name in accumulated_json: + return True + + elif se_type in ("content_block_stop", "message_stop"): + if pending_tool_name: + return clean_name in accumulated_json + if se_type == "message_stop": + return False + + # Fallback: full assistant message + elif event.get("type") == "assistant": + message = event.get("message", {}) + for content_item in message.get("content", []): + if content_item.get("type") != "tool_use": + continue + tool_name = content_item.get("name", "") + tool_input = content_item.get("input", {}) + if tool_name == "Skill" and clean_name in tool_input.get("skill", ""): + triggered = True + elif tool_name == "Read" and clean_name in tool_input.get("file_path", ""): + triggered = True + return triggered + + elif event.get("type") == "result": + return triggered + finally: + # Clean up process on any exit path (return, exception, timeout) + if process.poll() is None: + process.kill() + process.wait() + + return triggered + finally: + if command_file.exists(): + command_file.unlink() + + +def run_eval( + eval_set: list[dict], + skill_name: str, + description: str, + num_workers: int, + timeout: int, + project_root: Path, + runs_per_query: int = 1, + trigger_threshold: float = 0.5, + model: str | None = None, +) -> dict: + """Run the full eval set and return results.""" + results = [] + + with ProcessPoolExecutor(max_workers=num_workers) as executor: + future_to_info = {} + for item in eval_set: + for run_idx in range(runs_per_query): + future = executor.submit( + run_single_query, + item["query"], + skill_name, + description, + timeout, + str(project_root), + model, + ) + future_to_info[future] = (item, run_idx) + + query_triggers: dict[str, list[bool]] = {} + query_items: dict[str, dict] = {} + for future in as_completed(future_to_info): + item, _ = future_to_info[future] + query = item["query"] + query_items[query] = item + if query not in query_triggers: + query_triggers[query] = [] + try: + query_triggers[query].append(future.result()) + except Exception as e: + print(f"Warning: query failed: {e}", file=sys.stderr) + query_triggers[query].append(False) + + for query, triggers in query_triggers.items(): + item = query_items[query] + trigger_rate = sum(triggers) / len(triggers) + should_trigger = item["should_trigger"] + if should_trigger: + did_pass = trigger_rate >= trigger_threshold + else: + did_pass = trigger_rate < trigger_threshold + results.append({ + "query": query, + "should_trigger": should_trigger, + "trigger_rate": trigger_rate, + "triggers": sum(triggers), + "runs": len(triggers), + "pass": did_pass, + }) + + passed = sum(1 for r in results if r["pass"]) + total = len(results) + + return { + "skill_name": skill_name, + "description": description, + "results": results, + "summary": { + "total": total, + "passed": passed, + "failed": total - passed, + }, + } + + +def main(): + parser = argparse.ArgumentParser(description="Run trigger evaluation for a skill description") + parser.add_argument("--eval-set", required=True, help="Path to eval set JSON file") + parser.add_argument("--skill-path", required=True, help="Path to skill directory") + parser.add_argument("--description", default=None, help="Override description to test") + parser.add_argument("--num-workers", type=int, default=10, help="Number of parallel workers") + parser.add_argument("--timeout", type=int, default=30, help="Timeout per query in seconds") + parser.add_argument("--runs-per-query", type=int, default=3, help="Number of runs per query") + parser.add_argument("--trigger-threshold", type=float, default=0.5, help="Trigger rate threshold") + parser.add_argument("--model", default=None, help="Model to use for claude -p (default: user's configured model)") + parser.add_argument("--verbose", action="store_true", help="Print progress to stderr") + args = parser.parse_args() + + eval_set = json.loads(Path(args.eval_set).read_text()) + skill_path = Path(args.skill_path) + + if not (skill_path / "SKILL.md").exists(): + print(f"Error: No SKILL.md found at {skill_path}", file=sys.stderr) + sys.exit(1) + + name, original_description, content = parse_skill_md(skill_path) + description = args.description or original_description + project_root = find_project_root() + + if args.verbose: + print(f"Evaluating: {description}", file=sys.stderr) + + output = run_eval( + eval_set=eval_set, + skill_name=name, + description=description, + num_workers=args.num_workers, + timeout=args.timeout, + project_root=project_root, + runs_per_query=args.runs_per_query, + trigger_threshold=args.trigger_threshold, + model=args.model, + ) + + if args.verbose: + summary = output["summary"] + print(f"Results: {summary['passed']}/{summary['total']} passed", file=sys.stderr) + for r in output["results"]: + status = "PASS" if r["pass"] else "FAIL" + rate_str = f"{r['triggers']}/{r['runs']}" + print(f" [{status}] rate={rate_str} expected={r['should_trigger']}: {r['query'][:70]}", file=sys.stderr) + + print(json.dumps(output, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/run_loop.py b/.skills/skill-creator/scripts/run_loop.py new file mode 100644 index 00000000..36f9b4e0 --- /dev/null +++ b/.skills/skill-creator/scripts/run_loop.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python3 +"""Run the eval + improve loop until all pass or max iterations reached. + +Combines run_eval.py and improve_description.py in a loop, tracking history +and returning the best description found. Supports train/test split to prevent +overfitting. +""" + +import argparse +import json +import random +import sys +import tempfile +import time +import webbrowser +from pathlib import Path + +import anthropic + +from scripts.generate_report import generate_html +from scripts.improve_description import improve_description +from scripts.run_eval import find_project_root, run_eval +from scripts.utils import parse_skill_md + + +def split_eval_set(eval_set: list[dict], holdout: float, seed: int = 42) -> tuple[list[dict], list[dict]]: + """Split eval set into train and test sets, stratified by should_trigger.""" + random.seed(seed) + + # Separate by should_trigger + trigger = [e for e in eval_set if e["should_trigger"]] + no_trigger = [e for e in eval_set if not e["should_trigger"]] + + # Shuffle each group + random.shuffle(trigger) + random.shuffle(no_trigger) + + # Calculate split points + n_trigger_test = max(1, int(len(trigger) * holdout)) + n_no_trigger_test = max(1, int(len(no_trigger) * holdout)) + + # Split + test_set = trigger[:n_trigger_test] + no_trigger[:n_no_trigger_test] + train_set = trigger[n_trigger_test:] + no_trigger[n_no_trigger_test:] + + return train_set, test_set + + +def run_loop( + eval_set: list[dict], + skill_path: Path, + description_override: str | None, + num_workers: int, + timeout: int, + max_iterations: int, + runs_per_query: int, + trigger_threshold: float, + holdout: float, + model: str, + verbose: bool, + live_report_path: Path | None = None, + log_dir: Path | None = None, +) -> dict: + """Run the eval + improvement loop.""" + project_root = find_project_root() + name, original_description, content = parse_skill_md(skill_path) + current_description = description_override or original_description + + # Split into train/test if holdout > 0 + if holdout > 0: + train_set, test_set = split_eval_set(eval_set, holdout) + if verbose: + print(f"Split: {len(train_set)} train, {len(test_set)} test (holdout={holdout})", file=sys.stderr) + else: + train_set = eval_set + test_set = [] + + client = anthropic.Anthropic() + history = [] + exit_reason = "unknown" + + for iteration in range(1, max_iterations + 1): + if verbose: + print(f"\n{'='*60}", file=sys.stderr) + print(f"Iteration {iteration}/{max_iterations}", file=sys.stderr) + print(f"Description: {current_description}", file=sys.stderr) + print(f"{'='*60}", file=sys.stderr) + + # Evaluate train + test together in one batch for parallelism + all_queries = train_set + test_set + t0 = time.time() + all_results = run_eval( + eval_set=all_queries, + skill_name=name, + description=current_description, + num_workers=num_workers, + timeout=timeout, + project_root=project_root, + runs_per_query=runs_per_query, + trigger_threshold=trigger_threshold, + model=model, + ) + eval_elapsed = time.time() - t0 + + # Split results back into train/test by matching queries + train_queries_set = {q["query"] for q in train_set} + train_result_list = [r for r in all_results["results"] if r["query"] in train_queries_set] + test_result_list = [r for r in all_results["results"] if r["query"] not in train_queries_set] + + train_passed = sum(1 for r in train_result_list if r["pass"]) + train_total = len(train_result_list) + train_summary = {"passed": train_passed, "failed": train_total - train_passed, "total": train_total} + train_results = {"results": train_result_list, "summary": train_summary} + + if test_set: + test_passed = sum(1 for r in test_result_list if r["pass"]) + test_total = len(test_result_list) + test_summary = {"passed": test_passed, "failed": test_total - test_passed, "total": test_total} + test_results = {"results": test_result_list, "summary": test_summary} + else: + test_results = None + test_summary = None + + history.append({ + "iteration": iteration, + "description": current_description, + "train_passed": train_summary["passed"], + "train_failed": train_summary["failed"], + "train_total": train_summary["total"], + "train_results": train_results["results"], + "test_passed": test_summary["passed"] if test_summary else None, + "test_failed": test_summary["failed"] if test_summary else None, + "test_total": test_summary["total"] if test_summary else None, + "test_results": test_results["results"] if test_results else None, + # For backward compat with report generator + "passed": train_summary["passed"], + "failed": train_summary["failed"], + "total": train_summary["total"], + "results": train_results["results"], + }) + + # Write live report if path provided + if live_report_path: + partial_output = { + "original_description": original_description, + "best_description": current_description, + "best_score": "in progress", + "iterations_run": len(history), + "holdout": holdout, + "train_size": len(train_set), + "test_size": len(test_set), + "history": history, + } + live_report_path.write_text(generate_html(partial_output, auto_refresh=True, skill_name=name)) + + if verbose: + def print_eval_stats(label, results, elapsed): + pos = [r for r in results if r["should_trigger"]] + neg = [r for r in results if not r["should_trigger"]] + tp = sum(r["triggers"] for r in pos) + pos_runs = sum(r["runs"] for r in pos) + fn = pos_runs - tp + fp = sum(r["triggers"] for r in neg) + neg_runs = sum(r["runs"] for r in neg) + tn = neg_runs - fp + total = tp + tn + fp + fn + precision = tp / (tp + fp) if (tp + fp) > 0 else 1.0 + recall = tp / (tp + fn) if (tp + fn) > 0 else 1.0 + accuracy = (tp + tn) / total if total > 0 else 0.0 + print(f"{label}: {tp+tn}/{total} correct, precision={precision:.0%} recall={recall:.0%} accuracy={accuracy:.0%} ({elapsed:.1f}s)", file=sys.stderr) + for r in results: + status = "PASS" if r["pass"] else "FAIL" + rate_str = f"{r['triggers']}/{r['runs']}" + print(f" [{status}] rate={rate_str} expected={r['should_trigger']}: {r['query'][:60]}", file=sys.stderr) + + print_eval_stats("Train", train_results["results"], eval_elapsed) + if test_summary: + print_eval_stats("Test ", test_results["results"], 0) + + if train_summary["failed"] == 0: + exit_reason = f"all_passed (iteration {iteration})" + if verbose: + print(f"\nAll train queries passed on iteration {iteration}!", file=sys.stderr) + break + + if iteration == max_iterations: + exit_reason = f"max_iterations ({max_iterations})" + if verbose: + print(f"\nMax iterations reached ({max_iterations}).", file=sys.stderr) + break + + # Improve the description based on train results + if verbose: + print(f"\nImproving description...", file=sys.stderr) + + t0 = time.time() + # Strip test scores from history so improvement model can't see them + blinded_history = [ + {k: v for k, v in h.items() if not k.startswith("test_")} + for h in history + ] + new_description = improve_description( + client=client, + skill_name=name, + skill_content=content, + current_description=current_description, + eval_results=train_results, + history=blinded_history, + model=model, + log_dir=log_dir, + iteration=iteration, + ) + improve_elapsed = time.time() - t0 + + if verbose: + print(f"Proposed ({improve_elapsed:.1f}s): {new_description}", file=sys.stderr) + + current_description = new_description + + # Find the best iteration by TEST score (or train if no test set) + if test_set: + best = max(history, key=lambda h: h["test_passed"] or 0) + best_score = f"{best['test_passed']}/{best['test_total']}" + else: + best = max(history, key=lambda h: h["train_passed"]) + best_score = f"{best['train_passed']}/{best['train_total']}" + + if verbose: + print(f"\nExit reason: {exit_reason}", file=sys.stderr) + print(f"Best score: {best_score} (iteration {best['iteration']})", file=sys.stderr) + + return { + "exit_reason": exit_reason, + "original_description": original_description, + "best_description": best["description"], + "best_score": best_score, + "best_train_score": f"{best['train_passed']}/{best['train_total']}", + "best_test_score": f"{best['test_passed']}/{best['test_total']}" if test_set else None, + "final_description": current_description, + "iterations_run": len(history), + "holdout": holdout, + "train_size": len(train_set), + "test_size": len(test_set), + "history": history, + } + + +def main(): + parser = argparse.ArgumentParser(description="Run eval + improve loop") + parser.add_argument("--eval-set", required=True, help="Path to eval set JSON file") + parser.add_argument("--skill-path", required=True, help="Path to skill directory") + parser.add_argument("--description", default=None, help="Override starting description") + parser.add_argument("--num-workers", type=int, default=10, help="Number of parallel workers") + parser.add_argument("--timeout", type=int, default=30, help="Timeout per query in seconds") + parser.add_argument("--max-iterations", type=int, default=5, help="Max improvement iterations") + parser.add_argument("--runs-per-query", type=int, default=3, help="Number of runs per query") + parser.add_argument("--trigger-threshold", type=float, default=0.5, help="Trigger rate threshold") + parser.add_argument("--holdout", type=float, default=0.4, help="Fraction of eval set to hold out for testing (0 to disable)") + parser.add_argument("--model", required=True, help="Model for improvement") + parser.add_argument("--verbose", action="store_true", help="Print progress to stderr") + parser.add_argument("--report", default="auto", help="Generate HTML report at this path (default: 'auto' for temp file, 'none' to disable)") + parser.add_argument("--results-dir", default=None, help="Save all outputs (results.json, report.html, log.txt) to a timestamped subdirectory here") + args = parser.parse_args() + + eval_set = json.loads(Path(args.eval_set).read_text()) + skill_path = Path(args.skill_path) + + if not (skill_path / "SKILL.md").exists(): + print(f"Error: No SKILL.md found at {skill_path}", file=sys.stderr) + sys.exit(1) + + name, _, _ = parse_skill_md(skill_path) + + # Set up live report path + if args.report != "none": + if args.report == "auto": + timestamp = time.strftime("%Y%m%d_%H%M%S") + live_report_path = Path(tempfile.gettempdir()) / f"skill_description_report_{skill_path.name}_{timestamp}.html" + else: + live_report_path = Path(args.report) + # Open the report immediately so the user can watch + live_report_path.write_text("

Starting optimization loop...

") + webbrowser.open(str(live_report_path)) + else: + live_report_path = None + + # Determine output directory (create before run_loop so logs can be written) + if args.results_dir: + timestamp = time.strftime("%Y-%m-%d_%H%M%S") + results_dir = Path(args.results_dir) / timestamp + results_dir.mkdir(parents=True, exist_ok=True) + else: + results_dir = None + + log_dir = results_dir / "logs" if results_dir else None + + output = run_loop( + eval_set=eval_set, + skill_path=skill_path, + description_override=args.description, + num_workers=args.num_workers, + timeout=args.timeout, + max_iterations=args.max_iterations, + runs_per_query=args.runs_per_query, + trigger_threshold=args.trigger_threshold, + holdout=args.holdout, + model=args.model, + verbose=args.verbose, + live_report_path=live_report_path, + log_dir=log_dir, + ) + + # Save JSON output + json_output = json.dumps(output, indent=2) + print(json_output) + if results_dir: + (results_dir / "results.json").write_text(json_output) + + # Write final HTML report (without auto-refresh) + if live_report_path: + live_report_path.write_text(generate_html(output, auto_refresh=False, skill_name=name)) + print(f"\nReport: {live_report_path}", file=sys.stderr) + + if results_dir and live_report_path: + (results_dir / "report.html").write_text(generate_html(output, auto_refresh=False, skill_name=name)) + + if results_dir: + print(f"Results saved to: {results_dir}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/.skills/skill-creator/scripts/utils.py b/.skills/skill-creator/scripts/utils.py new file mode 100644 index 00000000..51b6a07d --- /dev/null +++ b/.skills/skill-creator/scripts/utils.py @@ -0,0 +1,47 @@ +"""Shared utilities for skill-creator scripts.""" + +from pathlib import Path + + + +def parse_skill_md(skill_path: Path) -> tuple[str, str, str]: + """Parse a SKILL.md file, returning (name, description, full_content).""" + content = (skill_path / "SKILL.md").read_text() + lines = content.split("\n") + + if lines[0].strip() != "---": + raise ValueError("SKILL.md missing frontmatter (no opening ---)") + + end_idx = None + for i, line in enumerate(lines[1:], start=1): + if line.strip() == "---": + end_idx = i + break + + if end_idx is None: + raise ValueError("SKILL.md missing frontmatter (no closing ---)") + + name = "" + description = "" + frontmatter_lines = lines[1:end_idx] + i = 0 + while i < len(frontmatter_lines): + line = frontmatter_lines[i] + if line.startswith("name:"): + name = line[len("name:"):].strip().strip('"').strip("'") + elif line.startswith("description:"): + value = line[len("description:"):].strip() + # Handle YAML multiline indicators (>, |, >-, |-) + if value in (">", "|", ">-", "|-"): + continuation_lines: list[str] = [] + i += 1 + while i < len(frontmatter_lines) and (frontmatter_lines[i].startswith(" ") or frontmatter_lines[i].startswith("\t")): + continuation_lines.append(frontmatter_lines[i].strip()) + i += 1 + description = " ".join(continuation_lines) + continue + else: + description = value.strip('"').strip("'") + i += 1 + + return name, description, content From 28834e7a86cae5dfcee61a3400a63867258fa374 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 20:07:20 +0100 Subject: [PATCH 085/484] Implemented .net 10 support. Updated all affected libraries and the code. Not testes yet. --- .github/workflows/build-and-release.yml | 7 ++- MinecraftClient/ChatBots/DiscordBridge.cs | 4 +- MinecraftClient/ChatBots/Map.cs | 3 +- MinecraftClient/ChatBots/TelegramBridge.cs | 32 ++++++----- MinecraftClient/MinecraftClient.csproj | 29 +++++----- MinecraftClient/Program.cs | 2 +- .../Protocol/Handlers/Protocol18.cs | 2 +- .../Protocol/Handlers/ZlibUtils.cs | 41 ++++++++------ MinecraftClient/Protocol/ReplayHandler.cs | 53 ++++++++++++------- .../Scripting/DynamicRun/Builder/Compiler.cs | 28 +++------- 10 files changed, 107 insertions(+), 94 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 144e9819..c421eb97 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -8,7 +8,7 @@ on: env: PROJECT: "MinecraftClient" - target-version: "net8.0" +/us target-version: "net10.0" compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded" jobs: @@ -45,6 +45,11 @@ jobs: run: | echo project-path=${{ github.workspace }}/${{ env.PROJECT }} >> $GITHUB_ENV echo file-ext=${{ (startsWith(matrix.target, 'win') && '.exe') || ' ' }} >> $GITHUB_ENV + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x - name: Setup Environment Variables run: | diff --git a/MinecraftClient/ChatBots/DiscordBridge.cs b/MinecraftClient/ChatBots/DiscordBridge.cs index b46ad770..6f3ab5c4 100644 --- a/MinecraftClient/ChatBots/DiscordBridge.cs +++ b/MinecraftClient/ChatBots/DiscordBridge.cs @@ -284,7 +284,7 @@ namespace MinecraftClient.ChatBots if (text != null) messageBuilder.WithContent(text); - messageBuilder.WithFiles(new Dictionary() { { $"attachment://{filePath}", fs } }); + messageBuilder.AddFiles(new Dictionary() { { filePath, fs } }); discordBotClient!.SendMessageAsync(discordChannel, messageBuilder).Wait(Config.Message_Send_Timeout * 1000); } @@ -301,7 +301,7 @@ namespace MinecraftClient.ChatBots if (!CanSendMessages()) return; - SendMessage(new DiscordMessageBuilder().WithFile(fileStream)); + SendMessage(new DiscordMessageBuilder().AddFile(fileStream)); } private bool CanSendMessages() diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs index c0c3aa8e..6a9f6bc4 100644 --- a/MinecraftClient/ChatBots/Map.cs +++ b/MinecraftClient/ChatBots/Map.cs @@ -259,7 +259,8 @@ namespace MinecraftClient.ChatBots { using (var image = new MagickImage(fileName)) { - var size = new MagickGeometry(Config.Resize_To, Config.Resize_To); + uint resizeTo = (uint)Math.Max(Config.Resize_To, 1); + var size = new MagickGeometry(resizeTo, resizeTo); size.IgnoreAspectRatio = true; image.Resize(size); diff --git a/MinecraftClient/ChatBots/TelegramBridge.cs b/MinecraftClient/ChatBots/TelegramBridge.cs index f30b7107..1140756a 100644 --- a/MinecraftClient/ChatBots/TelegramBridge.cs +++ b/MinecraftClient/ChatBots/TelegramBridge.cs @@ -12,7 +12,6 @@ using Telegram.Bot.Exceptions; using Telegram.Bot.Polling; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; -using Telegram.Bot.Types.InputFiles; using Tomlet.Attributes; using File = System.IO.File; @@ -205,7 +204,7 @@ namespace MinecraftClient.ChatBots try { - botClient!.SendTextMessageAsync(Config.ChannelId.Trim(), message, ParseMode.Markdown).Wait(Config.Message_Send_Timeout); + botClient!.SendMessage(Config.ChannelId.Trim(), message, parseMode: ParseMode.Markdown).Wait(Config.Message_Send_Timeout); } catch (Exception e) { @@ -224,9 +223,9 @@ namespace MinecraftClient.ChatBots string fileName = filePath[(filePath.IndexOf(Path.DirectorySeparatorChar) + 1)..]; Stream stream = File.OpenRead(filePath); - botClient!.SendDocumentAsync( + botClient!.SendDocument( Config.ChannelId.Trim(), - document: new InputOnlineFile(content: stream, fileName), + document: InputFile.FromStream(stream, fileName), caption: text, parseMode: ParseMode.Markdown).Wait(Config.Message_Send_Timeout * 1000); } @@ -260,14 +259,14 @@ namespace MinecraftClient.ChatBots cancellationToken = new CancellationTokenSource(); botClient.StartReceiving( - updateHandler: HandleUpdateAsync, - pollingErrorHandler: HandlePollingErrorAsync, - receiverOptions: new ReceiverOptions + HandleUpdateAsync, + HandlePollingErrorAsync, + new ReceiverOptions { // receive all update types AllowedUpdates = Array.Empty() }, - cancellationToken: cancellationToken.Token + cancellationToken.Token ); IsConnected = true; @@ -313,9 +312,9 @@ namespace MinecraftClient.ChatBots if (text.ToLower().Contains(".chatid")) { - await botClient.SendTextMessageAsync(chatId: chatId, - replyToMessageId: message.MessageId, + await botClient.SendMessage(chatId: chatId, text: $"Chat ID: {chatId}", + replyParameters: message.MessageId, cancellationToken: _cancellationToken, parseMode: ParseMode.Markdown); return; @@ -324,10 +323,10 @@ namespace MinecraftClient.ChatBots if (Config.Authorized_Chat_Ids.Length > 0 && !Config.Authorized_Chat_Ids.Contains(chatId)) { LogDebugToConsole($"Unauthorized message '{messageText}' received in a chat with with an ID: {chatId} !"); - await botClient.SendTextMessageAsync( + await botClient.SendMessage( chatId: chatId, - replyToMessageId: message.MessageId, text: Translations.bot_TelegramBridge_unauthorized, + replyParameters: message.MessageId, cancellationToken: _cancellationToken, parseMode: ParseMode.Markdown); return; @@ -347,10 +346,10 @@ namespace MinecraftClient.ChatBots if (command.ToLower().Contains("quit") || command.ToLower().Contains("exit")) { - await botClient.SendTextMessageAsync( + await botClient.SendMessage( chatId: chatId, - replyToMessageId: message.MessageId, text: $"{Translations.bot_TelegramBridge_quit_disabled}", + replyParameters: message.MessageId, cancellationToken: _cancellationToken, parseMode: ParseMode.Markdown); return;; @@ -359,11 +358,10 @@ namespace MinecraftClient.ChatBots CmdResult result = new(); PerformInternalCommand(command, ref result); - await botClient.SendTextMessageAsync( + await botClient.SendMessage( chatId: chatId, - replyToMessageId: - message.MessageId, text: $"{Translations.bot_TelegramBridge_command_executed}:\n\n{result}", + replyParameters: message.MessageId, cancellationToken: _cancellationToken, parseMode: ParseMode.Markdown); } diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index bd71f18a..68e605b1 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -1,6 +1,6 @@ - net8.0 + net10.0 Exe publish\ false @@ -28,25 +28,22 @@ - - - - + + + - - - - - - - - - + + + + + + + + NU1701 - - + diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index ae518b78..d09a8e8a 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -70,7 +70,7 @@ namespace MinecraftClient options.Dsn = SentryDSN; options.AutoSessionTracking = true; options.IsGlobalModeEnabled = true; - options.EnableTracing = true; + options.TracesSampleRate = 1.0; options.SendDefaultPii = false; }); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ab00dfc6..bdc1a8eb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -350,7 +350,7 @@ namespace MinecraftClient.Protocol.Handlers { break; } - catch (Ionic.Zlib.ZlibException) + catch (System.IO.InvalidDataException) { break; } diff --git a/MinecraftClient/Protocol/Handlers/ZlibUtils.cs b/MinecraftClient/Protocol/Handlers/ZlibUtils.cs index 62f8bf85..bff4131d 100644 --- a/MinecraftClient/Protocol/Handlers/ZlibUtils.cs +++ b/MinecraftClient/Protocol/Handlers/ZlibUtils.cs @@ -1,12 +1,10 @@ -using Ionic.Zlib; +using System.IO; +using System.IO.Compression; namespace MinecraftClient.Protocol.Handlers { /// /// Quick Zlib compression handling for network packet compression. - /// Note: Underlying compression handling is taken from the DotNetZip Library. - /// This library is open source and provided under the Microsoft Public License. - /// More info about DotNetZip at dotnetzip.codeplex.com. /// public static class ZlibUtils { @@ -17,16 +15,13 @@ namespace MinecraftClient.Protocol.Handlers /// Compressed data as a byte array public static byte[] Compress(byte[] to_compress) { - byte[] data; - using (System.IO.MemoryStream memstream = new()) + using MemoryStream memstream = new(); + using (ZLibStream stream = new(memstream, CompressionMode.Compress, leaveOpen: true)) { - using (ZlibStream stream = new(memstream, CompressionMode.Compress)) - { - stream.Write(to_compress, 0, to_compress.Length); - } - data = memstream.ToArray(); + stream.Write(to_compress, 0, to_compress.Length); } - return data; + + return memstream.ToArray(); } /// @@ -37,10 +32,20 @@ namespace MinecraftClient.Protocol.Handlers /// Decompressed data as a byte array public static byte[] Decompress(byte[] to_decompress, int size_uncompressed) { - ZlibStream stream = new(new System.IO.MemoryStream(to_decompress, false), CompressionMode.Decompress); + using MemoryStream compressedStream = new(to_decompress, writable: false); + using ZLibStream stream = new(compressedStream, CompressionMode.Decompress); + byte[] packetData_decompressed = new byte[size_uncompressed]; - stream.Read(packetData_decompressed, 0, size_uncompressed); - stream.Close(); + int totalRead = 0; + while (totalRead < size_uncompressed) + { + int read = stream.Read(packetData_decompressed, totalRead, size_uncompressed - totalRead); + if (read <= 0) + break; + + totalRead += read; + } + return packetData_decompressed; } @@ -51,12 +56,14 @@ namespace MinecraftClient.Protocol.Handlers /// Decompressed data as byte array public static byte[] Decompress(byte[] to_decompress) { - ZlibStream stream = new(new System.IO.MemoryStream(to_decompress, false), CompressionMode.Decompress); + using MemoryStream compressedStream = new(to_decompress, writable: false); + using ZLibStream stream = new(compressedStream, CompressionMode.Decompress); byte[] buffer = new byte[16 * 1024]; - using System.IO.MemoryStream decompressedBuffer = new(); + using MemoryStream decompressedBuffer = new(); int read; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) decompressedBuffer.Write(buffer, 0, read); + return decompressedBuffer.ToArray(); } } diff --git a/MinecraftClient/Protocol/ReplayHandler.cs b/MinecraftClient/Protocol/ReplayHandler.cs index be567caf..697e23c3 100644 --- a/MinecraftClient/Protocol/ReplayHandler.cs +++ b/MinecraftClient/Protocol/ReplayHandler.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Linq; -using Ionic.Zip; using MinecraftClient.Mapping; using MinecraftClient.Protocol.Handlers; using MinecraftClient.Protocol.Handlers.PacketPalettes; @@ -138,12 +138,18 @@ namespace MinecraftClient.Protocol using (Stream recordingFile = new FileStream(Path.Combine(temporaryCache, recordingTmpFileName), FileMode.Open)) { using Stream metaDataFile = new FileStream(Path.Combine(temporaryCache, MetaData.MetaDataFileName), FileMode.Open); - using ZipOutputStream zs = new(Path.Combine(ReplayFileDirectory, replayFileName)); - zs.PutNextEntry(recordingTmpFileName); - recordingFile.CopyTo(zs); - zs.PutNextEntry(MetaData.MetaDataFileName); - metaDataFile.CopyTo(zs); - zs.Close(); + using FileStream replayArchiveFile = new(Path.Combine(ReplayFileDirectory, replayFileName), FileMode.Create, FileAccess.Write); + using ZipArchive replayArchive = new(replayArchiveFile, ZipArchiveMode.Create); + + ZipArchiveEntry recordingEntry = replayArchive.CreateEntry(recordingTmpFileName); + using (Stream recordingEntryStream = recordingEntry.Open()) + { + recordingFile.CopyTo(recordingEntryStream); + } + + ZipArchiveEntry metadataEntry = replayArchive.CreateEntry(MetaData.MetaDataFileName); + using Stream metadataEntryStream = metadataEntry.Open(); + metaDataFile.CopyTo(metadataEntryStream); } File.Delete(Path.Combine(temporaryCache, recordingTmpFileName)); @@ -167,18 +173,29 @@ namespace MinecraftClient.Protocol using (Stream metaDataFile = new FileStream(Path.Combine(temporaryCache, MetaData.MetaDataFileName), FileMode.Open)) { - using ZipOutputStream zs = new(replayFileName); - zs.PutNextEntry(recordingTmpFileName); - // .CopyTo() method start from stream current position - // We need to reset position in order to get full content - var lastPosition = recordStream!.BaseStream.Position; - recordStream.BaseStream.Position = 0; - recordStream.BaseStream.CopyTo(zs); - recordStream.BaseStream.Position = lastPosition; + using FileStream replayArchiveFile = new(replayFileName, FileMode.Create, FileAccess.Write); + using ZipArchive replayArchive = new(replayArchiveFile, ZipArchiveMode.Create); - zs.PutNextEntry(MetaData.MetaDataFileName); - metaDataFile.CopyTo(zs); - zs.Close(); + ZipArchiveEntry recordingEntry = replayArchive.CreateEntry(recordingTmpFileName); + using (Stream recordingEntryStream = recordingEntry.Open()) + { + // .CopyTo() method start from stream current position + // We need to reset position in order to get full content + long lastPosition = recordStream!.BaseStream.Position; + try + { + recordStream.BaseStream.Position = 0; + recordStream.BaseStream.CopyTo(recordingEntryStream); + } + finally + { + recordStream.BaseStream.Position = lastPosition; + } + } + + ZipArchiveEntry metadataEntry = replayArchive.CreateEntry(MetaData.MetaDataFileName); + using Stream metadataEntryStream = metadataEntry.Open(); + metaDataFile.CopyTo(metadataEntryStream); } WriteDebugLog("Backup replay file created."); diff --git a/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs b/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs index 1e99f226..81417178 100644 --- a/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs +++ b/MinecraftClient/Scripting/DynamicRun/Builder/Compiler.cs @@ -7,7 +7,6 @@ https://github.com/laurentkempe/DynamicRun/blob/master/LICENSE using System; using System.Collections.Generic; using System.IO; -using System.IO.MemoryMappedFiles; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -117,10 +116,11 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder File.Copy(executablePath, tempFile); // Access the contents of the executable. - ExecutableReader e = new(); - var viewAccessor = MemoryMappedFile.CreateFromFile(tempFile, FileMode.Open).CreateViewAccessor(); - var manifest = e.ReadManifest(viewAccessor); - var files = manifest.Files; + using ExecutableReader executableReader = new(tempFile); + if (!executableReader.IsSingleFile) + throw new InvalidOperationException("[Script Error] The executable is not a single-file bundle."); + + var files = executableReader.Bundle.Files; Stream? assemblyStream; @@ -133,8 +133,8 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder if (string.IsNullOrEmpty(loadedAssembly.Location)) { // Check if we can access the file from the executable. var reference = files.FirstOrDefault(x => - x.RelativePath.Remove(x.RelativePath.Length - 4) == refs.Name); - var refCount = files.Count(x => x.RelativePath.Remove(x.RelativePath.Length - 4) == refs.Name); + Path.GetFileNameWithoutExtension(x.RelativePath) == refs.Name); + var refCount = files.Count(x => Path.GetFileNameWithoutExtension(x.RelativePath) == refs.Name); if (refCount > 1) { // Safety net for the case where the assembly is referenced multiple times. // Should not happen normally, but we can make exceptions when it does happen. @@ -147,17 +147,13 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder "[Script Error] The executable does not contain a referenced assembly. Assembly name: " + refs.Name); } - assemblyStream = GetStreamForFileEntry(viewAccessor, reference); + assemblyStream = reference.AsStream(); references.Add(MetadataReference.CreateFromStream(assemblyStream!)); continue; } references.Add(MetadataReference.CreateFromFile(loadedAssembly.Location)); } - - // Cleanup. - viewAccessor.Flush(); - viewAccessor.Dispose(); } else { @@ -176,14 +172,6 @@ namespace MinecraftClient.Scripting.DynamicRun.Builder assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default)); } - private static Stream? GetStreamForFileEntry(MemoryMappedViewAccessor viewAccessor, FileEntry file) - { - if (typeof(BundleExtractor).GetMethod("GetStreamForFileEntry", BindingFlags.NonPublic | BindingFlags.Static)!.Invoke(null, new object[] { viewAccessor, file }) is not Stream stream) - throw new InvalidOperationException("[Script Error] The executable does not contain the assembly. Assembly name: " + file.RelativePath); - - return stream; - } - internal struct CompileResult { internal byte[]? Assembly; From fb896c45a724c260b2e97db2f1dee05044fa622e Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 20:11:14 +0100 Subject: [PATCH 086/484] Fixed a typo in a workflow YAML. --- .github/workflows/build-and-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index c421eb97..40a22587 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -8,7 +8,7 @@ on: env: PROJECT: "MinecraftClient" -/us target-version: "net10.0" + target-version: "net10.0" compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded" jobs: From 5b9cc4aa0efb8ed70aa430bf3e953c3679cbe6f7 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 21:02:13 +0100 Subject: [PATCH 087/484] Tested the client against 1.21.11 on .net 10. Created a integration testing skill (end-to-end). --- .skills/mcc-integration-testing/SKILL.md | 56 +++++ .../mcc-integration-testing/evals/evals.json | 39 ++++ .../references/command-matrix.md | 53 +++++ .../scripts/ensure_offline_server.sh | 84 +++++++ .../scripts/run_full_spectrum_test.sh | 219 ++++++++++++++++++ .../scripts/summarize_test_run.sh | 25 ++ MinecraftClient/ChatBots/AntiAFK.cs | 8 +- MinecraftClient/ChatBots/AutoCraft.cs | 7 + MinecraftClient/ChatBots/AutoDig.cs | 7 + MinecraftClient/ChatBots/AutoFishing.cs | 19 ++ MinecraftClient/ChatBots/AutoRelog.cs | 6 + MinecraftClient/ChatBots/ScriptScheduler.cs | 13 ++ MinecraftClient/Settings.cs | 18 ++ 13 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 .skills/mcc-integration-testing/SKILL.md create mode 100644 .skills/mcc-integration-testing/evals/evals.json create mode 100644 .skills/mcc-integration-testing/references/command-matrix.md create mode 100755 .skills/mcc-integration-testing/scripts/ensure_offline_server.sh create mode 100755 .skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh create mode 100755 .skills/mcc-integration-testing/scripts/summarize_test_run.sh diff --git a/.skills/mcc-integration-testing/SKILL.md b/.skills/mcc-integration-testing/SKILL.md new file mode 100644 index 00000000..f6fe207f --- /dev/null +++ b/.skills/mcc-integration-testing/SKILL.md @@ -0,0 +1,56 @@ +--- +name: mcc-integration-testing +description: Repeatable local offline integration testing for Minecraft Console Client against a local Minecraft Java server. Use this whenever the user wants to validate MCC end-to-end against a local server, switch the server to persistent offline mode, run chat or server commands through FileInputBot, exercise inventory/entity handling, or perform deeper smoke testing with mobs, particles, sounds, TNT, and operator actions. +--- + +# MCC Integration Testing + +Use this skill for local MCC validation against the user's `mc-*` and `mcc-*` shell helpers. + +## Workflow + +1. Source `~/.zshrc` in command invocations. +2. Do not read `~/.zshrc` directly. +3. Ensure the target server is configured for persistent offline testing: + - `online-mode=false` + - `enforce-secure-profile=false` + - `enable-rcon=true` + - `rcon.password=test123` +4. Build with `mcc-build`. +5. Run the scripted scenario with `scripts/run_full_spectrum_test.sh`. +6. Summarize the evidence with `scripts/summarize_test_run.sh`. + +## Required Preconditions + +- Server jar exists under `~/Minecraft/Servers//server.jar` +- `eula.txt` contains `eula=true` +- Repo root `MinecraftClient.ini` is the offline MCC test profile +- The MCC config round-trip issue must be fixed before relying on repeated launches + +## Scripts + +- `scripts/ensure_offline_server.sh` + - Generates `server.properties` if missing + - Applies persistent offline and RCON settings +- `scripts/run_full_spectrum_test.sh` + - Builds MCC + - Starts server and MCC + - Runs the full-spectrum scenario + - Verifies key MCC and server log assertions +- `scripts/summarize_test_run.sh` + - Prints the most relevant evidence from the latest run directory + +## Scenario Coverage + +The scripted run should cover: + +- offline join +- MCC-originated chat +- MCC-originated slash command +- internal MCC commands such as `health`, `list`, `inventory`, and `entity` +- OP + creative mode +- passive and hostile mob spawns +- representative sound and particle events +- TNT / explosion handling + +If a command syntax needs to be checked, use `references/command-matrix.md`. diff --git a/.skills/mcc-integration-testing/evals/evals.json b/.skills/mcc-integration-testing/evals/evals.json new file mode 100644 index 00000000..1eb5a870 --- /dev/null +++ b/.skills/mcc-integration-testing/evals/evals.json @@ -0,0 +1,39 @@ +{ + "skill_name": "mcc-integration-testing", + "evals": [ + { + "id": 1, + "prompt": "Configure the local 1.21.11 MCC test server for persistent offline mode, then run a deep MCC integration test covering chat, operator actions, creative inventory, entity tracking, sounds, particles, and TNT.", + "expected_output": "The server is left in offline mode with RCON enabled, MCC joins successfully, and the run reports clear pass or fail evidence from both MCC and server logs.", + "files": [], + "expectations": [ + "The workflow sources ~/.zshrc without reading it directly.", + "The server is configured with online-mode=false and enable-rcon=true.", + "The run uses both mc-rcon and mcc-cmd.", + "The result includes evidence from MCC output and server logs." + ] + }, + { + "id": 2, + "prompt": "Validate that MCC still works after a runtime or framework change by performing a repeatable offline smoke test against the local vanilla server and exercising entity and inventory handling.", + "expected_output": "The response runs the repeatable local workflow, checks for a successful join, verifies inventory and entity commands, and calls out any configuration or protocol regression.", + "files": [], + "expectations": [ + "The workflow builds MCC before running the server scenario.", + "The workflow checks inventory and entity handling explicitly.", + "The response flags config reload failures as regressions." + ] + }, + { + "id": 3, + "prompt": "Use the local MCC testing workflow to run a full-spectrum client/server exercise and summarize the important evidence only.", + "expected_output": "The response runs the scripted scenario and returns a concise summary with pass/fail status, affected commands, and log evidence.", + "files": [], + "expectations": [ + "The workflow uses the scripted test runner.", + "The summary includes join status, MCC command coverage, and server-side effects.", + "The summary points to the saved log locations." + ] + } + ] +} diff --git a/.skills/mcc-integration-testing/references/command-matrix.md b/.skills/mcc-integration-testing/references/command-matrix.md new file mode 100644 index 00000000..9880f2f8 --- /dev/null +++ b/.skills/mcc-integration-testing/references/command-matrix.md @@ -0,0 +1,53 @@ +# Command Matrix + +This skill uses a fixed set of stable commands for local offline integration testing. + +## MCC-side commands via `mcc-cmd` + +- `health` +- `list` +- `inventory player list` +- `/gamemode creative` +- `inventory creativegive 36 Diamond 16` +- `entity` +- `/time query daytime` +- `smoke_test_from_mcc_full_spectrum` + +Notes: +- Lines starting with `/` are sent to the server as chat/commands. +- Non-slash lines are treated as MCC internal commands first, then fall back to chat. + +## Server-side commands via `mc-rcon` + +- `op CursorBot` +- `gamerule sendCommandFeedback true` +- `gamerule logAdminCommands true` +- `time set day` +- `weather clear` + +## Representative entity coverage + +- `execute as CursorBot at @s run summon minecraft:cow ~2 ~ ~` +- `execute as CursorBot at @s run summon minecraft:zombie ~4 ~ ~` +- `execute as CursorBot at @s run summon minecraft:creeper ~6 ~ ~` +- `execute as CursorBot at @s run summon minecraft:skeleton ~8 ~ ~` +- `execute as CursorBot at @s run summon minecraft:villager ~-2 ~ ~` +- `execute as CursorBot at @s run summon minecraft:allay ~-4 ~ ~` +- `execute as CursorBot at @s run summon minecraft:armor_stand ~ ~ ~2` + +## Representative particle coverage + +- `execute as CursorBot at @s run particle minecraft:happy_villager ~ ~1 ~ 0.5 0.5 0.5 0 12 force` +- `execute as CursorBot at @s run particle minecraft:end_rod ~ ~1 ~ 0.5 0.5 0.5 0.01 20 force` +- `execute as CursorBot at @s run particle minecraft:explosion ~ ~1 ~ 0 0 0 0 1 force` +- `execute as CursorBot at @s run particle minecraft:totem_of_undying ~ ~1 ~ 0.5 0.5 0.5 0.1 20 force` + +## Representative sound coverage + +- `execute as CursorBot at @s run playsound minecraft:entity.lightning_bolt.thunder master CursorBot ~ ~ ~ 1 1 0` +- `execute as CursorBot at @s run playsound minecraft:block.note_block.bell master CursorBot ~ ~ ~ 1 1 0` + +## Explosion coverage + +- `execute as CursorBot at @s run summon minecraft:tnt ~3 ~ ~` +- `execute as CursorBot at @s run summon minecraft:tnt ~6 ~ ~` diff --git a/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh new file mode 100755 index 00000000..2aab4267 --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env zsh +set -euo pipefail + +set +eu +source ~/.zshrc +set -eu + +VERSION="${1:-1.21.11-Vanilla}" +SERVER_DIR="${MCC_SERVERS:?}/$VERSION" +PROPS_FILE="$SERVER_DIR/server.properties" +SESSION_NAME="mc-${VERSION//./_}" + +if [[ ! -d "$SERVER_DIR" ]]; then + echo "Server directory not found: $SERVER_DIR" >&2 + exit 1 +fi + +if [[ ! -f "$SERVER_DIR/eula.txt" ]] || ! grep -Eq '^eula=true$' "$SERVER_DIR/eula.txt"; then + echo "Missing accepted EULA in $SERVER_DIR/eula.txt" >&2 + exit 1 +fi + +server_running() { + mc-list | grep -Fq "$SESSION_NAME" +} + +wait_for_server_ready() { + local timeout="${1:-60}" + local elapsed=0 + while (( elapsed < timeout )); do + if mc-log "$VERSION" 200 2>/dev/null | grep -Fq "Done ("; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + echo "Timed out waiting for $VERSION to become ready" >&2 + return 1 +} + +wait_for_server_stop() { + local timeout="${1:-60}" + local elapsed=0 + while (( elapsed < timeout )); do + if ! server_running; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + echo "Timed out waiting for $VERSION to stop" >&2 + return 1 +} + +upsert_property() { + local key="$1" + local value="$2" + + if grep -Eq "^${key}=" "$PROPS_FILE"; then + sed -i "s#^${key}=.*#${key}=${value}#" "$PROPS_FILE" + else + printf '%s=%s\n' "$key" "$value" >> "$PROPS_FILE" + fi +} + +if [[ ! -f "$PROPS_FILE" ]]; then + mc-start "$VERSION" + wait_for_server_ready + mc-stop "$VERSION" + wait_for_server_stop +fi + +if server_running; then + mc-stop "$VERSION" + wait_for_server_stop +fi + +upsert_property "online-mode" "false" +upsert_property "enforce-secure-profile" "false" +upsert_property "enable-rcon" "true" +upsert_property "rcon.port" "25575" +upsert_property "rcon.password" "test123" + +echo "Configured $VERSION for persistent offline testing" diff --git a/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh new file mode 100755 index 00000000..6648771a --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh @@ -0,0 +1,219 @@ +#!/usr/bin/env zsh +set -euo pipefail + +set +eu +source ~/.zshrc +set -eu + +SCRIPT_DIR="${0:A:h}" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +VERSION="${1:-1.21.11-Vanilla}" +RUN_ROOT="${TMPDIR:-/tmp}/mcc-integration-testing" +RUN_ID="$(date +%Y%m%d-%H%M%S)" +RUN_DIR="$RUN_ROOT/$RUN_ID" +SERVER_LOG_FILE="$MCC_SERVERS/$VERSION/logs/latest.log" +MCC_LOG="$RUN_DIR/mcc.log" +BUILD_LOG="$RUN_DIR/build.log" +SERVER_TMUX_LOG="$RUN_DIR/server-tmux.log" +SERVER_FILE_LOG="$RUN_DIR/server-latest.log" +INPUT_FILE="$REPO_ROOT/mcc_input.txt" +MCC_PID="" + +mkdir -p "$RUN_DIR" + +cleanup() { + if [[ -n "${MCC_PID:-}" ]] && kill -0 "$MCC_PID" 2>/dev/null; then + mcc-cmd "quit" >/dev/null 2>&1 || true + sleep 2 + kill "$MCC_PID" 2>/dev/null || true + wait "$MCC_PID" 2>/dev/null || true + fi + + mc-stop "$VERSION" >/dev/null 2>&1 || true +} +trap cleanup EXIT + +wait_for_file_pattern() { + local file="$1" + local pattern="$2" + local description="$3" + local timeout="${4:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if [[ -f "$file" ]] && grep -Fq "$pattern" "$file"; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for: $description" >&2 + return 1 +} + +wait_for_server_ready() { + local timeout="${1:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if mc-log "$VERSION" 250 2>/dev/null | grep -Fq "Done ("; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for server readiness" >&2 + return 1 +} + +wait_for_server_log_pattern() { + local pattern="$1" + local description="$2" + local timeout="${3:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if [[ -f "$SERVER_LOG_FILE" ]] && grep -Fq "$pattern" "$SERVER_LOG_FILE"; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for server log: $description" >&2 + return 1 +} + +capture_server_logs() { + mc-log "$VERSION" 400 > "$SERVER_TMUX_LOG" 2>/dev/null || true + if [[ -f "$SERVER_LOG_FILE" ]]; then + cp "$SERVER_LOG_FILE" "$SERVER_FILE_LOG" + fi +} + +fail() { + capture_server_logs + echo "FAIL: $1" >&2 + echo "Run directory: $RUN_DIR" >&2 + exit 1 +} + +assert_contains() { + local file="$1" + local pattern="$2" + local description="$3" + + grep -Fq "$pattern" "$file" || fail "$description" +} + +assert_not_contains() { + local file="$1" + local pattern="$2" + local description="$3" + + if grep -Fq "$pattern" "$file"; then + fail "$description" + fi +} + +run_server_command() { + local cmd="$1" + echo "SERVER> $cmd" + mc-rcon "$cmd" >/dev/null || fail "Server command failed: $cmd" +} + +run_mcc_command() { + local cmd="$1" + echo "MCC> $cmd" + mcc-cmd "$cmd" + sleep 2 +} + +"$SCRIPT_DIR/ensure_offline_server.sh" "$VERSION" + +: > "$INPUT_FILE" + +echo "Building MCC..." +mcc-build > "$BUILD_LOG" 2>&1 || fail "mcc-build failed" + +echo "Starting server..." +mc-start "$VERSION" >/dev/null +wait_for_server_ready || fail "Server did not become ready" + +echo "Starting MCC..." +mcc-run 25565 > "$MCC_LOG" 2>&1 & +MCC_PID=$! + +wait_for_file_pattern "$MCC_LOG" "Server was successfully joined." "MCC join success" 90 || fail "MCC failed to join" +wait_for_server_log_pattern "CursorBot joined the game" "server join entry" 30 || fail "Server never logged the join" + +run_server_command "op CursorBot" +run_server_command "gamerule sendCommandFeedback true" +run_server_command "gamerule logAdminCommands true" +run_server_command "time set day" +run_server_command "weather clear" +sleep 2 + +run_mcc_command "health" +run_mcc_command "list" +run_mcc_command "inventory player list" +run_mcc_command "/gamemode creative" +run_mcc_command "inventory creativegive 36 Diamond 16" +run_mcc_command "inventory player list" +run_mcc_command "entity" +run_mcc_command "/time query daytime" +run_mcc_command "smoke_test_from_mcc_full_spectrum" + +run_server_command "execute as CursorBot at @s run summon minecraft:cow ~2 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:zombie ~4 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:creeper ~6 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:skeleton ~8 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:villager ~-2 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:allay ~-4 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:armor_stand ~ ~ ~2" + +sleep 2 +run_mcc_command "entity" + +run_server_command "execute as CursorBot at @s run particle minecraft:happy_villager ~ ~1 ~ 0.5 0.5 0.5 0 12 force" +run_server_command "execute as CursorBot at @s run particle minecraft:end_rod ~ ~1 ~ 0.5 0.5 0.5 0.01 20 force" +run_server_command "execute as CursorBot at @s run particle minecraft:explosion ~ ~1 ~ 0 0 0 0 1 force" +run_server_command "execute as CursorBot at @s run particle minecraft:totem_of_undying ~ ~1 ~ 0.5 0.5 0.5 0.1 20 force" + +run_server_command "execute as CursorBot at @s run playsound minecraft:entity.lightning_bolt.thunder master CursorBot ~ ~ ~ 1 1 0" +run_server_command "execute as CursorBot at @s run playsound minecraft:block.note_block.bell master CursorBot ~ ~ ~ 1 1 0" + +run_server_command "execute as CursorBot at @s run summon minecraft:tnt ~3 ~ ~" +sleep 2 +run_server_command "execute as CursorBot at @s run summon minecraft:tnt ~6 ~ ~" + +sleep 6 +capture_server_logs + +assert_contains "$MCC_LOG" "Server was successfully joined." "MCC never joined the server" +assert_contains "$MCC_LOG" "[FileInput] > inventory player list" "Inventory command was not executed" +assert_contains "$MCC_LOG" "[FileInput] > entity" "Entity command was not executed" +assert_contains "$MCC_LOG" "[FileInput] > /gamemode creative" "Creative mode command was not executed from MCC" +assert_contains "$MCC_LOG" "Requested Diamond x16 in slot #36" "Creative inventory give did not succeed" +assert_contains "$MCC_LOG" "smoke_test_from_mcc_full_spectrum" "Client-originated chat was not observed" +assert_not_contains "$MCC_LOG" "Please enable InventoryHandling" "Inventory handling is still disabled" +assert_not_contains "$MCC_LOG" "Please enable EntityHandling" "Entity handling is still disabled" +assert_not_contains "$MCC_LOG" "You must be in Creative gamemode" "Creative mode was not active when creativegive ran" +assert_not_contains "$MCC_LOG" "Failed to load settings" "MCC failed to reload its config" + +assert_contains "$SERVER_FILE_LOG" "CursorBot joined the game" "Server never saw CursorBot join" +assert_contains "$SERVER_FILE_LOG" "smoke_test_from_mcc_full_spectrum" "Server never received the client chat message" +assert_contains "$SERVER_FILE_LOG" "Displaying particle minecraft:happy_villager" "Particle events were not recorded on the server" +assert_contains "$SERVER_FILE_LOG" "Played sound minecraft:block.note_block.bell to CursorBot" "Sound events were not recorded on the server" +assert_contains "$SERVER_FILE_LOG" "Summoned new Primed TNT" "TNT summon did not occur on the server" +assert_not_contains "$SERVER_FILE_LOG" "Sending unknown packet 'clientbound/minecraft:disconnect'" "Server hit the disconnect packet regression during the test" + +cat <&2 + exit 1 +fi + +MCC_LOG="$RUN_DIR/mcc.log" +SERVER_LOG="$RUN_DIR/server-latest.log" +BUILD_LOG="$RUN_DIR/build.log" + +echo "Run directory: $RUN_DIR" +echo +echo "Build result:" +grep -E "Warning\(s\)|Error\(s\)|Time Elapsed" "$BUILD_LOG" || true +echo +echo "MCC highlights:" +grep -E "Server was successfully joined|FileInput|smoke_test_from_mcc_full_spectrum|There are [0-9]+ of a max|health|Creative" "$MCC_LOG" || true +echo +echo "Server highlights:" +grep -E "joined the game|Made CursorBot a server operator|game mode|smoke_test_from_mcc_full_spectrum|summon|particle|playsound|tnt" "$SERVER_LOG" || true diff --git a/MinecraftClient/ChatBots/AntiAFK.cs b/MinecraftClient/ChatBots/AntiAFK.cs index 30d47189..055416a0 100644 --- a/MinecraftClient/ChatBots/AntiAFK.cs +++ b/MinecraftClient/ChatBots/AntiAFK.cs @@ -64,6 +64,12 @@ namespace MinecraftClient.ChatBots { public double min, max; + public Range() + { + min = 0; + max = 0; + } + public Range(int value) { min = max = value; @@ -180,4 +186,4 @@ namespace MinecraftClient.ChatBots currentLocation.Z + random.Next(range * -1, range)); } } -} \ No newline at end of file +} diff --git a/MinecraftClient/ChatBots/AutoCraft.cs b/MinecraftClient/ChatBots/AutoCraft.cs index 52d691ab..861bc2be 100644 --- a/MinecraftClient/ChatBots/AutoCraft.cs +++ b/MinecraftClient/ChatBots/AutoCraft.cs @@ -106,6 +106,13 @@ namespace MinecraftClient.ChatBots { public double X, Y, Z; + public LocationConfig() + { + X = 0; + Y = 0; + Z = 0; + } + public LocationConfig(double X, double Y, double Z) { this.X = X; diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index 17c27895..e1da7a51 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -85,6 +85,13 @@ namespace MinecraftClient.ChatBots { public double x, y, z; + public Coordination() + { + x = 0; + y = 0; + z = 0; + } + public Coordination(double x, double y, double z) { this.x = x; this.y = y; this.z = z; diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs index 09ee140f..f2ab906d 100644 --- a/MinecraftClient/ChatBots/AutoFishing.cs +++ b/MinecraftClient/ChatBots/AutoFishing.cs @@ -103,6 +103,12 @@ namespace MinecraftClient.ChatBots public Coordination? XYZ; public Facing? facing; + public LocationConfig() + { + XYZ = null; + facing = null; + } + public LocationConfig(double yaw, double pitch) { this.XYZ = null; @@ -125,6 +131,13 @@ namespace MinecraftClient.ChatBots { public double x, y, z; + public Coordination() + { + x = 0; + y = 0; + z = 0; + } + public Coordination(double x, double y, double z) { this.x = x; this.y = y; this.z = z; @@ -135,6 +148,12 @@ namespace MinecraftClient.ChatBots { public double yaw, pitch; + public Facing() + { + yaw = 0; + pitch = 0; + } + public Facing(double yaw, double pitch) { this.yaw = yaw; this.pitch = pitch; diff --git a/MinecraftClient/ChatBots/AutoRelog.cs b/MinecraftClient/ChatBots/AutoRelog.cs index 24e6570a..06dd4cb1 100644 --- a/MinecraftClient/ChatBots/AutoRelog.cs +++ b/MinecraftClient/ChatBots/AutoRelog.cs @@ -57,6 +57,12 @@ namespace MinecraftClient.ChatBots { public double min, max; + public Range() + { + min = 0; + max = 0; + } + public Range(int value) { min = max = value; diff --git a/MinecraftClient/ChatBots/ScriptScheduler.cs b/MinecraftClient/ChatBots/ScriptScheduler.cs index 0e15949d..9db48c09 100644 --- a/MinecraftClient/ChatBots/ScriptScheduler.cs +++ b/MinecraftClient/ChatBots/ScriptScheduler.cs @@ -116,6 +116,12 @@ namespace MinecraftClient.ChatBots public bool Enable = false; public TimeSpan[] Times; + public TriggerOnTimeConfig() + { + Enable = false; + Times = Array.Empty(); + } + public TriggerOnTimeConfig(bool Enable, TimeSpan[] Time) { this.Enable = Enable; @@ -134,6 +140,13 @@ namespace MinecraftClient.ChatBots public bool Enable = false; public double MinTime, MaxTime; + public TriggerOnIntervalConfig() + { + Enable = false; + MinTime = 0; + MaxTime = 0; + } + public TriggerOnIntervalConfig(double value) { this.Enable = true; diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 684e5a98..8a7ca0c1 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -658,6 +658,12 @@ namespace MinecraftClient { public string Login = string.Empty, Password = string.Empty; + public AccountInfoConfig() + { + Login = string.Empty; + Password = string.Empty; + } + public AccountInfoConfig(string Login) { this.Login = Login; @@ -676,6 +682,12 @@ namespace MinecraftClient public string Host = string.Empty; public ushort? Port = null; + public ServerInfoConfig() + { + Host = string.Empty; + Port = null; + } + public ServerInfoConfig(string Host) { string[] sip = Host.Split(new[] { ":", ":" }, StringSplitOptions.None); @@ -699,6 +711,12 @@ namespace MinecraftClient public string Host = string.Empty; public int Port = 443; + public AuthlibServer() + { + Host = string.Empty; + Port = 443; + } + public AuthlibServer(string Host) { string[] sip = Host.Split(new[] { ":", ":" }, StringSplitOptions.None); From abe6b9f01bd4c56fc449bdf43f7b65a3abd1ad32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 20:27:38 +0000 Subject: [PATCH 088/484] chore(deps): Bump immutable from 4.1.0 to 4.3.8 in /docs Bumps [immutable](https://github.com/immutable-js/immutable-js) from 4.1.0 to 4.3.8. - [Release notes](https://github.com/immutable-js/immutable-js/releases) - [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md) - [Commits](https://github.com/immutable-js/immutable-js/compare/v4.1.0...v4.3.8) --- updated-dependencies: - dependency-name: immutable dependency-version: 4.3.8 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 7a51e330..a53b20bd 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3165,9 +3165,9 @@ ignore@^5.2.0: integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immutable@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" - integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== + version "4.3.8" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.8.tgz#02d183c7727fb2bb1d5d0380da0d779dce9296a7" + integrity sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw== import-fresh@^3.2.1: version "3.3.0" From c38162584ddc3a7fa15b11e755f9e339d4a80416 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 20:28:32 +0000 Subject: [PATCH 089/484] chore(deps): Bump minimatch from 3.1.2 to 3.1.5 in /docs Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.2 to 3.1.5. - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5) --- updated-dependencies: - dependency-name: minimatch dependency-version: 3.1.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/yarn.lock b/docs/yarn.lock index 7a51e330..e6cc4778 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3714,9 +3714,9 @@ minimalistic-assert@^1.0.0: integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + version "3.1.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" + integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== dependencies: brace-expansion "^1.1.7" From c50b9a5b63b4575899e725c957c32d55e8a2f603 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 22:22:18 +0100 Subject: [PATCH 090/484] Fixed a crash on PlayerInfo packet. --- .../Protocol/Handlers/Protocol18.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index bdc1a8eb..95996b7e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2024,8 +2024,8 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_19_3_Version) { var actionBitset = dataTypes.ReadNextByte(packetData); - var numberOfActions = dataTypes.ReadNextVarInt(packetData); - for (var i = 0; i < numberOfActions; i++) + var entryCount = dataTypes.ReadNextVarInt(packetData); + for (var i = 0; i < entryCount; i++) { var playerUuid = dataTypes.ReadNextUUID(packetData); @@ -2107,10 +2107,19 @@ namespace MinecraftClient.Protocol.Handlers } // Actions bit 5: update display name - if ((actionBitset & 1 << 5) <= 0) continue; - player.DisplayName = dataTypes.ReadNextBool(packetData) - ? dataTypes.ReadNextChat(packetData) - : null; + if ((actionBitset & 1 << 5) > 0) + { + player.DisplayName = dataTypes.ReadNextBool(packetData) + ? dataTypes.ReadNextChat(packetData) + : null; + } + + // Consume all action-selected fields to keep entry boundaries aligned. + if (protocolVersion >= MC_1_21_2_Version && (actionBitset & 1 << 6) > 0) // Actions bit 6: update list order + dataTypes.ReadNextVarInt(packetData); + + if (protocolVersion >= MC_1_21_4_Version && (actionBitset & 1 << 7) > 0) // Actions bit 7: update hat + dataTypes.ReadNextBool(packetData); } } else if (protocolVersion >= MC_1_8_Version) From b4e69da81f1a1f0b3589127f2d6a77bc4b6065ba Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 21 Mar 2026 22:44:57 +0100 Subject: [PATCH 091/484] Temporary fix for Declare Commands crashing sending commands in chat. --- .../Handlers/Packet/s2c/DeclareCommands.cs | 48 +++++++++++++++++-- .../Protocol/Handlers/Protocol18.cs | 12 ++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs index a0a0d117..9a2a8e4f 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -7,15 +7,23 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c { private static int RootIdx; private static CommandNode[] Nodes = Array.Empty(); + private static bool HasLoadedTree; + + public static bool IsCommandTreeAvailable => HasValidCommandTree(); public static void Read(DataTypes dataTypes, Queue packetData, int protocolVersion) { + Reset(); + ConsoleIO.OnDeclareMinecraftCommand(Array.Empty()); + // TODO: Fix this // It crashes in 1.20.6+ , could not figure out why // it's hard to debug, so I'll just disable it for now - if(protocolVersion > Protocol18Handler.MC_1_20_4_Version) + if (protocolVersion > Protocol18Handler.MC_1_20_4_Version) + { return; - + } + int count = dataTypes.ReadNextVarInt(packetData); Nodes = new CommandNode[count]; for (int i = 0; i < count; ++i) @@ -159,16 +167,23 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c Nodes[i] = new(flags, childs, redirectNode, name, parser, suggestionsType, parserId); } RootIdx = dataTypes.ReadNextVarInt(packetData); + HasLoadedTree = IsValidNodeIndex(RootIdx); - ConsoleIO.OnDeclareMinecraftCommand(ExtractRootCommand()); + ConsoleIO.OnDeclareMinecraftCommand(HasLoadedTree ? ExtractRootCommand() : Array.Empty()); } private static string[] ExtractRootCommand() { + if (!HasValidCommandTree()) + return Array.Empty(); + List commands = new(); CommandNode root = Nodes[RootIdx]; foreach (var child in root.Clildren) { + if (!IsValidNodeIndex(child)) + continue; + string? childName = Nodes[child].Name; if (childName != null) commands.Add(childName); @@ -179,12 +194,18 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c public static List> CollectSignArguments(string command) { List> needSigned = new(); + if (!HasValidCommandTree()) + return needSigned; + CollectSignArguments(RootIdx, command, needSigned); return needSigned; } private static void CollectSignArguments(int NodeIdx, string command, List> arguments) { + if (!IsValidNodeIndex(NodeIdx)) + return; + CommandNode node = Nodes[NodeIdx]; string last_arg = command; switch (node.Flags & 0x03) @@ -218,12 +239,33 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c } while (Nodes[NodeIdx].RedirectNode >= 0) + { NodeIdx = Nodes[NodeIdx].RedirectNode; + if (!IsValidNodeIndex(NodeIdx)) + return; + } foreach (int childIdx in Nodes[NodeIdx].Clildren) CollectSignArguments(childIdx, last_arg, arguments); } + private static void Reset() + { + RootIdx = -1; + Nodes = Array.Empty(); + HasLoadedTree = false; + } + + private static bool HasValidCommandTree() + { + return HasLoadedTree && IsValidNodeIndex(RootIdx); + } + + private static bool IsValidNodeIndex(int nodeIdx) + { + return nodeIdx >= 0 && nodeIdx < Nodes.Length; + } + internal class CommandNode { public byte Flags; diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 95996b7e..98d7aec7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3704,7 +3704,17 @@ namespace MinecraftClient.Protocol.Handlers List>? needSigned = null; if (protocolVersion >= MC_1_19_Version && Config.Signature is { LoginWithSecureProfile: true, SignMessageInCommand: true }) - needSigned = DeclareCommands.CollectSignArguments(command); + { + if (DeclareCommands.IsCommandTreeAvailable) + { + needSigned = DeclareCommands.CollectSignArguments(command); + } + else + { + needSigned = []; + log.Debug("DeclareCommands tree unavailable, sending command without signed arguments."); + } + } lock (MessageSigningLock) { From e2746ae0d1fe2874d63f0d63592ea9d8e5f14e6d Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 00:42:43 +0100 Subject: [PATCH 092/484] Implemented new Delcare Command packet for new versions 1.20.6-1.21.11 and fixed it for 1.20.4. --- .../Handlers/Packet/s2c/DeclareCommands.cs | 1370 +++++++++-------- .../Protocol/Handlers/Protocol18.cs | 7 +- tools/README.md | 8 + tools/gen_command_argument_registry.py | 85 + 4 files changed, 804 insertions(+), 666 deletions(-) create mode 100644 tools/gen_command_argument_registry.py diff --git a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs index 9a2a8e4f..6883b6cf 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -5,9 +5,57 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c { internal static class DeclareCommands { - private static int RootIdx; + private const byte NodeTypeMask = 0x03; + private const byte NodeExecutableFlag = 0x04; + private const byte NodeRedirectFlag = 0x08; + private const byte NodeCustomSuggestionsFlag = 0x10; + private const byte NodeRestrictedFlag = 0x20; + + private static readonly Dictionary s_argumentTypeCatalog = CreateArgumentTypeCatalog(); + private static readonly ArgumentTypeLayout s_unknownLegacyArgumentType = new("minecraft:unknown"); + + // Generated from tools/gen_command_argument_registry.py with IDE-only registrations excluded. + private static readonly string[] s_modernArgumentTypes1206 = + [ + "brigadier:bool", "brigadier:float", "brigadier:double", "brigadier:integer", "brigadier:long", "brigadier:string", + "entity", "game_profile", "block_pos", "column_pos", "vec3", "vec2", "block_state", "block_predicate", + "item_stack", "item_predicate", "color", "component", "style", "message", "nbt_compound_tag", "nbt_tag", + "nbt_path", "objective", "objective_criteria", "operation", "particle", "angle", "rotation", + "scoreboard_slot", "score_holder", "swizzle", "team", "item_slot", "item_slots", "resource_location", + "function", "entity_anchor", "int_range", "float_range", "dimension", "gamemode", "time", + "resource_or_tag", "resource_or_tag_key", "resource", "resource_key", "template_mirror", + "template_rotation", "heightmap", "loot_table", "loot_predicate", "loot_modifier", "uuid" + ]; + + private static readonly string[] s_modernArgumentTypes1215 = + [ + "brigadier:bool", "brigadier:float", "brigadier:double", "brigadier:integer", "brigadier:long", "brigadier:string", + "entity", "game_profile", "block_pos", "column_pos", "vec3", "vec2", "block_state", "block_predicate", + "item_stack", "item_predicate", "color", "component", "style", "message", "nbt_compound_tag", "nbt_tag", + "nbt_path", "objective", "objective_criteria", "operation", "particle", "angle", "rotation", + "scoreboard_slot", "score_holder", "swizzle", "team", "item_slot", "item_slots", "resource_location", + "function", "entity_anchor", "int_range", "float_range", "dimension", "gamemode", "time", + "resource_or_tag", "resource_or_tag_key", "resource", "resource_key", "resource_selector", + "template_mirror", "template_rotation", "heightmap", "loot_table", "loot_predicate", "loot_modifier", "uuid" + ]; + + private static readonly string[] s_modernArgumentTypes1216 = + [ + "brigadier:bool", "brigadier:float", "brigadier:double", "brigadier:integer", "brigadier:long", "brigadier:string", + "entity", "game_profile", "block_pos", "column_pos", "vec3", "vec2", "block_state", "block_predicate", + "item_stack", "item_predicate", "color", "hex_color", "component", "style", "message", + "nbt_compound_tag", "nbt_tag", "nbt_path", "objective", "objective_criteria", "operation", "particle", + "angle", "rotation", "scoreboard_slot", "score_holder", "swizzle", "team", "item_slot", "item_slots", + "resource_location", "function", "entity_anchor", "int_range", "float_range", "dimension", "gamemode", + "time", "resource_or_tag", "resource_or_tag_key", "resource", "resource_key", "resource_selector", + "template_mirror", "template_rotation", "heightmap", "loot_table", "loot_predicate", "loot_modifier", + "dialog", "uuid" + ]; + + private static int RootIdx = -1; private static CommandNode[] Nodes = Array.Empty(); private static bool HasLoadedTree; + internal static string? LastReadError { get; private set; } public static bool IsCommandTreeAvailable => HasValidCommandTree(); @@ -16,160 +64,138 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c Reset(); ConsoleIO.OnDeclareMinecraftCommand(Array.Empty()); - // TODO: Fix this - // It crashes in 1.20.6+ , could not figure out why - // it's hard to debug, so I'll just disable it for now - if (protocolVersion > Protocol18Handler.MC_1_20_4_Version) + try { - return; + ReadCommandTree(dataTypes, packetData, protocolVersion); + } + catch (Exception ex) + { + LastReadError = ex.ToString(); + Reset(); } + ConsoleIO.OnDeclareMinecraftCommand(HasLoadedTree ? ExtractRootCommand() : Array.Empty()); + } + + public static List> CollectSignArguments(string command) + { + List> needSigned = new(); + if (!HasValidCommandTree() || string.IsNullOrEmpty(command)) + return needSigned; + + return TryMatchNode(RootIdx, command, 0, needSigned, out List> matchedArguments) + ? matchedArguments + : []; + } + + private static void ReadCommandTree(DataTypes dataTypes, Queue packetData, int protocolVersion) + { int count = dataTypes.ReadNextVarInt(packetData); Nodes = new CommandNode[count]; + for (int i = 0; i < count; ++i) { byte flags = dataTypes.ReadNextByte(packetData); + int[] children = ReadChildIndices(dataTypes, packetData); + int redirectNode = (flags & NodeRedirectFlag) != 0 ? dataTypes.ReadNextVarInt(packetData) : -1; - int childCount = dataTypes.ReadNextVarInt(packetData); - int[] childs = new int[childCount]; - for (int j = 0; j < childCount; ++j) - childs[j] = dataTypes.ReadNextVarInt(packetData); - - int redirectNode = ((flags & 0x08) == 0x08) ? dataTypes.ReadNextVarInt(packetData) : -1; - - string? name = ((flags & 0x03) == 1 || (flags & 0x03) == 2) ? dataTypes.ReadNextString(packetData) : null; - - int parserId = ((flags & 0x03) == 2) ? dataTypes.ReadNextVarInt(packetData) : -1; - Parser? parser = null; - if ((flags & 0x03) == 2) + CommandNodeKind nodeKind = (CommandNodeKind)(flags & NodeTypeMask); + CommandNode node = nodeKind switch { - if (protocolVersion <= Protocol18Handler.MC_1_19_2_Version) - parser = parserId switch - { - 1 => new ParserFloat(dataTypes, packetData), - 2 => new ParserDouble(dataTypes, packetData), - 3 => new ParserInteger(dataTypes, packetData), - 4 => new ParserLong(dataTypes, packetData), - 5 => new ParserString(dataTypes, packetData), - 6 => new ParserEntity(dataTypes, packetData), - 8 => new ParserBlockPos(dataTypes, packetData), - 9 => new ParserColumnPos(dataTypes, packetData), - 10 => new ParserVec3(dataTypes, packetData), - 11 => new ParserVec2(dataTypes, packetData), - 18 => new ParserMessage(dataTypes, packetData), - 27 => new ParserRotation(dataTypes, packetData), - 29 => new ParserScoreHolder(dataTypes, packetData), - 43 => new ParserResourceOrTag(dataTypes, packetData), - 44 => new ParserResource(dataTypes, packetData), - 50 => new ParserForgeEnum(dataTypes, packetData), - _ => new ParserEmpty(dataTypes, packetData), - }; - else if (protocolVersion <= Protocol18Handler.MC_1_19_3_Version) // 1.19.3 - parser = parserId switch - { - 1 => new ParserFloat(dataTypes, packetData), - 2 => new ParserDouble(dataTypes, packetData), - 3 => new ParserInteger(dataTypes, packetData), - 4 => new ParserLong(dataTypes, packetData), - 5 => new ParserString(dataTypes, packetData), - 6 => new ParserEntity(dataTypes, packetData), - 8 => new ParserBlockPos(dataTypes, packetData), - 9 => new ParserColumnPos(dataTypes, packetData), - 10 => new ParserVec3(dataTypes, packetData), - 11 => new ParserVec2(dataTypes, packetData), - 18 => new ParserMessage(dataTypes, packetData), - 27 => new ParserRotation(dataTypes, packetData), - 29 => new ParserScoreHolder(dataTypes, packetData), - 41 => new ParserResourceOrTag(dataTypes, packetData), - 42 => new ParserResourceOrTag(dataTypes, packetData), - 43 => new ParserResource(dataTypes, packetData), - 44 => new ParserResource(dataTypes, packetData), - 50 => new ParserForgeEnum(dataTypes, packetData), - _ => new ParserEmpty(dataTypes, packetData), - }; - else if (protocolVersion <= Protocol18Handler.MC_1_20_2_Version)// 1.19.4 - 1.20.2 - parser = parserId switch - { - 1 => new ParserFloat(dataTypes, packetData), - 2 => new ParserDouble(dataTypes, packetData), - 3 => new ParserInteger(dataTypes, packetData), - 4 => new ParserLong(dataTypes, packetData), - 5 => new ParserString(dataTypes, packetData), - 6 => new ParserEntity(dataTypes, packetData), - 8 => new ParserBlockPos(dataTypes, packetData), - 9 => new ParserColumnPos(dataTypes, packetData), - 10 => new ParserVec3(dataTypes, packetData), - 11 => new ParserVec2(dataTypes, packetData), - 18 => new ParserMessage(dataTypes, packetData), - 27 => new ParserRotation(dataTypes, packetData), - 29 => new ParserScoreHolder(dataTypes, packetData), - 40 => new ParserTime(dataTypes, packetData), - 41 => new ParserResourceOrTag(dataTypes, packetData), - 42 => new ParserResourceOrTag(dataTypes, packetData), - 43 => new ParserResource(dataTypes, packetData), - 44 => new ParserResource(dataTypes, packetData), - 50 => protocolVersion == Protocol18Handler.MC_1_19_4_Version ? - new ParserForgeEnum(dataTypes, packetData) : - new ParserEmpty(dataTypes, packetData), - 51 => (protocolVersion >= Protocol18Handler.MC_1_20_Version && - protocolVersion <= Protocol18Handler.MC_1_20_2_Version) ? // 1.20 - 1.20.2 - new ParserForgeEnum(dataTypes, packetData) : - new ParserEmpty(dataTypes, packetData), - _ => new ParserEmpty(dataTypes, packetData), - }; - else if (protocolVersion is > Protocol18Handler.MC_1_20_2_Version and < Protocol18Handler.MC_1_20_6_Version) - // 1.20.3 - 1.20.4 - parser = parserId switch - { - 1 => new ParserFloat(dataTypes, packetData), - 2 => new ParserDouble(dataTypes, packetData), - 3 => new ParserInteger(dataTypes, packetData), - 4 => new ParserLong(dataTypes, packetData), - 5 => new ParserString(dataTypes, packetData), - 6 => new ParserEntity(dataTypes, packetData), - 8 => new ParserBlockPos(dataTypes, packetData), - 9 => new ParserColumnPos(dataTypes, packetData), - 10 => new ParserVec3(dataTypes, packetData), - 11 => new ParserVec2(dataTypes, packetData), - 18 => new ParserMessage(dataTypes, packetData), - 27 => new ParserRotation(dataTypes, packetData), - 30 => new ParserScoreHolder(dataTypes, packetData), - 41 => new ParserTime(dataTypes, packetData), - 42 => new ParserResourceOrTag(dataTypes, packetData), - 43 => new ParserResourceOrTag(dataTypes, packetData), - 44 => new ParserResource(dataTypes, packetData), - 45 => new ParserResource(dataTypes, packetData), - 52 => new ParserForgeEnum(dataTypes, packetData), - _ => new ParserEmpty(dataTypes, packetData), - }; - else // 1.20.6+ - parser = parserId switch - { - 1 => new ParserFloat(dataTypes, packetData), - 2 => new ParserDouble(dataTypes, packetData), - 3 => new ParserInteger(dataTypes, packetData), - 4 => new ParserLong(dataTypes, packetData), - 5 => new ParserString(dataTypes, packetData), - 6 => new ParserEntity(dataTypes, packetData), - 30 => new ParserScoreHolder(dataTypes, packetData), - 41 => new ParserTime(dataTypes, packetData), - 42 => new ParserResourceOrTag(dataTypes, packetData), - 43 => new ParserResourceOrTag(dataTypes, packetData), - 44 => new ParserResource(dataTypes, packetData), - 45 => new ParserResource(dataTypes, packetData), - 52 => new ParserForgeEnum(dataTypes, packetData), - _ => new ParserEmpty(dataTypes, packetData), - }; - } + CommandNodeKind.Root => new(flags, children, redirectNode), + CommandNodeKind.Literal => new(flags, children, redirectNode, dataTypes.ReadNextString(packetData)), + CommandNodeKind.Argument => ReadArgumentNode(dataTypes, packetData, protocolVersion, flags, children, redirectNode), + _ => throw new InvalidOperationException($"Unsupported DeclareCommands node type {(byte)nodeKind}.") + }; - string? suggestionsType = ((flags & 0x10) == 0x10) ? dataTypes.ReadNextString(packetData) : null; - - Nodes[i] = new(flags, childs, redirectNode, name, parser, suggestionsType, parserId); + Nodes[i] = node; } + RootIdx = dataTypes.ReadNextVarInt(packetData); HasLoadedTree = IsValidNodeIndex(RootIdx); + } - ConsoleIO.OnDeclareMinecraftCommand(HasLoadedTree ? ExtractRootCommand() : Array.Empty()); + private static CommandNode ReadArgumentNode( + DataTypes dataTypes, + Queue packetData, + int protocolVersion, + byte flags, + int[] children, + int redirectNode) + { + string name = dataTypes.ReadNextString(packetData); + int parserId = dataTypes.ReadNextVarInt(packetData); + + if (!TryResolveArgumentTypeLayout(protocolVersion, parserId, out ArgumentTypeLayout layout)) + throw new InvalidOperationException($"Unsupported DeclareCommands argument type id {parserId} for protocol {protocolVersion}."); + + CommandArgumentDescriptor descriptor = ReadArgumentDescriptor(dataTypes, packetData, layout); + string? suggestionsType = (flags & NodeCustomSuggestionsFlag) != 0 ? dataTypes.ReadNextString(packetData) : null; + + return new(flags, children, redirectNode, name, descriptor, suggestionsType, parserId); + } + + private static int[] ReadChildIndices(DataTypes dataTypes, Queue packetData) + { + int childCount = dataTypes.ReadNextVarInt(packetData); + int[] children = new int[childCount]; + + for (int i = 0; i < childCount; ++i) + children[i] = dataTypes.ReadNextVarInt(packetData); + + return children; + } + + private static CommandArgumentDescriptor ReadArgumentDescriptor(DataTypes dataTypes, Queue packetData, ArgumentTypeLayout layout) + { + switch (layout.PayloadKind) + { + case ArgumentPayloadKind.None: + return layout.CreateDescriptor(); + case ArgumentPayloadKind.BrigadierFloat: + ReadNumberBounds(dataTypes, packetData, static (types, data) => types.ReadNextFloat(data)); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.BrigadierDouble: + ReadNumberBounds(dataTypes, packetData, static (types, data) => types.ReadNextDouble(data)); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.BrigadierInteger: + ReadNumberBounds(dataTypes, packetData, static (types, data) => types.ReadNextInt(data)); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.BrigadierLong: + ReadNumberBounds(dataTypes, packetData, static (types, data) => types.ReadNextLong(data)); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.BrigadierString: + ArgumentConsumption consumption = dataTypes.ReadNextVarInt(packetData) switch + { + 0 => ArgumentConsumption.SingleToken, + 1 => ArgumentConsumption.QuotedStringOrWord, + 2 => ArgumentConsumption.GreedyTail, + int stringType => throw new InvalidOperationException($"Unsupported brigadier:string type {stringType}.") + }; + return layout.CreateDescriptor(consumption); + case ArgumentPayloadKind.Entity: + case ArgumentPayloadKind.ScoreHolder: + dataTypes.ReadNextByte(packetData); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.Time: + dataTypes.ReadNextInt(packetData); + return layout.CreateDescriptor(); + case ArgumentPayloadKind.RegistryKey: + case ArgumentPayloadKind.ForgeEnum: + dataTypes.ReadNextString(packetData); + return layout.CreateDescriptor(); + default: + throw new InvalidOperationException($"Unsupported DeclareCommands payload kind {layout.PayloadKind}."); + } + } + + private static void ReadNumberBounds(DataTypes dataTypes, Queue packetData, Func, TValue> readValue) + { + byte flags = dataTypes.ReadNextByte(packetData); + if ((flags & 0x01) != 0) + _ = readValue(dataTypes, packetData); + if ((flags & 0x02) != 0) + _ = readValue(dataTypes, packetData); } private static string[] ExtractRootCommand() @@ -179,74 +205,398 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c List commands = new(); CommandNode root = Nodes[RootIdx]; - foreach (var child in root.Clildren) + + foreach (int child in root.Children) { if (!IsValidNodeIndex(child)) continue; string? childName = Nodes[child].Name; - if (childName != null) + if (!string.IsNullOrEmpty(childName)) commands.Add(childName); } + return commands.ToArray(); } - public static List> CollectSignArguments(string command) + private static bool TryMatchNode( + int nodeIdx, + string command, + int position, + List> signedArguments, + out List> matchedArguments) { - List> needSigned = new(); - if (!HasValidCommandTree()) - return needSigned; + matchedArguments = signedArguments; + if (!IsValidNodeIndex(nodeIdx)) + return false; - CollectSignArguments(RootIdx, command, needSigned); - return needSigned; + CommandNode node = Nodes[nodeIdx]; + if (!TryConsumeNode(node, command, position, out int nextPosition, out Tuple? signedCapture)) + return false; + + List> currentArguments = signedArguments; + if (signedCapture != null) + { + currentArguments = new List>(signedArguments.Count + 1); + currentArguments.AddRange(signedArguments); + currentArguments.Add(signedCapture); + } + + int traversalNodeIdx = ResolveRedirect(nodeIdx); + bool canStopHere = node.IsExecutable || + (traversalNodeIdx != nodeIdx && IsValidNodeIndex(traversalNodeIdx) && Nodes[traversalNodeIdx].IsExecutable); + + if (nextPosition == command.Length) + { + if (canStopHere) + { + matchedArguments = currentArguments; + return true; + } + + return false; + } + + int childPosition = nextPosition; + if (node.Kind != CommandNodeKind.Root) + { + if (command[childPosition] != ' ') + return false; + childPosition++; + } + + return TryMatchChildren(traversalNodeIdx, command, childPosition, currentArguments, out matchedArguments); } - private static void CollectSignArguments(int NodeIdx, string command, List> arguments) + private static bool TryMatchChildren( + int nodeIdx, + string command, + int position, + List> signedArguments, + out List> matchedArguments) { - if (!IsValidNodeIndex(NodeIdx)) - return; + matchedArguments = signedArguments; + if (!IsValidNodeIndex(nodeIdx)) + return false; - CommandNode node = Nodes[NodeIdx]; - string last_arg = command; - switch (node.Flags & 0x03) + int[] children = Nodes[nodeIdx].Children; + + for (int pass = 0; pass < 2; ++pass) { - case 0: // root - break; - case 1: // literal - { - string[] arg = command.Split(' ', 2, StringSplitOptions.None); - if (!(arg.Length == 2 && node.Name! == arg[0])) - return; - last_arg = arg[1]; - } - break; - case 2: // argument - { - int argCnt = (node.Paser == null) ? 1 : node.Paser.GetArgCnt(); - string[] arg = command.Split(' ', argCnt + 1, StringSplitOptions.None); - if ((node.Flags & 0x04) > 0) - { - if (node.Paser != null && node.Paser.GetName() == "minecraft:message") - arguments.Add(new(node.Name!, command)); - } - if (!(arg.Length == argCnt + 1)) - return; - last_arg = arg[^1]; - } - break; + foreach (int childIdx in children) + { + if (!IsValidNodeIndex(childIdx)) + continue; + + bool isLiteral = Nodes[childIdx].Kind == CommandNodeKind.Literal; + if ((pass == 0 && !isLiteral) || (pass == 1 && isLiteral)) + continue; + + if (TryMatchNode(childIdx, command, position, signedArguments, out matchedArguments)) + return true; + } + } + + return false; + } + + private static bool TryConsumeNode( + CommandNode node, + string command, + int position, + out int nextPosition, + out Tuple? signedCapture) + { + nextPosition = position; + signedCapture = null; + + switch (node.Kind) + { + case CommandNodeKind.Root: + return true; + case CommandNodeKind.Literal: + return TryConsumeLiteral(command, position, node.Name!, out nextPosition); + case CommandNodeKind.Argument: + if (node.Argument == null || !TryConsumeArgument(command, position, node.Argument.Value, out nextPosition)) + return false; + + if (node.Argument.Value.IsSigned) + signedCapture = new Tuple(node.Name!, command[position..nextPosition]); + + return true; default: - break; + return false; } + } - while (Nodes[NodeIdx].RedirectNode >= 0) + private static bool TryConsumeLiteral(string command, int position, string literal, out int nextPosition) + { + nextPosition = position; + if (position + literal.Length > command.Length) + return false; + + if (string.CompareOrdinal(command, position, literal, 0, literal.Length) != 0) + return false; + + nextPosition = position + literal.Length; + return nextPosition == command.Length || command[nextPosition] == ' '; + } + + private static bool TryConsumeArgument(string command, int position, CommandArgumentDescriptor descriptor, out int nextPosition) + { + nextPosition = position; + + return descriptor.Consumption switch { - NodeIdx = Nodes[NodeIdx].RedirectNode; - if (!IsValidNodeIndex(NodeIdx)) - return; + ArgumentConsumption.SingleToken => TryConsumeSingleToken(command, position, out nextPosition), + ArgumentConsumption.QuotedStringOrWord => TryConsumeQuotedStringOrWord(command, position, out nextPosition), + ArgumentConsumption.GreedyTail => TryConsumeGreedyTail(command, position, out nextPosition), + ArgumentConsumption.FixedTokenCount => TryConsumeFixedTokenCount(command, position, descriptor.TokenCount, out nextPosition), + _ => false + }; + } + + private static bool TryConsumeSingleToken(string command, int position, out int nextPosition) + { + nextPosition = position; + if (position >= command.Length) + return false; + + int cursor = position; + while (cursor < command.Length && command[cursor] != ' ') + cursor++; + + nextPosition = cursor; + return cursor > position; + } + + private static bool TryConsumeQuotedStringOrWord(string command, int position, out int nextPosition) + { + nextPosition = position; + if (position >= command.Length) + return false; + + if (command[position] != '"') + return TryConsumeSingleToken(command, position, out nextPosition); + + bool escaped = false; + for (int cursor = position + 1; cursor < command.Length; ++cursor) + { + char current = command[cursor]; + if (escaped) + { + escaped = false; + continue; + } + + if (current == '\\') + { + escaped = true; + continue; + } + + if (current == '"') + { + nextPosition = cursor + 1; + return nextPosition == command.Length || command[nextPosition] == ' '; + } } - foreach (int childIdx in Nodes[NodeIdx].Clildren) - CollectSignArguments(childIdx, last_arg, arguments); + return false; + } + + private static bool TryConsumeGreedyTail(string command, int position, out int nextPosition) + { + nextPosition = command.Length; + return position < command.Length; + } + + private static bool TryConsumeFixedTokenCount(string command, int position, int tokenCount, out int nextPosition) + { + nextPosition = position; + int cursor = position; + + for (int i = 0; i < tokenCount; ++i) + { + if (!TryConsumeSingleToken(command, cursor, out int tokenEnd)) + return false; + + cursor = tokenEnd; + if (i < tokenCount - 1) + { + if (cursor >= command.Length || command[cursor] != ' ') + return false; + + cursor++; + } + } + + nextPosition = cursor; + return true; + } + + private static int ResolveRedirect(int nodeIdx) + { + if (!IsValidNodeIndex(nodeIdx)) + return -1; + + HashSet visited = new(); + int current = nodeIdx; + + while (IsValidNodeIndex(current) && Nodes[current].RedirectNode >= 0) + { + if (!visited.Add(current)) + return current; + + current = Nodes[current].RedirectNode; + } + + return IsValidNodeIndex(current) ? current : -1; + } + + private static bool TryResolveArgumentTypeLayout(int protocolVersion, int parserId, out ArgumentTypeLayout layout) + { + return protocolVersion >= Protocol18Handler.MC_1_20_6_Version + ? TryResolveModernArgumentTypeLayout(protocolVersion, parserId, out layout) + : TryResolveLegacyArgumentTypeLayout(protocolVersion, parserId, out layout); + } + + private static bool TryResolveModernArgumentTypeLayout(int protocolVersion, int parserId, out ArgumentTypeLayout layout) + { + string[] registry = protocolVersion switch + { + >= Protocol18Handler.MC_1_21_6_Version => s_modernArgumentTypes1216, + >= Protocol18Handler.MC_1_21_5_Version => s_modernArgumentTypes1215, + _ => s_modernArgumentTypes1206 + }; + + if (parserId < 0 || parserId >= registry.Length) + { + layout = default; + return false; + } + + return s_argumentTypeCatalog.TryGetValue(ToCanonicalArgumentTypeName(registry[parserId]), out layout); + } + + private static bool TryResolveLegacyArgumentTypeLayout(int protocolVersion, int parserId, out ArgumentTypeLayout layout) + { + string? name; + + if (protocolVersion <= Protocol18Handler.MC_1_19_2_Version) + { + name = parserId switch + { + 1 => "brigadier:float", + 2 => "brigadier:double", + 3 => "brigadier:integer", + 4 => "brigadier:long", + 5 => "brigadier:string", + 6 => "minecraft:entity", + 8 => "minecraft:block_pos", + 9 => "minecraft:column_pos", + 10 => "minecraft:vec3", + 11 => "minecraft:vec2", + 18 => "minecraft:message", + 27 => "minecraft:rotation", + 29 => "minecraft:score_holder", + 43 => "minecraft:resource_or_tag", + 44 => "minecraft:resource", + 50 => "forge:enum", + _ => null + }; + } + else if (protocolVersion <= Protocol18Handler.MC_1_19_3_Version) + { + name = parserId switch + { + 1 => "brigadier:float", + 2 => "brigadier:double", + 3 => "brigadier:integer", + 4 => "brigadier:long", + 5 => "brigadier:string", + 6 => "minecraft:entity", + 8 => "minecraft:block_pos", + 9 => "minecraft:column_pos", + 10 => "minecraft:vec3", + 11 => "minecraft:vec2", + 18 => "minecraft:message", + 27 => "minecraft:rotation", + 29 => "minecraft:score_holder", + 41 => "minecraft:resource_or_tag", + 42 => "minecraft:resource_or_tag_key", + 43 => "minecraft:resource", + 44 => "minecraft:resource_key", + 50 => "forge:enum", + _ => null + }; + } + else if (protocolVersion <= Protocol18Handler.MC_1_20_2_Version) + { + name = parserId switch + { + 1 => "brigadier:float", + 2 => "brigadier:double", + 3 => "brigadier:integer", + 4 => "brigadier:long", + 5 => "brigadier:string", + 6 => "minecraft:entity", + 8 => "minecraft:block_pos", + 9 => "minecraft:column_pos", + 10 => "minecraft:vec3", + 11 => "minecraft:vec2", + 18 => "minecraft:message", + 27 => "minecraft:rotation", + 29 => "minecraft:score_holder", + 40 => "minecraft:time", + 41 => "minecraft:resource_or_tag", + 42 => "minecraft:resource_or_tag_key", + 43 => "minecraft:resource", + 44 => "minecraft:resource_key", + 50 when protocolVersion == Protocol18Handler.MC_1_19_4_Version => "forge:enum", + 51 when protocolVersion is >= Protocol18Handler.MC_1_20_Version and <= Protocol18Handler.MC_1_20_2_Version => "forge:enum", + _ => null + }; + } + else + { + name = parserId switch + { + 1 => "brigadier:float", + 2 => "brigadier:double", + 3 => "brigadier:integer", + 4 => "brigadier:long", + 5 => "brigadier:string", + 6 => "minecraft:entity", + 8 => "minecraft:block_pos", + 9 => "minecraft:column_pos", + 10 => "minecraft:vec3", + 11 => "minecraft:vec2", + 18 or 19 => "minecraft:message", + 27 => "minecraft:rotation", + 30 => "minecraft:score_holder", + 41 => "minecraft:time", + 42 => "minecraft:resource_or_tag", + 43 => "minecraft:resource_or_tag_key", + 44 => "minecraft:resource", + 45 => "minecraft:resource_key", + 52 => "forge:enum", + _ => null + }; + } + + if (name == null) + { + layout = s_unknownLegacyArgumentType; + return true; + } + + return s_argumentTypeCatalog.TryGetValue(name, out layout); + } + + private static string ToCanonicalArgumentTypeName(string rawName) + { + return rawName.Contains(':', StringComparison.Ordinal) ? rawName : "minecraft:" + rawName; } private static void Reset() @@ -254,6 +604,7 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c RootIdx = -1; Nodes = Array.Empty(); HasLoadedTree = false; + LastReadError = null; } private static bool HasValidCommandTree() @@ -266,508 +617,197 @@ namespace MinecraftClient.Protocol.Handlers.packet.s2c return nodeIdx >= 0 && nodeIdx < Nodes.Length; } - internal class CommandNode + private static Dictionary CreateArgumentTypeCatalog() { - public byte Flags; - public int[] Clildren; - public int RedirectNode; - public string? Name; - public Parser? Paser; - public string? SuggestionsType; - public int ParserId; // Added for easy debug + Dictionary catalog = new(StringComparer.Ordinal); - - public CommandNode(byte Flags, - int[] Clildren, - int RedirectNode = -1, - string? Name = null, - Parser? Paser = null, - string? SuggestionsType = null, - int parserId = -1) + static void Add( + Dictionary items, + string name, + ArgumentPayloadKind payloadKind = ArgumentPayloadKind.None, + ArgumentConsumption consumption = ArgumentConsumption.SingleToken, + int tokenCount = 1, + bool isSigned = false) { - this.Flags = Flags; - this.Clildren = Clildren; - this.RedirectNode = RedirectNode; - this.Name = Name; - this.Paser = Paser; - this.SuggestionsType = SuggestionsType; + items[name] = new ArgumentTypeLayout(name, payloadKind, consumption, tokenCount, isSigned); + } + + static void AddFixedTokens(Dictionary items, string name, int tokenCount) + { + Add(items, name, consumption: ArgumentConsumption.FixedTokenCount, tokenCount: tokenCount); + } + + Add(catalog, "brigadier:bool"); + Add(catalog, "brigadier:float", ArgumentPayloadKind.BrigadierFloat); + Add(catalog, "brigadier:double", ArgumentPayloadKind.BrigadierDouble); + Add(catalog, "brigadier:integer", ArgumentPayloadKind.BrigadierInteger); + Add(catalog, "brigadier:long", ArgumentPayloadKind.BrigadierLong); + Add(catalog, "brigadier:string", ArgumentPayloadKind.BrigadierString); + Add(catalog, "minecraft:entity", ArgumentPayloadKind.Entity); + Add(catalog, "minecraft:game_profile"); + AddFixedTokens(catalog, "minecraft:block_pos", 3); + AddFixedTokens(catalog, "minecraft:column_pos", 2); + AddFixedTokens(catalog, "minecraft:vec3", 3); + AddFixedTokens(catalog, "minecraft:vec2", 2); + Add(catalog, "minecraft:block_state"); + Add(catalog, "minecraft:block_predicate"); + Add(catalog, "minecraft:item_stack"); + Add(catalog, "minecraft:item_predicate"); + Add(catalog, "minecraft:color"); + Add(catalog, "minecraft:hex_color"); + Add(catalog, "minecraft:component"); + Add(catalog, "minecraft:style"); + Add(catalog, "minecraft:message", consumption: ArgumentConsumption.GreedyTail, isSigned: true); + Add(catalog, "minecraft:nbt_compound_tag"); + Add(catalog, "minecraft:nbt_tag"); + Add(catalog, "minecraft:nbt_path"); + Add(catalog, "minecraft:objective"); + Add(catalog, "minecraft:objective_criteria"); + Add(catalog, "minecraft:operation"); + Add(catalog, "minecraft:particle"); + Add(catalog, "minecraft:angle"); + AddFixedTokens(catalog, "minecraft:rotation", 2); + Add(catalog, "minecraft:scoreboard_slot"); + Add(catalog, "minecraft:score_holder", ArgumentPayloadKind.ScoreHolder); + Add(catalog, "minecraft:swizzle"); + Add(catalog, "minecraft:team"); + Add(catalog, "minecraft:item_slot"); + Add(catalog, "minecraft:item_slots"); + Add(catalog, "minecraft:resource_location"); + Add(catalog, "minecraft:function"); + Add(catalog, "minecraft:entity_anchor"); + Add(catalog, "minecraft:int_range"); + Add(catalog, "minecraft:float_range"); + Add(catalog, "minecraft:dimension"); + Add(catalog, "minecraft:gamemode"); + Add(catalog, "minecraft:time", ArgumentPayloadKind.Time); + Add(catalog, "minecraft:resource_or_tag", ArgumentPayloadKind.RegistryKey); + Add(catalog, "minecraft:resource_or_tag_key", ArgumentPayloadKind.RegistryKey); + Add(catalog, "minecraft:resource", ArgumentPayloadKind.RegistryKey); + Add(catalog, "minecraft:resource_key", ArgumentPayloadKind.RegistryKey); + Add(catalog, "minecraft:resource_selector", ArgumentPayloadKind.RegistryKey); + Add(catalog, "minecraft:template_mirror"); + Add(catalog, "minecraft:template_rotation"); + Add(catalog, "minecraft:heightmap"); + Add(catalog, "minecraft:loot_table"); + Add(catalog, "minecraft:loot_predicate"); + Add(catalog, "minecraft:loot_modifier"); + Add(catalog, "minecraft:dialog"); + Add(catalog, "minecraft:uuid"); + Add(catalog, "forge:enum", ArgumentPayloadKind.ForgeEnum); + + return catalog; + } + + private enum CommandNodeKind : byte + { + Root = 0, + Literal = 1, + Argument = 2 + } + + private enum ArgumentConsumption + { + SingleToken, + QuotedStringOrWord, + GreedyTail, + FixedTokenCount + } + + private enum ArgumentPayloadKind + { + None, + BrigadierFloat, + BrigadierDouble, + BrigadierInteger, + BrigadierLong, + BrigadierString, + Entity, + ScoreHolder, + Time, + RegistryKey, + ForgeEnum + } + + private sealed class CommandNode + { + public byte Flags { get; } + public int[] Children { get; } + public int RedirectNode { get; } + public string? Name { get; } + public CommandArgumentDescriptor? Argument { get; } + public string? SuggestionsType { get; } + public int ParserId { get; } + + public CommandNodeKind Kind => (CommandNodeKind)(Flags & NodeTypeMask); + public bool IsExecutable => (Flags & NodeExecutableFlag) != 0; + public bool IsRestricted => (Flags & NodeRestrictedFlag) != 0; + + public CommandNode( + byte flags, + int[] children, + int redirectNode = -1, + string? name = null, + CommandArgumentDescriptor? argument = null, + string? suggestionsType = null, + int parserId = -1) + { + Flags = flags; + Children = children; + RedirectNode = redirectNode; + Name = name; + Argument = argument; + SuggestionsType = suggestionsType; ParserId = parserId; } } - internal abstract class Parser + private readonly struct CommandArgumentDescriptor { - public abstract string GetName(); + public string Name { get; } + public ArgumentConsumption Consumption { get; } + public int TokenCount { get; } + public bool IsSigned { get; } - public abstract int GetArgCnt(); - - public abstract bool Check(string text); - } - - internal class ParserEmpty : Parser - { - - public ParserEmpty(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) + public CommandArgumentDescriptor(string name, ArgumentConsumption consumption, int tokenCount = 1, bool isSigned = false) { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return ""; + Name = name; + Consumption = consumption; + TokenCount = tokenCount; + IsSigned = isSigned; } } - internal class ParserFloat : Parser + private readonly struct ArgumentTypeLayout { - private byte Flags; - private float Min = float.MinValue, Max = float.MaxValue; + public string Name { get; } + public ArgumentPayloadKind PayloadKind { get; } + public ArgumentConsumption Consumption { get; } + public int TokenCount { get; } + public bool IsSigned { get; } - public ParserFloat(DataTypes dataTypes, Queue packetData) + public ArgumentTypeLayout( + string name, + ArgumentPayloadKind payloadKind = ArgumentPayloadKind.None, + ArgumentConsumption consumption = ArgumentConsumption.SingleToken, + int tokenCount = 1, + bool isSigned = false) { - Flags = dataTypes.ReadNextByte(packetData); - if ((Flags & 0x01) > 0) - Min = dataTypes.ReadNextFloat(packetData); - if ((Flags & 0x02) > 0) - Max = dataTypes.ReadNextFloat(packetData); + Name = name; + PayloadKind = payloadKind; + Consumption = consumption; + TokenCount = tokenCount; + IsSigned = isSigned; } - public override bool Check(string text) + public CommandArgumentDescriptor CreateDescriptor() { - return true; + return new CommandArgumentDescriptor(Name, Consumption, TokenCount, IsSigned); } - public override int GetArgCnt() + public CommandArgumentDescriptor CreateDescriptor(ArgumentConsumption consumption) { - return 1; - } - - public override string GetName() - { - return "brigadier:float"; - } - } - - internal class ParserDouble : Parser - { - private byte Flags; - private double Min = double.MinValue, Max = double.MaxValue; - - public ParserDouble(DataTypes dataTypes, Queue packetData) - { - Flags = dataTypes.ReadNextByte(packetData); - if ((Flags & 0x01) > 0) - Min = dataTypes.ReadNextDouble(packetData); - if ((Flags & 0x02) > 0) - Max = dataTypes.ReadNextDouble(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "brigadier:double"; - } - } - - internal class ParserInteger : Parser - { - private byte Flags; - private int Min = int.MinValue, Max = int.MaxValue; - - public ParserInteger(DataTypes dataTypes, Queue packetData) - { - Flags = dataTypes.ReadNextByte(packetData); - if ((Flags & 0x01) > 0) - Min = dataTypes.ReadNextInt(packetData); - if ((Flags & 0x02) > 0) - Max = dataTypes.ReadNextInt(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "brigadier:integer"; - } - } - - internal class ParserLong : Parser - { - private byte Flags; - private long Min = long.MinValue, Max = long.MaxValue; - - public ParserLong(DataTypes dataTypes, Queue packetData) - { - Flags = dataTypes.ReadNextByte(packetData); - if ((Flags & 0x01) > 0) - Min = dataTypes.ReadNextLong(packetData); - if ((Flags & 0x02) > 0) - Max = dataTypes.ReadNextLong(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "brigadier:long"; - } - } - - internal class ParserString : Parser - { - private StringType Type; - - private enum StringType { SINGLE_WORD, QUOTABLE_PHRASE, GREEDY_PHRASE }; - - public ParserString(DataTypes dataTypes, Queue packetData) - { - Type = (StringType)dataTypes.ReadNextVarInt(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "brigadier:string"; - } - } - - internal class ParserEntity : Parser - { - private byte Flags; - - public ParserEntity(DataTypes dataTypes, Queue packetData) - { - Flags = dataTypes.ReadNextByte(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:entity"; - } - } - - internal class ParserBlockPos : Parser - { - - public ParserBlockPos(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 3; - } - - public override string GetName() - { - return "minecraft:block_pos"; - } - } - - internal class ParserColumnPos : Parser - { - - public ParserColumnPos(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 3; - } - - public override string GetName() - { - return "minecraft:column_pos"; - } - } - - internal class ParserVec3 : Parser - { - - public ParserVec3(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 3; - } - - public override string GetName() - { - return "minecraft:vec3"; - } - } - - internal class ParserVec2 : Parser - { - - public ParserVec2(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 2; - } - - public override string GetName() - { - return "minecraft:vec2"; - } - } - - internal class ParserRotation : Parser - { - - public ParserRotation(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 2; - } - - public override string GetName() - { - return "minecraft:rotation"; - } - } - - internal class ParserMessage : Parser - { - public ParserMessage(DataTypes dataTypes, Queue packetData) { } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:message"; - } - } - - internal class ParserScoreHolder : Parser - { - private byte Flags; - - public ParserScoreHolder(DataTypes dataTypes, Queue packetData) - { - Flags = dataTypes.ReadNextByte(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:score_holder"; - } - } - - internal class ParserRange : Parser - { - private bool Decimals; - - public ParserRange(DataTypes dataTypes, Queue packetData) - { - Decimals = dataTypes.ReadNextBool(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:range"; - } - } - - internal class ParserResourceOrTag : Parser - { - private string Registry; - - public ParserResourceOrTag(DataTypes dataTypes, Queue packetData) - { - Registry = dataTypes.ReadNextString(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:resource_or_tag"; - } - } - - internal class ParserResource : Parser - { - private string Registry; - - public ParserResource(DataTypes dataTypes, Queue packetData) - { - Registry = dataTypes.ReadNextString(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:resource"; - } - } - - /// - /// Undocumented parser type for 1.19.4+ - /// - internal class ParserTime : Parser - { - public ParserTime(DataTypes dataTypes, Queue packetData) - { - dataTypes.ReadNextInt(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "minecraft:time"; - } - } - - internal class ParserForgeEnum : Parser - { - public ParserForgeEnum(DataTypes dataTypes, Queue packetData) - { - dataTypes.ReadNextString(packetData); - } - - public override bool Check(string text) - { - return true; - } - - public override int GetArgCnt() - { - return 1; - } - - public override string GetName() - { - return "forge:enum"; + return new CommandArgumentDescriptor(Name, consumption, TokenCount, IsSigned); } } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 98d7aec7..09d4f6bc 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3702,8 +3702,13 @@ namespace MinecraftClient.Protocol.Handlers try { List>? needSigned = null; + bool canSignCommand = protocolVersion >= MC_1_19_Version && + isOnlineMode && + playerKeyPair != null && + Config.Signature.LoginWithSecureProfile && + Config.Signature.SignMessageInCommand; - if (protocolVersion >= MC_1_19_Version && Config.Signature is { LoginWithSecureProfile: true, SignMessageInCommand: true }) + if (canSignCommand) { if (DeclareCommands.IsCommandTreeAvailable) { diff --git a/tools/README.md b/tools/README.md index 17df9676..f8ba7226 100644 --- a/tools/README.md +++ b/tools/README.md @@ -102,6 +102,14 @@ Reads `EntityDataSerializers.java` static block registration order. Maps Java fi 2. MCC's `EntityMetaDataType.cs` enum 3. `DataTypes.cs` ReadNextMetadata() read logic +## gen_command_argument_registry.py — Generate DeclareCommands registry arrays + +```bash +python3 tools/gen_command_argument_registry.py 1.20.6 1.21.5 1.21.6 +``` + +Reads `ArgumentTypeInfos.java`, skips the `SharedConstants.IS_RUNNING_IN_IDE` block, and prints C# array initializers for the runtime `COMMAND_ARGUMENT_TYPE` registry order. Use this when Mojang inserts new command argument types and the modern `DeclareCommands` parser needs updated ID routing. + ## Recommended workflow 1. Generate server reports (Step 0) diff --git a/tools/gen_command_argument_registry.py b/tools/gen_command_argument_registry.py new file mode 100644 index 00000000..6e6b70a2 --- /dev/null +++ b/tools/gen_command_argument_registry.py @@ -0,0 +1,85 @@ + +#!/usr/bin/env python3 +""" +Generate ordered DeclareCommands argument-type arrays from decompiled ArgumentTypeInfos.java. + +The runtime server registry excludes registrations guarded by SharedConstants.IS_RUNNING_IN_IDE, +so this script skips that block before emitting the final order. +""" + +from __future__ import annotations + +import argparse +import re +from pathlib import Path + + +REGISTER_RE = re.compile(r'register\(\$\$0, "([^"]+)"') + + +def extract_runtime_argument_types(path: Path) -> list[str]: + names: list[str] = [] + skipping_ide_block = False + brace_depth = 0 + + for line in path.read_text(encoding="utf-8").splitlines(): + if "if (SharedConstants.IS_RUNNING_IN_IDE)" in line: + skipping_ide_block = True + brace_depth += line.count("{") - line.count("}") + continue + + if skipping_ide_block: + brace_depth += line.count("{") - line.count("}") + if brace_depth <= 0: + skipping_ide_block = False + brace_depth = 0 + continue + + match = REGISTER_RE.search(line) + if match: + names.append(match.group(1)) + + return names + + +def emit_csharp_array(version: str, names: list[str]) -> str: + lines = [ + f"// {version} ({len(names)})", + f"private static readonly string[] s_modernArgumentTypes{version.replace('.', '')} =", + "[", + ] + + for index, name in enumerate(names): + suffix = "," if index < len(names) - 1 else "" + lines.append(f' "{name}"{suffix}') + + lines.append("];") + return "\n".join(lines) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "versions", + nargs="+", + help="Minecraft version folders under MinecraftOfficial/, for example: 1.20.6 1.21.5 1.21.6", + ) + parser.add_argument( + "--repo-root", + default=Path(__file__).resolve().parents[1], + type=Path, + help="Repository root. Defaults to the current repo.", + ) + args = parser.parse_args() + + for version in args.versions: + source = args.repo_root / "MinecraftOfficial" / f"{version}-decompiled" / "net" / "minecraft" / "commands" / "synchronization" / "ArgumentTypeInfos.java" + names = extract_runtime_argument_types(source) + print(emit_csharp_array(version, names)) + print() + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 9e3bfaa868e8433410d61369f990d5f0e8c4ea6f Mon Sep 17 00:00:00 2001 From: breadbyte <14045257+breadbyte@users.noreply.github.com> Date: Sun, 22 Mar 2026 13:50:20 +0800 Subject: [PATCH 093/484] Update ConsoleInteractive submodule --- ConsoleInteractive | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ConsoleInteractive b/ConsoleInteractive index a045f7ed..f6306528 160000 --- a/ConsoleInteractive +++ b/ConsoleInteractive @@ -1 +1 @@ -Subproject commit a045f7eddd0e6d914715f358dd7333071e5dd567 +Subproject commit f63065282a4bd64758e7e8d30f232e3dc8ce2622 From cca4134e8bb87cbafa256f5ce7d928a522829d91 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 15:23:55 +0800 Subject: [PATCH 094/484] feat: enhance decompilation and server management scripts - Introduced `decompile.sh` to automate the decompilation process, including downloading `MinecraftDecompiler.jar` and server.jar for specified Minecraft versions. - Added `mc-rcon.sh` for sending RCON commands to a Minecraft server, improving server management capabilities. - Created `mcc-env.sh` to provide helper functions for managing Minecraft servers, including starting, stopping, and sending commands. - Implemented `start-server.sh` to launch a Minecraft server in a tmux session with a named pipe for stdin, facilitating easier command input. - Updated `README.md` to reflect new tools and usage instructions for decompiling and server management. These changes streamline the workflow for adapting to new Minecraft versions and enhance the overall development experience. --- .skills/mcc-version-adaptation/SKILL.md | 44 ++++++-- tools/README.md | 12 ++- tools/decompile.sh | 138 ++++++++++++++++++++++++ tools/mc-rcon.sh | 46 ++++++++ tools/mcc-env.sh | 33 ++++++ tools/start-server.sh | 39 +++++++ 6 files changed, 301 insertions(+), 11 deletions(-) create mode 100644 tools/decompile.sh create mode 100644 tools/mc-rcon.sh create mode 100644 tools/mcc-env.sh create mode 100644 tools/start-server.sh diff --git a/.skills/mcc-version-adaptation/SKILL.md b/.skills/mcc-version-adaptation/SKILL.md index 44023b06..ce21cf04 100644 --- a/.skills/mcc-version-adaptation/SKILL.md +++ b/.skills/mcc-version-adaptation/SKILL.md @@ -10,13 +10,12 @@ Systematic workflow for updating Minecraft Console Client to support a new Minec ## Prerequisites - Decompiled server source for both the old and new MC versions in `$MCC_REPO/MinecraftOfficial/-decompiled/` -- If missing, decompile first: +- If missing, decompile and download server.jar: ```bash - cd $MCC_REPO/MinecraftOfficial - java -jar MinecraftDecompiler.jar --version --side SERVER \ - --decompile --output -remapped.jar --decompiled-output -decompiled + $MCC_REPO/tools/decompile.sh --version ``` -- A test server of the target version in `$MCC_SERVERS/` (see `mcc-dev-workflow` skill) + This auto-downloads `MinecraftDecompiler.jar` if needed, produces the decompiled source, and downloads `server.jar` into `$MCC_SERVERS//`. +- A test server of the target version in `$MCC_SERVERS//` (see `mcc-dev-workflow` skill) ## Step 0: Generate Server Reports (CRITICAL since 1.21.9) @@ -24,7 +23,7 @@ Systematic workflow for updating Minecraft Console Client to support a new Minec ```bash cd /tmp && java -DbundlerMainClass=net.minecraft.data.Main \ - -jar $MCC_SERVERS/-Vanilla/server.jar \ + -jar $MCC_SERVERS//server.jar \ --reports --output /tmp/mc_reports ``` @@ -186,7 +185,37 @@ Compare key packet codec classes between versions. Known changes: When in doubt, compare the relevant packet class (e.g. `ClientboundAddEntityPacket.java`) between versions. -## Step 8: Compile and Verify +## Step 8: Update Block Collision Shapes (Physics Engine) + +MCC's physics engine uses block collision shape data from PrismarineJS `minecraft-data` to perform accurate AABB collision detection (stored in `MinecraftClient/Physics/BlockShapeData.json`, embedded as a resource). + +When a new MC version introduces new blocks or changes block shapes, update this data: + +```bash +# Download and compact collision shapes for the target version +python3 $MCC_REPO/tools/gen_block_shapes.py +# e.g. python3 tools/gen_block_shapes.py 1.21.11 +``` + +If network is slow or unreliable, download the file manually and convert: +```bash +# Manual download +curl -L -o /tmp/bcs.json \ + "https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc//blockCollisionShapes.json" + +# Then compact from local file +python3 $MCC_REPO/tools/gen_block_shapes.py --from-file /tmp/bcs.json +``` + +Output: `MinecraftClient/Physics/BlockShapeData.json` (embedded via `MinecraftClient.csproj`) + +The JSON maps block names (snake_case) → collision shape IDs → AABB coordinates. At runtime, `BlockShapes.cs` maps MCC's block state IDs to these AABBs using the block palette. + +**When to update**: Whenever new blocks are added that have non-trivial collision shapes (e.g., new slab variants, stairs, fences). If only items or entities changed, this step can be skipped. + +**Data source**: PrismarineJS `minecraft-data` repo, path: `data/pc//blockCollisionShapes.json`. Version availability can be checked via `data/dataPaths.json`. + +## Step 9: Compile and Verify ```bash dotnet build $MCC_REPO/MinecraftClient.sln -c Release @@ -244,3 +273,4 @@ All scripts are in `$MCC_REPO/tools/`. See `tools/README.md` for detailed usage. | `gen_block_palette.py` | Generate BlockPalette C# | blocks.json | | `gen_entity_palette.py` | Generate EntityPalette C# | registries.json | | `gen_entity_metadata_palette.py` | Generate EntityMetadataPalette C# | Decompiled source | +| `gen_block_shapes.py` | Download & compact block collision shapes | PrismarineJS minecraft-data | diff --git a/tools/README.md b/tools/README.md index f8ba7226..17c2d5cb 100644 --- a/tools/README.md +++ b/tools/README.md @@ -18,17 +18,21 @@ Two types of data can be used as input: ### Decompiling a new MC version ```bash -cd MinecraftOfficial -java -jar MinecraftDecompiler.jar --version 1.21.9 --side SERVER \ - --decompile --output 1.21.9-remapped.jar --decompiled-output 1.21.9-decompiled +# Server side (default) — also downloads server.jar into MinecraftOfficial/downloads// +tools/decompile.sh --version 1.21.9 + +# Client side +tools/decompile.sh --version 1.21.9 --side CLIENT ``` +The script auto-downloads `MinecraftDecompiler.jar` from GitHub releases if it doesn't exist. + ### Generating server data reports ```bash cd /tmp java -DbundlerMainClass=net.minecraft.data.Main \ - -jar /path/to/server.jar \ + -jar $MCC_SERVERS//server.jar \ --reports --output /tmp/mc_reports ``` diff --git a/tools/decompile.sh b/tools/decompile.sh new file mode 100644 index 00000000..cd17ab7a --- /dev/null +++ b/tools/decompile.sh @@ -0,0 +1,138 @@ +#!/bin/bash +# Download (if needed) and run MinecraftDecompiler to produce decompiled source +# and server.jar for a given Minecraft version. +# +# Usage: +# ./tools/decompile.sh --version [--side SERVER|CLIENT] +# +# Examples: +# ./tools/decompile.sh --version 1.21.11 +# ./tools/decompile.sh --version 1.21.11 --side CLIENT + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +MC_OFFICIAL="$REPO_ROOT/MinecraftOfficial" +DECOMPILER_JAR="$MC_OFFICIAL/MinecraftDecompiler.jar" +DECOMPILER_REPO="MaxPixelStudios/MinecraftDecompiler" + +VERSION="" +SIDE="SERVER" + +while [[ $# -gt 0 ]]; do + case "$1" in + --version) VERSION="$2"; shift 2 ;; + --side) SIDE="$(echo "$2" | tr '[:lower:]' '[:upper:]')"; shift 2 ;; + -h|--help) + echo "Usage: $0 --version [--side SERVER|CLIENT]" + echo "" + echo "Options:" + echo " --version Minecraft version (e.g. 1.21.11)" + echo " --side SERVER (default) or CLIENT" + exit 0 + ;; + *) echo "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$VERSION" ]]; then + echo "Error: --version is required" + echo "Usage: $0 --version [--side SERVER|CLIENT]" + exit 1 +fi + +if [[ "$SIDE" != "SERVER" && "$SIDE" != "CLIENT" ]]; then + echo "Error: --side must be SERVER or CLIENT (got: $SIDE)" + exit 1 +fi + +# --- Ensure MinecraftDecompiler.jar exists --- +if [[ ! -f "$DECOMPILER_JAR" ]]; then + echo "MinecraftDecompiler.jar not found, downloading latest release..." + DOWNLOAD_URL=$(curl -sL "https://api.github.com/repos/$DECOMPILER_REPO/releases/latest" \ + | python3 -c " +import json, sys +data = json.load(sys.stdin) +for a in data['assets']: + if a['name'] == 'MinecraftDecompiler.jar': + print(a['browser_download_url']) + break +") + if [[ -z "$DOWNLOAD_URL" ]]; then + echo "Error: could not find MinecraftDecompiler.jar in latest release" + exit 1 + fi + echo "Downloading from $DOWNLOAD_URL ..." + curl -L -o "$DECOMPILER_JAR" "$DOWNLOAD_URL" + echo "Downloaded MinecraftDecompiler.jar" +fi + +# --- Build output paths --- +SIDE_LOWER="$(echo "$SIDE" | tr '[:upper:]' '[:lower:]')" + +if [[ "$SIDE" == "SERVER" ]]; then + REMAPPED_JAR="$MC_OFFICIAL/remapped_jar/${VERSION}-remapped.jar" + DECOMPILED_DIR="$MC_OFFICIAL/${VERSION}-decompiled" +else + REMAPPED_JAR="$MC_OFFICIAL/remapped_jar/${VERSION}-${SIDE_LOWER}-remapped.jar" + DECOMPILED_DIR="$MC_OFFICIAL/${VERSION}-${SIDE_LOWER}-decompiled" +fi + +if [[ -d "$DECOMPILED_DIR" ]]; then + echo "Decompiled source already exists: $DECOMPILED_DIR" + echo "Delete it first if you want to re-decompile." + exit 0 +fi + +mkdir -p "$MC_OFFICIAL/remapped_jar" + +echo "=== Decompiling Minecraft $VERSION ($SIDE) ===" +echo " Remapped JAR: $REMAPPED_JAR" +echo " Decompiled: $DECOMPILED_DIR" +echo "" + +cd "$MC_OFFICIAL" +java -jar "$DECOMPILER_JAR" \ + --version "$VERSION" \ + --side "$SIDE" \ + --decompile \ + --output "$REMAPPED_JAR" \ + --decompiled-output "$DECOMPILED_DIR" + +echo "" +echo "=== Done ===" +echo "Decompiled source: $DECOMPILED_DIR" + +# --- For SERVER side, also ensure downloads//server.jar exists --- +if [[ "$SIDE" == "SERVER" ]]; then + DOWNLOADS_DIR="$MC_OFFICIAL/downloads/$VERSION" + if [[ ! -f "$DOWNLOADS_DIR/server.jar" ]]; then + mkdir -p "$DOWNLOADS_DIR" + # MinecraftDecompiler downloads the original jar into its cache; + # extract it from the bundled remapped jar or re-download via manifest. + echo "" + echo "Downloading server.jar for $VERSION into $DOWNLOADS_DIR ..." + MANIFEST_URL="https://launchermeta.mojang.com/mc/game/version_manifest_v2.json" + VERSION_URL=$(curl -sL "$MANIFEST_URL" | python3 -c " +import json, sys +data = json.load(sys.stdin) +for v in data['versions']: + if v['id'] == '$VERSION': + print(v['url']) + break +") + if [[ -n "$VERSION_URL" ]]; then + SERVER_JAR_URL=$(curl -sL "$VERSION_URL" | python3 -c " +import json, sys +data = json.load(sys.stdin) +print(data['downloads']['server']['url']) +") + curl -L -o "$DOWNLOADS_DIR/server.jar" "$SERVER_JAR_URL" + echo "Downloaded server.jar" + else + echo "Warning: could not find version $VERSION in Mojang manifest; server.jar not downloaded." + fi + else + echo "server.jar already exists: $DOWNLOADS_DIR/server.jar" + fi +fi diff --git a/tools/mc-rcon.sh b/tools/mc-rcon.sh new file mode 100644 index 00000000..5017358a --- /dev/null +++ b/tools/mc-rcon.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Send an RCON command to a Minecraft server +# Usage: mc-rcon.sh [port] [password] +set -euo pipefail + +CMD="${1:?Usage: mc-rcon.sh [port] [password]}" +PORT="${2:-25575}" +PW="${3:-test123}" + +python3 -c " +import socket, struct, sys + +s = socket.socket() +s.settimeout(5) +try: + s.connect(('localhost', $PORT)) +except Exception as e: + print(f'Connection failed: {e}', file=sys.stderr) + sys.exit(1) + +def send(req_id, pkt_type, body): + body = body.encode() + s.send(struct.pack(' underscores) +_mc-session() { echo "mc-${1//\./_}"; } + +# --- Minecraft Server Management --- +mc-start() { "$MCC_REPO/tools/start-server.sh" "${1:-1.20.6}"; } +mc-stop() { local v="${1:-1.20.6}"; echo "stop" > "$MCC_SERVERS/$v/stdin.pipe"; } +mc-cmd() { local v="${2:-1.20.6}"; echo "$1" > "$MCC_SERVERS/$v/stdin.pipe"; } +mc-log() { local s; s=$(_mc-session "${1:-1.20.6}"); tmux capture-pane -t "$s" -p -S "-${2:-50}"; } +mc-kill() { local v="${1:-1.20.6}" s; s=$(_mc-session "$v"); tmux kill-session -t "$s" 2>/dev/null; rm -f "$MCC_SERVERS/$v/stdin.pipe"; echo "Killed $s"; } +mc-list() { tmux list-sessions 2>/dev/null | grep "^mc-" || echo "No running MC servers"; } + +# --- RCON --- +mc-rcon() { "$MCC_REPO/tools/mc-rcon.sh" "$@"; } + +# --- MCC Build/Run --- +mcc-build() { dotnet build "$MCC_REPO/MinecraftClient.sln" -c Release; } +mcc-run() { cd "$MCC_REPO" && MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release -- CursorBot - "localhost:${1:-25565}" 2>&1; } +mcc-cmd() { echo "$1" >> "$MCC_REPO/mcc_input.txt"; } +mcc-kill() { pkill -f "MinecraftClient" 2>/dev/null && echo "MCC killed" || echo "No MCC process found"; } +mcc-reload() { + mcc-kill + sleep 1 + mcc-build && mcc-run +} diff --git a/tools/start-server.sh b/tools/start-server.sh new file mode 100644 index 00000000..f4a8ccd7 --- /dev/null +++ b/tools/start-server.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Start a Minecraft server in a tmux session with named pipe for stdin +# Servers live in MinecraftOfficial/downloads// alongside the downloaded server.jar +VERSION="${1}" +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +DOWNLOADS="$REPO_ROOT/MinecraftOfficial/downloads" +DIR="$DOWNLOADS/$VERSION" +PIPE="$DIR/stdin.pipe" +SESSION="mc-${VERSION//\./_}" + +if [ -z "$VERSION" ] || [ ! -d "$DIR" ]; then + echo "Error: Server directory not found${VERSION:+: $DIR}" + echo "Available versions:" + ls "$DOWNLOADS" | grep -E '^[0-9]' | sort -V + exit 1 +fi + +if [ ! -f "$DIR/server.jar" ]; then + echo "Error: No server.jar in $DIR" + exit 1 +fi + +if tmux has-session -t "$SESSION" 2>/dev/null; then + echo "Server $VERSION already running in tmux session '$SESSION'" + echo "View output: tmux capture-pane -t '$SESSION' -p -S -50" + echo "Send command: echo 'say hello' > $PIPE" + exit 0 +fi + +rm -f "$DIR/world/session.lock" + +[ -p "$PIPE" ] || mkfifo "$PIPE" + +tmux new-session -d -s "$SESSION" -c "$DIR" \ + "tail -f $PIPE | java -Xmx2G -Xms2G -jar server.jar nogui 2>&1" + +echo "Server $VERSION started in tmux session '$SESSION'" +echo "Send commands: echo 'say hello' > $PIPE" +echo "View output: tmux capture-pane -t '$SESSION' -p -S -50" From a3c918e94658936a73a825d2d5c77fd0f0f88ea4 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 15:24:33 +0800 Subject: [PATCH 095/484] feat: implement physics engine for player movement and collision detection - Introduced a comprehensive physics engine that replicates Minecraft's movement mechanics, including player input handling, gravity, and collision detection. - Added classes for player physics, movement input, and collision detection, ensuring accurate simulation of player interactions with the game world. - Integrated AABB (Axis-Aligned Bounding Box) structures for precise collision detection against blocks. - Enhanced movement capabilities with support for jumping, sneaking, and sprinting, along with step-up mechanics for navigating terrain. These changes significantly improve the realism and responsiveness of player movement within the game environment. --- .gitignore | 2 +- MinecraftClient/McClient.cs | 158 ++++- MinecraftClient/MinecraftClient.csproj | 3 + MinecraftClient/Physics/Aabb.cs | 195 ++++++ MinecraftClient/Physics/BlockShapeData.json | 1 + MinecraftClient/Physics/BlockShapes.cs | 233 +++++++ MinecraftClient/Physics/CollisionDetector.cs | 204 ++++++ MinecraftClient/Physics/MovementInput.cs | 55 ++ MinecraftClient/Physics/PhysicsConsts.cs | 87 +++ MinecraftClient/Physics/PlayerPhysics.cs | 579 ++++++++++++++++++ MinecraftClient/Physics/Vec3d.cs | 102 +++ .../Protocol/Handlers/Protocol18.cs | 119 ++-- tools/README.md | 26 +- tools/gen_block_shapes.py | 167 +++++ 14 files changed, 1866 insertions(+), 65 deletions(-) create mode 100644 MinecraftClient/Physics/Aabb.cs create mode 100644 MinecraftClient/Physics/BlockShapeData.json create mode 100644 MinecraftClient/Physics/BlockShapes.cs create mode 100644 MinecraftClient/Physics/CollisionDetector.cs create mode 100644 MinecraftClient/Physics/MovementInput.cs create mode 100644 MinecraftClient/Physics/PhysicsConsts.cs create mode 100644 MinecraftClient/Physics/PlayerPhysics.cs create mode 100644 MinecraftClient/Physics/Vec3d.cs create mode 100644 tools/gen_block_shapes.py diff --git a/.gitignore b/.gitignore index b00da3f6..7553592d 100644 --- a/.gitignore +++ b/.gitignore @@ -423,7 +423,7 @@ FodyWeavers.xsd /docs/.vuepress/public/MCC-README/ # Floder to store the decompiled Minecraft official source code -MinecraftOfficial/ +/MinecraftOfficial/ # Possible debug files /lang/* diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 86d205d1..b5ee2278 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -13,6 +13,7 @@ using MinecraftClient.Commands; using MinecraftClient.Inventory; using MinecraftClient.Logger; using MinecraftClient.Mapping; +using MinecraftClient.Physics; using MinecraftClient.Protocol; using MinecraftClient.Protocol.Handlers; using MinecraftClient.Protocol.Handlers.Forge; @@ -68,6 +69,10 @@ namespace MinecraftClient private float playerYaw; private float playerPitch; private double motionY; + private readonly PlayerPhysics playerPhysics = new(); + private readonly MovementInput physicsInput = new(); + private bool physicsInitialized = false; + private Location? pathTarget; // Current waypoint for physics-driven pathfinding public enum MovementType { Sneak, Walk, Sprint } private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..) private bool CanSendMessage = false; @@ -495,33 +500,47 @@ namespace MinecraftClient { lock (locationLock) { - for (int i = 0; i < Config.Main.Advanced.MovementSpeed; i++) //Needs to run at 20 tps; MCC runs at 10 tps + if (!physicsInitialized) { - if (_yaw == null || _pitch == null) - { - if (steps != null && steps.Count > 0) - { - location = steps.Dequeue(); - } - else if (path != null && path.Count > 0) - { - Location next = path.Dequeue(); - steps = Movement.Move2Steps(location, next, ref motionY); - - if (Config.Main.Advanced.MoveHeadWhileWalking) // Disable head movements to avoid anti-cheat triggers - UpdateLocation(location, next + new Location(0, 1, 0)); // Update yaw and pitch to look at next step - } - else - { - location = Movement.HandleGravity(world, location, ref motionY); - } - } - playerYaw = _yaw == null ? playerYaw : _yaw.Value; - playerPitch = _pitch == null ? playerPitch : _pitch.Value; - handler.SendLocationUpdate(location, Movement.IsOnGround(world, location), _yaw, _pitch); + BlockShapes.Initialize(); + playerPhysics.SetPosition(location.X, location.Y, location.Z); + playerPhysics.Yaw = playerYaw; + playerPhysics.Pitch = playerPitch; + physicsInitialized = true; } - // First 2 updates must be player position AND look, and player must not move (to conform with vanilla) - // Once yaw and pitch have been sent, switch back to location-only updates (without yaw and pitch) + + // Run 2 physics ticks per OnUpdate call (10 Hz * 2 = 20 TPS) + for (int tick = 0; tick < 2; tick++) + { + // Navigate pathfinding: set input based on current path + UpdatePathfindingInput(); + + // Sync yaw/pitch if explicitly set (by commands/bots) + if (_yaw != null) playerPhysics.Yaw = _yaw.Value; + if (_pitch != null) playerPhysics.Pitch = _pitch.Value; + + // Update environment flags (water, lava, climbable) + playerPhysics.UpdateEnvironment(world); + + // Apply movement input + playerPhysics.ApplyInput(physicsInput); + + // Run one physics tick + playerPhysics.Tick(world); + + // Sync back to MCC location + location = new Location( + playerPhysics.Position.X, + playerPhysics.Position.Y, + playerPhysics.Position.Z); + + playerYaw = _yaw ?? playerYaw; + playerPitch = _pitch ?? playerPitch; + + // Send position packet + handler.SendLocationUpdate(location, playerPhysics.OnGround, _yaw, _pitch); + } + _yaw = null; _pitch = null; } @@ -1335,7 +1354,7 @@ namespace MinecraftClient } else { - // Calculate path through pathfinding. Path contains a list of 1-block movement that will be divided into steps + pathTarget = null; path = Movement.CalculatePath(world, location, goal, allowUnsafe, maxOffset, minOffset, timeout ?? TimeSpan.FromSeconds(5)); return path != null; } @@ -2684,6 +2703,87 @@ namespace MinecraftClient DispatchBotEvent(bot => bot.OnRespawn()); } + /// + /// Drive the physics engine input based on the current A* path. + /// Converts discrete waypoint pathfinding into continuous movement input. + /// + private void UpdatePathfindingInput() + { + physicsInput.Reset(); + + // Still heading toward a target (even if path queue is empty) + if (pathTarget != null && ReachedWaypoint(pathTarget.Value)) + { + // Arrived at current waypoint — advance to next, or finish + if (path != null && path.Count > 0) + { + pathTarget = path.Dequeue(); + if (Config.Main.Advanced.MoveHeadWhileWalking) + UpdateLocation(location, pathTarget.Value + new Location(0, 1, 0)); + } + else + { + pathTarget = null; + path = null; + } + } + + // Need a first target from a fresh path + if (pathTarget == null && path != null && path.Count > 0) + { + pathTarget = path.Dequeue(); + if (Config.Main.Advanced.MoveHeadWhileWalking) + UpdateLocation(location, pathTarget.Value + new Location(0, 1, 0)); + } + + if (pathTarget != null) + { + SetInputToward(pathTarget.Value); + } + } + + /// + /// Check if the player has approximately reached a waypoint. + /// + private bool ReachedWaypoint(Location target) + { + double dx = target.X - location.X; + double dz = target.Z - location.Z; + return dx * dx + dz * dz < 0.25; // within ~0.5 blocks horizontally + } + + /// + /// Set movement input to walk toward a target location. + /// Calculates the yaw needed and sets Forward + Sprint. + /// + private void SetInputToward(Location target) + { + double dx = target.X - location.X; + double dz = target.Z - location.Z; + double dy = target.Y - location.Y; + double distSqr = dx * dx + dz * dz; + + if (distSqr < 0.01) return; // Close enough horizontally + + // Calculate yaw to face target + float targetYaw = (float)(-Math.Atan2(dx, dz) / Math.PI * 180.0); + if (targetYaw < 0) targetYaw += 360; + playerPhysics.Yaw = targetYaw; + playerYaw = targetYaw; + + physicsInput.Forward = true; + + // Jump if target is above and we're on ground + if (dy > 0.5 && playerPhysics.OnGround) + physicsInput.Jump = true; + + // Map MovementSpeed setting: 1=sneak, 2-4=walk, 5=sprint + if (Config.Main.Advanced.MovementSpeed >= 5) + physicsInput.Sprint = true; + else if (Config.Main.Advanced.MovementSpeed <= 1) + physicsInput.Sneak = true; + } + /// /// Check if the client is currently processing a Movement. /// @@ -2752,6 +2852,12 @@ namespace MinecraftClient } else this.location = location; locationReceived = true; + + // Sync physics engine position + if (physicsInitialized) + { + playerPhysics.Teleport(this.location.X, this.location.Y, this.location.Z); + } } } diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 68e605b1..6b0e4198 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -18,6 +18,9 @@ MinecraftClient.Program + + + diff --git a/MinecraftClient/Physics/Aabb.cs b/MinecraftClient/Physics/Aabb.cs new file mode 100644 index 00000000..5ccff502 --- /dev/null +++ b/MinecraftClient/Physics/Aabb.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace MinecraftClient.Physics +{ + /// + /// Axis-aligned bounding box, mirrors net.minecraft.world.phys.AABB. + /// Immutable — mutating methods return new instances. + /// + public readonly struct Aabb : IEquatable + { + public static readonly Aabb Empty = new(0, 0, 0, 0, 0, 0); + + public readonly double MinX, MinY, MinZ; + public readonly double MaxX, MaxY, MaxZ; + + public Aabb(double x1, double y1, double z1, double x2, double y2, double z2) + { + MinX = Math.Min(x1, x2); + MinY = Math.Min(y1, y2); + MinZ = Math.Min(z1, z2); + MaxX = Math.Max(x1, x2); + MaxY = Math.Max(y1, y2); + MaxZ = Math.Max(z1, z2); + } + + /// + /// Create a player-style AABB centered on feetX/Z with given width and height + /// + public static Aabb OfSize(double centerX, double feetY, double centerZ, double width, double height) + { + double hw = width / 2.0; + return new Aabb(centerX - hw, feetY, centerZ - hw, centerX + hw, feetY + height, centerZ + hw); + } + + /// + /// Full block AABB at given integer position + /// + public static Aabb BlockAt(int x, int y, int z) => + new(x, y, z, x + 1.0, y + 1.0, z + 1.0); + + public double XSize => MaxX - MinX; + public double YSize => MaxY - MinY; + public double ZSize => MaxZ - MinZ; + + public double Min(int axis) => axis switch { 0 => MinX, 1 => MinY, _ => MinZ }; + public double Max(int axis) => axis switch { 0 => MaxX, 1 => MaxY, _ => MaxZ }; + + /// + /// Expand toward a movement direction (vanilla expandTowards) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb ExpandTowards(double dx, double dy, double dz) + { + double minX = MinX, minY = MinY, minZ = MinZ; + double maxX = MaxX, maxY = MaxY, maxZ = MaxZ; + if (dx < 0) minX += dx; else if (dx > 0) maxX += dx; + if (dy < 0) minY += dy; else if (dy > 0) maxY += dy; + if (dz < 0) minZ += dz; else if (dz > 0) maxZ += dz; + return new Aabb(minX, minY, minZ, maxX, maxY, maxZ); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb ExpandTowards(Vec3d v) => ExpandTowards(v.X, v.Y, v.Z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb Inflate(double x, double y, double z) => + new(MinX - x, MinY - y, MinZ - z, MaxX + x, MaxY + y, MaxZ + z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb Inflate(double v) => Inflate(v, v, v); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb Deflate(double x, double y, double z) => Inflate(-x, -y, -z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb Move(double dx, double dy, double dz) => + new(MinX + dx, MinY + dy, MinZ + dz, MaxX + dx, MaxY + dy, MaxZ + dz); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Aabb Move(Vec3d v) => Move(v.X, v.Y, v.Z); + + /// + /// Strict overlap test (vanilla uses < and >, not <=) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Intersects(Aabb other) => + MinX < other.MaxX && MaxX > other.MinX && + MinY < other.MaxY && MaxY > other.MinY && + MinZ < other.MaxZ && MaxZ > other.MinZ; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Intersects(double x1, double y1, double z1, double x2, double y2, double z2) => + MinX < x2 && MaxX > x1 && MinY < y2 && MaxY > y1 && MinZ < z2 && MaxZ > z1; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Contains(double x, double y, double z) => + x >= MinX && x < MaxX && y >= MinY && y < MaxY && z >= MinZ && z < MaxZ; + + /// + /// Collide this AABB along a single axis against another AABB. + /// Returns the clamped movement distance. + /// + /// + /// Clip entity movement along X against a block shape (other). + /// Vanilla semantics: VoxelShape.collide(Axis.X, entityBox, movement). + /// + public double CollideX(Aabb other, double movement) + { + if (other.MaxY <= MinY || other.MinY >= MaxY || other.MaxZ <= MinZ || other.MinZ >= MaxZ) + return movement; + if (movement > 0.0 && other.MinX >= MaxX) + { + double d = other.MinX - MaxX; + if (d < movement) movement = d; + } + else if (movement < 0.0 && other.MaxX <= MinX) + { + double d = other.MaxX - MinX; + if (d > movement) movement = d; + } + return movement; + } + + public double CollideY(Aabb other, double movement) + { + if (other.MaxX <= MinX || other.MinX >= MaxX || other.MaxZ <= MinZ || other.MinZ >= MaxZ) + return movement; + if (movement > 0.0 && other.MinY >= MaxY) + { + double d = other.MinY - MaxY; + if (d < movement) movement = d; + } + else if (movement < 0.0 && other.MaxY <= MinY) + { + double d = other.MaxY - MinY; + if (d > movement) movement = d; + } + return movement; + } + + public double CollideZ(Aabb other, double movement) + { + if (other.MaxX <= MinX || other.MinX >= MaxX || other.MaxY <= MinY || other.MinY >= MaxY) + return movement; + if (movement > 0.0 && other.MinZ >= MaxZ) + { + double d = other.MinZ - MaxZ; + if (d < movement) movement = d; + } + else if (movement < 0.0 && other.MaxZ <= MinZ) + { + double d = other.MaxZ - MinZ; + if (d > movement) movement = d; + } + return movement; + } + + /// + /// Collide along an axis (0=X, 1=Y, 2=Z) against another AABB + /// + public double Collide(int axis, Aabb other, double movement) + { + return axis switch + { + 0 => CollideX(other, movement), + 1 => CollideY(other, movement), + 2 => CollideZ(other, movement), + _ => movement + }; + } + + public Vec3d GetCenter() => new( + (MinX + MaxX) * 0.5, + (MinY + MaxY) * 0.5, + (MinZ + MaxZ) * 0.5); + + public Vec3d GetBottomCenter() => new( + (MinX + MaxX) * 0.5, + MinY, + (MinZ + MaxZ) * 0.5); + + public bool Equals(Aabb other) => + MinX == other.MinX && MinY == other.MinY && MinZ == other.MinZ && + MaxX == other.MaxX && MaxY == other.MaxY && MaxZ == other.MaxZ; + + public override bool Equals(object? obj) => obj is Aabb a && Equals(a); + public override int GetHashCode() => HashCode.Combine(MinX, MinY, MinZ, MaxX, MaxY, MaxZ); + public override string ToString() => $"AABB[{MinX:F3},{MinY:F3},{MinZ:F3} -> {MaxX:F3},{MaxY:F3},{MaxZ:F3}]"; + + public static bool operator ==(Aabb a, Aabb b) => a.Equals(b); + public static bool operator !=(Aabb a, Aabb b) => !a.Equals(b); + } +} diff --git a/MinecraftClient/Physics/BlockShapeData.json b/MinecraftClient/Physics/BlockShapeData.json new file mode 100644 index 00000000..2a7f10ff --- /dev/null +++ b/MinecraftClient/Physics/BlockShapeData.json @@ -0,0 +1 @@ +{"shapes":{"0":[],"1":[[0.0,0.0,0.0,1.0,1.0,1.0]],"2":[[0.0,0.0,0.0,0.1875,0.5625,0.1875],[0.8125,0.0,0.0,1.0,0.5625,0.1875],[0.0,0.1875,0.1875,1.0,0.5625,1.0],[0.1875,0.1875,0.0,0.8125,0.5625,0.1875]],"3":[[0.0,0.0,0.8125,0.1875,0.5625,1.0],[0.8125,0.0,0.8125,1.0,0.5625,1.0],[0.0,0.1875,0.0,1.0,0.5625,0.8125],[0.1875,0.1875,0.8125,0.8125,0.5625,1.0]],"4":[[0.0,0.0,0.0,0.1875,0.5625,0.1875],[0.0,0.0,0.8125,0.1875,0.5625,1.0],[0.0,0.1875,0.1875,1.0,0.5625,0.8125],[0.1875,0.1875,0.0,1.0,0.5625,0.1875],[0.1875,0.1875,0.8125,1.0,0.5625,1.0]],"5":[[0.8125,0.0,0.0,1.0,0.5625,0.1875],[0.8125,0.0,0.8125,1.0,0.5625,1.0],[0.0,0.1875,0.0,0.8125,0.5625,1.0],[0.8125,0.1875,0.1875,1.0,0.5625,0.8125]],"6":[[0.0,0.0,0.25,1.0,1.0,1.0]],"7":[[0.0,0.0,0.0,0.75,1.0,1.0]],"8":[[0.0,0.0,0.0,1.0,1.0,0.75]],"9":[[0.25,0.0,0.0,1.0,1.0,1.0]],"10":[[0.0,0.0,0.0,1.0,0.75,1.0]],"11":[[0.0,0.25,0.0,1.0,1.0,1.0]],"12":[[0.0,0.0,0.0,1.0,1.0,0.25],[0.375,0.375,0.25,0.625,0.625,1.0]],"13":[[0.0,0.0,0.0,1.0,1.0,0.25],[0.375,0.375,0.25,0.625,0.625,1.25]],"14":[[0.75,0.0,0.0,1.0,1.0,1.0],[0.0,0.375,0.375,0.75,0.625,0.625]],"15":[[0.75,0.0,0.0,1.0,1.0,1.0],[-0.25,0.375,0.375,0.75,0.625,0.625]],"16":[[0.0,0.0,0.75,1.0,1.0,1.0],[0.375,0.375,0.0,0.625,0.625,0.75]],"17":[[0.0,0.0,0.75,1.0,1.0,1.0],[0.375,0.375,-0.25,0.625,0.625,0.75]],"18":[[0.0,0.0,0.0,0.25,1.0,1.0],[0.25,0.375,0.375,1.0,0.625,0.625]],"19":[[0.0,0.0,0.0,0.25,1.0,1.0],[0.25,0.375,0.375,1.25,0.625,0.625]],"20":[[0.375,0.0,0.375,0.625,1.0,0.625],[0.0,0.75,0.0,0.375,1.0,1.0],[0.375,0.75,0.0,1.0,1.0,0.375],[0.375,0.75,0.625,1.0,1.0,1.0],[0.625,0.75,0.375,1.0,1.0,0.625]],"21":[[0.375,-0.25,0.375,0.625,1.0,0.625],[0.0,0.75,0.0,0.375,1.0,1.0],[0.375,0.75,0.0,1.0,1.0,0.375],[0.375,0.75,0.625,1.0,1.0,1.0],[0.625,0.75,0.375,1.0,1.0,0.625]],"22":[[0.0,0.0,0.0,1.0,0.25,1.0],[0.375,0.25,0.375,0.625,1.0,0.625]],"23":[[0.0,0.0,0.0,1.0,0.25,1.0],[0.375,0.25,0.375,0.625,1.25,0.625]],"24":[[0.0,0.0,0.6875,1.0,0.25,1.0],[0.0,0.25,0.8125,1.0,1.0,1.0],[0.0,0.75,0.6875,1.0,1.0,0.8125]],"25":[[0.0,0.0,0.0,1.0,0.25,0.3125],[0.0,0.25,0.0,1.0,1.0,0.1875],[0.0,0.75,0.1875,1.0,1.0,0.3125]],"26":[[0.6875,0.0,0.0,1.0,0.25,1.0],[0.8125,0.25,0.0,1.0,1.0,1.0],[0.6875,0.75,0.0,0.8125,1.0,1.0]],"27":[[0.0,0.0,0.0,0.3125,0.25,1.0],[0.0,0.25,0.0,0.1875,1.0,1.0],[0.1875,0.75,0.0,0.3125,1.0,1.0]],"28":[[0.0,0.0,0.0,1.0,1.0,0.5],[0.0,0.5,0.5,1.0,1.0,1.0]],"29":[[0.0,0.0,0.0,0.5,1.0,1.0],[0.5,0.0,0.0,1.0,1.0,0.5],[0.5,0.5,0.5,1.0,1.0,1.0]],"30":[[0.0,0.0,0.0,1.0,1.0,0.5],[0.5,0.0,0.5,1.0,1.0,1.0],[0.0,0.5,0.5,0.5,1.0,1.0]],"31":[[0.0,0.0,0.0,0.5,1.0,0.5],[0.0,0.5,0.5,1.0,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"32":[[0.5,0.0,0.0,1.0,1.0,0.5],[0.0,0.5,0.0,0.5,1.0,1.0],[0.5,0.5,0.5,1.0,1.0,1.0]],"33":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,1.0,1.0,0.5]],"34":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,0.5,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"35":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,1.0,1.0,0.5],[0.5,0.5,0.5,1.0,1.0,1.0]],"36":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,0.5,1.0,0.5]],"37":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"38":[[0.0,0.0,0.5,1.0,1.0,1.0],[0.0,0.5,0.0,1.0,1.0,0.5]],"39":[[0.0,0.0,0.5,1.0,1.0,1.0],[0.5,0.0,0.0,1.0,1.0,0.5],[0.0,0.5,0.0,0.5,1.0,0.5]],"40":[[0.0,0.0,0.0,0.5,1.0,1.0],[0.5,0.0,0.5,1.0,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"41":[[0.5,0.0,0.5,1.0,1.0,1.0],[0.0,0.5,0.0,0.5,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"42":[[0.0,0.0,0.5,0.5,1.0,1.0],[0.0,0.5,0.0,1.0,1.0,0.5],[0.5,0.5,0.5,1.0,1.0,1.0]],"43":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.5,1.0,1.0,1.0]],"44":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.5,1.0,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,0.5]],"45":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,0.5,1.0,1.0],[0.5,0.5,0.5,1.0,1.0,1.0]],"46":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.5,0.5,0.5,1.0,1.0,1.0]],"47":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.5,0.5,1.0,1.0]],"48":[[0.0,0.0,0.0,0.5,1.0,1.0],[0.5,0.5,0.0,1.0,1.0,1.0]],"49":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.0,0.5,0.0,0.5,1.0,1.0]],"50":[[0.5,0.0,0.0,1.0,1.0,1.0],[0.0,0.5,0.0,0.5,1.0,1.0]],"51":[[0.0,0.0,0.0,1.0,0.5,1.0],[0.5,0.5,0.0,1.0,1.0,1.0]],"52":[[0.0625,0.0,0.0625,0.9375,0.875,0.9375]],"53":[[0.0625,0.0,0.0625,1.0,0.875,0.9375]],"54":[[0.0,0.0,0.0625,0.9375,0.875,0.9375]],"55":[[0.0625,0.0,0.0,0.9375,0.875,0.9375]],"56":[[0.0625,0.0,0.0625,0.9375,0.875,1.0]],"57":[[0.0,0.0,0.0,1.0,0.9375,1.0]],"58":[[0.0,0.0,0.0,0.1875,1.0,1.0]],"59":[[0.0,0.0,0.8125,1.0,1.0,1.0]],"60":[[0.8125,0.0,0.0,1.0,1.0,1.0]],"61":[[0.0,0.0,0.0,1.0,1.0,0.1875]],"62":[[0.0,0.0,0.8125,1.0,1.0,1.0]],"63":[[0.0,0.0,0.0,1.0,1.0,0.1875]],"64":[[0.8125,0.0,0.0,1.0,1.0,1.0]],"65":[[0.0,0.0,0.0,0.1875,1.0,1.0]],"66":[[0.0,0.875,0.375,1.0,1.0,0.625]],"67":[[0.375,0.875,0.0,0.625,1.0,1.0]],"68":[[0.0,0.0,0.0,1.0,0.125,1.0]],"69":[[0.0,0.0,0.0,1.0,0.25,1.0]],"70":[[0.0,0.0,0.0,1.0,0.375,1.0]],"71":[[0.0,0.0,0.0,1.0,0.5,1.0]],"72":[[0.0,0.0,0.0,1.0,0.625,1.0]],"73":[[0.0,0.0,0.0,1.0,0.75,1.0]],"74":[[0.0,0.0,0.0,1.0,0.875,1.0]],"75":[[0.0625,0.0,0.0625,0.9375,0.9375,0.9375]],"76":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"77":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"78":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"79":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"80":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"81":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"82":[[0.0,0.0,0.375,1.0,1.5,0.625]],"83":[[0.375,0.0,0.375,1.0,1.5,0.625]],"84":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"85":[[0.375,0.0,0.0,0.625,1.5,1.0]],"86":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"87":[[0.375,0.0,0.0,0.625,1.5,0.625]],"88":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"89":[[0.375,0.0,0.375,0.625,1.5,1.0]],"90":[[0.0,0.0,0.375,0.625,1.5,0.625]],"91":[[0.375,0.0,0.375,0.625,1.5,0.625]],"92":[[0.0,0.0,0.0,1.0,0.875,1.0]],"93":[[0.0625,0.0,0.0625,0.9375,0.5,0.9375]],"94":[[0.1875,0.0,0.0625,0.9375,0.5,0.9375]],"95":[[0.3125,0.0,0.0625,0.9375,0.5,0.9375]],"96":[[0.4375,0.0,0.0625,0.9375,0.5,0.9375]],"97":[[0.5625,0.0,0.0625,0.9375,0.5,0.9375]],"98":[[0.6875,0.0,0.0625,0.9375,0.5,0.9375]],"99":[[0.8125,0.0,0.0625,0.9375,0.5,0.9375]],"100":[[0.0,0.0,0.0,1.0,0.125,1.0]],"101":[[0.0,0.0,0.8125,1.0,1.0,1.0]],"102":[[0.0,0.8125,0.0,1.0,1.0,1.0]],"103":[[0.0,0.0,0.0,1.0,0.1875,1.0]],"104":[[0.0,0.0,0.0,1.0,1.0,0.1875]],"105":[[0.8125,0.0,0.0,1.0,1.0,1.0]],"106":[[0.0,0.0,0.0,0.1875,1.0,1.0]],"107":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"108":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"109":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"110":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"111":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"112":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"113":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"114":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"115":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"116":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"117":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"118":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"119":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"120":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"121":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"122":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"123":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"124":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"125":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"126":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"127":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"128":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"129":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"130":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"131":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"132":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"133":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"134":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"135":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"136":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"137":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"138":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"139":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"140":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"141":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"142":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"143":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"144":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"145":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"146":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"147":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"148":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"149":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"150":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"151":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"152":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"153":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"154":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"155":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"156":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"157":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"158":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"159":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"160":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"161":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"162":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"163":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"164":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"165":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"166":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"167":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"168":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"169":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"170":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"171":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"172":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"173":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"174":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"175":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"176":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"177":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"178":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"179":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"180":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"181":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"182":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"183":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"184":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"185":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"186":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"187":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"188":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"189":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"190":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"191":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"192":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"193":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"194":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"195":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"196":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"197":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"198":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"199":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"200":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"201":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"202":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"203":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"204":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"205":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"206":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"207":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"208":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"209":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"210":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"211":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"212":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"213":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"214":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"215":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"216":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"217":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"218":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"219":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"220":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"221":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"222":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"223":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"224":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"225":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"226":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"227":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"228":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"229":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"230":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"231":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"232":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"233":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"234":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"235":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"236":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"237":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"238":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"239":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"240":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"241":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"242":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"243":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"244":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"245":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"246":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"247":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"248":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"249":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"250":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"251":[[0.0,0.40625,0.40625,1.0,0.59375,0.59375]],"252":[[0.40625,0.0,0.40625,0.59375,1.0,0.59375]],"253":[[0.40625,0.40625,0.0,0.59375,0.59375,1.0]],"254":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"255":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"256":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"257":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"258":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"259":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"260":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"261":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"262":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"263":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"264":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"265":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"266":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"267":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"268":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"269":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"270":[[0.0,0.0,0.375,1.0,1.5,0.625]],"271":[[0.375,0.0,0.0,0.625,1.5,1.0]],"272":[[0.0625,0.0,0.0625,0.9375,0.09375,0.9375]],"273":[[0.0,0.5,0.0,1.0,1.0,1.0]],"274":[[0.0,0.0,0.0,1.0,0.5,1.0]],"275":[[0.25,0.0,0.25,0.75,1.5,0.75]],"276":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"277":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"278":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"279":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"280":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"281":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"282":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"283":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"284":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"285":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"286":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"287":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"288":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"289":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"290":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"291":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"292":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"293":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"294":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"295":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"296":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"297":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"298":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"299":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"300":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"301":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"302":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"303":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"304":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"305":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"306":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"307":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"308":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"309":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"310":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"311":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"312":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"313":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"314":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"315":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"316":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"317":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"318":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"319":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"320":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"321":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"322":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"323":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"324":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"325":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"326":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"327":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"328":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"329":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"330":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"331":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"332":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"333":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"334":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"335":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"336":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"337":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"338":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"339":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"340":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"341":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"342":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"343":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"344":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"345":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"346":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"347":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"348":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"349":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"350":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"351":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"352":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"353":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"354":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"355":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"356":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"357":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"358":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"359":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"360":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"361":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"362":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"363":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"364":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"365":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"366":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"367":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"368":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"369":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"370":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"371":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"372":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"373":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"374":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"375":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"376":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"377":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"378":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"379":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"380":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"381":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"382":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"383":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"384":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"385":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"386":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"387":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"388":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"389":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"390":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"391":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"392":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"393":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"394":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"395":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"396":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"397":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"398":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"399":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"400":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"401":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"402":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"403":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"404":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"405":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"406":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"407":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"408":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"409":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"410":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"411":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"412":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"413":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"414":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"415":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"416":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"417":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"418":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"419":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"420":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"421":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"422":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"423":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"424":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"425":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"426":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"427":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"428":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"429":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"430":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"431":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"432":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"433":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"434":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"435":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"436":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"437":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"438":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"439":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"440":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"441":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"442":[[0.0,0.0,0.375,1.0,1.5,0.625]],"443":[[0.375,0.0,0.375,1.0,1.5,0.625]],"444":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"445":[[0.375,0.0,0.0,0.625,1.5,1.0]],"446":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"447":[[0.375,0.0,0.0,0.625,1.5,0.625]],"448":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"449":[[0.375,0.0,0.375,0.625,1.5,1.0]],"450":[[0.0,0.0,0.375,0.625,1.5,0.625]],"451":[[0.375,0.0,0.375,0.625,1.5,0.625]],"452":[[0.0,0.0,0.0,1.0,0.75,1.0]],"453":[[0.0625,0.0,0.0625,0.9375,0.125,0.9375],[0.4375,0.125,0.4375,0.5625,0.875,0.5625]],"454":[[0.0,0.0,0.0,0.125,1.0,0.25],[0.0,0.0,0.75,0.125,1.0,1.0],[0.125,0.0,0.0,0.25,1.0,0.125],[0.125,0.0,0.875,0.25,1.0,1.0],[0.75,0.0,0.0,1.0,1.0,0.125],[0.75,0.0,0.875,1.0,1.0,1.0],[0.875,0.0,0.125,1.0,1.0,0.25],[0.875,0.0,0.75,1.0,1.0,0.875],[0.0,0.1875,0.25,1.0,0.25,0.75],[0.125,0.1875,0.125,0.875,0.25,0.25],[0.125,0.1875,0.75,0.875,0.25,0.875],[0.25,0.1875,0.0,0.75,1.0,0.125],[0.25,0.1875,0.875,0.75,1.0,1.0],[0.0,0.25,0.25,0.125,1.0,0.75],[0.875,0.25,0.25,1.0,1.0,0.75]],"455":[[0.0,0.0,0.0,1.0,0.8125,1.0],[0.25,0.8125,0.25,0.75,1.0,0.75]],"456":[[0.0,0.0,0.0,1.0,0.8125,1.0]],"457":[[0.0625,0.0,0.0625,0.9375,1.0,0.9375]],"458":[[0.375,0.4375,0.0625,0.625,0.75,0.3125]],"459":[[0.375,0.4375,0.6875,0.625,0.75,0.9375]],"460":[[0.0625,0.4375,0.375,0.3125,0.75,0.625]],"461":[[0.6875,0.4375,0.375,0.9375,0.75,0.625]],"462":[[0.3125,0.3125,0.0625,0.6875,0.75,0.4375]],"463":[[0.3125,0.3125,0.5625,0.6875,0.75,0.9375]],"464":[[0.0625,0.3125,0.3125,0.4375,0.75,0.6875]],"465":[[0.5625,0.3125,0.3125,0.9375,0.75,0.6875]],"466":[[0.25,0.1875,0.0625,0.75,0.75,0.5625]],"467":[[0.25,0.1875,0.4375,0.75,0.75,0.9375]],"468":[[0.0625,0.1875,0.25,0.5625,0.75,0.75]],"469":[[0.4375,0.1875,0.25,0.9375,0.75,0.75]],"470":[[0.0625,0.0,0.0625,0.9375,0.875,0.9375]],"471":[[0.25,0.0,0.25,0.75,1.5,0.75]],"472":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"473":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"474":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"475":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"476":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"477":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"478":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"479":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"480":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"481":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"482":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"483":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"484":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"485":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"486":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"487":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"488":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"489":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"490":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"491":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"492":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"493":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"494":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"495":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"496":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"497":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"498":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"499":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"500":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"501":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"502":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"503":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"504":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"505":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"506":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"507":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"508":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"509":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"510":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"511":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"512":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"513":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"514":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"515":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"516":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"517":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"518":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"519":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"520":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"521":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"522":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"523":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"524":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"525":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"526":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"527":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"528":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"529":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"530":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"531":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"532":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"533":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"534":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"535":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"536":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"537":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"538":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"539":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"540":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"541":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"542":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"543":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"544":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"545":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"546":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"547":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"548":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"549":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"550":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"551":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"552":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"553":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"554":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"555":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"556":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"557":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"558":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"559":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"560":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"561":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"562":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"563":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"564":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"565":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"566":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"567":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"568":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"569":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"570":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"571":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"572":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"573":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"574":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"575":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"576":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"577":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"578":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"579":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"580":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"581":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"582":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"583":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"584":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"585":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"586":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"587":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"588":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"589":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"590":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"591":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"592":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"593":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"594":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"595":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"596":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"597":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"598":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"599":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"600":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"601":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"602":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"603":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"604":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"605":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"606":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"607":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"608":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"609":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"610":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"611":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"612":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"613":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"614":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"615":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"616":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"617":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"618":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"619":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"620":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"621":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"622":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"623":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"624":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"625":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"626":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"627":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"628":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"629":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"630":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"631":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"632":[[0.25,0.0,0.25,0.75,1.5,0.75]],"633":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"634":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"635":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"636":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"637":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"638":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"639":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"640":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"641":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"642":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"643":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"644":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"645":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"646":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"647":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"648":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"649":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"650":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"651":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"652":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"653":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"654":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"655":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"656":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"657":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"658":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"659":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"660":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"661":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"662":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"663":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"664":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"665":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"666":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"667":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"668":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"669":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"670":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"671":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"672":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"673":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"674":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"675":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"676":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"677":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"678":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"679":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"680":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"681":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"682":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"683":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"684":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"685":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"686":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"687":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"688":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"689":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"690":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"691":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"692":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"693":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"694":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"695":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"696":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"697":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"698":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"699":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"700":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"701":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"702":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"703":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"704":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"705":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"706":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"707":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"708":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"709":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"710":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"711":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"712":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"713":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"714":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"715":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"716":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"717":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"718":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"719":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"720":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"721":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"722":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"723":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"724":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"725":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"726":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"727":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"728":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"729":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"730":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"731":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"732":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"733":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"734":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"735":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"736":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"737":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"738":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"739":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"740":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"741":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"742":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"743":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"744":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"745":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"746":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"747":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"748":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"749":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"750":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"751":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"752":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"753":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"754":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"755":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"756":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"757":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"758":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"759":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"760":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"761":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"762":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"763":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"764":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"765":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"766":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"767":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"768":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"769":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"770":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"771":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"772":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"773":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"774":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"775":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"776":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"777":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"778":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"779":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"780":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"781":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"782":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"783":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"784":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"785":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"786":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"787":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"788":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"789":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"790":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"791":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"792":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"793":[[0.3125,0.0,0.3125,0.6875,0.375,0.6875]],"794":[[0.25,0.0,0.25,0.75,0.5,0.75]],"795":[[0.25,0.25,0.5,0.75,0.75,1.0]],"796":[[0.25,0.25,0.0,0.75,0.75,0.5]],"797":[[0.5,0.25,0.25,1.0,0.75,0.75]],"798":[[0.0,0.25,0.25,0.5,0.75,0.75]],"799":[[0.1875,0.0,0.1875,0.8125,0.5,0.8125]],"800":[[0.1875,0.25,0.5,0.8125,0.75,1.0]],"801":[[0.1875,0.25,0.0,0.8125,0.75,0.5]],"802":[[0.5,0.25,0.1875,1.0,0.75,0.8125]],"803":[[0.0,0.25,0.1875,0.5,0.75,0.8125]],"804":[[0.125,0.0,0.125,0.875,0.25,0.875],[0.25,0.25,0.1875,0.75,0.3125,0.8125],[0.375,0.3125,0.25,0.625,1.0,0.75],[0.1875,0.625,0.0,0.375,1.0,1.0],[0.375,0.625,0.0,0.8125,1.0,0.25],[0.375,0.625,0.75,0.8125,1.0,1.0],[0.625,0.625,0.25,0.8125,1.0,0.75]],"805":[[0.125,0.0,0.125,0.875,0.25,0.875],[0.1875,0.25,0.25,0.8125,0.3125,0.75],[0.25,0.3125,0.375,0.75,1.0,0.625],[0.0,0.625,0.1875,0.25,1.0,0.8125],[0.25,0.625,0.1875,1.0,1.0,0.375],[0.25,0.625,0.625,1.0,1.0,0.8125],[0.75,0.625,0.375,1.0,1.0,0.625]],"806":[[0.0,0.0,0.0,1.0,0.375,1.0]],"807":[[0.375,0.0,0.375,0.625,0.6875,0.625],[0.25,0.25,0.25,0.375,0.6875,0.75],[0.375,0.25,0.25,0.75,0.6875,0.375],[0.375,0.25,0.625,0.75,0.6875,0.75],[0.625,0.25,0.375,0.75,0.6875,0.625],[0.0,0.625,0.0,0.25,0.6875,1.0],[0.25,0.625,0.0,1.0,0.6875,0.25],[0.25,0.625,0.75,1.0,0.6875,1.0],[0.75,0.625,0.25,1.0,0.6875,0.75],[0.0,0.6875,0.0,0.125,1.0,1.0],[0.125,0.6875,0.0,1.0,1.0,0.125],[0.125,0.6875,0.875,1.0,1.0,1.0],[0.875,0.6875,0.125,1.0,1.0,0.875]],"808":[[0.25,0.25,0.25,0.75,0.6875,0.75],[0.375,0.25,0.0,0.625,0.5,0.25],[0.0,0.625,0.0,0.25,0.6875,1.0],[0.25,0.625,0.0,1.0,0.6875,0.25],[0.25,0.625,0.75,1.0,0.6875,1.0],[0.75,0.625,0.25,1.0,0.6875,0.75],[0.0,0.6875,0.0,0.125,1.0,1.0],[0.125,0.6875,0.0,1.0,1.0,0.125],[0.125,0.6875,0.875,1.0,1.0,1.0],[0.875,0.6875,0.125,1.0,1.0,0.875]],"809":[[0.25,0.25,0.25,0.75,0.6875,0.75],[0.375,0.25,0.75,0.625,0.5,1.0],[0.0,0.625,0.0,0.25,0.6875,1.0],[0.25,0.625,0.0,1.0,0.6875,0.25],[0.25,0.625,0.75,1.0,0.6875,1.0],[0.75,0.625,0.25,1.0,0.6875,0.75],[0.0,0.6875,0.0,0.125,1.0,1.0],[0.125,0.6875,0.0,1.0,1.0,0.125],[0.125,0.6875,0.875,1.0,1.0,1.0],[0.875,0.6875,0.125,1.0,1.0,0.875]],"810":[[0.0,0.25,0.375,0.75,0.5,0.625],[0.25,0.25,0.25,0.75,0.6875,0.375],[0.25,0.25,0.625,0.75,0.6875,0.75],[0.25,0.5,0.375,0.75,0.6875,0.625],[0.0,0.625,0.0,0.25,0.6875,1.0],[0.25,0.625,0.0,1.0,0.6875,0.25],[0.25,0.625,0.75,1.0,0.6875,1.0],[0.75,0.625,0.25,1.0,0.6875,0.75],[0.0,0.6875,0.0,0.125,1.0,1.0],[0.125,0.6875,0.0,1.0,1.0,0.125],[0.125,0.6875,0.875,1.0,1.0,1.0],[0.875,0.6875,0.125,1.0,1.0,0.875]],"811":[[0.25,0.25,0.25,0.75,0.6875,0.75],[0.75,0.25,0.375,1.0,0.5,0.625],[0.0,0.625,0.0,0.25,0.6875,1.0],[0.25,0.625,0.0,1.0,0.6875,0.25],[0.25,0.625,0.75,1.0,0.6875,1.0],[0.75,0.625,0.25,1.0,0.6875,0.75],[0.0,0.6875,0.0,0.125,1.0,1.0],[0.125,0.6875,0.0,1.0,1.0,0.125],[0.125,0.6875,0.875,1.0,1.0,1.0],[0.875,0.6875,0.125,1.0,1.0,0.875]],"812":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"813":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"814":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"815":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"816":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"817":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"818":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"819":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"820":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"821":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"822":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"823":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"824":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"825":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"826":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"827":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"828":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"829":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"830":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"831":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"832":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"833":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"834":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"835":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"836":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"837":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"838":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"839":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"840":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"841":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"842":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"843":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"844":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"845":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"846":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"847":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"848":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"849":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"850":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"851":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"852":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"853":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"854":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"855":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"856":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"857":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"858":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"859":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"860":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"861":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"862":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"863":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"864":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"865":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"866":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"867":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"868":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"869":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"870":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"871":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"872":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"873":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"874":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"875":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"876":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"877":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"878":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"879":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"880":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"881":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"882":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"883":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"884":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"885":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"886":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"887":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"888":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"889":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"890":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"891":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"892":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"893":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"894":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"895":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"896":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"897":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"898":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"899":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"900":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"901":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"902":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"903":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"904":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"905":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"906":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"907":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"908":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"909":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"910":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"911":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"912":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"913":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"914":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"915":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"916":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"917":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"918":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"919":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"920":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"921":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"922":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"923":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"924":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"925":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"926":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"927":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"928":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"929":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"930":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"931":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"932":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"933":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"934":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"935":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"936":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"937":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"938":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"939":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"940":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"941":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"942":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"943":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"944":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"945":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"946":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"947":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"948":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"949":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"950":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"951":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"952":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"953":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"954":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"955":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"956":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"957":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"958":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"959":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"960":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"961":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"962":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"963":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"964":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"965":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"966":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"967":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"968":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"969":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"970":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"971":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"972":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"973":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"974":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"975":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"976":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"977":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"978":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"979":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"980":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"981":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"982":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"983":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"984":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"985":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"986":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"987":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"988":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"989":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"990":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"991":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"992":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"993":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"994":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"995":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"996":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"997":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"998":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"999":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"1000":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1001":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"1002":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"1003":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"1004":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1005":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1006":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1007":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1008":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1009":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1010":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"1011":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"1012":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1013":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"1014":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1015":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"1016":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1017":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"1018":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"1019":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"1020":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1021":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1022":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1023":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1024":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1025":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1026":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"1027":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"1028":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1029":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"1030":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1031":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"1032":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1033":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"1034":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"1035":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"1036":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1037":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1038":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1039":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1040":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1041":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1042":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"1043":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"1044":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1045":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"1046":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1047":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"1048":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1049":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"1050":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"1051":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"1052":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1053":[[0.4375,0.0,0.0,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1054":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1055":[[0.4375,0.0,0.0,0.5625,1.0,0.5625],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1056":[[0.0,0.0,0.4375,1.0,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1057":[[0.4375,0.0,0.4375,0.5625,1.0,1.0],[0.5625,0.0,0.4375,1.0,1.0,0.5625]],"1058":[[0.0,0.0,0.4375,1.0,1.0,0.5625]],"1059":[[0.4375,0.0,0.4375,1.0,1.0,0.5625]],"1060":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1061":[[0.4375,0.0,0.0,0.5625,1.0,1.0]],"1062":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.0,0.5625,1.0,0.4375]],"1063":[[0.4375,0.0,0.0,0.5625,1.0,0.5625]],"1064":[[0.0,0.0,0.4375,0.5625,1.0,0.5625],[0.4375,0.0,0.5625,0.5625,1.0,1.0]],"1065":[[0.4375,0.0,0.4375,0.5625,1.0,1.0]],"1066":[[0.0,0.0,0.4375,0.5625,1.0,0.5625]],"1067":[[0.4375,0.0,0.4375,0.5625,1.0,0.5625]],"1068":[[0.0,0.0,0.0,1.0,0.0625,1.0]],"1069":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1070":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1071":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1072":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1073":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1074":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1075":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1076":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1077":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1078":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1079":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1080":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1081":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1082":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1083":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1084":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1085":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1086":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1087":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1088":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1089":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1090":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1091":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1092":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1093":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1094":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1095":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1096":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1097":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1098":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1099":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1100":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1101":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1102":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1103":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1104":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1105":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1106":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1107":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1108":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1109":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1110":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1111":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1112":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1113":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1114":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1115":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1116":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1117":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1118":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1119":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1120":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1121":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1122":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1123":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1124":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1125":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1126":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1127":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1128":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1129":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1130":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1131":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1132":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1133":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1134":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1135":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1136":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1137":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1138":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1139":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1140":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1141":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1142":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1143":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1144":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1145":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1146":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1147":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1148":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1149":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1150":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1151":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1152":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1153":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1154":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1155":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1156":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1157":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1158":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1159":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1160":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1161":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1162":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1163":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1164":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1165":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1166":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1167":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1168":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1169":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1170":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1171":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1172":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1173":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1174":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1175":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1176":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1177":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1178":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1179":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1180":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1181":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1182":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1183":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1184":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1185":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1186":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1187":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1188":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1189":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1190":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1191":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1192":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1193":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1194":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1195":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1196":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1197":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1198":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1199":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1200":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"1201":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1202":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"1203":[[0.0,0.0,0.375,1.0,1.5,0.625]],"1204":[[0.375,0.0,0.375,1.0,1.5,0.625]],"1205":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"1206":[[0.375,0.0,0.0,0.625,1.5,1.0]],"1207":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"1208":[[0.375,0.0,0.0,0.625,1.5,0.625]],"1209":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"1210":[[0.375,0.0,0.375,0.625,1.5,1.0]],"1211":[[0.0,0.0,0.375,0.625,1.5,0.625]],"1212":[[0.375,0.0,0.375,0.625,1.5,0.625]],"1213":[[0.375,0.375,0.0,0.625,0.625,1.0]],"1214":[[0.0,0.375,0.375,1.0,0.625,0.625]],"1215":[[0.375,0.0,0.375,0.625,1.0,0.625]],"1216":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1217":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1218":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1219":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1220":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1221":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1222":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1223":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1224":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1225":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1226":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1227":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1228":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1229":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1230":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1231":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1232":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1233":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1234":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1235":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1236":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1237":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1238":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1239":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1240":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1241":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1242":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1243":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1244":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125]],"1245":[[0.1875,0.0,0.1875,0.8125,1.0,0.8125]],"1246":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125],[0.0,0.1875,0.1875,0.1875,0.8125,0.8125]],"1247":[[0.1875,0.0,0.1875,0.8125,0.8125,0.8125]],"1248":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1249":[[0.1875,0.1875,0.0,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1250":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1251":[[0.1875,0.1875,0.0,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1252":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1253":[[0.1875,0.1875,0.0,0.8125,0.8125,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1254":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1255":[[0.1875,0.1875,0.0,0.8125,0.8125,0.8125],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1256":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1257":[[0.1875,0.1875,0.1875,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1258":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1259":[[0.1875,0.1875,0.1875,0.8125,0.8125,1.0],[0.8125,0.1875,0.1875,1.0,0.8125,0.8125]],"1260":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1261":[[0.1875,0.1875,0.1875,1.0,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1262":[[0.0,0.1875,0.1875,1.0,0.8125,0.8125]],"1263":[[0.1875,0.1875,0.1875,1.0,0.8125,0.8125]],"1264":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1265":[[0.1875,0.1875,0.0,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1266":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1267":[[0.1875,0.1875,0.0,0.8125,0.8125,1.0]],"1268":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1269":[[0.1875,0.1875,0.0,0.8125,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1270":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.0,0.8125,0.8125,0.1875]],"1271":[[0.1875,0.1875,0.0,0.8125,0.8125,0.8125]],"1272":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1273":[[0.1875,0.1875,0.1875,0.8125,0.8125,1.0],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1274":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.1875,0.8125,0.8125,0.8125,1.0]],"1275":[[0.1875,0.1875,0.1875,0.8125,0.8125,1.0]],"1276":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125],[0.1875,0.8125,0.1875,0.8125,1.0,0.8125]],"1277":[[0.1875,0.1875,0.1875,0.8125,1.0,0.8125]],"1278":[[0.0,0.1875,0.1875,0.8125,0.8125,0.8125]],"1279":[[0.1875,0.1875,0.1875,0.8125,0.8125,0.8125]],"1280":[[0.3125,-0.0625,0.3125,0.6875,0.1875,0.6875]],"1281":[[0.1875,-0.0625,0.1875,0.8125,0.3125,0.8125]],"1282":[[0.0,0.0,0.0,1.0,0.9375,1.0]],"1283":[[0.1875,0.0,0.1875,0.75,0.4375,0.75]],"1284":[[0.0625,0.0,0.0625,0.9375,0.4375,0.9375]],"1285":[[0.0625,0.0,0.125,0.9375,1.0,0.875]],"1286":[[0.1875,0.0,0.1875,0.8125,0.625,0.8125]],"1287":[[0.375,0.0,0.375,0.625,0.375,0.625]],"1288":[[0.1875,0.0,0.1875,0.8125,0.375,0.8125]],"1289":[[0.125,0.0,0.125,0.875,0.375,0.875]],"1290":[[0.125,0.0,0.125,0.875,0.4375,0.875]],"1291":[[0.3125,0.3125,0.3125,0.6875,0.6875,0.6875]],"1292":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1293":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1294":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1295":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1296":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1297":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1298":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1299":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1300":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1301":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1302":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1303":[[0.15625,0.0,0.15625,0.34375,1.0,0.34375]],"1304":[[0.25,0.0,0.25,0.75,1.5,0.75]],"1305":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1306":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1307":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1308":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1309":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1310":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1311":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1312":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1313":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1314":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1315":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1316":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1317":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1318":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1319":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1320":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1321":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1322":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1323":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1324":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1325":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1326":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1327":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1328":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1329":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1330":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1331":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1332":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1333":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1334":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1335":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1336":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1337":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1338":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1339":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1340":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1341":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1342":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1343":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1344":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1345":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1346":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1347":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1348":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1349":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1350":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1351":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1352":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1353":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1354":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1355":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1356":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1357":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1358":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1359":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1360":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1361":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1362":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1363":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1364":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1365":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1366":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1367":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1368":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1369":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1370":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1371":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1372":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1373":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1374":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1375":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1376":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1377":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1378":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1379":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1380":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1381":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1382":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1383":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1384":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1385":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1386":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1387":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1388":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1389":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1390":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1391":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1392":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1393":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1394":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1395":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1396":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1397":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1398":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1399":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1400":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1401":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1402":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1403":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1404":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1405":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1406":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1407":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1408":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1409":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1410":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1411":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1412":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1413":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1414":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1415":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1416":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1417":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1418":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1419":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1420":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1421":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1422":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1423":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1424":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1425":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1426":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1427":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1428":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1429":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1430":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1431":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1432":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1433":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1434":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1435":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1436":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1437":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1438":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1439":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1440":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1441":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1442":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1443":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1444":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1445":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1446":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1447":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1448":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1449":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1450":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1451":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1452":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1453":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1454":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1455":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1456":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1457":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1458":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1459":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1460":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1461":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1462":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1463":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1464":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1465":[[0.25,0.0,0.25,0.75,1.5,0.75]],"1466":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1467":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1468":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1469":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1470":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1471":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1472":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1473":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1474":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1475":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1476":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1477":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1478":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1479":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1480":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1481":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1482":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1483":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1484":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1485":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1486":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1487":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1488":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1489":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1490":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1491":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1492":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1493":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1494":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1495":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1496":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1497":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1498":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1499":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1500":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1501":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1502":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1503":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1504":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1505":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1506":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1507":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1508":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1509":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1510":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1511":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1512":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1513":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1514":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1515":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1516":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1517":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1518":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1519":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1520":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1521":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1522":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1523":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1524":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1525":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1526":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1527":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1528":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1529":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1530":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1531":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1532":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1533":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1534":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1535":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1536":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1537":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1538":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1539":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1540":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1541":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1542":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1543":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1544":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1545":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1546":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1547":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1548":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1549":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1550":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1551":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1552":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1553":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1554":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1555":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1556":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1557":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1558":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1559":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1560":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1561":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1562":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1563":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1564":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1565":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1566":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1567":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1568":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1569":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1570":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1571":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1572":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1573":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1574":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1575":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1576":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1577":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1578":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1579":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1580":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1581":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1582":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1583":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1584":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1585":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1586":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1587":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1588":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1589":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1590":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1591":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1592":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1593":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1594":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1595":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1596":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1597":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1598":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1599":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1600":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1601":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1602":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1603":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1604":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1605":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1606":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1607":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1608":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1609":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1610":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1611":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1612":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1613":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1614":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1615":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1616":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1617":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1618":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1619":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1620":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1621":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1622":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1623":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1624":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1625":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1626":[[0.25,0.0,0.25,0.75,1.5,0.75]],"1627":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1628":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1629":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1630":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1631":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1632":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1633":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1634":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1635":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1636":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1637":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1638":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1639":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1640":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1641":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1642":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1643":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1644":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1645":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1646":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1647":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1648":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1649":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1650":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1651":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1652":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1653":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1654":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1655":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1656":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1657":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1658":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1659":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1660":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1661":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1662":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1663":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1664":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1665":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1666":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1667":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1668":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1669":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1670":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1671":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1672":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1673":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1674":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1675":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1676":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1677":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1678":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1679":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1680":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1681":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1682":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1683":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1684":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1685":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1686":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1687":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1688":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1689":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1690":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1691":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1692":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1693":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1694":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1695":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1696":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1697":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1698":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1699":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1700":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1701":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1702":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1703":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1704":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1705":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1706":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1707":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1708":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1709":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1710":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1711":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1712":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1713":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1714":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1715":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1716":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1717":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1718":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1719":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1720":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1721":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1722":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1723":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1724":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1725":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1726":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1727":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1728":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1729":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1730":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1731":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1732":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1733":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1734":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1735":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1736":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1737":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1738":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1739":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1740":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1741":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1742":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1743":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1744":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1745":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1746":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1747":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1748":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1749":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1750":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1751":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1752":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1753":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1754":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1755":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1756":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1757":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1758":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1759":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1760":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1761":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1762":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1763":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1764":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1765":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1766":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1767":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1768":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1769":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1770":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1771":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1772":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1773":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1774":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1775":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1776":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1777":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1778":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1779":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1780":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1781":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1782":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1783":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1784":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1785":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1786":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1787":[[0.25,0.0,0.25,0.75,1.5,0.75]],"1788":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1789":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1790":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1791":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1792":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1793":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1794":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1795":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1796":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1797":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1798":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1799":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1800":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1801":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1802":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1803":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1804":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1805":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1806":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1807":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1808":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1809":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1810":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1811":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1812":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1813":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1814":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1815":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1816":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1817":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1818":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1819":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1820":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1821":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1822":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1823":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1824":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1825":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1826":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1827":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1828":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1829":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1830":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1831":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1832":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1833":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1834":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1835":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1836":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1837":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1838":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1839":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1840":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1841":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1842":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1843":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1844":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1845":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1846":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1847":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1848":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1849":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1850":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1851":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1852":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1853":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1854":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1855":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1856":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1857":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1858":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1859":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1860":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1861":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1862":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1863":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1864":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1865":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1866":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1867":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1868":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1869":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1870":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1871":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1872":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1873":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1874":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1875":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1876":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1877":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1878":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1879":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1880":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1881":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1882":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1883":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1884":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1885":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1886":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1887":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1888":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1889":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1890":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1891":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1892":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1893":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1894":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1895":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1896":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1897":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"1898":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1899":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"1900":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1901":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1902":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1903":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1904":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1905":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1906":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1907":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1908":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1909":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1910":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1911":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1912":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1913":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1914":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1915":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1916":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1917":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1918":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1919":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1920":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1921":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1922":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1923":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1924":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1925":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1926":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1927":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1928":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1929":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1930":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1931":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1932":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1933":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1934":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1935":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1936":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1937":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1938":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1939":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1940":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1941":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1942":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"1943":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1944":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1945":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"1946":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1947":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1948":[[0.25,0.0,0.25,0.75,1.5,0.75]],"1949":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1950":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"1951":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1952":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"1953":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1954":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1955":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1956":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1957":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1958":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1959":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1960":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1961":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1962":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"1963":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1964":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1965":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1966":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1967":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1968":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1969":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1970":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1971":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1972":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1973":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1974":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1975":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1976":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1977":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1978":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1979":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1980":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1981":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1982":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1983":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1984":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1985":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"1986":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"1987":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1988":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"1989":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1990":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1991":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1992":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1993":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1994":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"1995":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1996":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1997":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"1998":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"1999":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2000":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2001":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2002":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2003":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2004":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2005":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2006":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2007":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2008":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2009":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2010":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2011":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2012":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2013":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2014":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2015":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2016":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2017":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2018":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2019":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2020":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2021":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2022":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2023":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2024":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2025":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2026":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2027":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2028":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2029":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2030":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2031":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2032":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2033":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2034":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2035":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2036":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2037":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2038":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2039":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2040":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2041":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2042":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2043":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2044":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2045":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2046":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2047":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2048":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2049":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2050":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2051":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2052":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2053":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2054":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2055":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2056":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2057":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2058":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2059":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2060":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2061":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2062":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2063":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2064":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2065":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2066":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2067":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2068":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2069":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2070":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2071":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2072":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2073":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2074":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2075":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2076":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2077":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2078":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2079":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2080":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2081":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2082":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2083":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2084":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2085":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2086":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2087":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2088":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2089":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2090":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2091":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2092":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2093":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2094":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2095":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2096":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2097":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2098":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2099":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2100":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2101":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2102":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2103":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2104":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2105":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2106":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2107":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2108":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2109":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2110":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2111":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2112":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2113":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2114":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2115":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2116":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2117":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2118":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2119":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2120":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2121":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2122":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2123":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2124":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2125":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2126":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2127":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2128":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2129":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2130":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2131":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2132":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2133":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2134":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2135":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2136":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2137":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2138":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2139":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2140":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2141":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2142":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2143":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2144":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2145":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2146":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2147":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2148":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2149":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2150":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2151":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2152":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2153":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2154":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2155":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2156":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2157":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2158":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2159":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2160":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2161":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2162":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2163":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2164":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2165":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2166":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2167":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2168":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2169":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2170":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2171":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2172":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2173":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2174":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2175":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2176":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2177":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2178":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2179":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2180":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2181":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2182":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2183":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2184":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2185":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2186":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2187":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2188":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2189":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2190":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2191":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2192":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2193":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2194":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2195":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2196":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2197":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2198":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2199":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2200":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2201":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2202":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2203":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2204":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2205":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2206":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2207":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2208":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2209":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2210":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2211":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2212":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2213":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2214":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2215":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2216":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2217":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2218":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2219":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2220":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2221":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2222":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2223":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2224":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2225":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2226":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2227":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2228":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2229":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2230":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2231":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2232":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2233":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2234":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2235":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2236":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2237":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2238":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2239":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2240":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2241":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2242":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2243":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2244":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2245":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2246":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2247":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2248":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2249":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2250":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2251":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2252":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2253":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2254":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2255":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2256":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2257":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2258":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2259":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2260":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2261":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2262":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2263":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2264":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2265":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2266":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2267":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2268":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2269":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2270":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2271":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2272":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2273":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2274":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2275":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2276":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2277":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2278":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2279":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2280":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2281":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2282":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2283":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2284":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2285":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2286":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2287":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2288":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2289":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2290":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2291":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2292":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2293":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2294":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2295":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2296":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2297":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2298":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2299":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2300":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2301":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2302":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2303":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2304":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2305":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2306":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2307":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2308":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2309":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2310":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2311":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2312":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2313":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2314":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2315":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2316":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2317":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2318":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2319":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2320":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2321":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2322":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2323":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2324":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2325":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2326":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2327":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2328":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2329":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2330":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2331":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2332":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2333":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2334":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2335":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2336":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2337":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2338":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2339":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2340":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2341":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2342":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2343":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2344":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2345":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2346":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2347":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2348":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2349":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2350":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2351":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2352":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2353":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2354":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2355":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2356":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2357":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2358":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2359":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2360":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2361":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2362":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2363":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2364":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2365":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2366":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2367":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2368":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2369":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2370":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2371":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2372":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2373":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2374":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2375":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2376":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2377":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2378":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2379":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2380":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2381":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2382":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2383":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2384":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2385":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2386":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2387":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2388":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2389":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2390":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2391":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2392":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2393":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2394":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2395":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2396":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2397":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2398":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2399":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2400":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2401":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2402":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2403":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2404":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2405":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2406":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2407":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2408":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2409":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2410":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2411":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2412":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2413":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2414":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2415":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2416":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2417":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2418":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2419":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2420":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2421":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2422":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2423":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2424":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2425":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2426":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2427":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2428":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2429":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2430":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2431":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2432":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2433":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2434":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2435":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2436":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2437":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2438":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2439":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2440":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2441":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2442":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2443":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2444":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2445":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2446":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2447":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2448":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2449":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2450":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2451":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2452":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2453":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2454":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2455":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2456":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2457":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2458":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2459":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2460":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2461":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2462":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2463":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2464":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2465":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2466":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2467":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2468":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2469":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2470":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2471":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2472":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2473":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2474":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2475":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2476":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2477":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2478":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2479":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2480":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2481":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2482":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2483":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2484":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2485":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2486":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2487":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2488":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2489":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2490":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2491":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2492":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2493":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2494":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2495":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2496":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2497":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2498":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2499":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2500":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2501":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2502":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2503":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2504":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2505":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2506":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2507":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2508":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2509":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2510":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2511":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2512":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2513":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2514":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2515":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2516":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2517":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2518":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2519":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2520":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2521":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2522":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2523":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2524":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2525":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2526":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2527":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2528":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2529":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2530":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2531":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2532":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2533":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2534":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2535":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2536":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2537":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2538":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2539":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2540":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2541":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2542":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2543":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2544":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2545":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2546":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2547":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2548":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2549":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2550":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2551":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2552":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2553":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2554":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2555":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2556":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2557":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2558":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2559":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2560":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2561":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2562":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2563":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2564":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2565":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2566":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2567":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2568":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2569":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2570":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2571":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2572":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2573":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2574":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2575":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2576":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2577":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2578":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2579":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2580":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2581":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2582":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2583":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2584":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2585":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2586":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2587":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2588":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2589":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2590":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2591":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2592":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2593":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2594":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2595":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2596":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2597":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2598":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2599":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2600":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2601":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2602":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2603":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2604":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2605":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2606":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2607":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2608":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2609":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2610":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2611":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2612":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2613":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2614":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2615":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2616":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2617":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2618":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2619":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2620":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2621":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2622":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2623":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2624":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2625":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2626":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2627":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2628":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2629":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2630":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2631":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2632":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2633":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2634":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2635":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2636":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2637":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2638":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2639":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2640":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2641":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2642":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2643":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2644":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2645":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2646":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2647":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2648":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2649":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2650":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2651":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2652":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2653":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2654":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2655":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2656":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2657":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2658":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2659":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2660":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2661":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2662":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2663":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2664":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2665":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2666":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2667":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2668":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2669":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2670":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2671":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2672":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2673":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2674":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2675":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2676":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2677":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2678":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2679":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2680":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2681":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2682":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2683":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2684":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2685":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2686":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2687":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2688":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2689":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2690":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2691":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2692":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2693":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2694":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2695":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2696":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2697":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2698":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2699":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2700":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2701":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2702":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2703":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2704":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2705":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2706":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2707":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2708":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2709":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2710":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2711":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2712":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2713":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2714":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2715":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2716":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2717":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2718":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2719":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2720":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2721":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2722":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2723":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2724":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2725":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2726":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2727":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2728":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2729":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2730":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2731":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2732":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2733":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2734":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2735":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2736":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2737":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2738":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2739":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2740":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2741":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2742":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2743":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2744":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2745":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2746":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2747":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2748":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2749":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2750":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2751":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2752":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2753":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2754":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2755":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2756":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2757":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2758":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2759":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2760":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2761":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2762":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2763":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2764":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2765":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2766":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2767":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2768":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2769":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2770":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2771":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2772":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2773":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2774":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2775":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2776":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2777":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2778":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2779":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2780":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2781":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2782":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2783":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2784":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2785":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2786":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2787":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2788":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2789":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2790":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2791":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2792":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2793":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2794":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2795":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2796":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2797":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2798":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2799":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2800":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2801":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2802":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2803":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2804":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2805":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2806":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2807":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2808":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2809":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2810":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2811":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2812":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2813":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2814":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2815":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2816":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2817":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2818":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2819":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2820":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2821":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2822":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2823":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2824":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2825":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2826":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2827":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2828":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2829":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2830":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2831":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2832":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2833":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2834":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2835":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2836":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2837":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2838":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2839":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2840":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2841":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2842":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2843":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2844":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2845":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2846":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2847":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2848":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2849":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2850":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2851":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2852":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2853":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2854":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2855":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2856":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2857":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2858":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2859":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2860":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2861":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2862":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2863":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2864":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2865":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2866":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2867":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2868":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2869":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2870":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2871":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2872":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2873":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2874":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2875":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2876":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2877":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2878":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2879":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2880":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2881":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2882":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2883":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2884":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2885":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2886":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2887":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2888":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2889":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2890":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2891":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2892":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2893":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2894":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2895":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2896":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2897":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2898":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2899":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2900":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2901":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2902":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2903":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2904":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2905":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2906":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2907":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2908":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2909":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2910":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2911":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2912":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2913":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2914":[[0.25,0.0,0.25,0.75,1.5,0.75]],"2915":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2916":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2917":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2918":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"2919":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2920":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2921":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2922":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2923":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2924":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2925":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2926":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2927":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2928":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"2929":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2930":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2931":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2932":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2933":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2934":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2935":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2936":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2937":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2938":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2939":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2940":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2941":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2942":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2943":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2944":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2945":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2946":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2947":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2948":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2949":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2950":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2951":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2952":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"2953":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2954":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2955":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2956":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2957":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2958":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2959":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2960":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2961":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2962":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2963":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2964":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"2965":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2966":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2967":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2968":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2969":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"2970":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"2971":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2972":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"2973":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2974":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2975":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2976":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2977":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2978":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2979":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2980":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2981":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2982":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2983":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2984":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2985":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2986":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2987":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"2988":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2989":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2990":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"2991":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2992":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2993":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2994":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"2995":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2996":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"2997":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"2998":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"2999":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3000":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3001":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3002":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3003":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3004":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3005":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3006":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3007":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3008":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3009":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3010":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3011":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3012":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3013":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3014":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3015":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3016":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3017":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3018":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3019":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3020":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3021":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3022":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3023":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3024":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3025":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3026":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3027":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3028":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3029":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3030":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3031":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3032":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3033":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3034":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3035":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3036":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3037":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3038":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3039":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3040":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3041":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3042":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3043":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3044":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3045":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3046":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3047":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3048":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3049":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3050":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3051":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3052":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3053":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3054":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3055":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3056":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3057":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3058":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3059":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3060":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3061":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3062":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3063":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3064":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3065":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3066":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3067":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3068":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3069":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3070":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3071":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3072":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3073":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3074":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3075":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3076":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3077":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3078":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3079":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3080":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3081":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3082":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3083":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3084":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3085":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3086":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3087":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3088":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3089":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3090":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3091":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3092":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3093":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3094":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3095":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3096":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3097":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3098":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3099":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3100":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3101":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3102":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3103":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3104":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3105":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3106":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3107":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3108":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3109":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3110":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3111":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3112":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3113":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3114":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3115":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3116":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3117":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3118":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3119":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3120":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3121":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3122":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3123":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3124":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3125":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3126":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3127":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3128":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3129":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3130":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3131":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3132":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3133":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3134":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3135":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3136":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3137":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3138":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3139":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3140":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3141":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3142":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3143":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3144":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3145":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3146":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3147":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3148":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3149":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3150":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3151":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3152":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3153":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3154":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3155":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3156":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3157":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3158":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3159":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3160":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3161":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3162":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3163":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3164":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3165":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3166":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3167":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3168":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3169":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3170":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3171":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3172":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3173":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3174":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3175":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3176":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3177":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3178":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3179":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3180":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3181":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3182":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3183":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3184":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3185":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3186":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3187":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3188":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3189":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3190":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3191":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3192":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3193":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3194":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3195":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3196":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3197":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3198":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3199":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3200":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3201":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3202":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3203":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3204":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3205":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3206":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3207":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3208":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3209":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3210":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3211":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3212":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3213":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3214":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3215":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3216":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3217":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3218":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3219":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3220":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3221":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3222":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3223":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3224":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3225":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3226":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3227":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3228":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3229":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3230":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3231":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3232":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3233":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3234":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3235":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3236":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3237":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3238":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3239":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3240":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3241":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3242":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3243":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3244":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3245":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3246":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3247":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3248":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3249":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3250":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3251":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3252":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3253":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3254":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3255":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3256":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3257":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3258":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3259":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3260":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3261":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3262":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3263":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3264":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3265":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3266":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3267":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3268":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3269":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3270":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3271":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3272":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3273":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3274":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3275":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3276":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3277":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3278":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3279":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3280":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3281":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3282":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3283":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3284":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3285":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3286":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3287":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3288":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3289":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3290":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3291":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3292":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3293":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3294":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3295":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3296":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3297":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3298":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3299":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3300":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3301":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3302":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3303":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3304":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3305":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3306":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3307":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3308":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3309":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3310":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3311":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3312":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3313":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3314":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3315":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3316":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3317":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3318":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3319":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3320":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3321":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3322":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3323":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3324":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3325":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3326":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3327":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3328":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3329":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3330":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3331":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3332":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3333":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3334":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3335":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3336":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3337":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3338":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3339":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3340":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3341":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3342":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3343":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3344":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3345":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3346":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3347":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3348":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3349":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3350":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3351":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3352":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3353":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3354":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3355":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3356":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3357":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3358":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3359":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3360":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3361":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3362":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3363":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3364":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3365":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3366":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3367":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3368":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3369":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3370":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3371":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3372":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3373":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3374":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3375":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3376":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3377":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3378":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3379":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3380":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3381":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3382":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3383":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3384":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3385":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3386":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3387":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3388":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3389":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3390":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3391":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3392":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3393":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3394":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3395":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3396":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3397":[[0.0,0.0,0.0,0.125,1.0,0.125],[0.0,0.0,0.875,0.125,1.0,1.0],[0.875,0.0,0.0,1.0,1.0,0.125],[0.875,0.0,0.875,1.0,1.0,1.0],[0.0,0.875,0.125,1.0,1.0,0.875],[0.125,0.875,0.0,0.875,1.0,0.125],[0.125,0.875,0.875,0.875,1.0,1.0]],"3398":[[0.125,0.0,0.375,0.25,0.8125,0.625],[0.75,0.0,0.375,0.875,0.8125,0.625],[0.25,0.25,0.125,0.75,1.0,0.875],[0.125,0.4375,0.3125,0.25,0.8125,0.375],[0.125,0.4375,0.625,0.25,0.8125,0.6875],[0.75,0.4375,0.3125,0.875,0.8125,0.375],[0.75,0.4375,0.625,0.875,0.8125,0.6875]],"3399":[[0.125,0.0,0.375,0.25,0.8125,0.625],[0.75,0.0,0.375,0.875,0.8125,0.625],[0.25,0.25,0.125,0.75,1.0,0.875],[0.125,0.4375,0.3125,0.25,0.8125,0.375],[0.125,0.4375,0.625,0.25,0.8125,0.6875],[0.75,0.4375,0.3125,0.875,0.8125,0.375],[0.75,0.4375,0.625,0.875,0.8125,0.6875]],"3400":[[0.375,0.0,0.125,0.625,0.8125,0.25],[0.375,0.0,0.75,0.625,0.8125,0.875],[0.125,0.25,0.25,0.875,1.0,0.75],[0.3125,0.4375,0.125,0.375,0.8125,0.25],[0.3125,0.4375,0.75,0.375,0.8125,0.875],[0.625,0.4375,0.125,0.6875,0.8125,0.25],[0.625,0.4375,0.75,0.6875,0.8125,0.875]],"3401":[[0.375,0.0,0.125,0.625,0.8125,0.25],[0.375,0.0,0.75,0.625,0.8125,0.875],[0.125,0.25,0.25,0.875,1.0,0.75],[0.3125,0.4375,0.125,0.375,0.8125,0.25],[0.3125,0.4375,0.75,0.375,0.8125,0.875],[0.625,0.4375,0.125,0.6875,0.8125,0.25],[0.625,0.4375,0.75,0.6875,0.8125,0.875]],"3402":[[0.25,0.125,0.0,0.75,0.875,0.75],[0.125,0.3125,0.1875,0.25,0.6875,0.5625],[0.75,0.3125,0.1875,0.875,0.6875,0.5625],[0.125,0.375,0.5625,0.25,0.625,1.0],[0.75,0.375,0.5625,0.875,0.625,1.0]],"3403":[[0.25,0.125,0.25,0.75,0.875,1.0],[0.125,0.3125,0.4375,0.25,0.6875,0.8125],[0.75,0.3125,0.4375,0.875,0.6875,0.8125],[0.125,0.375,0.0,0.25,0.625,0.4375],[0.75,0.375,0.0,0.875,0.625,0.4375]],"3404":[[0.0,0.125,0.25,0.75,0.875,0.75],[0.1875,0.3125,0.125,0.5625,0.6875,0.25],[0.1875,0.3125,0.75,0.5625,0.6875,0.875],[0.5625,0.375,0.125,1.0,0.625,0.25],[0.5625,0.375,0.75,1.0,0.625,0.875]],"3405":[[0.25,0.125,0.25,1.0,0.875,0.75],[0.4375,0.3125,0.125,0.8125,0.6875,0.25],[0.4375,0.3125,0.75,0.8125,0.6875,0.875],[0.0,0.375,0.125,0.4375,0.625,0.25],[0.0,0.375,0.75,0.4375,0.625,0.875]],"3406":[[0.25,0.0,0.125,0.75,0.75,0.875],[0.125,0.1875,0.3125,0.25,0.5625,0.6875],[0.75,0.1875,0.3125,0.875,0.5625,0.6875],[0.125,0.5625,0.375,0.25,1.0,0.625],[0.75,0.5625,0.375,0.875,1.0,0.625]],"3407":[[0.25,0.0,0.125,0.75,0.75,0.875],[0.125,0.1875,0.3125,0.25,0.5625,0.6875],[0.75,0.1875,0.3125,0.875,0.5625,0.6875],[0.125,0.5625,0.375,0.25,1.0,0.625],[0.75,0.5625,0.375,0.875,1.0,0.625]],"3408":[[0.125,0.0,0.25,0.875,0.75,0.75],[0.3125,0.1875,0.125,0.6875,0.5625,0.25],[0.3125,0.1875,0.75,0.6875,0.5625,0.875],[0.375,0.5625,0.125,0.625,1.0,0.25],[0.375,0.5625,0.75,0.625,1.0,0.875]],"3409":[[0.125,0.0,0.25,0.875,0.75,0.75],[0.3125,0.1875,0.125,0.6875,0.5625,0.25],[0.3125,0.1875,0.75,0.6875,0.5625,0.875],[0.375,0.5625,0.125,0.625,1.0,0.25],[0.375,0.5625,0.75,0.625,1.0,0.875]],"3410":[[0.0,0.0,0.0,1.0,0.125,1.0],[0.25,0.125,0.25,0.75,0.875,0.75]],"3411":[[0.0,0.0,0.0,1.0,0.5625,1.0]],"3412":[[0.0,0.0,0.25,1.0,1.0,0.75]],"3413":[[0.25,0.0,0.0,0.75,1.0,1.0]],"3414":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.4375,0.8125,0.4375,0.5625,1.0,0.5625]],"3415":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.4375,0.8125,0.0,0.5625,0.9375,0.8125]],"3416":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.4375,0.8125,0.1875,0.5625,0.9375,1.0]],"3417":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.0,0.8125,0.4375,0.8125,0.9375,0.5625]],"3418":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.1875,0.8125,0.4375,1.0,0.9375,0.5625]],"3419":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.4375,0.8125,0.0,0.5625,0.9375,1.0]],"3420":[[0.25,0.25,0.25,0.75,0.375,0.75],[0.3125,0.375,0.3125,0.6875,0.8125,0.6875],[0.0,0.8125,0.4375,1.0,0.9375,0.5625]],"3421":[[0.3125,0.0625,0.3125,0.6875,0.5,0.6875],[0.375,0.5,0.375,0.625,0.625,0.625]],"3422":[[0.3125,0.0,0.3125,0.6875,0.4375,0.6875],[0.375,0.4375,0.375,0.625,0.5625,0.625]],"3423":[[0.0,0.0,0.0,1.0,0.4375,1.0]],"3424":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"3425":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"3426":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"3427":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"3428":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"3429":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"3430":[[0.0,0.0,0.375,1.0,1.5,0.625]],"3431":[[0.375,0.0,0.375,1.0,1.5,0.625]],"3432":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"3433":[[0.375,0.0,0.0,0.625,1.5,1.0]],"3434":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"3435":[[0.375,0.0,0.0,0.625,1.5,0.625]],"3436":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"3437":[[0.375,0.0,0.375,0.625,1.5,1.0]],"3438":[[0.0,0.0,0.375,0.625,1.5,0.625]],"3439":[[0.375,0.0,0.375,0.625,1.5,0.625]],"3440":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"3441":[[0.375,0.0,0.0,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"3442":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"3443":[[0.375,0.0,0.0,0.625,1.5,0.625],[0.625,0.0,0.375,1.0,1.5,0.625]],"3444":[[0.0,0.0,0.375,1.0,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"3445":[[0.375,0.0,0.375,0.625,1.5,1.0],[0.625,0.0,0.375,1.0,1.5,0.625]],"3446":[[0.0,0.0,0.375,1.0,1.5,0.625]],"3447":[[0.375,0.0,0.375,1.0,1.5,0.625]],"3448":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375],[0.375,0.0,0.625,0.625,1.5,1.0]],"3449":[[0.375,0.0,0.0,0.625,1.5,1.0]],"3450":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.0,0.625,1.5,0.375]],"3451":[[0.375,0.0,0.0,0.625,1.5,0.625]],"3452":[[0.0,0.0,0.375,0.625,1.5,0.625],[0.375,0.0,0.625,0.625,1.5,1.0]],"3453":[[0.375,0.0,0.375,0.625,1.5,1.0]],"3454":[[0.0,0.0,0.375,0.625,1.5,0.625]],"3455":[[0.375,0.0,0.375,0.625,1.5,0.625]],"3456":[[0.0,0.0,0.0,1.0,0.125,1.0],[0.0,0.125,0.0,0.125,1.0,1.0],[0.125,0.125,0.0,1.0,1.0,0.125],[0.125,0.125,0.875,1.0,1.0,1.0],[0.875,0.125,0.125,1.0,1.0,0.875]],"3457":[[0.0625,0.0,0.0625,0.9375,0.9375,0.9375]],"3458":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3459":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3460":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3461":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3462":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3463":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3464":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3465":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3466":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3467":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3468":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3469":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3470":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3471":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3472":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3473":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3474":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3475":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3476":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3477":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3478":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3479":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3480":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3481":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3482":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3483":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3484":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3485":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3486":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3487":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3488":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3489":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3490":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3491":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3492":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3493":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3494":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3495":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3496":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3497":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3498":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3499":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3500":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3501":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3502":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3503":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3504":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3505":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3506":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3507":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3508":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3509":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3510":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3511":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3512":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3513":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3514":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3515":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3516":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3517":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3518":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3519":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3520":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3521":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3522":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3523":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3524":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3525":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3526":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3527":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3528":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3529":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3530":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3531":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3532":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3533":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3534":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3535":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3536":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3537":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3538":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3539":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3540":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3541":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3542":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3543":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3544":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3545":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3546":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3547":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3548":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3549":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3550":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3551":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3552":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3553":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3554":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3555":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3556":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3557":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3558":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3559":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3560":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3561":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3562":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3563":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3564":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3565":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3566":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3567":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3568":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3569":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3570":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3571":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3572":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3573":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3574":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3575":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3576":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3577":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3578":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3579":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3580":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3581":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3582":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3583":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3584":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3585":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3586":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3587":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3588":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3589":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3590":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3591":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3592":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3593":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3594":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3595":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3596":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3597":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3598":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3599":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3600":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3601":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3602":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3603":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3604":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3605":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3606":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3607":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3608":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3609":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3610":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3611":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3612":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3613":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3614":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3615":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3616":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3617":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3618":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3619":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3620":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3621":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3622":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3623":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3624":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3625":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3626":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3627":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3628":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3629":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3630":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3631":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3632":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3633":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3634":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3635":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3636":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3637":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3638":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3639":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3640":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3641":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3642":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3643":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3644":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3645":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3646":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3647":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3648":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3649":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3650":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3651":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3652":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3653":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3654":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3655":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3656":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3657":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3658":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3659":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3660":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3661":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3662":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3663":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3664":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3665":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3666":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3667":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3668":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3669":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3670":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3671":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3672":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3673":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3674":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3675":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3676":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3677":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3678":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3679":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3680":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3681":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3682":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3683":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3684":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3685":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3686":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3687":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3688":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3689":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3690":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3691":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3692":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3693":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3694":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3695":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3696":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3697":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3698":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3699":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3700":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3701":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3702":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3703":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3704":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3705":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3706":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3707":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3708":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3709":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3710":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3711":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3712":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3713":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3714":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3715":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3716":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3717":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3718":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3719":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3720":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3721":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3722":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3723":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3724":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3725":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3726":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3727":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3728":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3729":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3730":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3731":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3732":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3733":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3734":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3735":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3736":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3737":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3738":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3739":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3740":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3741":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3742":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3743":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3744":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3745":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3746":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3747":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3748":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3749":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3750":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3751":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3752":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3753":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3754":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3755":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3756":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3757":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3758":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3759":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3760":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3761":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3762":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3763":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3764":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3765":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3766":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3767":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3768":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3769":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3770":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3771":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3772":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3773":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3774":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3775":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3776":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3777":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3778":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3779":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3780":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3781":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3782":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3783":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3784":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3785":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3786":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3787":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3788":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3789":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3790":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3791":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3792":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3793":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3794":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3795":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3796":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3797":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3798":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3799":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3800":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3801":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3802":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3803":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3804":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3805":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3806":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3807":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3808":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3809":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3810":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3811":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3812":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3813":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3814":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3815":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3816":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3817":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3818":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3819":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3820":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3821":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3822":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3823":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3824":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3825":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3826":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3827":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3828":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3829":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3830":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3831":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3832":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3833":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3834":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3835":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3836":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3837":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3838":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3839":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3840":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3841":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3842":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3843":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3844":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3845":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3846":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3847":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3848":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3849":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3850":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3851":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3852":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3853":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3854":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3855":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3856":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3857":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3858":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3859":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3860":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3861":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3862":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3863":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3864":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3865":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3866":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3867":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3868":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3869":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3870":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3871":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3872":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3873":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3874":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3875":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3876":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3877":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3878":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3879":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3880":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3881":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3882":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3883":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3884":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3885":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3886":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3887":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3888":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3889":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3890":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"3891":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3892":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"3893":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3894":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3895":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3896":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3897":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3898":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3899":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3900":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3901":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3902":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3903":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3904":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3905":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3906":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3907":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3908":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3909":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3910":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3911":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3912":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3913":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3914":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3915":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3916":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3917":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3918":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3919":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3920":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3921":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3922":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3923":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3924":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3925":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3926":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3927":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3928":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3929":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3930":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3931":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3932":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3933":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3934":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3935":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"3936":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3937":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3938":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"3939":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3940":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3941":[[0.4375,0.0,0.4375,0.5625,0.375,0.5625]],"3942":[[0.3125,0.0,0.375,0.6875,0.375,0.5625]],"3943":[[0.3125,0.0,0.375,0.625,0.375,0.6875]],"3944":[[0.3125,0.0,0.3125,0.6875,0.375,0.625]],"3945":[[0.0625,0.0,0.0625,0.9375,0.5,0.9375],[0.4375,0.5,0.4375,0.5625,0.875,0.5625]],"3946":[[0.1875,0.1875,0.5625,0.8125,0.8125,1.0]],"3947":[[0.0,0.1875,0.1875,0.4375,0.8125,0.8125]],"3948":[[0.1875,0.1875,0.0,0.8125,0.8125,0.4375]],"3949":[[0.5625,0.1875,0.1875,1.0,0.8125,0.8125]],"3950":[[0.1875,0.0,0.1875,0.8125,0.4375,0.8125]],"3951":[[0.1875,0.5625,0.1875,0.8125,1.0,0.8125]],"3952":[[0.1875,0.1875,0.6875,0.8125,0.8125,1.0]],"3953":[[0.0,0.1875,0.1875,0.3125,0.8125,0.8125]],"3954":[[0.1875,0.1875,0.0,0.8125,0.8125,0.3125]],"3955":[[0.6875,0.1875,0.1875,1.0,0.8125,0.8125]],"3956":[[0.1875,0.0,0.1875,0.8125,0.3125,0.8125]],"3957":[[0.1875,0.6875,0.1875,0.8125,1.0,0.8125]],"3958":[[0.1875,0.1875,0.75,0.8125,0.8125,1.0]],"3959":[[0.0,0.1875,0.1875,0.25,0.8125,0.8125]],"3960":[[0.1875,0.1875,0.0,0.8125,0.8125,0.25]],"3961":[[0.75,0.1875,0.1875,1.0,0.8125,0.8125]],"3962":[[0.1875,0.0,0.1875,0.8125,0.25,0.8125]],"3963":[[0.1875,0.75,0.1875,0.8125,1.0,0.8125]],"3964":[[0.25,0.25,0.8125,0.75,0.75,1.0]],"3965":[[0.0,0.25,0.25,0.1875,0.75,0.75]],"3966":[[0.25,0.25,0.0,0.75,0.75,0.1875]],"3967":[[0.8125,0.25,0.25,1.0,0.75,0.75]],"3968":[[0.25,0.0,0.25,0.75,0.1875,0.75]],"3969":[[0.25,0.8125,0.25,0.75,1.0,0.75]],"3970":[[0.25,0.0,0.25,0.75,1.5,0.75]],"3971":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3972":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"3973":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3974":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"3975":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3976":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3977":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3978":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3979":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3980":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3981":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3982":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3983":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3984":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"3985":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3986":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3987":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3988":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3989":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"3990":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"3991":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3992":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"3993":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3994":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3995":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"3996":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"3997":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3998":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"3999":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4000":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4001":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4002":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4003":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4004":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4005":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4006":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4007":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4008":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4009":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4010":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4011":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4012":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4013":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4014":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4015":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4016":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4017":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4018":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4019":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4020":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4021":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4022":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4023":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4024":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4025":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4026":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4027":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4028":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4029":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4030":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4031":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4032":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4033":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4034":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4035":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4036":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4037":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4038":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4039":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4040":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4041":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4042":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4043":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4044":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4045":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4046":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4047":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4048":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4049":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4050":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4051":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4052":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4053":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4054":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4055":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4056":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4057":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4058":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4059":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4060":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4061":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4062":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4063":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4064":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4065":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4066":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4067":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4068":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4069":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4070":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4071":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4072":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4073":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4074":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4075":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4076":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4077":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4078":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4079":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4080":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4081":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4082":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4083":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4084":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4085":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4086":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4087":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4088":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4089":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4090":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4091":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4092":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4093":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4094":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4095":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4096":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4097":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4098":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4099":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4100":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4101":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4102":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4103":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4104":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4105":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4106":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4107":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4108":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4109":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4110":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4111":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4112":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4113":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4114":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4115":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4116":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4117":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4118":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4119":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4120":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4121":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4122":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4123":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4124":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4125":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4126":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4127":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4128":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4129":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4130":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4131":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4132":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4133":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4134":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4135":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4136":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4137":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4138":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4139":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4140":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4141":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4142":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4143":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4144":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4145":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4146":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4147":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4148":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4149":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4150":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4151":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4152":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4153":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4154":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4155":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4156":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4157":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4158":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4159":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4160":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4161":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4162":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4163":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4164":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4165":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4166":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4167":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4168":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4169":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4170":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4171":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4172":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4173":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4174":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4175":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4176":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4177":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4178":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4179":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4180":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4181":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4182":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4183":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4184":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4185":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4186":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4187":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4188":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4189":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4190":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4191":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4192":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4193":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4194":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4195":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4196":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4197":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4198":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4199":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4200":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4201":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4202":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4203":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4204":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4205":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4206":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4207":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4208":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4209":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4210":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4211":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4212":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4213":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4214":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4215":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4216":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4217":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4218":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4219":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4220":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4221":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4222":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4223":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4224":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4225":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4226":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4227":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4228":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4229":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4230":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4231":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4232":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4233":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4234":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4235":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4236":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4237":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4238":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4239":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4240":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4241":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4242":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4243":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4244":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4245":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4246":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4247":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4248":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4249":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4250":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4251":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4252":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4253":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4254":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4255":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4256":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4257":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4258":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4259":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4260":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4261":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4262":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4263":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4264":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4265":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4266":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4267":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4268":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4269":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4270":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4271":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4272":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4273":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4274":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4275":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4276":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4277":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4278":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4279":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4280":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4281":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4282":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4283":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4284":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4285":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4286":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4287":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4288":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4289":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4290":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4291":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4292":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4293":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4294":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4295":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4296":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4297":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4298":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4299":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4300":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4301":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4302":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4303":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4304":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4305":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4306":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4307":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4308":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4309":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4310":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4311":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4312":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4313":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4314":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4315":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4316":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4317":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4318":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4319":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4320":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4321":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4322":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4323":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4324":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4325":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4326":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4327":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4328":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4329":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4330":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4331":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4332":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4333":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4334":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4335":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4336":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4337":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4338":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4339":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4340":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4341":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4342":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4343":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4344":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4345":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4346":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4347":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4348":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4349":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4350":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4351":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4352":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4353":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4354":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4355":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4356":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4357":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4358":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4359":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4360":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4361":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4362":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4363":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4364":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4365":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4366":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4367":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4368":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4369":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4370":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4371":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4372":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4373":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4374":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4375":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4376":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4377":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4378":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4379":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4380":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4381":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4382":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4383":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4384":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4385":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4386":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4387":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4388":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4389":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4390":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4391":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4392":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4393":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4394":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4395":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4396":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4397":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4398":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4399":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4400":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4401":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4402":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4403":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4404":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4405":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4406":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4407":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4408":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4409":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4410":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4411":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4412":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4413":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4414":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4415":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4416":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4417":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4418":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4419":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4420":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4421":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4422":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4423":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4424":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4425":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4426":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4427":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4428":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4429":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4430":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4431":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4432":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4433":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4434":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4435":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4436":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4437":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4438":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4439":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4440":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4441":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4442":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4443":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4444":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4445":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4446":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4447":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4448":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4449":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4450":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4451":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4452":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4453":[[0.0,0.0,0.0,1.0,0.5,1.0]],"4454":[[0.0,0.0,0.0,1.0,0.5,1.0]],"4455":[[0.1875,0.0,0.1875,0.8125,0.875,0.8125]],"4456":[[0.1875,0.0,0.1875,0.5625,1.0,0.5625]],"4457":[[0.1875,0.0,0.1875,0.5625,1.0,0.5625]],"4458":[[0.1875,0.0,0.1875,0.5625,1.0,0.5625]],"4459":[[0.1875,0.0,0.1875,0.5625,1.0,0.5625]],"4460":[[0.1875,0.0,0.1875,0.5625,0.6875,0.5625]],"4461":[[0.1875,0.0,0.1875,0.5625,0.6875,0.5625]],"4462":[[0.1875,0.3125,0.1875,0.5625,1.0,0.5625]],"4463":[[0.1875,0.3125,0.1875,0.5625,1.0,0.5625]],"4464":[[0.125,0.0,0.125,0.625,1.0,0.625]],"4465":[[0.125,0.0,0.125,0.625,1.0,0.625]],"4466":[[0.125,0.0,0.125,0.625,1.0,0.625]],"4467":[[0.125,0.0,0.125,0.625,1.0,0.625]],"4468":[[0.0625,0.0,0.0625,0.6875,1.0,0.6875]],"4469":[[0.0625,0.0,0.0625,0.6875,1.0,0.6875]],"4470":[[0.0625,0.0,0.0625,0.6875,1.0,0.6875]],"4471":[[0.0625,0.0,0.0625,0.6875,1.0,0.6875]],"4472":[[0.0,0.0,0.0,0.75,1.0,0.75]],"4473":[[0.0,0.0,0.0,0.75,1.0,0.75]],"4474":[[0.0,0.0,0.0,0.75,1.0,0.75]],"4475":[[0.0,0.0,0.0,0.75,1.0,0.75]],"4476":[[0.375,0.0,0.375,0.625,1.0,0.625],[0.0,0.5,0.0,0.375,1.0,1.0],[0.375,0.5,0.0,1.0,1.0,0.375],[0.375,0.5,0.625,1.0,1.0,1.0],[0.625,0.5,0.375,1.0,1.0,0.625]],"4477":[[0.0,0.6875,0.0,1.0,0.9375,1.0]],"4478":[[0.0,0.6875,0.0,1.0,0.9375,1.0]],"4479":[[0.0,0.6875,0.0,1.0,0.8125,1.0]],"4480":[[0.0,0.0,0.0,1.0,0.875,1.0]],"4481":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4482":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4483":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4484":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4485":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4486":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4487":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4488":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4489":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4490":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4491":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4492":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4493":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4494":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4495":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4496":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4497":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4498":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4499":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4500":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4501":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4502":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4503":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4504":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4505":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4506":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4507":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4508":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4509":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4510":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4511":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4512":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4513":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4514":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4515":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4516":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4517":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4518":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4519":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4520":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4521":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4522":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4523":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4524":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4525":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4526":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4527":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4528":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4529":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4530":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4531":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4532":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4533":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4534":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4535":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4536":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4537":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4538":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4539":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4540":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4541":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4542":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4543":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4544":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4545":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4546":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4547":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4548":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4549":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4550":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4551":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4552":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4553":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4554":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4555":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4556":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4557":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4558":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4559":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4560":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4561":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4562":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4563":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4564":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4565":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4566":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4567":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4568":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4569":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4570":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4571":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4572":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4573":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4574":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4575":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4576":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4577":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4578":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4579":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4580":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4581":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4582":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4583":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4584":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4585":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4586":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4587":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4588":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4589":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4590":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4591":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4592":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4593":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4594":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4595":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4596":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4597":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4598":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4599":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4600":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4601":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4602":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4603":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4604":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4605":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4606":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4607":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4608":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4609":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4610":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4611":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4612":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4613":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4614":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4615":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4616":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4617":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4618":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4619":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4620":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4621":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4622":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4623":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4624":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4625":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4626":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4627":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4628":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4629":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4630":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4631":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4632":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4633":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4634":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4635":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4636":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4637":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4638":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4639":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4640":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4641":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4642":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4643":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4644":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4645":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4646":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4647":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4648":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4649":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4650":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4651":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4652":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4653":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4654":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4655":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4656":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4657":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4658":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4659":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4660":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4661":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4662":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4663":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4664":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4665":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4666":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4667":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4668":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4669":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4670":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4671":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4672":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4673":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4674":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4675":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4676":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4677":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4678":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4679":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4680":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4681":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4682":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4683":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4684":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4685":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4686":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4687":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4688":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4689":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4690":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4691":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4692":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4693":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4694":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4695":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4696":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4697":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4698":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4699":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4700":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4701":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4702":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4703":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4704":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4705":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4706":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4707":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4708":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4709":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4710":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4711":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4712":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4713":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4714":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4715":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4716":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4717":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4718":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4719":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4720":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4721":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4722":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4723":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4724":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4725":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4726":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4727":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4728":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4729":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4730":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4731":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4732":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4733":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4734":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4735":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4736":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4737":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4738":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4739":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4740":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4741":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4742":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4743":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4744":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4745":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4746":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4747":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4748":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4749":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4750":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4751":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4752":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4753":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4754":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4755":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4756":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4757":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4758":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4759":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4760":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4761":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4762":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4763":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4764":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4765":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4766":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4767":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4768":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4769":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4770":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4771":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4772":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4773":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4774":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4775":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4776":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4777":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4778":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4779":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4780":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4781":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4782":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4783":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4784":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4785":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4786":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4787":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4788":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4789":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4790":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4791":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4792":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4793":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4794":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4795":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4796":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4797":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4798":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4799":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4800":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4801":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4802":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4803":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4804":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4805":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4806":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4807":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4808":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4809":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4810":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4811":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4812":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4813":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4814":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4815":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4816":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4817":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4818":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4819":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4820":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4821":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4822":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4823":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4824":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4825":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4826":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4827":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4828":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4829":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4830":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4831":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4832":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4833":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4834":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4835":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4836":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4837":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4838":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4839":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4840":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4841":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4842":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4843":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4844":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4845":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4846":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4847":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4848":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4849":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4850":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4851":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4852":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4853":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4854":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4855":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4856":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4857":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4858":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4859":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4860":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4861":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4862":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4863":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4864":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4865":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4866":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4867":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4868":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4869":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4870":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4871":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4872":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4873":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4874":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4875":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4876":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4877":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4878":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4879":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4880":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4881":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4882":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4883":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4884":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4885":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4886":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4887":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4888":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4889":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4890":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4891":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4892":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4893":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4894":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4895":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4896":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4897":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4898":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4899":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4900":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4901":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4902":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4903":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4904":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4905":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4906":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4907":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4908":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4909":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4910":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4911":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4912":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4913":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"4914":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4915":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"4916":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4917":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4918":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4919":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4920":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4921":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4922":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4923":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4924":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4925":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4926":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4927":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4928":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4929":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4930":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4931":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4932":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4933":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4934":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4935":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4936":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4937":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4938":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4939":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4940":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4941":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4942":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4943":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4944":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4945":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4946":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4947":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4948":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4949":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4950":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4951":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4952":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4953":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4954":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4955":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4956":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4957":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4958":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"4959":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4960":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4961":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"4962":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4963":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4964":[[0.25,0.0,0.25,0.75,1.5,0.75]],"4965":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4966":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"4967":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4968":[[0.0,0.0,0.3125,0.6875,1.5,0.6875]],"4969":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4970":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4971":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4972":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4973":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4974":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4975":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4976":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4977":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4978":[[0.3125,0.0,0.3125,0.6875,1.5,1.0]],"4979":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4980":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4981":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4982":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4983":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"4984":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"4985":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4986":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"4987":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4988":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4989":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4990":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4991":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4992":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4993":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4994":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4995":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"4996":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"4997":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4998":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"4999":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5000":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5001":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5002":[[0.3125,0.0,0.0,0.6875,1.5,0.6875]],"5003":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5004":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5005":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5006":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5007":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5008":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"5009":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5010":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5011":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5012":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5013":[[0.0,0.0,0.3125,0.75,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5014":[[0.3125,0.0,0.0,0.6875,1.5,1.0]],"5015":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5016":[[0.0,0.0,0.3125,0.6875,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5017":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5018":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"5019":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"5020":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"5021":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"5022":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"5023":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5024":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5025":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5026":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5027":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5028":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5029":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5030":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5031":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5032":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5033":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5034":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5035":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5036":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5037":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5038":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5039":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5040":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5041":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5042":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5043":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5044":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5045":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5046":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5047":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5048":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5049":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5050":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5051":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5052":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5053":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5054":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5055":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5056":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5057":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5058":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5059":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5060":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5061":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5062":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5063":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5064":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5065":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5066":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5067":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5068":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5069":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5070":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5071":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5072":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"5073":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75]],"5074":[[0.3125,0.0,0.3125,1.0,1.5,0.6875]],"5075":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"5076":[[0.0,0.0,0.3125,1.0,1.5,0.6875]],"5077":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5078":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5079":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5080":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5081":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5082":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5083":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5084":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5085":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5086":[[0.3125,0.0,0.3125,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5087":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5088":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5089":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5090":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5091":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5092":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5093":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5094":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5095":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5096":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5097":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5098":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5099":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5100":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5101":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5102":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5103":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5104":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5105":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5106":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5107":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5108":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5109":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25]],"5110":[[0.3125,0.0,0.0,0.6875,1.5,0.6875],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5111":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5112":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125]],"5113":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5114":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5115":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5116":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5117":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5118":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5119":[[0.25,0.0,0.25,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0],[0.75,0.0,0.3125,1.0,1.5,0.6875]],"5120":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5121":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.25,0.0,0.25,0.75,1.5,0.3125],[0.25,0.0,0.6875,0.75,1.5,0.75],[0.3125,0.0,0.0,0.6875,1.5,0.25],[0.3125,0.0,0.75,0.6875,1.5,1.0]],"5122":[[0.3125,0.0,0.0,0.6875,1.5,1.0],[0.6875,0.0,0.3125,1.0,1.5,0.6875]],"5123":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5124":[[0.0,0.0,0.3125,1.0,1.5,0.6875],[0.3125,0.0,0.0,0.6875,1.5,0.3125],[0.3125,0.0,0.6875,0.6875,1.5,1.0]],"5125":[[0.0625,0.0,0.0625,0.9375,1.0,0.9375]],"5126":[[0.25,0.0,0.25,0.75,0.5,0.75]],"5127":[[0.0,0.0,0.0,1.0,0.0625,1.0]]},"blocks":{"air":0,"stone":1,"granite":1,"polished_granite":1,"diorite":1,"polished_diorite":1,"andesite":1,"polished_andesite":1,"grass_block":1,"dirt":1,"coarse_dirt":1,"podzol":1,"cobblestone":1,"oak_planks":1,"spruce_planks":1,"birch_planks":1,"jungle_planks":1,"acacia_planks":1,"cherry_planks":1,"dark_oak_planks":1,"pale_oak_wood":1,"pale_oak_planks":1,"mangrove_planks":1,"bamboo_planks":1,"bamboo_mosaic":1,"oak_sapling":0,"spruce_sapling":0,"birch_sapling":0,"jungle_sapling":0,"acacia_sapling":0,"cherry_sapling":0,"dark_oak_sapling":0,"pale_oak_sapling":0,"mangrove_propagule":0,"bedrock":1,"water":0,"lava":0,"sand":1,"suspicious_sand":1,"red_sand":1,"gravel":1,"suspicious_gravel":1,"gold_ore":1,"deepslate_gold_ore":1,"iron_ore":1,"deepslate_iron_ore":1,"coal_ore":1,"deepslate_coal_ore":1,"nether_gold_ore":1,"oak_log":1,"spruce_log":1,"birch_log":1,"jungle_log":1,"acacia_log":1,"cherry_log":1,"dark_oak_log":1,"pale_oak_log":1,"mangrove_log":1,"mangrove_roots":1,"muddy_mangrove_roots":1,"bamboo_block":1,"stripped_spruce_log":1,"stripped_birch_log":1,"stripped_jungle_log":1,"stripped_acacia_log":1,"stripped_cherry_log":1,"stripped_dark_oak_log":1,"stripped_pale_oak_log":1,"stripped_oak_log":1,"stripped_mangrove_log":1,"stripped_bamboo_block":1,"oak_wood":1,"spruce_wood":1,"birch_wood":1,"jungle_wood":1,"acacia_wood":1,"cherry_wood":1,"dark_oak_wood":1,"mangrove_wood":1,"stripped_oak_wood":1,"stripped_spruce_wood":1,"stripped_birch_wood":1,"stripped_jungle_wood":1,"stripped_acacia_wood":1,"stripped_cherry_wood":1,"stripped_dark_oak_wood":1,"stripped_pale_oak_wood":1,"stripped_mangrove_wood":1,"oak_leaves":1,"spruce_leaves":1,"birch_leaves":1,"jungle_leaves":1,"acacia_leaves":1,"cherry_leaves":1,"dark_oak_leaves":1,"pale_oak_leaves":1,"mangrove_leaves":1,"azalea_leaves":1,"flowering_azalea_leaves":1,"sponge":1,"wet_sponge":1,"glass":1,"lapis_ore":1,"deepslate_lapis_ore":1,"lapis_block":1,"dispenser":1,"sandstone":1,"chiseled_sandstone":1,"cut_sandstone":1,"note_block":1,"white_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"orange_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"magenta_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"light_blue_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"yellow_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"lime_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"pink_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"gray_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"light_gray_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"cyan_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"purple_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"blue_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"brown_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"green_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"red_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"black_bed":[2,3,2,3,3,2,3,2,4,5,4,5,5,4,5,4],"powered_rail":0,"detector_rail":0,"sticky_piston":[6,7,8,9,10,11,1,1,1,1,1,1],"cobweb":0,"short_grass":0,"fern":0,"dead_bush":0,"bush":0,"short_dry_grass":0,"tall_dry_grass":0,"seagrass":0,"tall_seagrass":0,"piston":[6,7,8,9,10,11,1,1,1,1,1,1],"piston_head":[12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23],"white_wool":1,"orange_wool":1,"magenta_wool":1,"light_blue_wool":1,"yellow_wool":1,"lime_wool":1,"pink_wool":1,"gray_wool":1,"light_gray_wool":1,"cyan_wool":1,"purple_wool":1,"blue_wool":1,"brown_wool":1,"green_wool":1,"red_wool":1,"black_wool":1,"moving_piston":0,"dandelion":0,"torchflower":0,"poppy":0,"blue_orchid":0,"allium":0,"azure_bluet":0,"red_tulip":0,"orange_tulip":0,"white_tulip":0,"pink_tulip":0,"oxeye_daisy":0,"cornflower":0,"wither_rose":0,"lily_of_the_valley":0,"brown_mushroom":0,"red_mushroom":0,"gold_block":1,"iron_block":1,"bricks":1,"tnt":1,"bookshelf":1,"chiseled_bookshelf":1,"acacia_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"bamboo_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"birch_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"cherry_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"crimson_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"dark_oak_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"jungle_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"mangrove_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"oak_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"pale_oak_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"spruce_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"warped_shelf":[24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27],"mossy_cobblestone":1,"obsidian":1,"torch":0,"wall_torch":0,"fire":0,"soul_fire":0,"spawner":1,"creaking_heart":1,"oak_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"redstone_wire":0,"diamond_ore":1,"deepslate_diamond_ore":1,"diamond_block":1,"crafting_table":1,"wheat":0,"farmland":57,"furnace":1,"oak_sign":0,"spruce_sign":0,"birch_sign":0,"acacia_sign":0,"cherry_sign":0,"jungle_sign":0,"dark_oak_sign":0,"pale_oak_sign":0,"mangrove_sign":0,"bamboo_sign":0,"oak_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"ladder":[62,62,63,63,64,64,65,65],"rail":0,"cobblestone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"oak_wall_sign":0,"spruce_wall_sign":0,"birch_wall_sign":0,"acacia_wall_sign":0,"cherry_wall_sign":0,"jungle_wall_sign":0,"dark_oak_wall_sign":0,"pale_oak_wall_sign":0,"mangrove_wall_sign":0,"bamboo_wall_sign":0,"oak_hanging_sign":0,"spruce_hanging_sign":0,"birch_hanging_sign":0,"acacia_hanging_sign":0,"cherry_hanging_sign":0,"jungle_hanging_sign":0,"dark_oak_hanging_sign":0,"pale_oak_hanging_sign":0,"crimson_hanging_sign":0,"warped_hanging_sign":0,"mangrove_hanging_sign":0,"bamboo_hanging_sign":0,"oak_wall_hanging_sign":[66,66,66,66,67,67,67,67],"spruce_wall_hanging_sign":[66,66,66,66,67,67,67,67],"birch_wall_hanging_sign":[66,66,66,66,67,67,67,67],"acacia_wall_hanging_sign":[66,66,66,66,67,67,67,67],"cherry_wall_hanging_sign":[66,66,66,66,67,67,67,67],"jungle_wall_hanging_sign":[66,66,66,66,67,67,67,67],"dark_oak_wall_hanging_sign":[66,66,66,66,67,67,67,67],"pale_oak_wall_hanging_sign":[66,66,66,66,67,67,67,67],"mangrove_wall_hanging_sign":[66,66,66,66,67,67,67,67],"crimson_wall_hanging_sign":[66,66,66,66,67,67,67,67],"warped_wall_hanging_sign":[66,66,66,66,67,67,67,67],"bamboo_wall_hanging_sign":[66,66,66,66,67,67,67,67],"lever":0,"stone_pressure_plate":0,"iron_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"oak_pressure_plate":0,"spruce_pressure_plate":0,"birch_pressure_plate":0,"jungle_pressure_plate":0,"acacia_pressure_plate":0,"cherry_pressure_plate":0,"dark_oak_pressure_plate":0,"pale_oak_pressure_plate":0,"mangrove_pressure_plate":0,"bamboo_pressure_plate":0,"redstone_ore":1,"deepslate_redstone_ore":1,"redstone_torch":0,"redstone_wall_torch":0,"stone_button":0,"snow":[0,68,69,70,71,72,73,74],"ice":1,"snow_block":1,"cactus":75,"cactus_flower":0,"clay":1,"sugar_cane":0,"jukebox":1,"oak_fence":[76,77,76,77,78,79,78,79,80,81,80,81,82,83,82,83,84,85,84,85,86,87,86,87,88,89,88,89,90,91,90,91],"netherrack":1,"soul_sand":92,"soul_soil":1,"basalt":1,"polished_basalt":1,"soul_torch":0,"soul_wall_torch":0,"copper_torch":0,"copper_wall_torch":0,"glowstone":1,"nether_portal":0,"carved_pumpkin":1,"jack_o_lantern":1,"cake":[93,94,95,96,97,98,99],"repeater":100,"white_stained_glass":1,"orange_stained_glass":1,"magenta_stained_glass":1,"light_blue_stained_glass":1,"yellow_stained_glass":1,"lime_stained_glass":1,"pink_stained_glass":1,"gray_stained_glass":1,"light_gray_stained_glass":1,"cyan_stained_glass":1,"purple_stained_glass":1,"blue_stained_glass":1,"brown_stained_glass":1,"green_stained_glass":1,"red_stained_glass":1,"black_stained_glass":1,"oak_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"spruce_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"birch_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"jungle_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"acacia_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"cherry_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"dark_oak_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"pale_oak_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"mangrove_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"bamboo_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"stone_bricks":1,"mossy_stone_bricks":1,"cracked_stone_bricks":1,"chiseled_stone_bricks":1,"packed_mud":1,"mud_bricks":1,"infested_stone":1,"infested_cobblestone":1,"infested_stone_bricks":1,"infested_mossy_stone_bricks":1,"infested_cracked_stone_bricks":1,"infested_chiseled_stone_bricks":1,"brown_mushroom_block":1,"red_mushroom_block":1,"mushroom_stem":1,"iron_bars":[107,108,107,108,109,110,109,110,111,112,111,112,113,114,113,114,115,116,115,116,117,118,117,118,119,120,119,120,121,122,121,122],"copper_bars":[123,124,123,124,125,126,125,126,127,128,127,128,129,130,129,130,131,132,131,132,133,134,133,134,135,136,135,136,137,138,137,138],"exposed_copper_bars":[139,140,139,140,141,142,141,142,143,144,143,144,145,146,145,146,147,148,147,148,149,150,149,150,151,152,151,152,153,154,153,154],"weathered_copper_bars":[155,156,155,156,157,158,157,158,159,160,159,160,161,162,161,162,163,164,163,164,165,166,165,166,167,168,167,168,169,170,169,170],"oxidized_copper_bars":[171,172,171,172,173,174,173,174,175,176,175,176,177,178,177,178,179,180,179,180,181,182,181,182,183,184,183,184,185,186,185,186],"waxed_copper_bars":[187,188,187,188,189,190,189,190,191,192,191,192,193,194,193,194,195,196,195,196,197,198,197,198,199,200,199,200,201,202,201,202],"waxed_exposed_copper_bars":[203,204,203,204,205,206,205,206,207,208,207,208,209,210,209,210,211,212,211,212,213,214,213,214,215,216,215,216,217,218,217,218],"waxed_weathered_copper_bars":[219,220,219,220,221,222,221,222,223,224,223,224,225,226,225,226,227,228,227,228,229,230,229,230,231,232,231,232,233,234,233,234],"waxed_oxidized_copper_bars":[235,236,235,236,237,238,237,238,239,240,239,240,241,242,241,242,243,244,243,244,245,246,245,246,247,248,247,248,249,250,249,250],"iron_chain":[251,251,252,252,253,253],"copper_chain":[251,251,252,252,253,253],"exposed_copper_chain":[251,251,252,252,253,253],"weathered_copper_chain":[251,251,252,252,253,253],"oxidized_copper_chain":[251,251,252,252,253,253],"waxed_copper_chain":[251,251,252,252,253,253],"waxed_exposed_copper_chain":[251,251,252,252,253,253],"waxed_weathered_copper_chain":[251,251,252,252,253,253],"waxed_oxidized_copper_chain":[251,251,252,252,253,253],"glass_pane":[254,255,254,255,256,257,256,257,258,259,258,259,260,261,260,261,262,263,262,263,264,265,264,265,266,267,266,267,268,269,268,269],"pumpkin":1,"melon":1,"attached_pumpkin_stem":0,"attached_melon_stem":0,"pumpkin_stem":0,"melon_stem":0,"vine":0,"glow_lichen":0,"resin_clump":0,"oak_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"stone_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"mud_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"mycelium":1,"lily_pad":272,"resin_block":1,"resin_bricks":1,"resin_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"resin_brick_slab":[273,273,274,274,1,1],"resin_brick_wall":[275,276,277,275,276,277,0,278,279,0,278,279,280,281,282,280,281,282,283,284,285,283,284,285,286,287,288,286,287,288,289,290,291,289,290,291,292,293,294,292,293,294,295,296,297,295,296,297,298,299,300,298,299,300,301,302,303,301,302,303,304,305,306,304,305,306,307,308,309,307,308,309,310,311,312,310,311,312,313,314,315,313,314,315,316,317,318,316,317,318,319,320,321,319,320,321,322,323,324,322,323,324,325,326,327,325,326,327,328,329,330,328,329,330,331,332,333,331,332,333,334,335,336,334,335,336,337,338,339,337,338,339,340,341,342,340,341,342,343,344,345,343,344,345,346,347,348,346,347,348,349,350,351,349,350,351,352,353,354,352,353,354,355,356,357,355,356,357,358,359,360,358,359,360,361,362,363,361,362,363,364,365,366,364,365,366,367,368,369,367,368,369,370,371,372,370,371,372,373,374,375,373,374,375,376,377,378,376,377,378,379,380,381,379,380,381,382,383,384,382,383,384,385,386,387,385,386,387,388,389,390,388,389,390,391,392,393,391,392,393,394,395,396,394,395,396,397,398,399,397,398,399,400,401,402,400,401,402,403,404,405,403,404,405,406,407,408,406,407,408,409,410,411,409,410,411,412,413,414,412,413,414,415,416,417,415,416,417,418,419,420,418,419,420,421,422,423,421,422,423,424,425,426,424,425,426,427,428,429,427,428,429,430,431,432,430,431,432,433,434,435,433,434,435],"chiseled_resin_bricks":1,"nether_bricks":1,"nether_brick_fence":[436,437,436,437,438,439,438,439,440,441,440,441,442,443,442,443,444,445,444,445,446,447,446,447,448,449,448,449,450,451,450,451],"nether_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"nether_wart":0,"enchanting_table":452,"brewing_stand":453,"cauldron":454,"water_cauldron":454,"lava_cauldron":454,"powder_snow_cauldron":454,"end_portal":0,"end_portal_frame":[455,455,455,455,456,456,456,456],"end_stone":1,"dragon_egg":457,"redstone_lamp":1,"cocoa":[458,459,460,461,462,463,464,465,466,467,468,469],"sandstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"emerald_ore":1,"deepslate_emerald_ore":1,"ender_chest":470,"tripwire_hook":0,"tripwire":0,"emerald_block":1,"spruce_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"birch_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"jungle_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"command_block":1,"beacon":1,"cobblestone_wall":[471,472,473,471,472,473,0,474,475,0,474,475,476,477,478,476,477,478,479,480,481,479,480,481,482,483,484,482,483,484,485,486,487,485,486,487,488,489,490,488,489,490,491,492,493,491,492,493,494,495,496,494,495,496,497,498,499,497,498,499,500,501,502,500,501,502,503,504,505,503,504,505,506,507,508,506,507,508,509,510,511,509,510,511,512,513,514,512,513,514,515,516,517,515,516,517,518,519,520,518,519,520,521,522,523,521,522,523,524,525,526,524,525,526,527,528,529,527,528,529,530,531,532,530,531,532,533,534,535,533,534,535,536,537,538,536,537,538,539,540,541,539,540,541,542,543,544,542,543,544,545,546,547,545,546,547,548,549,550,548,549,550,551,552,553,551,552,553,554,555,556,554,555,556,557,558,559,557,558,559,560,561,562,560,561,562,563,564,565,563,564,565,566,567,568,566,567,568,569,570,571,569,570,571,572,573,574,572,573,574,575,576,577,575,576,577,578,579,580,578,579,580,581,582,583,581,582,583,584,585,586,584,585,586,587,588,589,587,588,589,590,591,592,590,591,592,593,594,595,593,594,595,596,597,598,596,597,598,599,600,601,599,600,601,602,603,604,602,603,604,605,606,607,605,606,607,608,609,610,608,609,610,611,612,613,611,612,613,614,615,616,614,615,616,617,618,619,617,618,619,620,621,622,620,621,622,623,624,625,623,624,625,626,627,628,626,627,628,629,630,631,629,630,631],"mossy_cobblestone_wall":[632,633,634,632,633,634,0,635,636,0,635,636,637,638,639,637,638,639,640,641,642,640,641,642,643,644,645,643,644,645,646,647,648,646,647,648,649,650,651,649,650,651,652,653,654,652,653,654,655,656,657,655,656,657,658,659,660,658,659,660,661,662,663,661,662,663,664,665,666,664,665,666,667,668,669,667,668,669,670,671,672,670,671,672,673,674,675,673,674,675,676,677,678,676,677,678,679,680,681,679,680,681,682,683,684,682,683,684,685,686,687,685,686,687,688,689,690,688,689,690,691,692,693,691,692,693,694,695,696,694,695,696,697,698,699,697,698,699,700,701,702,700,701,702,703,704,705,703,704,705,706,707,708,706,707,708,709,710,711,709,710,711,712,713,714,712,713,714,715,716,717,715,716,717,718,719,720,718,719,720,721,722,723,721,722,723,724,725,726,724,725,726,727,728,729,727,728,729,730,731,732,730,731,732,733,734,735,733,734,735,736,737,738,736,737,738,739,740,741,739,740,741,742,743,744,742,743,744,745,746,747,745,746,747,748,749,750,748,749,750,751,752,753,751,752,753,754,755,756,754,755,756,757,758,759,757,758,759,760,761,762,760,761,762,763,764,765,763,764,765,766,767,768,766,767,768,769,770,771,769,770,771,772,773,774,772,773,774,775,776,777,775,776,777,778,779,780,778,779,780,781,782,783,781,782,783,784,785,786,784,785,786,787,788,789,787,788,789,790,791,792,790,791,792],"flower_pot":793,"potted_torchflower":793,"potted_oak_sapling":793,"potted_spruce_sapling":793,"potted_birch_sapling":793,"potted_jungle_sapling":793,"potted_acacia_sapling":793,"potted_cherry_sapling":793,"potted_dark_oak_sapling":793,"potted_pale_oak_sapling":793,"potted_mangrove_propagule":793,"potted_fern":793,"potted_dandelion":793,"potted_poppy":793,"potted_blue_orchid":793,"potted_allium":793,"potted_azure_bluet":793,"potted_red_tulip":793,"potted_orange_tulip":793,"potted_white_tulip":793,"potted_pink_tulip":793,"potted_oxeye_daisy":793,"potted_cornflower":793,"potted_lily_of_the_valley":793,"potted_wither_rose":793,"potted_red_mushroom":793,"potted_brown_mushroom":793,"potted_dead_bush":793,"potted_cactus":793,"carrots":0,"potatoes":0,"oak_button":0,"spruce_button":0,"birch_button":0,"jungle_button":0,"acacia_button":0,"cherry_button":0,"dark_oak_button":0,"pale_oak_button":0,"mangrove_button":0,"bamboo_button":0,"skeleton_skull":794,"skeleton_wall_skull":[795,795,796,796,797,797,798,798],"wither_skeleton_skull":794,"wither_skeleton_wall_skull":[795,795,796,796,797,797,798,798],"zombie_head":794,"zombie_wall_head":[795,795,796,796,797,797,798,798],"player_head":794,"player_wall_head":[795,795,796,796,797,797,798,798],"creeper_head":794,"creeper_wall_head":[795,795,796,796,797,797,798,798],"dragon_head":794,"dragon_wall_head":[795,795,796,796,797,797,798,798],"piglin_head":799,"piglin_wall_head":[800,800,801,801,802,802,803,803],"anvil":[804,804,805,805],"chipped_anvil":[804,804,805,805],"damaged_anvil":[804,804,805,805],"trapped_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"light_weighted_pressure_plate":0,"heavy_weighted_pressure_plate":0,"comparator":100,"daylight_detector":806,"redstone_block":1,"nether_quartz_ore":1,"hopper":[807,808,809,810,811,807,808,809,810,811],"quartz_block":1,"chiseled_quartz_block":1,"quartz_pillar":1,"quartz_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"activator_rail":0,"dropper":1,"white_terracotta":1,"orange_terracotta":1,"magenta_terracotta":1,"light_blue_terracotta":1,"yellow_terracotta":1,"lime_terracotta":1,"pink_terracotta":1,"gray_terracotta":1,"light_gray_terracotta":1,"cyan_terracotta":1,"purple_terracotta":1,"blue_terracotta":1,"brown_terracotta":1,"green_terracotta":1,"red_terracotta":1,"black_terracotta":1,"white_stained_glass_pane":[812,813,812,813,814,815,814,815,816,817,816,817,818,819,818,819,820,821,820,821,822,823,822,823,824,825,824,825,826,827,826,827],"orange_stained_glass_pane":[828,829,828,829,830,831,830,831,832,833,832,833,834,835,834,835,836,837,836,837,838,839,838,839,840,841,840,841,842,843,842,843],"magenta_stained_glass_pane":[844,845,844,845,846,847,846,847,848,849,848,849,850,851,850,851,852,853,852,853,854,855,854,855,856,857,856,857,858,859,858,859],"light_blue_stained_glass_pane":[860,861,860,861,862,863,862,863,864,865,864,865,866,867,866,867,868,869,868,869,870,871,870,871,872,873,872,873,874,875,874,875],"yellow_stained_glass_pane":[876,877,876,877,878,879,878,879,880,881,880,881,882,883,882,883,884,885,884,885,886,887,886,887,888,889,888,889,890,891,890,891],"lime_stained_glass_pane":[892,893,892,893,894,895,894,895,896,897,896,897,898,899,898,899,900,901,900,901,902,903,902,903,904,905,904,905,906,907,906,907],"pink_stained_glass_pane":[908,909,908,909,910,911,910,911,912,913,912,913,914,915,914,915,916,917,916,917,918,919,918,919,920,921,920,921,922,923,922,923],"gray_stained_glass_pane":[924,925,924,925,926,927,926,927,928,929,928,929,930,931,930,931,932,933,932,933,934,935,934,935,936,937,936,937,938,939,938,939],"light_gray_stained_glass_pane":[940,941,940,941,942,943,942,943,944,945,944,945,946,947,946,947,948,949,948,949,950,951,950,951,952,953,952,953,954,955,954,955],"cyan_stained_glass_pane":[956,957,956,957,958,959,958,959,960,961,960,961,962,963,962,963,964,965,964,965,966,967,966,967,968,969,968,969,970,971,970,971],"purple_stained_glass_pane":[972,973,972,973,974,975,974,975,976,977,976,977,978,979,978,979,980,981,980,981,982,983,982,983,984,985,984,985,986,987,986,987],"blue_stained_glass_pane":[988,989,988,989,990,991,990,991,992,993,992,993,994,995,994,995,996,997,996,997,998,999,998,999,1000,1001,1000,1001,1002,1003,1002,1003],"brown_stained_glass_pane":[1004,1005,1004,1005,1006,1007,1006,1007,1008,1009,1008,1009,1010,1011,1010,1011,1012,1013,1012,1013,1014,1015,1014,1015,1016,1017,1016,1017,1018,1019,1018,1019],"green_stained_glass_pane":[1020,1021,1020,1021,1022,1023,1022,1023,1024,1025,1024,1025,1026,1027,1026,1027,1028,1029,1028,1029,1030,1031,1030,1031,1032,1033,1032,1033,1034,1035,1034,1035],"red_stained_glass_pane":[1036,1037,1036,1037,1038,1039,1038,1039,1040,1041,1040,1041,1042,1043,1042,1043,1044,1045,1044,1045,1046,1047,1046,1047,1048,1049,1048,1049,1050,1051,1050,1051],"black_stained_glass_pane":[1052,1053,1052,1053,1054,1055,1054,1055,1056,1057,1056,1057,1058,1059,1058,1059,1060,1061,1060,1061,1062,1063,1062,1063,1064,1065,1064,1065,1066,1067,1066,1067],"acacia_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"cherry_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"dark_oak_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"pale_oak_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"mangrove_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"bamboo_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"bamboo_mosaic_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"slime_block":1,"barrier":1,"light":0,"iron_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"prismarine":1,"prismarine_bricks":1,"dark_prismarine":1,"prismarine_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"prismarine_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"dark_prismarine_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"prismarine_slab":[273,273,274,274,1,1],"prismarine_brick_slab":[273,273,274,274,1,1],"dark_prismarine_slab":[273,273,274,274,1,1],"sea_lantern":1,"hay_block":1,"white_carpet":1068,"orange_carpet":1068,"magenta_carpet":1068,"light_blue_carpet":1068,"yellow_carpet":1068,"lime_carpet":1068,"pink_carpet":1068,"gray_carpet":1068,"light_gray_carpet":1068,"cyan_carpet":1068,"purple_carpet":1068,"blue_carpet":1068,"brown_carpet":1068,"green_carpet":1068,"red_carpet":1068,"black_carpet":1068,"terracotta":1,"coal_block":1,"packed_ice":1,"sunflower":0,"lilac":0,"rose_bush":0,"peony":0,"tall_grass":0,"large_fern":0,"white_banner":0,"orange_banner":0,"magenta_banner":0,"light_blue_banner":0,"yellow_banner":0,"lime_banner":0,"pink_banner":0,"gray_banner":0,"light_gray_banner":0,"cyan_banner":0,"purple_banner":0,"blue_banner":0,"brown_banner":0,"green_banner":0,"red_banner":0,"black_banner":0,"white_wall_banner":0,"orange_wall_banner":0,"magenta_wall_banner":0,"light_blue_wall_banner":0,"yellow_wall_banner":0,"lime_wall_banner":0,"pink_wall_banner":0,"gray_wall_banner":0,"light_gray_wall_banner":0,"cyan_wall_banner":0,"purple_wall_banner":0,"blue_wall_banner":0,"brown_wall_banner":0,"green_wall_banner":0,"red_wall_banner":0,"black_wall_banner":0,"red_sandstone":1,"chiseled_red_sandstone":1,"cut_red_sandstone":1,"red_sandstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"oak_slab":[273,273,274,274,1,1],"spruce_slab":[273,273,274,274,1,1],"birch_slab":[273,273,274,274,1,1],"jungle_slab":[273,273,274,274,1,1],"acacia_slab":[273,273,274,274,1,1],"cherry_slab":[273,273,274,274,1,1],"dark_oak_slab":[273,273,274,274,1,1],"pale_oak_slab":[273,273,274,274,1,1],"mangrove_slab":[273,273,274,274,1,1],"bamboo_slab":[273,273,274,274,1,1],"bamboo_mosaic_slab":[273,273,274,274,1,1],"stone_slab":[273,273,274,274,1,1],"smooth_stone_slab":[273,273,274,274,1,1],"sandstone_slab":[273,273,274,274,1,1],"cut_sandstone_slab":[273,273,274,274,1,1],"petrified_oak_slab":[273,273,274,274,1,1],"cobblestone_slab":[273,273,274,274,1,1],"brick_slab":[273,273,274,274,1,1],"stone_brick_slab":[273,273,274,274,1,1],"mud_brick_slab":[273,273,274,274,1,1],"nether_brick_slab":[273,273,274,274,1,1],"quartz_slab":[273,273,274,274,1,1],"red_sandstone_slab":[273,273,274,274,1,1],"cut_red_sandstone_slab":[273,273,274,274,1,1],"purpur_slab":[273,273,274,274,1,1],"smooth_stone":1,"smooth_sandstone":1,"smooth_quartz":1,"smooth_red_sandstone":1,"spruce_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"birch_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"jungle_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"acacia_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"cherry_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"dark_oak_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"pale_oak_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"mangrove_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"bamboo_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"spruce_fence":[1069,1070,1069,1070,1071,1072,1071,1072,1073,1074,1073,1074,1075,1076,1075,1076,1077,1078,1077,1078,1079,1080,1079,1080,1081,1082,1081,1082,1083,1084,1083,1084],"birch_fence":[1085,1086,1085,1086,1087,1088,1087,1088,1089,1090,1089,1090,1091,1092,1091,1092,1093,1094,1093,1094,1095,1096,1095,1096,1097,1098,1097,1098,1099,1100,1099,1100],"jungle_fence":[1101,1102,1101,1102,1103,1104,1103,1104,1105,1106,1105,1106,1107,1108,1107,1108,1109,1110,1109,1110,1111,1112,1111,1112,1113,1114,1113,1114,1115,1116,1115,1116],"acacia_fence":[1117,1118,1117,1118,1119,1120,1119,1120,1121,1122,1121,1122,1123,1124,1123,1124,1125,1126,1125,1126,1127,1128,1127,1128,1129,1130,1129,1130,1131,1132,1131,1132],"cherry_fence":[1133,1134,1133,1134,1135,1136,1135,1136,1137,1138,1137,1138,1139,1140,1139,1140,1141,1142,1141,1142,1143,1144,1143,1144,1145,1146,1145,1146,1147,1148,1147,1148],"dark_oak_fence":[1149,1150,1149,1150,1151,1152,1151,1152,1153,1154,1153,1154,1155,1156,1155,1156,1157,1158,1157,1158,1159,1160,1159,1160,1161,1162,1161,1162,1163,1164,1163,1164],"pale_oak_fence":[1165,1166,1165,1166,1167,1168,1167,1168,1169,1170,1169,1170,1171,1172,1171,1172,1173,1174,1173,1174,1175,1176,1175,1176,1177,1178,1177,1178,1179,1180,1179,1180],"mangrove_fence":[1181,1182,1181,1182,1183,1184,1183,1184,1185,1186,1185,1186,1187,1188,1187,1188,1189,1190,1189,1190,1191,1192,1191,1192,1193,1194,1193,1194,1195,1196,1195,1196],"bamboo_fence":[1197,1198,1197,1198,1199,1200,1199,1200,1201,1202,1201,1202,1203,1204,1203,1204,1205,1206,1205,1206,1207,1208,1207,1208,1209,1210,1209,1210,1211,1212,1211,1212],"spruce_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"birch_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"jungle_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"acacia_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"cherry_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"dark_oak_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"pale_oak_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"mangrove_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"bamboo_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"end_rod":[1213,1214,1213,1214,1215,1215],"chorus_plant":[1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279],"chorus_flower":1,"purpur_block":1,"purpur_pillar":1,"purpur_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"end_stone_bricks":1,"torchflower_crop":0,"pitcher_crop":[0,1280,0,1281,0,1281,0,1281,0,1281],"pitcher_plant":0,"beetroots":0,"dirt_path":1282,"end_gateway":0,"repeating_command_block":1,"chain_command_block":1,"frosted_ice":1,"magma_block":1,"nether_wart_block":1,"red_nether_bricks":1,"bone_block":1,"structure_void":0,"observer":1,"shulker_box":1,"white_shulker_box":1,"orange_shulker_box":1,"magenta_shulker_box":1,"light_blue_shulker_box":1,"yellow_shulker_box":1,"lime_shulker_box":1,"pink_shulker_box":1,"gray_shulker_box":1,"light_gray_shulker_box":1,"cyan_shulker_box":1,"purple_shulker_box":1,"blue_shulker_box":1,"brown_shulker_box":1,"green_shulker_box":1,"red_shulker_box":1,"black_shulker_box":1,"white_glazed_terracotta":1,"orange_glazed_terracotta":1,"magenta_glazed_terracotta":1,"light_blue_glazed_terracotta":1,"yellow_glazed_terracotta":1,"lime_glazed_terracotta":1,"pink_glazed_terracotta":1,"gray_glazed_terracotta":1,"light_gray_glazed_terracotta":1,"cyan_glazed_terracotta":1,"purple_glazed_terracotta":1,"blue_glazed_terracotta":1,"brown_glazed_terracotta":1,"green_glazed_terracotta":1,"red_glazed_terracotta":1,"black_glazed_terracotta":1,"white_concrete":1,"orange_concrete":1,"magenta_concrete":1,"light_blue_concrete":1,"yellow_concrete":1,"lime_concrete":1,"pink_concrete":1,"gray_concrete":1,"light_gray_concrete":1,"cyan_concrete":1,"purple_concrete":1,"blue_concrete":1,"brown_concrete":1,"green_concrete":1,"red_concrete":1,"black_concrete":1,"white_concrete_powder":1,"orange_concrete_powder":1,"magenta_concrete_powder":1,"light_blue_concrete_powder":1,"yellow_concrete_powder":1,"lime_concrete_powder":1,"pink_concrete_powder":1,"gray_concrete_powder":1,"light_gray_concrete_powder":1,"cyan_concrete_powder":1,"purple_concrete_powder":1,"blue_concrete_powder":1,"brown_concrete_powder":1,"green_concrete_powder":1,"red_concrete_powder":1,"black_concrete_powder":1,"kelp":0,"kelp_plant":0,"dried_kelp_block":1,"turtle_egg":[1283,1283,1283,1284,1284,1284,1284,1284,1284,1284,1284,1284],"sniffer_egg":1285,"dried_ghast":1286,"dead_tube_coral_block":1,"dead_brain_coral_block":1,"dead_bubble_coral_block":1,"dead_fire_coral_block":1,"dead_horn_coral_block":1,"tube_coral_block":1,"brain_coral_block":1,"bubble_coral_block":1,"fire_coral_block":1,"horn_coral_block":1,"dead_tube_coral":0,"dead_brain_coral":0,"dead_bubble_coral":0,"dead_fire_coral":0,"dead_horn_coral":0,"tube_coral":0,"brain_coral":0,"bubble_coral":0,"fire_coral":0,"horn_coral":0,"dead_tube_coral_fan":0,"dead_brain_coral_fan":0,"dead_bubble_coral_fan":0,"dead_fire_coral_fan":0,"dead_horn_coral_fan":0,"tube_coral_fan":0,"brain_coral_fan":0,"bubble_coral_fan":0,"fire_coral_fan":0,"horn_coral_fan":0,"dead_tube_coral_wall_fan":0,"dead_brain_coral_wall_fan":0,"dead_bubble_coral_wall_fan":0,"dead_fire_coral_wall_fan":0,"dead_horn_coral_wall_fan":0,"tube_coral_wall_fan":0,"brain_coral_wall_fan":0,"bubble_coral_wall_fan":0,"fire_coral_wall_fan":0,"horn_coral_wall_fan":0,"sea_pickle":[1287,1287,1288,1288,1289,1289,1290,1290],"blue_ice":1,"conduit":1291,"bamboo_sapling":0,"bamboo":[1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303],"potted_bamboo":793,"void_air":0,"cave_air":0,"bubble_column":0,"polished_granite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"smooth_red_sandstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"mossy_stone_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_diorite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"mossy_cobblestone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"end_stone_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"stone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"smooth_sandstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"smooth_quartz_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"granite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"andesite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"red_nether_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_andesite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"diorite_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_granite_slab":[273,273,274,274,1,1],"smooth_red_sandstone_slab":[273,273,274,274,1,1],"mossy_stone_brick_slab":[273,273,274,274,1,1],"polished_diorite_slab":[273,273,274,274,1,1],"mossy_cobblestone_slab":[273,273,274,274,1,1],"end_stone_brick_slab":[273,273,274,274,1,1],"smooth_sandstone_slab":[273,273,274,274,1,1],"smooth_quartz_slab":[273,273,274,274,1,1],"granite_slab":[273,273,274,274,1,1],"andesite_slab":[273,273,274,274,1,1],"red_nether_brick_slab":[273,273,274,274,1,1],"polished_andesite_slab":[273,273,274,274,1,1],"diorite_slab":[273,273,274,274,1,1],"brick_wall":[1304,1305,1306,1304,1305,1306,0,1307,1308,0,1307,1308,1309,1310,1311,1309,1310,1311,1312,1313,1314,1312,1313,1314,1315,1316,1317,1315,1316,1317,1318,1319,1320,1318,1319,1320,1321,1322,1323,1321,1322,1323,1324,1325,1326,1324,1325,1326,1327,1328,1329,1327,1328,1329,1330,1331,1332,1330,1331,1332,1333,1334,1335,1333,1334,1335,1336,1337,1338,1336,1337,1338,1339,1340,1341,1339,1340,1341,1342,1343,1344,1342,1343,1344,1345,1346,1347,1345,1346,1347,1348,1349,1350,1348,1349,1350,1351,1352,1353,1351,1352,1353,1354,1355,1356,1354,1355,1356,1357,1358,1359,1357,1358,1359,1360,1361,1362,1360,1361,1362,1363,1364,1365,1363,1364,1365,1366,1367,1368,1366,1367,1368,1369,1370,1371,1369,1370,1371,1372,1373,1374,1372,1373,1374,1375,1376,1377,1375,1376,1377,1378,1379,1380,1378,1379,1380,1381,1382,1383,1381,1382,1383,1384,1385,1386,1384,1385,1386,1387,1388,1389,1387,1388,1389,1390,1391,1392,1390,1391,1392,1393,1394,1395,1393,1394,1395,1396,1397,1398,1396,1397,1398,1399,1400,1401,1399,1400,1401,1402,1403,1404,1402,1403,1404,1405,1406,1407,1405,1406,1407,1408,1409,1410,1408,1409,1410,1411,1412,1413,1411,1412,1413,1414,1415,1416,1414,1415,1416,1417,1418,1419,1417,1418,1419,1420,1421,1422,1420,1421,1422,1423,1424,1425,1423,1424,1425,1426,1427,1428,1426,1427,1428,1429,1430,1431,1429,1430,1431,1432,1433,1434,1432,1433,1434,1435,1436,1437,1435,1436,1437,1438,1439,1440,1438,1439,1440,1441,1442,1443,1441,1442,1443,1444,1445,1446,1444,1445,1446,1447,1448,1449,1447,1448,1449,1450,1451,1452,1450,1451,1452,1453,1454,1455,1453,1454,1455,1456,1457,1458,1456,1457,1458,1459,1460,1461,1459,1460,1461,1462,1463,1464,1462,1463,1464],"prismarine_wall":[1465,1466,1467,1465,1466,1467,0,1468,1469,0,1468,1469,1470,1471,1472,1470,1471,1472,1473,1474,1475,1473,1474,1475,1476,1477,1478,1476,1477,1478,1479,1480,1481,1479,1480,1481,1482,1483,1484,1482,1483,1484,1485,1486,1487,1485,1486,1487,1488,1489,1490,1488,1489,1490,1491,1492,1493,1491,1492,1493,1494,1495,1496,1494,1495,1496,1497,1498,1499,1497,1498,1499,1500,1501,1502,1500,1501,1502,1503,1504,1505,1503,1504,1505,1506,1507,1508,1506,1507,1508,1509,1510,1511,1509,1510,1511,1512,1513,1514,1512,1513,1514,1515,1516,1517,1515,1516,1517,1518,1519,1520,1518,1519,1520,1521,1522,1523,1521,1522,1523,1524,1525,1526,1524,1525,1526,1527,1528,1529,1527,1528,1529,1530,1531,1532,1530,1531,1532,1533,1534,1535,1533,1534,1535,1536,1537,1538,1536,1537,1538,1539,1540,1541,1539,1540,1541,1542,1543,1544,1542,1543,1544,1545,1546,1547,1545,1546,1547,1548,1549,1550,1548,1549,1550,1551,1552,1553,1551,1552,1553,1554,1555,1556,1554,1555,1556,1557,1558,1559,1557,1558,1559,1560,1561,1562,1560,1561,1562,1563,1564,1565,1563,1564,1565,1566,1567,1568,1566,1567,1568,1569,1570,1571,1569,1570,1571,1572,1573,1574,1572,1573,1574,1575,1576,1577,1575,1576,1577,1578,1579,1580,1578,1579,1580,1581,1582,1583,1581,1582,1583,1584,1585,1586,1584,1585,1586,1587,1588,1589,1587,1588,1589,1590,1591,1592,1590,1591,1592,1593,1594,1595,1593,1594,1595,1596,1597,1598,1596,1597,1598,1599,1600,1601,1599,1600,1601,1602,1603,1604,1602,1603,1604,1605,1606,1607,1605,1606,1607,1608,1609,1610,1608,1609,1610,1611,1612,1613,1611,1612,1613,1614,1615,1616,1614,1615,1616,1617,1618,1619,1617,1618,1619,1620,1621,1622,1620,1621,1622,1623,1624,1625,1623,1624,1625],"red_sandstone_wall":[1626,1627,1628,1626,1627,1628,0,1629,1630,0,1629,1630,1631,1632,1633,1631,1632,1633,1634,1635,1636,1634,1635,1636,1637,1638,1639,1637,1638,1639,1640,1641,1642,1640,1641,1642,1643,1644,1645,1643,1644,1645,1646,1647,1648,1646,1647,1648,1649,1650,1651,1649,1650,1651,1652,1653,1654,1652,1653,1654,1655,1656,1657,1655,1656,1657,1658,1659,1660,1658,1659,1660,1661,1662,1663,1661,1662,1663,1664,1665,1666,1664,1665,1666,1667,1668,1669,1667,1668,1669,1670,1671,1672,1670,1671,1672,1673,1674,1675,1673,1674,1675,1676,1677,1678,1676,1677,1678,1679,1680,1681,1679,1680,1681,1682,1683,1684,1682,1683,1684,1685,1686,1687,1685,1686,1687,1688,1689,1690,1688,1689,1690,1691,1692,1693,1691,1692,1693,1694,1695,1696,1694,1695,1696,1697,1698,1699,1697,1698,1699,1700,1701,1702,1700,1701,1702,1703,1704,1705,1703,1704,1705,1706,1707,1708,1706,1707,1708,1709,1710,1711,1709,1710,1711,1712,1713,1714,1712,1713,1714,1715,1716,1717,1715,1716,1717,1718,1719,1720,1718,1719,1720,1721,1722,1723,1721,1722,1723,1724,1725,1726,1724,1725,1726,1727,1728,1729,1727,1728,1729,1730,1731,1732,1730,1731,1732,1733,1734,1735,1733,1734,1735,1736,1737,1738,1736,1737,1738,1739,1740,1741,1739,1740,1741,1742,1743,1744,1742,1743,1744,1745,1746,1747,1745,1746,1747,1748,1749,1750,1748,1749,1750,1751,1752,1753,1751,1752,1753,1754,1755,1756,1754,1755,1756,1757,1758,1759,1757,1758,1759,1760,1761,1762,1760,1761,1762,1763,1764,1765,1763,1764,1765,1766,1767,1768,1766,1767,1768,1769,1770,1771,1769,1770,1771,1772,1773,1774,1772,1773,1774,1775,1776,1777,1775,1776,1777,1778,1779,1780,1778,1779,1780,1781,1782,1783,1781,1782,1783,1784,1785,1786,1784,1785,1786],"mossy_stone_brick_wall":[1787,1788,1789,1787,1788,1789,0,1790,1791,0,1790,1791,1792,1793,1794,1792,1793,1794,1795,1796,1797,1795,1796,1797,1798,1799,1800,1798,1799,1800,1801,1802,1803,1801,1802,1803,1804,1805,1806,1804,1805,1806,1807,1808,1809,1807,1808,1809,1810,1811,1812,1810,1811,1812,1813,1814,1815,1813,1814,1815,1816,1817,1818,1816,1817,1818,1819,1820,1821,1819,1820,1821,1822,1823,1824,1822,1823,1824,1825,1826,1827,1825,1826,1827,1828,1829,1830,1828,1829,1830,1831,1832,1833,1831,1832,1833,1834,1835,1836,1834,1835,1836,1837,1838,1839,1837,1838,1839,1840,1841,1842,1840,1841,1842,1843,1844,1845,1843,1844,1845,1846,1847,1848,1846,1847,1848,1849,1850,1851,1849,1850,1851,1852,1853,1854,1852,1853,1854,1855,1856,1857,1855,1856,1857,1858,1859,1860,1858,1859,1860,1861,1862,1863,1861,1862,1863,1864,1865,1866,1864,1865,1866,1867,1868,1869,1867,1868,1869,1870,1871,1872,1870,1871,1872,1873,1874,1875,1873,1874,1875,1876,1877,1878,1876,1877,1878,1879,1880,1881,1879,1880,1881,1882,1883,1884,1882,1883,1884,1885,1886,1887,1885,1886,1887,1888,1889,1890,1888,1889,1890,1891,1892,1893,1891,1892,1893,1894,1895,1896,1894,1895,1896,1897,1898,1899,1897,1898,1899,1900,1901,1902,1900,1901,1902,1903,1904,1905,1903,1904,1905,1906,1907,1908,1906,1907,1908,1909,1910,1911,1909,1910,1911,1912,1913,1914,1912,1913,1914,1915,1916,1917,1915,1916,1917,1918,1919,1920,1918,1919,1920,1921,1922,1923,1921,1922,1923,1924,1925,1926,1924,1925,1926,1927,1928,1929,1927,1928,1929,1930,1931,1932,1930,1931,1932,1933,1934,1935,1933,1934,1935,1936,1937,1938,1936,1937,1938,1939,1940,1941,1939,1940,1941,1942,1943,1944,1942,1943,1944,1945,1946,1947,1945,1946,1947],"granite_wall":[1948,1949,1950,1948,1949,1950,0,1951,1952,0,1951,1952,1953,1954,1955,1953,1954,1955,1956,1957,1958,1956,1957,1958,1959,1960,1961,1959,1960,1961,1962,1963,1964,1962,1963,1964,1965,1966,1967,1965,1966,1967,1968,1969,1970,1968,1969,1970,1971,1972,1973,1971,1972,1973,1974,1975,1976,1974,1975,1976,1977,1978,1979,1977,1978,1979,1980,1981,1982,1980,1981,1982,1983,1984,1985,1983,1984,1985,1986,1987,1988,1986,1987,1988,1989,1990,1991,1989,1990,1991,1992,1993,1994,1992,1993,1994,1995,1996,1997,1995,1996,1997,1998,1999,2000,1998,1999,2000,2001,2002,2003,2001,2002,2003,2004,2005,2006,2004,2005,2006,2007,2008,2009,2007,2008,2009,2010,2011,2012,2010,2011,2012,2013,2014,2015,2013,2014,2015,2016,2017,2018,2016,2017,2018,2019,2020,2021,2019,2020,2021,2022,2023,2024,2022,2023,2024,2025,2026,2027,2025,2026,2027,2028,2029,2030,2028,2029,2030,2031,2032,2033,2031,2032,2033,2034,2035,2036,2034,2035,2036,2037,2038,2039,2037,2038,2039,2040,2041,2042,2040,2041,2042,2043,2044,2045,2043,2044,2045,2046,2047,2048,2046,2047,2048,2049,2050,2051,2049,2050,2051,2052,2053,2054,2052,2053,2054,2055,2056,2057,2055,2056,2057,2058,2059,2060,2058,2059,2060,2061,2062,2063,2061,2062,2063,2064,2065,2066,2064,2065,2066,2067,2068,2069,2067,2068,2069,2070,2071,2072,2070,2071,2072,2073,2074,2075,2073,2074,2075,2076,2077,2078,2076,2077,2078,2079,2080,2081,2079,2080,2081,2082,2083,2084,2082,2083,2084,2085,2086,2087,2085,2086,2087,2088,2089,2090,2088,2089,2090,2091,2092,2093,2091,2092,2093,2094,2095,2096,2094,2095,2096,2097,2098,2099,2097,2098,2099,2100,2101,2102,2100,2101,2102,2103,2104,2105,2103,2104,2105,2106,2107,2108,2106,2107,2108],"stone_brick_wall":[2109,2110,2111,2109,2110,2111,0,2112,2113,0,2112,2113,2114,2115,2116,2114,2115,2116,2117,2118,2119,2117,2118,2119,2120,2121,2122,2120,2121,2122,2123,2124,2125,2123,2124,2125,2126,2127,2128,2126,2127,2128,2129,2130,2131,2129,2130,2131,2132,2133,2134,2132,2133,2134,2135,2136,2137,2135,2136,2137,2138,2139,2140,2138,2139,2140,2141,2142,2143,2141,2142,2143,2144,2145,2146,2144,2145,2146,2147,2148,2149,2147,2148,2149,2150,2151,2152,2150,2151,2152,2153,2154,2155,2153,2154,2155,2156,2157,2158,2156,2157,2158,2159,2160,2161,2159,2160,2161,2162,2163,2164,2162,2163,2164,2165,2166,2167,2165,2166,2167,2168,2169,2170,2168,2169,2170,2171,2172,2173,2171,2172,2173,2174,2175,2176,2174,2175,2176,2177,2178,2179,2177,2178,2179,2180,2181,2182,2180,2181,2182,2183,2184,2185,2183,2184,2185,2186,2187,2188,2186,2187,2188,2189,2190,2191,2189,2190,2191,2192,2193,2194,2192,2193,2194,2195,2196,2197,2195,2196,2197,2198,2199,2200,2198,2199,2200,2201,2202,2203,2201,2202,2203,2204,2205,2206,2204,2205,2206,2207,2208,2209,2207,2208,2209,2210,2211,2212,2210,2211,2212,2213,2214,2215,2213,2214,2215,2216,2217,2218,2216,2217,2218,2219,2220,2221,2219,2220,2221,2222,2223,2224,2222,2223,2224,2225,2226,2227,2225,2226,2227,2228,2229,2230,2228,2229,2230,2231,2232,2233,2231,2232,2233,2234,2235,2236,2234,2235,2236,2237,2238,2239,2237,2238,2239,2240,2241,2242,2240,2241,2242,2243,2244,2245,2243,2244,2245,2246,2247,2248,2246,2247,2248,2249,2250,2251,2249,2250,2251,2252,2253,2254,2252,2253,2254,2255,2256,2257,2255,2256,2257,2258,2259,2260,2258,2259,2260,2261,2262,2263,2261,2262,2263,2264,2265,2266,2264,2265,2266,2267,2268,2269,2267,2268,2269],"mud_brick_wall":[2270,2271,2272,2270,2271,2272,0,2273,2274,0,2273,2274,2275,2276,2277,2275,2276,2277,2278,2279,2280,2278,2279,2280,2281,2282,2283,2281,2282,2283,2284,2285,2286,2284,2285,2286,2287,2288,2289,2287,2288,2289,2290,2291,2292,2290,2291,2292,2293,2294,2295,2293,2294,2295,2296,2297,2298,2296,2297,2298,2299,2300,2301,2299,2300,2301,2302,2303,2304,2302,2303,2304,2305,2306,2307,2305,2306,2307,2308,2309,2310,2308,2309,2310,2311,2312,2313,2311,2312,2313,2314,2315,2316,2314,2315,2316,2317,2318,2319,2317,2318,2319,2320,2321,2322,2320,2321,2322,2323,2324,2325,2323,2324,2325,2326,2327,2328,2326,2327,2328,2329,2330,2331,2329,2330,2331,2332,2333,2334,2332,2333,2334,2335,2336,2337,2335,2336,2337,2338,2339,2340,2338,2339,2340,2341,2342,2343,2341,2342,2343,2344,2345,2346,2344,2345,2346,2347,2348,2349,2347,2348,2349,2350,2351,2352,2350,2351,2352,2353,2354,2355,2353,2354,2355,2356,2357,2358,2356,2357,2358,2359,2360,2361,2359,2360,2361,2362,2363,2364,2362,2363,2364,2365,2366,2367,2365,2366,2367,2368,2369,2370,2368,2369,2370,2371,2372,2373,2371,2372,2373,2374,2375,2376,2374,2375,2376,2377,2378,2379,2377,2378,2379,2380,2381,2382,2380,2381,2382,2383,2384,2385,2383,2384,2385,2386,2387,2388,2386,2387,2388,2389,2390,2391,2389,2390,2391,2392,2393,2394,2392,2393,2394,2395,2396,2397,2395,2396,2397,2398,2399,2400,2398,2399,2400,2401,2402,2403,2401,2402,2403,2404,2405,2406,2404,2405,2406,2407,2408,2409,2407,2408,2409,2410,2411,2412,2410,2411,2412,2413,2414,2415,2413,2414,2415,2416,2417,2418,2416,2417,2418,2419,2420,2421,2419,2420,2421,2422,2423,2424,2422,2423,2424,2425,2426,2427,2425,2426,2427,2428,2429,2430,2428,2429,2430],"nether_brick_wall":[2431,2432,2433,2431,2432,2433,0,2434,2435,0,2434,2435,2436,2437,2438,2436,2437,2438,2439,2440,2441,2439,2440,2441,2442,2443,2444,2442,2443,2444,2445,2446,2447,2445,2446,2447,2448,2449,2450,2448,2449,2450,2451,2452,2453,2451,2452,2453,2454,2455,2456,2454,2455,2456,2457,2458,2459,2457,2458,2459,2460,2461,2462,2460,2461,2462,2463,2464,2465,2463,2464,2465,2466,2467,2468,2466,2467,2468,2469,2470,2471,2469,2470,2471,2472,2473,2474,2472,2473,2474,2475,2476,2477,2475,2476,2477,2478,2479,2480,2478,2479,2480,2481,2482,2483,2481,2482,2483,2484,2485,2486,2484,2485,2486,2487,2488,2489,2487,2488,2489,2490,2491,2492,2490,2491,2492,2493,2494,2495,2493,2494,2495,2496,2497,2498,2496,2497,2498,2499,2500,2501,2499,2500,2501,2502,2503,2504,2502,2503,2504,2505,2506,2507,2505,2506,2507,2508,2509,2510,2508,2509,2510,2511,2512,2513,2511,2512,2513,2514,2515,2516,2514,2515,2516,2517,2518,2519,2517,2518,2519,2520,2521,2522,2520,2521,2522,2523,2524,2525,2523,2524,2525,2526,2527,2528,2526,2527,2528,2529,2530,2531,2529,2530,2531,2532,2533,2534,2532,2533,2534,2535,2536,2537,2535,2536,2537,2538,2539,2540,2538,2539,2540,2541,2542,2543,2541,2542,2543,2544,2545,2546,2544,2545,2546,2547,2548,2549,2547,2548,2549,2550,2551,2552,2550,2551,2552,2553,2554,2555,2553,2554,2555,2556,2557,2558,2556,2557,2558,2559,2560,2561,2559,2560,2561,2562,2563,2564,2562,2563,2564,2565,2566,2567,2565,2566,2567,2568,2569,2570,2568,2569,2570,2571,2572,2573,2571,2572,2573,2574,2575,2576,2574,2575,2576,2577,2578,2579,2577,2578,2579,2580,2581,2582,2580,2581,2582,2583,2584,2585,2583,2584,2585,2586,2587,2588,2586,2587,2588,2589,2590,2591,2589,2590,2591],"andesite_wall":[2592,2593,2594,2592,2593,2594,0,2595,2596,0,2595,2596,2597,2598,2599,2597,2598,2599,2600,2601,2602,2600,2601,2602,2603,2604,2605,2603,2604,2605,2606,2607,2608,2606,2607,2608,2609,2610,2611,2609,2610,2611,2612,2613,2614,2612,2613,2614,2615,2616,2617,2615,2616,2617,2618,2619,2620,2618,2619,2620,2621,2622,2623,2621,2622,2623,2624,2625,2626,2624,2625,2626,2627,2628,2629,2627,2628,2629,2630,2631,2632,2630,2631,2632,2633,2634,2635,2633,2634,2635,2636,2637,2638,2636,2637,2638,2639,2640,2641,2639,2640,2641,2642,2643,2644,2642,2643,2644,2645,2646,2647,2645,2646,2647,2648,2649,2650,2648,2649,2650,2651,2652,2653,2651,2652,2653,2654,2655,2656,2654,2655,2656,2657,2658,2659,2657,2658,2659,2660,2661,2662,2660,2661,2662,2663,2664,2665,2663,2664,2665,2666,2667,2668,2666,2667,2668,2669,2670,2671,2669,2670,2671,2672,2673,2674,2672,2673,2674,2675,2676,2677,2675,2676,2677,2678,2679,2680,2678,2679,2680,2681,2682,2683,2681,2682,2683,2684,2685,2686,2684,2685,2686,2687,2688,2689,2687,2688,2689,2690,2691,2692,2690,2691,2692,2693,2694,2695,2693,2694,2695,2696,2697,2698,2696,2697,2698,2699,2700,2701,2699,2700,2701,2702,2703,2704,2702,2703,2704,2705,2706,2707,2705,2706,2707,2708,2709,2710,2708,2709,2710,2711,2712,2713,2711,2712,2713,2714,2715,2716,2714,2715,2716,2717,2718,2719,2717,2718,2719,2720,2721,2722,2720,2721,2722,2723,2724,2725,2723,2724,2725,2726,2727,2728,2726,2727,2728,2729,2730,2731,2729,2730,2731,2732,2733,2734,2732,2733,2734,2735,2736,2737,2735,2736,2737,2738,2739,2740,2738,2739,2740,2741,2742,2743,2741,2742,2743,2744,2745,2746,2744,2745,2746,2747,2748,2749,2747,2748,2749,2750,2751,2752,2750,2751,2752],"red_nether_brick_wall":[2753,2754,2755,2753,2754,2755,0,2756,2757,0,2756,2757,2758,2759,2760,2758,2759,2760,2761,2762,2763,2761,2762,2763,2764,2765,2766,2764,2765,2766,2767,2768,2769,2767,2768,2769,2770,2771,2772,2770,2771,2772,2773,2774,2775,2773,2774,2775,2776,2777,2778,2776,2777,2778,2779,2780,2781,2779,2780,2781,2782,2783,2784,2782,2783,2784,2785,2786,2787,2785,2786,2787,2788,2789,2790,2788,2789,2790,2791,2792,2793,2791,2792,2793,2794,2795,2796,2794,2795,2796,2797,2798,2799,2797,2798,2799,2800,2801,2802,2800,2801,2802,2803,2804,2805,2803,2804,2805,2806,2807,2808,2806,2807,2808,2809,2810,2811,2809,2810,2811,2812,2813,2814,2812,2813,2814,2815,2816,2817,2815,2816,2817,2818,2819,2820,2818,2819,2820,2821,2822,2823,2821,2822,2823,2824,2825,2826,2824,2825,2826,2827,2828,2829,2827,2828,2829,2830,2831,2832,2830,2831,2832,2833,2834,2835,2833,2834,2835,2836,2837,2838,2836,2837,2838,2839,2840,2841,2839,2840,2841,2842,2843,2844,2842,2843,2844,2845,2846,2847,2845,2846,2847,2848,2849,2850,2848,2849,2850,2851,2852,2853,2851,2852,2853,2854,2855,2856,2854,2855,2856,2857,2858,2859,2857,2858,2859,2860,2861,2862,2860,2861,2862,2863,2864,2865,2863,2864,2865,2866,2867,2868,2866,2867,2868,2869,2870,2871,2869,2870,2871,2872,2873,2874,2872,2873,2874,2875,2876,2877,2875,2876,2877,2878,2879,2880,2878,2879,2880,2881,2882,2883,2881,2882,2883,2884,2885,2886,2884,2885,2886,2887,2888,2889,2887,2888,2889,2890,2891,2892,2890,2891,2892,2893,2894,2895,2893,2894,2895,2896,2897,2898,2896,2897,2898,2899,2900,2901,2899,2900,2901,2902,2903,2904,2902,2903,2904,2905,2906,2907,2905,2906,2907,2908,2909,2910,2908,2909,2910,2911,2912,2913,2911,2912,2913],"sandstone_wall":[2914,2915,2916,2914,2915,2916,0,2917,2918,0,2917,2918,2919,2920,2921,2919,2920,2921,2922,2923,2924,2922,2923,2924,2925,2926,2927,2925,2926,2927,2928,2929,2930,2928,2929,2930,2931,2932,2933,2931,2932,2933,2934,2935,2936,2934,2935,2936,2937,2938,2939,2937,2938,2939,2940,2941,2942,2940,2941,2942,2943,2944,2945,2943,2944,2945,2946,2947,2948,2946,2947,2948,2949,2950,2951,2949,2950,2951,2952,2953,2954,2952,2953,2954,2955,2956,2957,2955,2956,2957,2958,2959,2960,2958,2959,2960,2961,2962,2963,2961,2962,2963,2964,2965,2966,2964,2965,2966,2967,2968,2969,2967,2968,2969,2970,2971,2972,2970,2971,2972,2973,2974,2975,2973,2974,2975,2976,2977,2978,2976,2977,2978,2979,2980,2981,2979,2980,2981,2982,2983,2984,2982,2983,2984,2985,2986,2987,2985,2986,2987,2988,2989,2990,2988,2989,2990,2991,2992,2993,2991,2992,2993,2994,2995,2996,2994,2995,2996,2997,2998,2999,2997,2998,2999,3000,3001,3002,3000,3001,3002,3003,3004,3005,3003,3004,3005,3006,3007,3008,3006,3007,3008,3009,3010,3011,3009,3010,3011,3012,3013,3014,3012,3013,3014,3015,3016,3017,3015,3016,3017,3018,3019,3020,3018,3019,3020,3021,3022,3023,3021,3022,3023,3024,3025,3026,3024,3025,3026,3027,3028,3029,3027,3028,3029,3030,3031,3032,3030,3031,3032,3033,3034,3035,3033,3034,3035,3036,3037,3038,3036,3037,3038,3039,3040,3041,3039,3040,3041,3042,3043,3044,3042,3043,3044,3045,3046,3047,3045,3046,3047,3048,3049,3050,3048,3049,3050,3051,3052,3053,3051,3052,3053,3054,3055,3056,3054,3055,3056,3057,3058,3059,3057,3058,3059,3060,3061,3062,3060,3061,3062,3063,3064,3065,3063,3064,3065,3066,3067,3068,3066,3067,3068,3069,3070,3071,3069,3070,3071,3072,3073,3074,3072,3073,3074],"end_stone_brick_wall":[3075,3076,3077,3075,3076,3077,0,3078,3079,0,3078,3079,3080,3081,3082,3080,3081,3082,3083,3084,3085,3083,3084,3085,3086,3087,3088,3086,3087,3088,3089,3090,3091,3089,3090,3091,3092,3093,3094,3092,3093,3094,3095,3096,3097,3095,3096,3097,3098,3099,3100,3098,3099,3100,3101,3102,3103,3101,3102,3103,3104,3105,3106,3104,3105,3106,3107,3108,3109,3107,3108,3109,3110,3111,3112,3110,3111,3112,3113,3114,3115,3113,3114,3115,3116,3117,3118,3116,3117,3118,3119,3120,3121,3119,3120,3121,3122,3123,3124,3122,3123,3124,3125,3126,3127,3125,3126,3127,3128,3129,3130,3128,3129,3130,3131,3132,3133,3131,3132,3133,3134,3135,3136,3134,3135,3136,3137,3138,3139,3137,3138,3139,3140,3141,3142,3140,3141,3142,3143,3144,3145,3143,3144,3145,3146,3147,3148,3146,3147,3148,3149,3150,3151,3149,3150,3151,3152,3153,3154,3152,3153,3154,3155,3156,3157,3155,3156,3157,3158,3159,3160,3158,3159,3160,3161,3162,3163,3161,3162,3163,3164,3165,3166,3164,3165,3166,3167,3168,3169,3167,3168,3169,3170,3171,3172,3170,3171,3172,3173,3174,3175,3173,3174,3175,3176,3177,3178,3176,3177,3178,3179,3180,3181,3179,3180,3181,3182,3183,3184,3182,3183,3184,3185,3186,3187,3185,3186,3187,3188,3189,3190,3188,3189,3190,3191,3192,3193,3191,3192,3193,3194,3195,3196,3194,3195,3196,3197,3198,3199,3197,3198,3199,3200,3201,3202,3200,3201,3202,3203,3204,3205,3203,3204,3205,3206,3207,3208,3206,3207,3208,3209,3210,3211,3209,3210,3211,3212,3213,3214,3212,3213,3214,3215,3216,3217,3215,3216,3217,3218,3219,3220,3218,3219,3220,3221,3222,3223,3221,3222,3223,3224,3225,3226,3224,3225,3226,3227,3228,3229,3227,3228,3229,3230,3231,3232,3230,3231,3232,3233,3234,3235,3233,3234,3235],"diorite_wall":[3236,3237,3238,3236,3237,3238,0,3239,3240,0,3239,3240,3241,3242,3243,3241,3242,3243,3244,3245,3246,3244,3245,3246,3247,3248,3249,3247,3248,3249,3250,3251,3252,3250,3251,3252,3253,3254,3255,3253,3254,3255,3256,3257,3258,3256,3257,3258,3259,3260,3261,3259,3260,3261,3262,3263,3264,3262,3263,3264,3265,3266,3267,3265,3266,3267,3268,3269,3270,3268,3269,3270,3271,3272,3273,3271,3272,3273,3274,3275,3276,3274,3275,3276,3277,3278,3279,3277,3278,3279,3280,3281,3282,3280,3281,3282,3283,3284,3285,3283,3284,3285,3286,3287,3288,3286,3287,3288,3289,3290,3291,3289,3290,3291,3292,3293,3294,3292,3293,3294,3295,3296,3297,3295,3296,3297,3298,3299,3300,3298,3299,3300,3301,3302,3303,3301,3302,3303,3304,3305,3306,3304,3305,3306,3307,3308,3309,3307,3308,3309,3310,3311,3312,3310,3311,3312,3313,3314,3315,3313,3314,3315,3316,3317,3318,3316,3317,3318,3319,3320,3321,3319,3320,3321,3322,3323,3324,3322,3323,3324,3325,3326,3327,3325,3326,3327,3328,3329,3330,3328,3329,3330,3331,3332,3333,3331,3332,3333,3334,3335,3336,3334,3335,3336,3337,3338,3339,3337,3338,3339,3340,3341,3342,3340,3341,3342,3343,3344,3345,3343,3344,3345,3346,3347,3348,3346,3347,3348,3349,3350,3351,3349,3350,3351,3352,3353,3354,3352,3353,3354,3355,3356,3357,3355,3356,3357,3358,3359,3360,3358,3359,3360,3361,3362,3363,3361,3362,3363,3364,3365,3366,3364,3365,3366,3367,3368,3369,3367,3368,3369,3370,3371,3372,3370,3371,3372,3373,3374,3375,3373,3374,3375,3376,3377,3378,3376,3377,3378,3379,3380,3381,3379,3380,3381,3382,3383,3384,3382,3383,3384,3385,3386,3387,3385,3386,3387,3388,3389,3390,3388,3389,3390,3391,3392,3393,3391,3392,3393,3394,3395,3396,3394,3395,3396],"scaffolding":3397,"loom":1,"barrel":1,"smoker":1,"blast_furnace":1,"cartography_table":1,"fletching_table":1,"grindstone":[3398,3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409],"lectern":3410,"smithing_table":1,"stonecutter":3411,"bell":[3412,3412,3412,3412,3413,3413,3413,3413,3414,3414,3414,3414,3414,3414,3414,3414,3415,3415,3416,3416,3417,3417,3418,3418,3419,3419,3419,3419,3420,3420,3420,3420],"lantern":[3421,3421,3422,3422],"soul_lantern":[3421,3421,3422,3422],"copper_lantern":[3421,3421,3422,3422],"exposed_copper_lantern":[3421,3421,3422,3422],"weathered_copper_lantern":[3421,3421,3422,3422],"oxidized_copper_lantern":[3421,3421,3422,3422],"waxed_copper_lantern":[3421,3421,3422,3422],"waxed_exposed_copper_lantern":[3421,3421,3422,3422],"waxed_weathered_copper_lantern":[3421,3421,3422,3422],"waxed_oxidized_copper_lantern":[3421,3421,3422,3422],"campfire":3423,"soul_campfire":3423,"sweet_berry_bush":0,"warped_stem":1,"stripped_warped_stem":1,"warped_hyphae":1,"stripped_warped_hyphae":1,"warped_nylium":1,"warped_fungus":0,"warped_wart_block":1,"warped_roots":0,"nether_sprouts":0,"crimson_stem":1,"stripped_crimson_stem":1,"crimson_hyphae":1,"stripped_crimson_hyphae":1,"crimson_nylium":1,"crimson_fungus":0,"shroomlight":1,"weeping_vines":0,"weeping_vines_plant":0,"twisting_vines":0,"twisting_vines_plant":0,"crimson_roots":0,"crimson_planks":1,"warped_planks":1,"crimson_slab":[273,273,274,274,1,1],"warped_slab":[273,273,274,274,1,1],"crimson_pressure_plate":0,"warped_pressure_plate":0,"crimson_fence":[3424,3425,3424,3425,3426,3427,3426,3427,3428,3429,3428,3429,3430,3431,3430,3431,3432,3433,3432,3433,3434,3435,3434,3435,3436,3437,3436,3437,3438,3439,3438,3439],"warped_fence":[3440,3441,3440,3441,3442,3443,3442,3443,3444,3445,3444,3445,3446,3447,3446,3447,3448,3449,3448,3449,3450,3451,3450,3451,3452,3453,3452,3453,3454,3455,3454,3455],"crimson_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"warped_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"crimson_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"warped_fence_gate":[0,0,270,270,0,0,270,270,0,0,270,270,0,0,270,270,0,0,271,271,0,0,271,271,0,0,271,271,0,0,271,271],"crimson_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"warped_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"crimson_button":0,"warped_button":0,"crimson_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"warped_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"crimson_sign":0,"warped_sign":0,"crimson_wall_sign":0,"warped_wall_sign":0,"structure_block":1,"jigsaw":1,"test_block":1,"test_instance_block":1,"composter":3456,"target":1,"bee_nest":1,"beehive":1,"honey_block":3457,"honeycomb_block":1,"netherite_block":1,"ancient_debris":1,"crying_obsidian":1,"respawn_anchor":1,"potted_crimson_fungus":793,"potted_warped_fungus":793,"potted_crimson_roots":793,"potted_warped_roots":793,"lodestone":1,"blackstone":1,"blackstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"blackstone_wall":[3458,3459,3460,3458,3459,3460,0,3461,3462,0,3461,3462,3463,3464,3465,3463,3464,3465,3466,3467,3468,3466,3467,3468,3469,3470,3471,3469,3470,3471,3472,3473,3474,3472,3473,3474,3475,3476,3477,3475,3476,3477,3478,3479,3480,3478,3479,3480,3481,3482,3483,3481,3482,3483,3484,3485,3486,3484,3485,3486,3487,3488,3489,3487,3488,3489,3490,3491,3492,3490,3491,3492,3493,3494,3495,3493,3494,3495,3496,3497,3498,3496,3497,3498,3499,3500,3501,3499,3500,3501,3502,3503,3504,3502,3503,3504,3505,3506,3507,3505,3506,3507,3508,3509,3510,3508,3509,3510,3511,3512,3513,3511,3512,3513,3514,3515,3516,3514,3515,3516,3517,3518,3519,3517,3518,3519,3520,3521,3522,3520,3521,3522,3523,3524,3525,3523,3524,3525,3526,3527,3528,3526,3527,3528,3529,3530,3531,3529,3530,3531,3532,3533,3534,3532,3533,3534,3535,3536,3537,3535,3536,3537,3538,3539,3540,3538,3539,3540,3541,3542,3543,3541,3542,3543,3544,3545,3546,3544,3545,3546,3547,3548,3549,3547,3548,3549,3550,3551,3552,3550,3551,3552,3553,3554,3555,3553,3554,3555,3556,3557,3558,3556,3557,3558,3559,3560,3561,3559,3560,3561,3562,3563,3564,3562,3563,3564,3565,3566,3567,3565,3566,3567,3568,3569,3570,3568,3569,3570,3571,3572,3573,3571,3572,3573,3574,3575,3576,3574,3575,3576,3577,3578,3579,3577,3578,3579,3580,3581,3582,3580,3581,3582,3583,3584,3585,3583,3584,3585,3586,3587,3588,3586,3587,3588,3589,3590,3591,3589,3590,3591,3592,3593,3594,3592,3593,3594,3595,3596,3597,3595,3596,3597,3598,3599,3600,3598,3599,3600,3601,3602,3603,3601,3602,3603,3604,3605,3606,3604,3605,3606,3607,3608,3609,3607,3608,3609,3610,3611,3612,3610,3611,3612,3613,3614,3615,3613,3614,3615,3616,3617,3618,3616,3617,3618],"blackstone_slab":[273,273,274,274,1,1],"polished_blackstone":1,"polished_blackstone_bricks":1,"cracked_polished_blackstone_bricks":1,"chiseled_polished_blackstone":1,"polished_blackstone_brick_slab":[273,273,274,274,1,1],"polished_blackstone_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_blackstone_brick_wall":[3619,3620,3621,3619,3620,3621,0,3622,3623,0,3622,3623,3624,3625,3626,3624,3625,3626,3627,3628,3629,3627,3628,3629,3630,3631,3632,3630,3631,3632,3633,3634,3635,3633,3634,3635,3636,3637,3638,3636,3637,3638,3639,3640,3641,3639,3640,3641,3642,3643,3644,3642,3643,3644,3645,3646,3647,3645,3646,3647,3648,3649,3650,3648,3649,3650,3651,3652,3653,3651,3652,3653,3654,3655,3656,3654,3655,3656,3657,3658,3659,3657,3658,3659,3660,3661,3662,3660,3661,3662,3663,3664,3665,3663,3664,3665,3666,3667,3668,3666,3667,3668,3669,3670,3671,3669,3670,3671,3672,3673,3674,3672,3673,3674,3675,3676,3677,3675,3676,3677,3678,3679,3680,3678,3679,3680,3681,3682,3683,3681,3682,3683,3684,3685,3686,3684,3685,3686,3687,3688,3689,3687,3688,3689,3690,3691,3692,3690,3691,3692,3693,3694,3695,3693,3694,3695,3696,3697,3698,3696,3697,3698,3699,3700,3701,3699,3700,3701,3702,3703,3704,3702,3703,3704,3705,3706,3707,3705,3706,3707,3708,3709,3710,3708,3709,3710,3711,3712,3713,3711,3712,3713,3714,3715,3716,3714,3715,3716,3717,3718,3719,3717,3718,3719,3720,3721,3722,3720,3721,3722,3723,3724,3725,3723,3724,3725,3726,3727,3728,3726,3727,3728,3729,3730,3731,3729,3730,3731,3732,3733,3734,3732,3733,3734,3735,3736,3737,3735,3736,3737,3738,3739,3740,3738,3739,3740,3741,3742,3743,3741,3742,3743,3744,3745,3746,3744,3745,3746,3747,3748,3749,3747,3748,3749,3750,3751,3752,3750,3751,3752,3753,3754,3755,3753,3754,3755,3756,3757,3758,3756,3757,3758,3759,3760,3761,3759,3760,3761,3762,3763,3764,3762,3763,3764,3765,3766,3767,3765,3766,3767,3768,3769,3770,3768,3769,3770,3771,3772,3773,3771,3772,3773,3774,3775,3776,3774,3775,3776,3777,3778,3779,3777,3778,3779],"gilded_blackstone":1,"polished_blackstone_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_blackstone_slab":[273,273,274,274,1,1],"polished_blackstone_pressure_plate":0,"polished_blackstone_button":0,"polished_blackstone_wall":[3780,3781,3782,3780,3781,3782,0,3783,3784,0,3783,3784,3785,3786,3787,3785,3786,3787,3788,3789,3790,3788,3789,3790,3791,3792,3793,3791,3792,3793,3794,3795,3796,3794,3795,3796,3797,3798,3799,3797,3798,3799,3800,3801,3802,3800,3801,3802,3803,3804,3805,3803,3804,3805,3806,3807,3808,3806,3807,3808,3809,3810,3811,3809,3810,3811,3812,3813,3814,3812,3813,3814,3815,3816,3817,3815,3816,3817,3818,3819,3820,3818,3819,3820,3821,3822,3823,3821,3822,3823,3824,3825,3826,3824,3825,3826,3827,3828,3829,3827,3828,3829,3830,3831,3832,3830,3831,3832,3833,3834,3835,3833,3834,3835,3836,3837,3838,3836,3837,3838,3839,3840,3841,3839,3840,3841,3842,3843,3844,3842,3843,3844,3845,3846,3847,3845,3846,3847,3848,3849,3850,3848,3849,3850,3851,3852,3853,3851,3852,3853,3854,3855,3856,3854,3855,3856,3857,3858,3859,3857,3858,3859,3860,3861,3862,3860,3861,3862,3863,3864,3865,3863,3864,3865,3866,3867,3868,3866,3867,3868,3869,3870,3871,3869,3870,3871,3872,3873,3874,3872,3873,3874,3875,3876,3877,3875,3876,3877,3878,3879,3880,3878,3879,3880,3881,3882,3883,3881,3882,3883,3884,3885,3886,3884,3885,3886,3887,3888,3889,3887,3888,3889,3890,3891,3892,3890,3891,3892,3893,3894,3895,3893,3894,3895,3896,3897,3898,3896,3897,3898,3899,3900,3901,3899,3900,3901,3902,3903,3904,3902,3903,3904,3905,3906,3907,3905,3906,3907,3908,3909,3910,3908,3909,3910,3911,3912,3913,3911,3912,3913,3914,3915,3916,3914,3915,3916,3917,3918,3919,3917,3918,3919,3920,3921,3922,3920,3921,3922,3923,3924,3925,3923,3924,3925,3926,3927,3928,3926,3927,3928,3929,3930,3931,3929,3930,3931,3932,3933,3934,3932,3933,3934,3935,3936,3937,3935,3936,3937,3938,3939,3940,3938,3939,3940],"chiseled_nether_bricks":1,"cracked_nether_bricks":1,"quartz_bricks":1,"candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"white_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"orange_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"magenta_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"light_blue_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"yellow_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"lime_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"pink_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"gray_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"light_gray_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"cyan_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"purple_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"blue_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"brown_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"green_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"red_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"black_candle":[3941,3941,3941,3941,3942,3942,3942,3942,3943,3943,3943,3943,3944,3944,3944,3944],"candle_cake":3945,"white_candle_cake":3945,"orange_candle_cake":3945,"magenta_candle_cake":3945,"light_blue_candle_cake":3945,"yellow_candle_cake":3945,"lime_candle_cake":3945,"pink_candle_cake":3945,"gray_candle_cake":3945,"light_gray_candle_cake":3945,"cyan_candle_cake":3945,"purple_candle_cake":3945,"blue_candle_cake":3945,"brown_candle_cake":3945,"green_candle_cake":3945,"red_candle_cake":3945,"black_candle_cake":3945,"amethyst_block":1,"budding_amethyst":1,"amethyst_cluster":[3946,3946,3947,3947,3948,3948,3949,3949,3950,3950,3951,3951],"large_amethyst_bud":[3952,3952,3953,3953,3954,3954,3955,3955,3956,3956,3957,3957],"medium_amethyst_bud":[3958,3958,3959,3959,3960,3960,3961,3961,3962,3962,3963,3963],"small_amethyst_bud":[3964,3964,3965,3965,3966,3966,3967,3967,3968,3968,3969,3969],"tuff":1,"tuff_slab":[273,273,274,274,1,1],"tuff_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"tuff_wall":[3970,3971,3972,3970,3971,3972,0,3973,3974,0,3973,3974,3975,3976,3977,3975,3976,3977,3978,3979,3980,3978,3979,3980,3981,3982,3983,3981,3982,3983,3984,3985,3986,3984,3985,3986,3987,3988,3989,3987,3988,3989,3990,3991,3992,3990,3991,3992,3993,3994,3995,3993,3994,3995,3996,3997,3998,3996,3997,3998,3999,4000,4001,3999,4000,4001,4002,4003,4004,4002,4003,4004,4005,4006,4007,4005,4006,4007,4008,4009,4010,4008,4009,4010,4011,4012,4013,4011,4012,4013,4014,4015,4016,4014,4015,4016,4017,4018,4019,4017,4018,4019,4020,4021,4022,4020,4021,4022,4023,4024,4025,4023,4024,4025,4026,4027,4028,4026,4027,4028,4029,4030,4031,4029,4030,4031,4032,4033,4034,4032,4033,4034,4035,4036,4037,4035,4036,4037,4038,4039,4040,4038,4039,4040,4041,4042,4043,4041,4042,4043,4044,4045,4046,4044,4045,4046,4047,4048,4049,4047,4048,4049,4050,4051,4052,4050,4051,4052,4053,4054,4055,4053,4054,4055,4056,4057,4058,4056,4057,4058,4059,4060,4061,4059,4060,4061,4062,4063,4064,4062,4063,4064,4065,4066,4067,4065,4066,4067,4068,4069,4070,4068,4069,4070,4071,4072,4073,4071,4072,4073,4074,4075,4076,4074,4075,4076,4077,4078,4079,4077,4078,4079,4080,4081,4082,4080,4081,4082,4083,4084,4085,4083,4084,4085,4086,4087,4088,4086,4087,4088,4089,4090,4091,4089,4090,4091,4092,4093,4094,4092,4093,4094,4095,4096,4097,4095,4096,4097,4098,4099,4100,4098,4099,4100,4101,4102,4103,4101,4102,4103,4104,4105,4106,4104,4105,4106,4107,4108,4109,4107,4108,4109,4110,4111,4112,4110,4111,4112,4113,4114,4115,4113,4114,4115,4116,4117,4118,4116,4117,4118,4119,4120,4121,4119,4120,4121,4122,4123,4124,4122,4123,4124,4125,4126,4127,4125,4126,4127,4128,4129,4130,4128,4129,4130],"polished_tuff":1,"polished_tuff_slab":[273,273,274,274,1,1],"polished_tuff_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_tuff_wall":[4131,4132,4133,4131,4132,4133,0,4134,4135,0,4134,4135,4136,4137,4138,4136,4137,4138,4139,4140,4141,4139,4140,4141,4142,4143,4144,4142,4143,4144,4145,4146,4147,4145,4146,4147,4148,4149,4150,4148,4149,4150,4151,4152,4153,4151,4152,4153,4154,4155,4156,4154,4155,4156,4157,4158,4159,4157,4158,4159,4160,4161,4162,4160,4161,4162,4163,4164,4165,4163,4164,4165,4166,4167,4168,4166,4167,4168,4169,4170,4171,4169,4170,4171,4172,4173,4174,4172,4173,4174,4175,4176,4177,4175,4176,4177,4178,4179,4180,4178,4179,4180,4181,4182,4183,4181,4182,4183,4184,4185,4186,4184,4185,4186,4187,4188,4189,4187,4188,4189,4190,4191,4192,4190,4191,4192,4193,4194,4195,4193,4194,4195,4196,4197,4198,4196,4197,4198,4199,4200,4201,4199,4200,4201,4202,4203,4204,4202,4203,4204,4205,4206,4207,4205,4206,4207,4208,4209,4210,4208,4209,4210,4211,4212,4213,4211,4212,4213,4214,4215,4216,4214,4215,4216,4217,4218,4219,4217,4218,4219,4220,4221,4222,4220,4221,4222,4223,4224,4225,4223,4224,4225,4226,4227,4228,4226,4227,4228,4229,4230,4231,4229,4230,4231,4232,4233,4234,4232,4233,4234,4235,4236,4237,4235,4236,4237,4238,4239,4240,4238,4239,4240,4241,4242,4243,4241,4242,4243,4244,4245,4246,4244,4245,4246,4247,4248,4249,4247,4248,4249,4250,4251,4252,4250,4251,4252,4253,4254,4255,4253,4254,4255,4256,4257,4258,4256,4257,4258,4259,4260,4261,4259,4260,4261,4262,4263,4264,4262,4263,4264,4265,4266,4267,4265,4266,4267,4268,4269,4270,4268,4269,4270,4271,4272,4273,4271,4272,4273,4274,4275,4276,4274,4275,4276,4277,4278,4279,4277,4278,4279,4280,4281,4282,4280,4281,4282,4283,4284,4285,4283,4284,4285,4286,4287,4288,4286,4287,4288,4289,4290,4291,4289,4290,4291],"chiseled_tuff":1,"tuff_bricks":1,"tuff_brick_slab":[273,273,274,274,1,1],"tuff_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"tuff_brick_wall":[4292,4293,4294,4292,4293,4294,0,4295,4296,0,4295,4296,4297,4298,4299,4297,4298,4299,4300,4301,4302,4300,4301,4302,4303,4304,4305,4303,4304,4305,4306,4307,4308,4306,4307,4308,4309,4310,4311,4309,4310,4311,4312,4313,4314,4312,4313,4314,4315,4316,4317,4315,4316,4317,4318,4319,4320,4318,4319,4320,4321,4322,4323,4321,4322,4323,4324,4325,4326,4324,4325,4326,4327,4328,4329,4327,4328,4329,4330,4331,4332,4330,4331,4332,4333,4334,4335,4333,4334,4335,4336,4337,4338,4336,4337,4338,4339,4340,4341,4339,4340,4341,4342,4343,4344,4342,4343,4344,4345,4346,4347,4345,4346,4347,4348,4349,4350,4348,4349,4350,4351,4352,4353,4351,4352,4353,4354,4355,4356,4354,4355,4356,4357,4358,4359,4357,4358,4359,4360,4361,4362,4360,4361,4362,4363,4364,4365,4363,4364,4365,4366,4367,4368,4366,4367,4368,4369,4370,4371,4369,4370,4371,4372,4373,4374,4372,4373,4374,4375,4376,4377,4375,4376,4377,4378,4379,4380,4378,4379,4380,4381,4382,4383,4381,4382,4383,4384,4385,4386,4384,4385,4386,4387,4388,4389,4387,4388,4389,4390,4391,4392,4390,4391,4392,4393,4394,4395,4393,4394,4395,4396,4397,4398,4396,4397,4398,4399,4400,4401,4399,4400,4401,4402,4403,4404,4402,4403,4404,4405,4406,4407,4405,4406,4407,4408,4409,4410,4408,4409,4410,4411,4412,4413,4411,4412,4413,4414,4415,4416,4414,4415,4416,4417,4418,4419,4417,4418,4419,4420,4421,4422,4420,4421,4422,4423,4424,4425,4423,4424,4425,4426,4427,4428,4426,4427,4428,4429,4430,4431,4429,4430,4431,4432,4433,4434,4432,4433,4434,4435,4436,4437,4435,4436,4437,4438,4439,4440,4438,4439,4440,4441,4442,4443,4441,4442,4443,4444,4445,4446,4444,4445,4446,4447,4448,4449,4447,4448,4449,4450,4451,4452,4450,4451,4452],"chiseled_tuff_bricks":1,"calcite":1,"tinted_glass":1,"powder_snow":0,"sculk_sensor":4453,"calibrated_sculk_sensor":4453,"sculk":1,"sculk_vein":0,"sculk_catalyst":1,"sculk_shrieker":4454,"copper_block":1,"exposed_copper":1,"weathered_copper":1,"oxidized_copper":1,"copper_ore":1,"deepslate_copper_ore":1,"oxidized_cut_copper":1,"weathered_cut_copper":1,"exposed_cut_copper":1,"cut_copper":1,"oxidized_chiseled_copper":1,"weathered_chiseled_copper":1,"exposed_chiseled_copper":1,"chiseled_copper":1,"waxed_oxidized_chiseled_copper":1,"waxed_weathered_chiseled_copper":1,"waxed_exposed_chiseled_copper":1,"waxed_chiseled_copper":1,"oxidized_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"weathered_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"exposed_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"oxidized_cut_copper_slab":[273,273,274,274,1,1],"weathered_cut_copper_slab":[273,273,274,274,1,1],"exposed_cut_copper_slab":[273,273,274,274,1,1],"cut_copper_slab":[273,273,274,274,1,1],"waxed_copper_block":1,"waxed_weathered_copper":1,"waxed_exposed_copper":1,"waxed_oxidized_copper":1,"waxed_oxidized_cut_copper":1,"waxed_weathered_cut_copper":1,"waxed_exposed_cut_copper":1,"waxed_cut_copper":1,"waxed_oxidized_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"waxed_weathered_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"waxed_exposed_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"waxed_cut_copper_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"waxed_oxidized_cut_copper_slab":[273,273,274,274,1,1],"waxed_weathered_cut_copper_slab":[273,273,274,274,1,1],"waxed_exposed_cut_copper_slab":[273,273,274,274,1,1],"waxed_cut_copper_slab":[273,273,274,274,1,1],"copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"exposed_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"oxidized_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"weathered_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"waxed_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"waxed_exposed_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"waxed_oxidized_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"waxed_weathered_copper_door":[58,58,59,59,60,60,59,59,58,58,59,59,60,60,59,59,60,60,61,61,58,58,61,61,60,60,61,61,58,58,61,61,59,59,60,60,61,61,60,60,59,59,60,60,61,61,60,60,61,61,58,58,59,59,58,58,61,61,58,58,59,59,58,58],"copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"exposed_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"oxidized_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"weathered_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"waxed_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"waxed_exposed_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"waxed_oxidized_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"waxed_weathered_copper_trapdoor":[101,101,101,101,102,102,102,102,101,101,101,101,103,103,103,103,104,104,104,104,102,102,102,102,104,104,104,104,103,103,103,103,105,105,105,105,102,102,102,102,105,105,105,105,103,103,103,103,106,106,106,106,102,102,102,102,106,106,106,106,103,103,103,103],"copper_grate":1,"exposed_copper_grate":1,"weathered_copper_grate":1,"oxidized_copper_grate":1,"waxed_copper_grate":1,"waxed_exposed_copper_grate":1,"waxed_weathered_copper_grate":1,"waxed_oxidized_copper_grate":1,"copper_bulb":1,"exposed_copper_bulb":1,"weathered_copper_bulb":1,"oxidized_copper_bulb":1,"waxed_copper_bulb":1,"waxed_exposed_copper_bulb":1,"waxed_weathered_copper_bulb":1,"waxed_oxidized_copper_bulb":1,"copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"exposed_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"weathered_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"oxidized_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"waxed_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"waxed_exposed_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"waxed_weathered_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"waxed_oxidized_copper_chest":[52,52,53,53,54,54,52,52,54,54,53,53,52,52,55,55,56,56,52,52,56,56,55,55],"copper_golem_statue":4455,"exposed_copper_golem_statue":4455,"weathered_copper_golem_statue":4455,"oxidized_copper_golem_statue":4455,"waxed_copper_golem_statue":4455,"waxed_exposed_copper_golem_statue":4455,"waxed_weathered_copper_golem_statue":4455,"waxed_oxidized_copper_golem_statue":4455,"lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"exposed_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"weathered_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"oxidized_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"waxed_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"waxed_exposed_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"waxed_weathered_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"waxed_oxidized_lightning_rod":[1213,1213,1213,1213,1214,1214,1214,1214,1213,1213,1213,1213,1214,1214,1214,1214,1215,1215,1215,1215,1215,1215,1215,1215],"pointed_dripstone":[4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475],"dripstone_block":1,"cave_vines":0,"cave_vines_plant":0,"spore_blossom":0,"azalea":4476,"flowering_azalea":4476,"moss_carpet":1068,"pink_petals":0,"wildflowers":0,"leaf_litter":0,"moss_block":1,"big_dripleaf":[4477,4477,4478,4478,4479,4479,0,0,4477,4477,4478,4478,4479,4479,0,0,4477,4477,4478,4478,4479,4479,0,0,4477,4477,4478,4478,4479,4479,0,0],"big_dripleaf_stem":0,"small_dripleaf":0,"hanging_roots":0,"rooted_dirt":1,"mud":4480,"deepslate":1,"cobbled_deepslate":1,"cobbled_deepslate_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"cobbled_deepslate_slab":[273,273,274,274,1,1],"cobbled_deepslate_wall":[4481,4482,4483,4481,4482,4483,0,4484,4485,0,4484,4485,4486,4487,4488,4486,4487,4488,4489,4490,4491,4489,4490,4491,4492,4493,4494,4492,4493,4494,4495,4496,4497,4495,4496,4497,4498,4499,4500,4498,4499,4500,4501,4502,4503,4501,4502,4503,4504,4505,4506,4504,4505,4506,4507,4508,4509,4507,4508,4509,4510,4511,4512,4510,4511,4512,4513,4514,4515,4513,4514,4515,4516,4517,4518,4516,4517,4518,4519,4520,4521,4519,4520,4521,4522,4523,4524,4522,4523,4524,4525,4526,4527,4525,4526,4527,4528,4529,4530,4528,4529,4530,4531,4532,4533,4531,4532,4533,4534,4535,4536,4534,4535,4536,4537,4538,4539,4537,4538,4539,4540,4541,4542,4540,4541,4542,4543,4544,4545,4543,4544,4545,4546,4547,4548,4546,4547,4548,4549,4550,4551,4549,4550,4551,4552,4553,4554,4552,4553,4554,4555,4556,4557,4555,4556,4557,4558,4559,4560,4558,4559,4560,4561,4562,4563,4561,4562,4563,4564,4565,4566,4564,4565,4566,4567,4568,4569,4567,4568,4569,4570,4571,4572,4570,4571,4572,4573,4574,4575,4573,4574,4575,4576,4577,4578,4576,4577,4578,4579,4580,4581,4579,4580,4581,4582,4583,4584,4582,4583,4584,4585,4586,4587,4585,4586,4587,4588,4589,4590,4588,4589,4590,4591,4592,4593,4591,4592,4593,4594,4595,4596,4594,4595,4596,4597,4598,4599,4597,4598,4599,4600,4601,4602,4600,4601,4602,4603,4604,4605,4603,4604,4605,4606,4607,4608,4606,4607,4608,4609,4610,4611,4609,4610,4611,4612,4613,4614,4612,4613,4614,4615,4616,4617,4615,4616,4617,4618,4619,4620,4618,4619,4620,4621,4622,4623,4621,4622,4623,4624,4625,4626,4624,4625,4626,4627,4628,4629,4627,4628,4629,4630,4631,4632,4630,4631,4632,4633,4634,4635,4633,4634,4635,4636,4637,4638,4636,4637,4638,4639,4640,4641,4639,4640,4641],"polished_deepslate":1,"polished_deepslate_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"polished_deepslate_slab":[273,273,274,274,1,1],"polished_deepslate_wall":[4642,4643,4644,4642,4643,4644,0,4645,4646,0,4645,4646,4647,4648,4649,4647,4648,4649,4650,4651,4652,4650,4651,4652,4653,4654,4655,4653,4654,4655,4656,4657,4658,4656,4657,4658,4659,4660,4661,4659,4660,4661,4662,4663,4664,4662,4663,4664,4665,4666,4667,4665,4666,4667,4668,4669,4670,4668,4669,4670,4671,4672,4673,4671,4672,4673,4674,4675,4676,4674,4675,4676,4677,4678,4679,4677,4678,4679,4680,4681,4682,4680,4681,4682,4683,4684,4685,4683,4684,4685,4686,4687,4688,4686,4687,4688,4689,4690,4691,4689,4690,4691,4692,4693,4694,4692,4693,4694,4695,4696,4697,4695,4696,4697,4698,4699,4700,4698,4699,4700,4701,4702,4703,4701,4702,4703,4704,4705,4706,4704,4705,4706,4707,4708,4709,4707,4708,4709,4710,4711,4712,4710,4711,4712,4713,4714,4715,4713,4714,4715,4716,4717,4718,4716,4717,4718,4719,4720,4721,4719,4720,4721,4722,4723,4724,4722,4723,4724,4725,4726,4727,4725,4726,4727,4728,4729,4730,4728,4729,4730,4731,4732,4733,4731,4732,4733,4734,4735,4736,4734,4735,4736,4737,4738,4739,4737,4738,4739,4740,4741,4742,4740,4741,4742,4743,4744,4745,4743,4744,4745,4746,4747,4748,4746,4747,4748,4749,4750,4751,4749,4750,4751,4752,4753,4754,4752,4753,4754,4755,4756,4757,4755,4756,4757,4758,4759,4760,4758,4759,4760,4761,4762,4763,4761,4762,4763,4764,4765,4766,4764,4765,4766,4767,4768,4769,4767,4768,4769,4770,4771,4772,4770,4771,4772,4773,4774,4775,4773,4774,4775,4776,4777,4778,4776,4777,4778,4779,4780,4781,4779,4780,4781,4782,4783,4784,4782,4783,4784,4785,4786,4787,4785,4786,4787,4788,4789,4790,4788,4789,4790,4791,4792,4793,4791,4792,4793,4794,4795,4796,4794,4795,4796,4797,4798,4799,4797,4798,4799,4800,4801,4802,4800,4801,4802],"deepslate_tiles":1,"deepslate_tile_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"deepslate_tile_slab":[273,273,274,274,1,1],"deepslate_tile_wall":[4803,4804,4805,4803,4804,4805,0,4806,4807,0,4806,4807,4808,4809,4810,4808,4809,4810,4811,4812,4813,4811,4812,4813,4814,4815,4816,4814,4815,4816,4817,4818,4819,4817,4818,4819,4820,4821,4822,4820,4821,4822,4823,4824,4825,4823,4824,4825,4826,4827,4828,4826,4827,4828,4829,4830,4831,4829,4830,4831,4832,4833,4834,4832,4833,4834,4835,4836,4837,4835,4836,4837,4838,4839,4840,4838,4839,4840,4841,4842,4843,4841,4842,4843,4844,4845,4846,4844,4845,4846,4847,4848,4849,4847,4848,4849,4850,4851,4852,4850,4851,4852,4853,4854,4855,4853,4854,4855,4856,4857,4858,4856,4857,4858,4859,4860,4861,4859,4860,4861,4862,4863,4864,4862,4863,4864,4865,4866,4867,4865,4866,4867,4868,4869,4870,4868,4869,4870,4871,4872,4873,4871,4872,4873,4874,4875,4876,4874,4875,4876,4877,4878,4879,4877,4878,4879,4880,4881,4882,4880,4881,4882,4883,4884,4885,4883,4884,4885,4886,4887,4888,4886,4887,4888,4889,4890,4891,4889,4890,4891,4892,4893,4894,4892,4893,4894,4895,4896,4897,4895,4896,4897,4898,4899,4900,4898,4899,4900,4901,4902,4903,4901,4902,4903,4904,4905,4906,4904,4905,4906,4907,4908,4909,4907,4908,4909,4910,4911,4912,4910,4911,4912,4913,4914,4915,4913,4914,4915,4916,4917,4918,4916,4917,4918,4919,4920,4921,4919,4920,4921,4922,4923,4924,4922,4923,4924,4925,4926,4927,4925,4926,4927,4928,4929,4930,4928,4929,4930,4931,4932,4933,4931,4932,4933,4934,4935,4936,4934,4935,4936,4937,4938,4939,4937,4938,4939,4940,4941,4942,4940,4941,4942,4943,4944,4945,4943,4944,4945,4946,4947,4948,4946,4947,4948,4949,4950,4951,4949,4950,4951,4952,4953,4954,4952,4953,4954,4955,4956,4957,4955,4956,4957,4958,4959,4960,4958,4959,4960,4961,4962,4963,4961,4962,4963],"deepslate_bricks":1,"deepslate_brick_stairs":[28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,40,40,29,29,42,42,31,31,49,49,45,45,34,34,47,47,36,36,50,50,30,30,39,39,32,32,41,41,51,51,35,35,44,44,37,37,46,46],"deepslate_brick_slab":[273,273,274,274,1,1],"deepslate_brick_wall":[4964,4965,4966,4964,4965,4966,0,4967,4968,0,4967,4968,4969,4970,4971,4969,4970,4971,4972,4973,4974,4972,4973,4974,4975,4976,4977,4975,4976,4977,4978,4979,4980,4978,4979,4980,4981,4982,4983,4981,4982,4983,4984,4985,4986,4984,4985,4986,4987,4988,4989,4987,4988,4989,4990,4991,4992,4990,4991,4992,4993,4994,4995,4993,4994,4995,4996,4997,4998,4996,4997,4998,4999,5000,5001,4999,5000,5001,5002,5003,5004,5002,5003,5004,5005,5006,5007,5005,5006,5007,5008,5009,5010,5008,5009,5010,5011,5012,5013,5011,5012,5013,5014,5015,5016,5014,5015,5016,5017,5018,5019,5017,5018,5019,5020,5021,5022,5020,5021,5022,5023,5024,5025,5023,5024,5025,5026,5027,5028,5026,5027,5028,5029,5030,5031,5029,5030,5031,5032,5033,5034,5032,5033,5034,5035,5036,5037,5035,5036,5037,5038,5039,5040,5038,5039,5040,5041,5042,5043,5041,5042,5043,5044,5045,5046,5044,5045,5046,5047,5048,5049,5047,5048,5049,5050,5051,5052,5050,5051,5052,5053,5054,5055,5053,5054,5055,5056,5057,5058,5056,5057,5058,5059,5060,5061,5059,5060,5061,5062,5063,5064,5062,5063,5064,5065,5066,5067,5065,5066,5067,5068,5069,5070,5068,5069,5070,5071,5072,5073,5071,5072,5073,5074,5075,5076,5074,5075,5076,5077,5078,5079,5077,5078,5079,5080,5081,5082,5080,5081,5082,5083,5084,5085,5083,5084,5085,5086,5087,5088,5086,5087,5088,5089,5090,5091,5089,5090,5091,5092,5093,5094,5092,5093,5094,5095,5096,5097,5095,5096,5097,5098,5099,5100,5098,5099,5100,5101,5102,5103,5101,5102,5103,5104,5105,5106,5104,5105,5106,5107,5108,5109,5107,5108,5109,5110,5111,5112,5110,5111,5112,5113,5114,5115,5113,5114,5115,5116,5117,5118,5116,5117,5118,5119,5120,5121,5119,5120,5121,5122,5123,5124,5122,5123,5124],"chiseled_deepslate":1,"cracked_deepslate_bricks":1,"cracked_deepslate_tiles":1,"infested_deepslate":1,"smooth_basalt":1,"raw_iron_block":1,"raw_copper_block":1,"raw_gold_block":1,"potted_azalea_bush":793,"potted_flowering_azalea_bush":793,"ochre_froglight":1,"verdant_froglight":1,"pearlescent_froglight":1,"frogspawn":0,"reinforced_deepslate":1,"decorated_pot":5125,"crafter":1,"trial_spawner":1,"vault":1,"heavy_core":5126,"pale_moss_block":1,"pale_moss_carpet":[5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,5127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"pale_hanging_moss":0,"open_eyeblossom":0,"closed_eyeblossom":0,"potted_open_eyeblossom":793,"potted_closed_eyeblossom":793,"firefly_bush":0}} \ No newline at end of file diff --git a/MinecraftClient/Physics/BlockShapes.cs b/MinecraftClient/Physics/BlockShapes.cs new file mode 100644 index 00000000..5575644b --- /dev/null +++ b/MinecraftClient/Physics/BlockShapes.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text.Json; +using MinecraftClient.Mapping; +using MinecraftClient.Mapping.BlockPalettes; + +namespace MinecraftClient.Physics +{ + /// + /// Registry of block collision shapes. Maps block state IDs to collision AABBs. + /// Data sourced from PrismarineJS/minecraft-data blockCollisionShapes.json. + /// + public static class BlockShapes + { + private static readonly Aabb FullBlock = new(0, 0, 0, 1, 1, 1); + private static readonly Aabb[] FullBlockArray = { FullBlock }; + private static readonly Aabb[] EmptyArray = Array.Empty(); + + private static Dictionary? stateToShape; + private static Dictionary? prismarineBlocks; + private static Dictionary? prismarineShapes; + + /// + /// Initialize the shape registry from embedded data + current palette. + /// Call once after the block palette is set. + /// + public static void Initialize() + { + LoadPrismarineData(); + BuildStateMap(); + } + + /// + /// Get collision shapes for a block state ID. + /// Returns empty array for air/passable blocks, single full-block for solid cubes, etc. + /// + public static Aabb[] GetShapes(int blockStateId) + { + if (stateToShape != null && stateToShape.TryGetValue(blockStateId, out var shapes)) + return shapes; + return FallbackShape(blockStateId); + } + + /// + /// Get collision shapes for a Block at a specific position (state-aware) + /// + public static Aabb[] GetShapes(Block block) => GetShapes(block.BlockId); + + /// + /// Check if a block state is effectively empty (no collision) + /// + public static bool IsEmpty(int blockStateId) + { + var shapes = GetShapes(blockStateId); + return shapes.Length == 0; + } + + private static Aabb[] FallbackShape(int blockStateId) + { + Material mat = Block.Palette.FromId(blockStateId); + if (mat == Material.Air) return EmptyArray; + if (mat.IsLiquid()) return EmptyArray; + if (mat.IsSolid()) return FullBlockArray; + return EmptyArray; + } + + private static void LoadPrismarineData() + { + prismarineBlocks = new Dictionary(); + prismarineShapes = new Dictionary(); + + try + { + var assembly = Assembly.GetExecutingAssembly(); + using var stream = assembly.GetManifestResourceStream("BlockShapeData.json"); + if (stream == null) + { + ConsoleInteractive.ConsoleWriter.WriteLineFormatted("§e[Physics] BlockShapeData.json not found as embedded resource"); + return; + } + using var doc = JsonDocument.Parse(stream); + var root = doc.RootElement; + + // Parse shapes: shapeId -> list of AABB boxes + if (root.TryGetProperty("shapes", out var shapesEl)) + { + foreach (var prop in shapesEl.EnumerateObject()) + { + if (int.TryParse(prop.Name, out int shapeId)) + { + var boxes = new List(); + foreach (var boxEl in prop.Value.EnumerateArray()) + { + var coords = new double[6]; + int idx = 0; + foreach (var c in boxEl.EnumerateArray()) + { + if (idx < 6) coords[idx++] = c.GetDouble(); + } + if (idx == 6) + boxes.Add(new Aabb(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5])); + } + prismarineShapes[shapeId] = boxes.ToArray(); + } + } + } + + // Parse blocks: blockName -> shapeId (int) or list of shapeIds + if (root.TryGetProperty("blocks", out var blocksEl)) + { + foreach (var prop in blocksEl.EnumerateObject()) + { + string blockName = prop.Name; + if (prop.Value.ValueKind == JsonValueKind.Number) + { + prismarineBlocks[blockName] = prop.Value.GetInt32(); + } + else if (prop.Value.ValueKind == JsonValueKind.Array) + { + var ids = new List(); + foreach (var el in prop.Value.EnumerateArray()) + ids.Add(el.GetInt32()); + prismarineBlocks[blockName] = ids; + } + } + } + } + catch (Exception ex) + { + ConsoleInteractive.ConsoleWriter.WriteLineFormatted($"§e[Physics] Failed to load BlockShapeData.json: {ex.Message}"); + } + } + + private static void BuildStateMap() + { + stateToShape = new Dictionary(); + + if (prismarineBlocks == null || prismarineShapes == null) + return; + + var palette = Block.Palette; + var dict = GetPaletteDict(palette); + if (dict == null) return; + + // Group consecutive state IDs by Material to find state ranges per block + var materialRanges = new Dictionary>(); + int? rangeStart = null; + Material? currentMat = null; + + foreach (var kvp in dict.OrderBy(k => k.Key)) + { + if (currentMat == kvp.Value && rangeStart.HasValue && kvp.Key == (materialRanges[currentMat.Value].Last().end + 1)) + { + var ranges = materialRanges[currentMat.Value]; + ranges[ranges.Count - 1] = (ranges.Last().start, kvp.Key); + } + else + { + currentMat = kvp.Value; + if (!materialRanges.ContainsKey(currentMat.Value)) + materialRanges[currentMat.Value] = new List<(int, int)>(); + materialRanges[currentMat.Value].Add((kvp.Key, kvp.Key)); + } + } + + // Map each Material to PrismarineJS block name + foreach (var kvp in materialRanges) + { + string snakeName = MaterialToSnakeCase(kvp.Key); + if (!prismarineBlocks.TryGetValue(snakeName, out var blockShapeData)) + continue; + + foreach (var (start, end) in kvp.Value) + { + int stateCount = end - start + 1; + + if (blockShapeData is int singleShapeId) + { + var shapes = prismarineShapes.GetValueOrDefault(singleShapeId, EmptyArray); + for (int sid = start; sid <= end; sid++) + stateToShape[sid] = shapes; + } + else if (blockShapeData is List shapeIdList) + { + for (int i = 0; i < stateCount && i < shapeIdList.Count; i++) + { + int shapeId = shapeIdList[i]; + stateToShape[start + i] = prismarineShapes.GetValueOrDefault(shapeId, EmptyArray); + } + } + } + } + + } + + /// + /// Convert Material enum name (PascalCase) to snake_case block name + /// + private static string MaterialToSnakeCase(Material mat) + { + string name = mat.ToString(); + var sb = new System.Text.StringBuilder(name.Length + 5); + for (int i = 0; i < name.Length; i++) + { + char c = name[i]; + if (char.IsUpper(c) && i > 0) + sb.Append('_'); + sb.Append(char.ToLowerInvariant(c)); + } + return sb.ToString(); + } + + /// + /// Access the internal dictionary of a palette via reflection (all palettes store it the same way) + /// + private static Dictionary? GetPaletteDict(BlockPalette palette) + { + try + { + var method = palette.GetType().GetMethod("GetDict", + BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + return method?.Invoke(palette, null) as Dictionary; + } + catch + { + return null; + } + } + } +} diff --git a/MinecraftClient/Physics/CollisionDetector.cs b/MinecraftClient/Physics/CollisionDetector.cs new file mode 100644 index 00000000..0788e93b --- /dev/null +++ b/MinecraftClient/Physics/CollisionDetector.cs @@ -0,0 +1,204 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Physics +{ + /// + /// Performs AABB collision detection against the block world. + /// Mirrors Entity.collide(), collideBoundingBox(), collideWithShapes() from vanilla MC. + /// + public static class CollisionDetector + { + /// + /// Resolve movement with full collision detection including step-up. + /// This is the main entry point, equivalent to Entity.collide(Vec3). + /// + public static Vec3d Collide(World world, Aabb entityBox, Vec3d movement, bool onGround, float maxUpStep) + { + if (movement.LengthSqr() == 0.0) + return movement; + + // Collect block collision shapes in the movement path + var colliders = CollectBlockColliders(world, entityBox.ExpandTowards(movement)); + Vec3d resolved = CollideWithShapes(movement, entityBox, colliders); + + bool blockedX = movement.X != resolved.X; + bool blockedZ = movement.Z != resolved.Z; + bool blockedY = movement.Y != resolved.Y; + bool hitGroundDuringMove = blockedY && movement.Y < 0.0; + + // Step-up logic: if blocked horizontally and on ground or just landed + if (maxUpStep > 0.0f && (hitGroundDuringMove || onGround) && (blockedX || blockedZ)) + { + // Try stepping up + Aabb stepBase = hitGroundDuringMove ? entityBox.Move(0, resolved.Y, 0) : entityBox; + Aabb expanded = stepBase.ExpandTowards(movement.X, maxUpStep, movement.Z) + .ExpandTowards(0, hitGroundDuringMove ? 0 : -1.0E-5, 0); + + var stepColliders = CollectBlockColliders(world, expanded); + + // Try various step heights + float[] candidateHeights = CollectCandidateStepHeights(stepBase, stepColliders, maxUpStep, (float)resolved.Y); + + foreach (float stepY in candidateHeights) + { + Vec3d stepMovement = new Vec3d(movement.X, stepY, movement.Z); + Vec3d stepResolved = CollideWithShapes(stepMovement, stepBase, stepColliders); + + if (stepResolved.HorizontalDistanceSqr() > resolved.HorizontalDistanceSqr()) + { + double yOffset = entityBox.MinY - stepBase.MinY; + return stepResolved.Subtract(0, yOffset, 0); + } + } + } + + return resolved; + } + + /// + /// Collide movement against a list of shapes using axis-separated resolution. + /// Matches Entity.collideWithShapes() — processes axes in order of smallest movement first. + /// + private static Vec3d CollideWithShapes(Vec3d movement, Aabb entityBox, List colliders) + { + if (colliders.Count == 0) + return movement; + + Vec3d accumulated = Vec3d.Zero; + int[] axisOrder = GetAxisStepOrder(movement); + + foreach (int axis in axisOrder) + { + double dist = movement.Get(axis); + if (dist == 0.0) continue; + + double resolved = CollideAxis(axis, entityBox.Move(accumulated), colliders, dist); + accumulated = accumulated.With(axis, resolved); + } + + return accumulated; + } + + /// + /// Get axis processing order: Y first if moving down, otherwise smallest absolute movement first. + /// Vanilla uses Direction.axisStepOrder(Vec3) which returns axes sorted by absolute movement. + /// + private static int[] GetAxisStepOrder(Vec3d movement) + { + double absX = Math.Abs(movement.X); + double absY = Math.Abs(movement.Y); + double absZ = Math.Abs(movement.Z); + + if (absX > absZ) + { + if (absZ > absY) + return new[] { 1, 2, 0 }; // Y Z X + if (absX > absY) + return new[] { 1, 0, 2 }; // Y X Z + return new[] { 0, 1, 2 }; // X Y Z + } + else + { + if (absX > absY) + return new[] { 1, 0, 2 }; // Y X Z + if (absZ > absY) + return new[] { 1, 2, 0 }; // Y Z X + return new[] { 2, 1, 0 }; // Z Y X + } + } + + /// + /// Collide along a single axis against all block shapes. + /// Equivalent to Shapes.collide(axis, box, shapes, distance). + /// + private static double CollideAxis(int axis, Aabb entityBox, List colliders, double movement) + { + foreach (var collider in colliders) + { + if (Math.Abs(movement) < PhysicsConsts.CollisionEpsilon) + return 0.0; + movement = entityBox.Collide(axis, collider, movement); + } + return movement; + } + + /// + /// Collect all block collision AABBs that overlap the given search area. + /// Equivalent to BlockCollisions iterator in vanilla. + /// + public static List CollectBlockColliders(World world, Aabb searchBox) + { + var result = new List(); + + int minBX = (int)Math.Floor(searchBox.MinX - PhysicsConsts.CollisionEpsilon) - 1; + int maxBX = (int)Math.Floor(searchBox.MaxX + PhysicsConsts.CollisionEpsilon) + 1; + int minBY = (int)Math.Floor(searchBox.MinY - PhysicsConsts.CollisionEpsilon) - 1; + int maxBY = (int)Math.Floor(searchBox.MaxY + PhysicsConsts.CollisionEpsilon) + 1; + int minBZ = (int)Math.Floor(searchBox.MinZ - PhysicsConsts.CollisionEpsilon) - 1; + int maxBZ = (int)Math.Floor(searchBox.MaxZ + PhysicsConsts.CollisionEpsilon) + 1; + + for (int bx = minBX; bx <= maxBX; bx++) + { + for (int bz = minBZ; bz <= maxBZ; bz++) + { + for (int by = minBY; by <= maxBY; by++) + { + Block block = world.GetBlock(new Location(bx, by, bz)); + Aabb[] shapes = BlockShapes.GetShapes(block); + + foreach (var shape in shapes) + { + Aabb worldShape = shape.Move(bx, by, bz); + if (worldShape.Intersects(searchBox)) + result.Add(worldShape); + } + } + } + } + + return result; + } + + /// + /// Collect candidate step-up heights, matching Entity.collectCandidateStepUpHeights(). + /// Returns sorted distinct step heights between current resolved Y and maxUpStep. + /// + private static float[] CollectCandidateStepHeights(Aabb stepBase, List colliders, float maxUpStep, float currentY) + { + var heights = new SortedSet(); + + foreach (var collider in colliders) + { + float h = (float)(collider.MaxY - stepBase.MinY); + if (h > currentY && h <= maxUpStep) + heights.Add(h); + } + + if (heights.Count == 0) + return new[] { maxUpStep }; + + var result = new float[heights.Count]; + heights.CopyTo(result); + return result; + } + + /// + /// Check if a position is on ground by testing for vertical collision below. + /// + public static bool IsOnGround(World world, Aabb entityBox) + { + Aabb testBox = entityBox.ExpandTowards(0, -0.06, 0); + return CollectBlockColliders(world, testBox).Count > 0; + } + + /// + /// Check if a given position has no collision (for checking if player fits somewhere). + /// + public static bool NoCollision(World world, Aabb entityBox) + { + return CollectBlockColliders(world, entityBox).Count == 0; + } + } +} diff --git a/MinecraftClient/Physics/MovementInput.cs b/MinecraftClient/Physics/MovementInput.cs new file mode 100644 index 00000000..f1899d57 --- /dev/null +++ b/MinecraftClient/Physics/MovementInput.cs @@ -0,0 +1,55 @@ +using System; + +namespace MinecraftClient.Physics +{ + /// + /// Represents movement input state, equivalent to vanilla ClientInput / KeyboardInput. + /// + public class MovementInput + { + public bool Forward; + public bool Back; + public bool Left; + public bool Right; + public bool Jump; + public bool Sneak; + public bool Sprint; + + /// + /// Get the raw input vector (xxa, zza) before rotation. + /// Forward = +zza, Back = -zza, Left = +xxa, Right = -xxa. + /// Then normalized if magnitude > 1. + /// + public (float xxa, float zza) GetMoveVector() + { + float xxa = 0; + float zza = 0; + + if (Forward) zza += 1.0f; + if (Back) zza -= 1.0f; + if (Left) xxa += 1.0f; + if (Right) xxa -= 1.0f; + + float lenSqr = xxa * xxa + zza * zza; + if (lenSqr > 1.0f) + { + float len = MathF.Sqrt(lenSqr); + xxa /= len; + zza /= len; + } + + return (xxa, zza); + } + + public void Reset() + { + Forward = false; + Back = false; + Left = false; + Right = false; + Jump = false; + Sneak = false; + Sprint = false; + } + } +} diff --git a/MinecraftClient/Physics/PhysicsConsts.cs b/MinecraftClient/Physics/PhysicsConsts.cs new file mode 100644 index 00000000..95cb02c1 --- /dev/null +++ b/MinecraftClient/Physics/PhysicsConsts.cs @@ -0,0 +1,87 @@ +namespace MinecraftClient.Physics +{ + /// + /// All physics constants matching vanilla Minecraft 1.21.11. + /// Values sourced from Entity.java, LivingEntity.java, Player.java, LocalPlayer.java. + /// + public static class PhysicsConsts + { + // --- Player dimensions --- + public const double PlayerWidth = 0.6; + public const double PlayerHeight = 1.8; + public const double PlayerSneakHeight = 1.5; + public const double PlayerSwimHeight = 0.6; + public const double PlayerEyeHeight = 1.62; + + // --- Gravity --- + public const double DefaultGravity = 0.08; + public const double SlowFallingCap = 0.01; + + // --- Step height --- + public const float StepHeight = 0.6f; + + // --- Friction / drag --- + public const float FrictionMultiplier = 0.91f; + public const float DragY = 0.98f; + public const float InputFriction = 0.98f; + public const float GroundAccelerationFactor = 0.21600002f; // 0.216 / (f^3) + public const float AirAcceleration = 0.02f; + + // --- Default block friction --- + public const float DefaultBlockFriction = 0.6f; + public const float IceFriction = 0.98f; + public const float PackedIceFriction = 0.98f; + public const float BlueIceFriction = 0.989f; + public const float SlimeBlockFriction = 0.8f; + + // --- Speed factors --- + public const float DefaultSpeedFactor = 1.0f; + public const float SoulSandSpeedFactor = 0.4f; + public const float HoneySpeedFactor = 0.4f; + + // --- Water --- + public const float WaterSlowDown = 0.8f; + public const float WaterSprintSlowDown = 0.9f; + public const float DolphinsGraceSlowDown = 0.96f; + public const float WaterBaseSpeed = 0.02f; + public const float WaterYDamping = 0.8f; + public const float WaterFloatImpulse = 0.04f; + + // --- Lava --- + public const float LavaSpeed = 0.02f; + public const double LavaHorizontalDamping = 0.5; + public const double LavaVerticalDamping = 0.8; + + // --- Jump --- + public const float BaseJumpPower = 0.42f; + public const double SprintJumpHorizontalBoost = 0.2; + + // --- Climb --- + public const float ClimbMaxSpeed = 0.15f; + public const double ClimbWallBump = 0.2; + + // --- Velocity zeroing thresholds (from LivingEntity.aiStep) --- + public const double PlayerHorizontalVelocityThresholdSqr = 9.0E-6; // < 0.003 length + public const double NonPlayerVelocityThreshold = 0.003; + public const double VerticalVelocityThreshold = 0.003; + + // --- Collision epsilon --- + public const double CollisionEpsilon = 1.0E-7; + + // --- Position packet sending (from LocalPlayer.sendPosition) --- + public const double PositionSendThresholdSqr = 4.0E-8; // (2e-4)^2 + public const int PositionReminderInterval = 20; + + // --- Flying detection --- + public const double FloatingYThreshold = -0.03125; + + // --- Elytra --- + public const double ElytraXZDrag = 0.99; + public const double ElytraYDrag = 0.98; + + // --- Creative/spectator fly --- + public const float DefaultFlySpeed = 0.05f; + public const double FlyVerticalDamping = 0.6; + public const double FlyVerticalBoostScale = 3.0; + } +} diff --git a/MinecraftClient/Physics/PlayerPhysics.cs b/MinecraftClient/Physics/PlayerPhysics.cs new file mode 100644 index 00000000..bf18429f --- /dev/null +++ b/MinecraftClient/Physics/PlayerPhysics.cs @@ -0,0 +1,579 @@ +using System; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Physics +{ + /// + /// Core physics tick engine for the player, faithfully replicating vanilla 1.21.11 physics. + /// Mirrors the combined logic of Entity.move(), LivingEntity.aiStep()/travel()/travelInAir(), + /// Player.travel(), and LocalPlayer.aiStep(). + /// + public class PlayerPhysics + { + // --- State --- + public Vec3d Position; + public Vec3d DeltaMovement; + public float Yaw; + public float Pitch; + public bool OnGround; + public bool HorizontalCollision; + public bool VerticalCollision; + public bool VerticalCollisionBelow; + public double FallDistance; + public Vec3d StuckSpeedMultiplier = Vec3d.Zero; + + // Movement input + public float Xxa; // strafe + public float Zza; // forward + public float Yya; // vertical (creative fly) + public bool Jumping; + + // Movement mode flags + public bool Sprinting; + public bool Sneaking; + public bool CreativeFlying; + public bool InWater; + public bool InLava; + public bool OnClimbable; + public bool HasSlowFalling; + public bool HasLevitation; + public int LevitationAmplifier; + + // Player dimensions + public double PlayerWidth = PhysicsConsts.PlayerWidth; + public double PlayerHeight = PhysicsConsts.PlayerHeight; + + // Anti-jump-spam + private int noJumpDelay; + + // Tick counter for position packet timing + public int TickCount; + + // Movement speed attribute (base = 0.1 for players) + public float MovementSpeed = 0.1f; + + /// + /// Get the player's bounding box at current position + /// + public Aabb GetBoundingBox() + { + return Aabb.OfSize(Position.X, Position.Y, Position.Z, PlayerWidth, PlayerHeight); + } + + /// + /// Run one physics tick. Call at 20 TPS. + /// + public void Tick(World world) + { + TickCount++; + + // Velocity threshold zeroing (LivingEntity.aiStep) + ZeroTinyVelocity(); + + // Jump handling + HandleJumping(world); + + // Build travel input + Vec3d travelInput = new(Xxa, Yya, Zza); + + // Travel (dispatches to air/water/lava/fly) + Travel(world, travelInput); + + if (noJumpDelay > 0) + noJumpDelay--; + } + + /// + /// Apply the movement input from MovementInput to xxa/zza. + /// Call before Tick() each frame. + /// + public void ApplyInput(MovementInput input) + { + var (rawXxa, rawZza) = input.GetMoveVector(); + + // Scale by INPUT_FRICTION (0.98) — this matches LocalPlayer.modifyInput + rawXxa *= PhysicsConsts.InputFriction; + rawZza *= PhysicsConsts.InputFriction; + + // Sneak slowdown + if (input.Sneak) + { + rawXxa *= 0.3f; + rawZza *= 0.3f; + } + + Xxa = rawXxa; + Zza = rawZza; + Yya = 0; + Jumping = input.Jump; + Sneaking = input.Sneak; + Sprinting = input.Sprint; + + // Creative/spectator fly vertical + if (CreativeFlying) + { + if (input.Jump) + Yya += (float)(PhysicsConsts.DefaultFlySpeed * PhysicsConsts.FlyVerticalBoostScale); + if (input.Sneak) + Yya -= (float)(PhysicsConsts.DefaultFlySpeed * PhysicsConsts.FlyVerticalBoostScale); + } + } + + private void ZeroTinyVelocity() + { + double dx = DeltaMovement.X; + double dy = DeltaMovement.Y; + double dz = DeltaMovement.Z; + + // Player-specific: zero horizontal if combined length < 0.003 + if (dx * dx + dz * dz < PhysicsConsts.PlayerHorizontalVelocityThresholdSqr) + { + dx = 0; + dz = 0; + } + if (Math.Abs(dy) < PhysicsConsts.VerticalVelocityThreshold) + dy = 0; + + DeltaMovement = new Vec3d(dx, dy, dz); + } + + private void HandleJumping(World world) + { + if (!Jumping) { noJumpDelay = 0; return; } + + if (InWater || InLava) + { + // Jump in fluid: add upward impulse + DeltaMovement = DeltaMovement.Add(0, PhysicsConsts.WaterFloatImpulse, 0); + } + else if (OnGround && noJumpDelay == 0) + { + JumpFromGround(); + noJumpDelay = 10; + } + } + + private void JumpFromGround() + { + float jumpPower = PhysicsConsts.BaseJumpPower; + if (jumpPower <= 1.0E-5f) return; + + DeltaMovement = new Vec3d( + DeltaMovement.X, + Math.Max(jumpPower, DeltaMovement.Y), + DeltaMovement.Z); + + if (Sprinting) + { + float yawRad = Yaw * (MathF.PI / 180.0f); + DeltaMovement = DeltaMovement.Add( + -MathF.Sin(yawRad) * PhysicsConsts.SprintJumpHorizontalBoost, + 0, + MathF.Cos(yawRad) * PhysicsConsts.SprintJumpHorizontalBoost); + } + } + + private void Travel(World world, Vec3d input) + { + if (InWater && !CreativeFlying) + { + TravelInWater(world, input); + } + else if (InLava && !CreativeFlying) + { + TravelInLava(world, input); + } + else + { + TravelInAir(world, input); + } + } + + /// + /// Ground/air travel — LivingEntity.travelInAir(Vec3) + /// + private void TravelInAir(World world, Vec3d input) + { + // Get block friction at feet + float blockFriction = OnGround ? GetBlockFriction(world) : 1.0f; + float f = blockFriction * PhysicsConsts.FrictionMultiplier; + + // Apply input → velocity (handleRelativeFrictionAndCalculateMovement) + float speed = GetFrictionInfluencedSpeed(blockFriction); + MoveRelative(speed, input); + + // Handle climbable + HandleOnClimbable(); + + // Execute collision + Move(world, DeltaMovement); + + Vec3d postMoveVel = DeltaMovement; + double vy = postMoveVel.Y; + + // Climbing wall bump + if ((HorizontalCollision || Jumping) && OnClimbable) + { + vy = PhysicsConsts.ClimbWallBump; + } + + // Apply gravity + if (HasLevitation) + { + vy += (0.05 * (LevitationAmplifier + 1) - vy) * 0.2; + } + else + { + vy -= GetEffectiveGravity(); + } + + // Apply drag/friction + if (CreativeFlying) + { + // Player.travel override: creative fly preserves horizontal from parent, damps Y + DeltaMovement = new Vec3d(postMoveVel.X * f, vy * PhysicsConsts.FlyVerticalDamping, postMoveVel.Z * f); + } + else + { + DeltaMovement = new Vec3d(postMoveVel.X * f, vy * PhysicsConsts.DragY, postMoveVel.Z * f); + } + + // Block speed factor (soul sand, honey, etc.) + ApplyBlockSpeedFactor(world); + } + + /// + /// Water travel — LivingEntity.travelInWater(Vec3, ...) + /// + private void TravelInWater(World world, Vec3d input) + { + float slowDown = Sprinting ? PhysicsConsts.WaterSprintSlowDown : PhysicsConsts.WaterSlowDown; + float speed = PhysicsConsts.WaterBaseSpeed; + + MoveRelative(speed, input); + Move(world, DeltaMovement); + + Vec3d vel = DeltaMovement; + + // Climbing bump in water + if (HorizontalCollision && OnClimbable) + vel = new Vec3d(vel.X, PhysicsConsts.ClimbWallBump, vel.Z); + + vel = vel.Multiply(slowDown, PhysicsConsts.WaterYDamping, slowDown); + + // Gravity adjustment in water + double gravity = GetEffectiveGravity(); + if (gravity != 0.0) + { + double adjustedY = vel.Y; + bool falling = vel.Y <= 0.0; + if (falling && Math.Abs(vel.Y - 0.005) >= PhysicsConsts.VerticalVelocityThreshold) + { + adjustedY -= gravity / 16.0; + } + + if (!OnGround) + adjustedY -= gravity / 16.0; + + vel = new Vec3d(vel.X, adjustedY, vel.Z); + } + + DeltaMovement = vel; + } + + /// + /// Lava travel — LivingEntity.travelInLava(Vec3, ...) + /// + private void TravelInLava(World world, Vec3d input) + { + MoveRelative(PhysicsConsts.LavaSpeed, input); + Move(world, DeltaMovement); + + double gravity = GetEffectiveGravity(); + Vec3d vel = DeltaMovement; + vel = vel.Multiply(PhysicsConsts.LavaHorizontalDamping, PhysicsConsts.LavaVerticalDamping, PhysicsConsts.LavaHorizontalDamping); + + if (gravity != 0.0) + { + vel = vel.Add(0, -gravity / 4.0, 0); + } + + DeltaMovement = vel; + } + + /// + /// Add input vector rotated by yaw to deltaMovement. + /// Equivalent to Entity.moveRelative(float, Vec3) + getInputVector(). + /// + private void MoveRelative(float speed, Vec3d input) + { + Vec3d rotated = GetInputVector(input, speed, Yaw); + DeltaMovement = DeltaMovement.Add(rotated); + } + + /// + /// Rotate input by yaw and scale by speed. Equivalent to Entity.getInputVector(). + /// + private static Vec3d GetInputVector(Vec3d input, float speed, float yaw) + { + double lenSqr = input.LengthSqr(); + if (lenSqr < 1.0E-7) + return Vec3d.Zero; + + Vec3d scaled = (lenSqr > 1.0 ? input.Normalize() : input).Scale(speed); + float sinYaw = MathF.Sin(yaw * (MathF.PI / 180.0f)); + float cosYaw = MathF.Cos(yaw * (MathF.PI / 180.0f)); + + return new Vec3d( + scaled.X * cosYaw - scaled.Z * sinYaw, + scaled.Y, + scaled.Z * cosYaw + scaled.X * sinYaw); + } + + /// + /// Execute movement with collision detection. + /// Equivalent to Entity.move(MoverType.SELF, delta). + /// + private void Move(World world, Vec3d movement) + { + if (StuckSpeedMultiplier.LengthSqr() > 1.0E-7) + { + movement = movement.Multiply(StuckSpeedMultiplier); + StuckSpeedMultiplier = Vec3d.Zero; + DeltaMovement = Vec3d.Zero; + } + + // Sneak edge back-off + if (Sneaking && OnGround) + movement = MaybeBackOffFromEdge(world, movement); + + Aabb box = GetBoundingBox(); + Vec3d resolved = CollisionDetector.Collide(world, box, movement, OnGround, PhysicsConsts.StepHeight); + + double resolvedLenSqr = resolved.LengthSqr(); + if (resolvedLenSqr > 1.0E-7 || movement.LengthSqr() - resolvedLenSqr < 1.0E-7) + { + // Fall distance reset via trace (simplified: reset on hitting ground) + if (FallDistance != 0.0 && resolvedLenSqr >= 1.0) + { + // Simplified: just check vertical collision + } + + Position = Position.Add(resolved); + } + + // Collision flags + bool blockedX = !MthEqual(movement.X, resolved.X); + bool blockedZ = !MthEqual(movement.Z, resolved.Z); + HorizontalCollision = blockedX || blockedZ; + VerticalCollision = movement.Y != resolved.Y; + VerticalCollisionBelow = VerticalCollision && movement.Y < 0.0; + OnGround = VerticalCollisionBelow; + + // Fall distance tracking + if (OnGround) + FallDistance = 0; + else if (resolved.Y < 0) + FallDistance -= resolved.Y; + + // Zero velocity on blocked axes + if (HorizontalCollision) + { + DeltaMovement = new Vec3d( + blockedX ? 0 : DeltaMovement.X, + DeltaMovement.Y, + blockedZ ? 0 : DeltaMovement.Z); + } + + if (VerticalCollision) + { + // Slime block bounce would go here; for now just zero Y + DeltaMovement = new Vec3d(DeltaMovement.X, 0, DeltaMovement.Z); + } + } + + /// + /// Sneak edge detection: prevent walking off edges while sneaking. + /// Equivalent to Player.maybeBackOffFromEdge(Vec3, MoverType). + /// + private Vec3d MaybeBackOffFromEdge(World world, Vec3d movement) + { + if (movement.Y > 0) return movement; + + double step = 0.05; + double dx = movement.X; + double dz = movement.Z; + Aabb box = GetBoundingBox(); + + while (dx != 0.0 && CollisionDetector.CollectBlockColliders(world, + box.Move(dx, -1.0, 0)).Count == 0) + { + dx = dx < step && dx >= -step ? 0.0 : (dx > 0.0 ? dx - step : dx + step); + } + + while (dz != 0.0 && CollisionDetector.CollectBlockColliders(world, + box.Move(0, -1.0, dz)).Count == 0) + { + dz = dz < step && dz >= -step ? 0.0 : (dz > 0.0 ? dz - step : dz + step); + } + + while (dx != 0.0 && dz != 0.0 && CollisionDetector.CollectBlockColliders(world, + box.Move(dx, -1.0, dz)).Count == 0) + { + dx = dx < step && dx >= -step ? 0.0 : (dx > 0.0 ? dx - step : dx + step); + dz = dz < step && dz >= -step ? 0.0 : (dz > 0.0 ? dz - step : dz + step); + } + + return new Vec3d(dx, movement.Y, dz); + } + + /// + /// Clamp velocity for climbable blocks. + /// Equivalent to LivingEntity.handleOnClimbable(Vec3). + /// + private void HandleOnClimbable() + { + if (!OnClimbable) return; + + FallDistance = 0; + double vx = Math.Clamp(DeltaMovement.X, -PhysicsConsts.ClimbMaxSpeed, PhysicsConsts.ClimbMaxSpeed); + double vz = Math.Clamp(DeltaMovement.Z, -PhysicsConsts.ClimbMaxSpeed, PhysicsConsts.ClimbMaxSpeed); + double vy = Math.Max(DeltaMovement.Y, -PhysicsConsts.ClimbMaxSpeed); + + // Sneaking on ladder prevents sliding down + if (vy < 0.0 && Sneaking) + vy = 0.0; + + DeltaMovement = new Vec3d(vx, vy, vz); + } + + /// + /// Get effective gravity considering slow falling effect. + /// + private double GetEffectiveGravity() + { + double gravity = PhysicsConsts.DefaultGravity; + if (HasSlowFalling && DeltaMovement.Y <= 0.0) + return Math.Min(gravity, PhysicsConsts.SlowFallingCap); + return gravity; + } + + /// + /// Get speed based on friction: ground uses attribute speed * 0.216/(f^3), air uses 0.02. + /// Equivalent to LivingEntity.getFrictionInfluencedSpeed(float). + /// + private float GetFrictionInfluencedSpeed(float friction) + { + if (OnGround) + { + return MovementSpeed * (PhysicsConsts.GroundAccelerationFactor / (friction * friction * friction)); + } + else + { + return CreativeFlying ? MovementSpeed * 0.1f : PhysicsConsts.AirAcceleration; + } + } + + /// + /// Get the friction of the block below the player's feet. + /// + private float GetBlockFriction(World world) + { + Location belowFeet = new(Position.X, Position.Y - 0.5000010, Position.Z); + Material mat = world.GetBlock(belowFeet).Type; + return GetMaterialFriction(mat); + } + + /// + /// Apply block speed factor (soul sand, honey, etc.) + /// Equivalent to Entity.getBlockSpeedFactor(). + /// + private void ApplyBlockSpeedFactor(World world) + { + Location atFeet = new(Position.X, Position.Y, Position.Z); + Material mat = world.GetBlock(atFeet).Type; + float factor = GetMaterialSpeedFactor(mat); + + if (factor == 1.0f) + { + Location belowFeet = new(Position.X, Position.Y - 0.5000010, Position.Z); + mat = world.GetBlock(belowFeet).Type; + factor = GetMaterialSpeedFactor(mat); + } + + if (factor != 1.0f) + { + DeltaMovement = DeltaMovement.Multiply(factor, 1.0, factor); + } + } + + /// + /// Get friction value for a material. Default 0.6, special blocks differ. + /// + public static float GetMaterialFriction(Material mat) + { + return mat switch + { + Material.Ice or Material.PackedIce => PhysicsConsts.IceFriction, + Material.BlueIce => PhysicsConsts.BlueIceFriction, + Material.SlimeBlock => PhysicsConsts.SlimeBlockFriction, + Material.FrostedIce => PhysicsConsts.IceFriction, + _ => PhysicsConsts.DefaultBlockFriction + }; + } + + /// + /// Get speed factor for a material. + /// + public static float GetMaterialSpeedFactor(Material mat) + { + return mat switch + { + Material.SoulSand or Material.SoulSoil => PhysicsConsts.SoulSandSpeedFactor, + Material.HoneyBlock => PhysicsConsts.HoneySpeedFactor, + _ => PhysicsConsts.DefaultSpeedFactor + }; + } + + /// + /// Update environmental state flags (in water, in lava, on climbable, etc.) + /// Call before each Tick(). + /// + public void UpdateEnvironment(World world) + { + Location feetLoc = new(Position.X, Position.Y, Position.Z); + Location headLoc = new(Position.X, Position.Y + PlayerHeight * 0.5, Position.Z); + + Material feetBlock = world.GetBlock(feetLoc).Type; + Material headBlock = world.GetBlock(headLoc).Type; + + InWater = feetBlock == Material.Water || headBlock == Material.Water + || feetBlock == Material.BubbleColumn; + InLava = feetBlock == Material.Lava || headBlock == Material.Lava; + OnClimbable = feetBlock.CanBeClimbedOn(); + } + + /// + /// Set position from server teleport / initial spawn. + /// + public void SetPosition(double x, double y, double z) + { + Position = new Vec3d(x, y, z); + } + + /// + /// Set position and reset velocity (for teleports). + /// + public void Teleport(double x, double y, double z) + { + Position = new Vec3d(x, y, z); + DeltaMovement = Vec3d.Zero; + FallDistance = 0; + } + + private static bool MthEqual(double a, double b) + { + return Math.Abs(a - b) < 1.0E-5; + } + } +} diff --git a/MinecraftClient/Physics/Vec3d.cs b/MinecraftClient/Physics/Vec3d.cs new file mode 100644 index 00000000..bbda4331 --- /dev/null +++ b/MinecraftClient/Physics/Vec3d.cs @@ -0,0 +1,102 @@ +using System; +using System.Runtime.CompilerServices; + +namespace MinecraftClient.Physics +{ + /// + /// Immutable 3D double vector, mirrors net.minecraft.world.phys.Vec3 + /// + public readonly struct Vec3d : IEquatable + { + public static readonly Vec3d Zero = new(0, 0, 0); + + public readonly double X; + public readonly double Y; + public readonly double Z; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d(double x, double y, double z) + { + X = x; + Y = y; + Z = z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Add(double x, double y, double z) => new(X + x, Y + y, Z + z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Add(Vec3d other) => new(X + other.X, Y + other.Y, Z + other.Z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Subtract(Vec3d other) => new(X - other.X, Y - other.Y, Z - other.Z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Subtract(double x, double y, double z) => new(X - x, Y - y, Z - z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Scale(double factor) => new(X * factor, Y * factor, Z * factor); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Multiply(double x, double y, double z) => new(X * x, Y * y, Z * z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vec3d Multiply(Vec3d other) => new(X * other.X, Y * other.Y, Z * other.Z); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double LengthSqr() => X * X + Y * Y + Z * Z; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double Length() => Math.Sqrt(LengthSqr()); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double HorizontalDistanceSqr() => X * X + Z * Z; + + public Vec3d Normalize() + { + double len = Length(); + return len < 1.0E-7 ? Zero : new Vec3d(X / len, Y / len, Z / len); + } + + /// + /// Get component by axis index: 0=X, 1=Y, 2=Z + /// + public double Get(int axis) => axis switch + { + 0 => X, + 1 => Y, + 2 => Z, + _ => throw new ArgumentOutOfRangeException(nameof(axis)) + }; + + /// + /// Return a new Vec3d with one axis replaced + /// + public Vec3d With(int axis, double value) => axis switch + { + 0 => new Vec3d(value, Y, Z), + 1 => new Vec3d(X, value, Z), + 2 => new Vec3d(X, Y, value), + _ => throw new ArgumentOutOfRangeException(nameof(axis)) + }; + + public bool Equals(Vec3d other) => + X == other.X && Y == other.Y && Z == other.Z; + + public override bool Equals(object? obj) => + obj is Vec3d other && Equals(other); + + public override int GetHashCode() => + HashCode.Combine(X, Y, Z); + + public override string ToString() => + $"({X:F4}, {Y:F4}, {Z:F4})"; + + public static bool operator ==(Vec3d a, Vec3d b) => a.Equals(b); + public static bool operator !=(Vec3d a, Vec3d b) => !a.Equals(b); + public static Vec3d operator +(Vec3d a, Vec3d b) => a.Add(b); + public static Vec3d operator -(Vec3d a, Vec3d b) => a.Subtract(b); + public static Vec3d operator *(Vec3d a, double s) => a.Scale(s); + public static Vec3d operator -(Vec3d a) => new(-a.X, -a.Y, -a.Z); + } +} diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 09d4f6bc..ac69e14f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -90,6 +90,10 @@ namespace MinecraftClient.Protocol.Handlers private bool isOnlineMode = false; private readonly BlockingCollection>> packetQueue = new(); private float LastYaw, LastPitch; + private double lastSentX, lastSentY, lastSentZ; + private float lastSentYaw, lastSentPitch; + private bool lastSentOnGround; + private int positionReminder; private long chunkBatchStartTime; private double aggregatedNanosPerChunk = 2000000.0; private int oldSamplesWeight = 1; @@ -4061,47 +4065,92 @@ namespace MinecraftClient.Protocol.Handlers { if (handler.GetTerrainEnabled()) { - var yawPitch = Array.Empty(); - var packetType = PacketTypesOut.PlayerPosition; + // Vanilla-like packet selection (LocalPlayer.sendPosition): + // Send position if delta > (2e-4)^2 or every 20 ticks + // Send rotation if yaw/pitch changed + // Send StatusOnly if only onGround changed - if (Config.Main.Advanced.TemporaryFixBadpacket) - { - if (yaw.HasValue && pitch.HasValue && - (forceUpdate || yaw.Value != LastYaw || pitch.Value != LastPitch)) - { - yawPitch = dataTypes.ConcatBytes(dataTypes.GetFloat(yaw.Value), - dataTypes.GetFloat(pitch.Value)); - packetType = PacketTypesOut.PlayerPositionAndRotation; + double dx = location.X - lastSentX; + double dy = location.Y - lastSentY; + double dz = location.Z - lastSentZ; + double distSqr = dx * dx + dy * dy + dz * dz; - LastYaw = yaw.Value; - LastPitch = pitch.Value; - } - } - else - { - if (yaw.HasValue && pitch.HasValue) - { - yawPitch = dataTypes.ConcatBytes(dataTypes.GetFloat(yaw.Value), - dataTypes.GetFloat(pitch.Value)); - packetType = PacketTypesOut.PlayerPositionAndRotation; + bool positionChanged = distSqr > 4.0E-8 || positionReminder >= 20; + bool rotationChanged = false; + if (yaw.HasValue && pitch.HasValue) + rotationChanged = forceUpdate || yaw.Value != lastSentYaw || pitch.Value != lastSentPitch; + bool groundChanged = onGround != lastSentOnGround; - LastYaw = yaw.Value; - LastPitch = pitch.Value; - } - } + positionReminder++; + + if (!positionChanged && !rotationChanged && !groundChanged) + return true; // Nothing to send try { - SendPacket(packetType, dataTypes.ConcatBytes( - dataTypes.GetDouble(location.X), - dataTypes.GetDouble(location.Y), - protocolVersion < MC_1_8_Version - ? dataTypes.GetDouble(location.Y + 1.62) - : Array.Empty(), - dataTypes.GetDouble(location.Z), - yawPitch, - new byte[] { onGround ? (byte)1 : (byte)0 }) - ); + PacketTypesOut packetType; + byte[] payload; + byte flags = (byte)(onGround ? 1 : 0); + + if (positionChanged && rotationChanged && yaw.HasValue && pitch.HasValue) + { + packetType = PacketTypesOut.PlayerPositionAndRotation; + payload = dataTypes.ConcatBytes( + dataTypes.GetDouble(location.X), + dataTypes.GetDouble(location.Y), + protocolVersion < MC_1_8_Version + ? dataTypes.GetDouble(location.Y + 1.62) + : Array.Empty(), + dataTypes.GetDouble(location.Z), + dataTypes.GetFloat(yaw.Value), + dataTypes.GetFloat(pitch.Value), + new[] { flags }); + lastSentYaw = yaw.Value; + lastSentPitch = pitch.Value; + LastYaw = yaw.Value; + LastPitch = pitch.Value; + } + else if (positionChanged) + { + packetType = PacketTypesOut.PlayerPosition; + payload = dataTypes.ConcatBytes( + dataTypes.GetDouble(location.X), + dataTypes.GetDouble(location.Y), + protocolVersion < MC_1_8_Version + ? dataTypes.GetDouble(location.Y + 1.62) + : Array.Empty(), + dataTypes.GetDouble(location.Z), + new[] { flags }); + } + else if (rotationChanged && yaw.HasValue && pitch.HasValue) + { + packetType = PacketTypesOut.PlayerRotation; + payload = dataTypes.ConcatBytes( + dataTypes.GetFloat(yaw.Value), + dataTypes.GetFloat(pitch.Value), + new[] { flags }); + lastSentYaw = yaw.Value; + lastSentPitch = pitch.Value; + LastYaw = yaw.Value; + LastPitch = pitch.Value; + } + else + { + // Only onGround changed — send StatusOnly (PlayerMovement) + packetType = PacketTypesOut.PlayerMovement; + payload = new[] { flags }; + } + + if (positionChanged) + { + lastSentX = location.X; + lastSentY = location.Y; + lastSentZ = location.Z; + positionReminder = 0; + } + lastSentOnGround = onGround; + + SendPacket(packetType, payload); return true; } catch (SocketException) diff --git a/tools/README.md b/tools/README.md index 17c2d5cb..01e2ced6 100644 --- a/tools/README.md +++ b/tools/README.md @@ -114,6 +114,25 @@ python3 tools/gen_command_argument_registry.py 1.20.6 1.21.5 1.21.6 Reads `ArgumentTypeInfos.java`, skips the `SharedConstants.IS_RUNNING_IN_IDE` block, and prints C# array initializers for the runtime `COMMAND_ARGUMENT_TYPE` registry order. Use this when Mojang inserts new command argument types and the modern `DeclareCommands` parser needs updated ID routing. +## gen_block_shapes.py — Download & compact block collision shapes + +Downloads block collision shapes from PrismarineJS `minecraft-data` and compacts them into a single JSON for MCC's physics engine. + +```bash +# Auto-download for a specific MC version +python3 tools/gen_block_shapes.py 1.21.11 +# → MinecraftClient/Physics/BlockShapeData.json + +# From a local file (if network is slow) +python3 tools/gen_block_shapes.py --from-file /path/to/blockCollisionShapes.json +``` + +Output: `MinecraftClient/Physics/BlockShapeData.json` (embedded as a resource via `.csproj`). + +Data source: `https://raw.githubusercontent.com/PrismarineJS/minecraft-data/master/data/pc//blockCollisionShapes.json` + +Uses `curl` with resume (`-C -`) for reliable download over slow connections. Falls back to manual download if retries are exhausted. + ## Recommended workflow 1. Generate server reports (Step 0) @@ -123,6 +142,7 @@ Reads `ArgumentTypeInfos.java`, skips the `SharedConstants.IS_RUNNING_IN_IDE` bl - Blocks: `gen_block_palette.py` - Entities: `gen_entity_palette.py` - Metadata: `gen_entity_metadata_palette.py` -4. Add any missing enum values to `ItemType.cs`, `Material.cs`, `EntityType.cs`, `EntityMetaDataType.cs` -5. Update version routing (see SKILL.md) -6. Build and test +4. Update block collision shapes: `gen_block_shapes.py` +5. Add any missing enum values to `ItemType.cs`, `Material.cs`, `EntityType.cs`, `EntityMetaDataType.cs` +6. Update version routing (see SKILL.md) +7. Build and test diff --git a/tools/gen_block_shapes.py b/tools/gen_block_shapes.py new file mode 100644 index 00000000..d0d3455d --- /dev/null +++ b/tools/gen_block_shapes.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +""" +Download block collision shapes from PrismarineJS minecraft-data and compact +them into a single JSON file for embedding in MCC's physics engine. + +Usage: + python3 tools/gen_block_shapes.py + python3 tools/gen_block_shapes.py --from-file /path/to/blockCollisionShapes.json + # e.g. python3 tools/gen_block_shapes.py 1.21.11 + +Output: + MinecraftClient/Physics/BlockShapeData.json + +The output JSON has two top-level keys: + - "shapes": { shapeId -> [[x0,y0,z0,x1,y1,z1], ...] } + - "blocks": { blockName -> shapeId | [shapeId, ...] } +""" + +import json +import sys +import os +import subprocess +import tempfile + +REPO = "PrismarineJS/minecraft-data" +BRANCH = "master" + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +REPO_ROOT = os.path.dirname(SCRIPT_DIR) +OUTPUT_PATH = os.path.join(REPO_ROOT, "MinecraftClient", "Physics", "BlockShapeData.json") + + +def resolve_version_path(version: str) -> str: + """Resolve actual data path using PrismarineJS dataPaths.json.""" + url = f"https://raw.githubusercontent.com/{REPO}/{BRANCH}/data/dataPaths.json" + tmp = tempfile.mktemp(suffix=".json") + try: + subprocess.run( + ["curl", "-sL", "--connect-timeout", "10", "--max-time", "30", + "-o", tmp, url], + check=True, timeout=35 + ) + with open(tmp) as f: + data = json.load(f) + pc = data.get("pc", {}) + if version in pc: + entry = pc[version] + bcs_path = entry.get("blockCollisionShapes", "") + if bcs_path: + return bcs_path # e.g. "pc/1.21.11" + return f"pc/{version}" + except Exception as e: + print(f" Warning: could not resolve version path ({e}), using default") + return f"pc/{version}" + finally: + if os.path.exists(tmp): + os.remove(tmp) + + +def download_collision_shapes(version: str) -> dict: + """Download blockCollisionShapes.json with curl and resume support.""" + ver_path = resolve_version_path(version) + url = f"https://raw.githubusercontent.com/{REPO}/{BRANCH}/data/{ver_path}/blockCollisionShapes.json" + print(f"Downloading: {url}") + + tmp = tempfile.mktemp(suffix=".json") + max_retries = 5 + + for attempt in range(1, max_retries + 1): + print(f" Attempt {attempt}/{max_retries}...") + result = subprocess.run( + ["curl", "-sL", "-C", "-", + "--connect-timeout", "15", "--max-time", "180", + "--retry", "3", "--retry-delay", "2", + "-o", tmp, url], + timeout=200 + ) + + if not os.path.exists(tmp): + print(f" No file downloaded") + continue + + size = os.path.getsize(tmp) + print(f" Downloaded {size:,} bytes") + + try: + with open(tmp) as f: + data = json.load(f) + os.remove(tmp) + return data + except json.JSONDecodeError as e: + print(f" Incomplete/corrupt JSON ({e}), retrying...") + # Don't delete tmp, curl -C - will resume + + if os.path.exists(tmp): + os.remove(tmp) + print(f"ERROR: Failed to download complete file after {max_retries} attempts.") + print(f"You can manually download from: {url}") + print(f"Then run: {sys.argv[0]} --from-file /path/to/blockCollisionShapes.json") + sys.exit(1) + + +def compact(raw: dict) -> dict: + """Convert PrismarineJS format to compacted format for embedding.""" + shapes_raw = raw.get("shapes", {}) + blocks_raw = raw.get("blocks", {}) + + if not shapes_raw: + raise ValueError("Could not find 'shapes' key in input JSON") + if not blocks_raw: + raise ValueError("Could not find 'blocks' key in input JSON") + + shapes = {} + for sid, boxes in shapes_raw.items(): + compacted = [] + for box in boxes: + compacted.append([round(c, 6) for c in box]) + shapes[sid] = compacted + + blocks = {} + for name, data in blocks_raw.items(): + blocks[name] = data + + return {"shapes": shapes, "blocks": blocks} + + +def main(): + if len(sys.argv) < 2: + print(f"Usage: {sys.argv[0]} ") + print(f" {sys.argv[0]} --from-file ") + print() + print(f"Example: {sys.argv[0]} 1.21.11") + sys.exit(1) + + if sys.argv[1] == "--from-file": + if len(sys.argv) < 3: + print("Error: --from-file requires a file path") + sys.exit(1) + input_path = sys.argv[2] + print(f"Reading from: {input_path}") + with open(input_path) as f: + raw = json.load(f) + else: + version = sys.argv[1] + print(f"Fetching block collision shapes for MC {version}...") + raw = download_collision_shapes(version) + + result = compact(raw) + + shape_count = len(result["shapes"]) + block_count = len(result["blocks"]) + print(f" Shapes: {shape_count}") + print(f" Blocks: {block_count}") + + with open(OUTPUT_PATH, "w") as f: + json.dump(result, f, separators=(",", ":")) + + file_size = os.path.getsize(OUTPUT_PATH) + print(f" Written to: {OUTPUT_PATH}") + print(f" File size: {file_size:,} bytes") + print() + print("Done. The file is embedded as a resource via MinecraftClient.csproj.") + print("Rebuild MCC to include updated collision data.") + + +if __name__ == "__main__": + main() From e3a25937815a515161458631ba0811e108d9a4ce Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 15:30:42 +0800 Subject: [PATCH 096/484] feat: add cursor indexing ignore rules for SpecStory files - Introduced a new `.cursorindexingignore` file to prevent indexing of SpecStory auto-save files while allowing explicit context inclusion via @ references. - Updated `.gitignore` to exclude the entire `.specstory/` directory and `.vscode/settings.json`, ensuring these files are not tracked by Git. These changes help streamline project management by excluding unnecessary files from indexing and version control. --- .cursorindexingignore | 3 +++ .gitignore | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 .cursorindexingignore diff --git a/.cursorindexingignore b/.cursorindexingignore new file mode 100644 index 00000000..953908e7 --- /dev/null +++ b/.cursorindexingignore @@ -0,0 +1,3 @@ + +# Don't index SpecStory auto-save files, but allow explicit context inclusion via @ references +.specstory/** diff --git a/.gitignore b/.gitignore index 7553592d..df83a1de 100644 --- a/.gitignore +++ b/.gitignore @@ -430,3 +430,7 @@ FodyWeavers.xsd /mcc_input.txt /MinecraftClient.ini /MinecraftClient.backup.ini + +# SpecStory files +/.specstory/ +/.vscode/settings.json From 3afbae4f899111b62b14fede9a92f2ebd3383bbc Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 15:49:14 +0800 Subject: [PATCH 097/484] fix: correct global state indexing in block shape processing - Adjusted the indexing logic in BlockShapes.cs to ensure proper mapping of state counts to shape IDs. - Introduced a global state offset to accurately reference shape IDs in the list, preventing out-of-bounds errors during shape assignment. These changes enhance the reliability of block shape processing in the physics engine. --- MinecraftClient/Physics/BlockShapes.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Physics/BlockShapes.cs b/MinecraftClient/Physics/BlockShapes.cs index 5575644b..2fbe5b27 100644 --- a/MinecraftClient/Physics/BlockShapes.cs +++ b/MinecraftClient/Physics/BlockShapes.cs @@ -173,6 +173,7 @@ namespace MinecraftClient.Physics if (!prismarineBlocks.TryGetValue(snakeName, out var blockShapeData)) continue; + int globalStateOffset = 0; foreach (var (start, end) in kvp.Value) { int stateCount = end - start + 1; @@ -185,12 +186,13 @@ namespace MinecraftClient.Physics } else if (blockShapeData is List shapeIdList) { - for (int i = 0; i < stateCount && i < shapeIdList.Count; i++) + for (int i = 0; i < stateCount && (globalStateOffset + i) < shapeIdList.Count; i++) { - int shapeId = shapeIdList[i]; + int shapeId = shapeIdList[globalStateOffset + i]; stateToShape[start + i] = prismarineShapes.GetValueOrDefault(shapeId, EmptyArray); } } + globalStateOffset += stateCount; } } From 397ab07d1fcecc8f173ab7d061630cfd68e8b506 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 16:20:15 +0800 Subject: [PATCH 098/484] [skipci] docs: update MCC development workflow documentation - Revised the SKILL.md file to enhance clarity and detail regarding the development workflow for Minecraft Console Client (MCC). - Expanded sections on project structure, build commands, and debugging steps, including specific instructions for compiling, starting a test server, and running MCC. - Added environment setup details and a checklist for server configuration, improving usability for developers. - Included new tools and scripts for server management and decompilation processes, streamlining the development experience. These updates provide comprehensive guidance for developers working with MCC in WSL. --- .skills/mcc-dev-workflow/SKILL.md | 154 ++++++++++++++++++++++++++---- 1 file changed, 135 insertions(+), 19 deletions(-) diff --git a/.skills/mcc-dev-workflow/SKILL.md b/.skills/mcc-dev-workflow/SKILL.md index f0c3c5b9..eb2aff31 100644 --- a/.skills/mcc-dev-workflow/SKILL.md +++ b/.skills/mcc-dev-workflow/SKILL.md @@ -1,33 +1,149 @@ --- -name: mcc-development-workflow -description: Documentation of the typical development workflow for Minecraft Console Client (MCC), including project structure, build commands, and debugging steps. +name: mcc-dev-workflow +description: Build, run, and debug Minecraft Console Client (MCC) in WSL. Use when the user wants to compile MCC, start a Minecraft test server, connect MCC to a server, debug MCC protocol issues, or run MCC commands. --- # MCC Development Workflow ## Project Overview -- Repo: `~/Minecraft/Minecraft-Console-Client` (env var `$MCC_REPO`) + - Solution: `MinecraftClient.sln` (projects: `MinecraftClient` + `ConsoleInteractive`) - Build: `dotnet build MinecraftClient.sln -c Release` -- Servers: `~/Minecraft/Servers/` (env var `$MCC_SERVERS`) +- Output: `MinecraftClient/bin/Release/net10.0/MinecraftClient` +- Servers: `MinecraftOfficial/downloads//` — server.jar + runtime data (config, world, etc.) + +Environment: WSL Ubuntu, Java 21, .NET 10 SDK, tmux, python3. + +## Compile + +```bash +dotnet build MinecraftClient.sln -c Release +``` + +## Start a Test Server + +Servers live in `MinecraftOfficial/downloads/` with directories named by version (e.g. `1.20.6`, `1.21.11`). + +```bash +tools/start-server.sh 1.20.6 +``` + +Creates a tmux session `mc-1_20_6` with a named pipe `stdin.pipe` for command input. The server persists across Cursor sessions. + +```bash +echo "op CursorBot" > MinecraftOfficial/downloads/1.20.6/stdin.pipe # server command +tmux capture-pane -t mc-1_20_6 -p -S -50 # view output +echo "stop" > MinecraftOfficial/downloads/1.20.6/stdin.pipe # stop +``` + +### Server config checklist + +- `eula.txt`: `eula=true` +- `server.properties`: `online-mode=false` for offline testing + +## Run MCC + +ConsoleInteractive is patched for non-interactive terminals. + +```bash +MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release -- CursorBot - localhost 2>&1 +``` + +- Format: `MinecraftClient `, password `-` = offline mode +- Use `block_until_ms: 0` to background; `sleep 2` then read terminal to confirm join +- Config: `MinecraftClient.ini` (auto-generated). Set `MinecraftVersion = "auto"` unless pinning. + +### FileInputBot + +Set `MCC_FILE_INPUT=1` (shown above). MCC monitors `mcc_input.txt`: + +```bash +echo "inventory player list" >> mcc_input.txt +``` + +Polled every ~500ms. `sleep 1` then read terminal for response. + +### RCON + +```bash +tools/mc-rcon.sh "give CursorBot diamond_sword 1" +tools/mc-rcon.sh "op CursorBot" +tools/mc-rcon.sh "say hello" 25575 test123 # explicit port and password +``` + +## Verify Connection + +MCC output: `[MCC] Server was successfully joined.` +Server output: `CursorBot joined the game` + +## Server Lifecycle + +**Keep the server running** unless you need to restart/switch version/user asks to stop. + +Check before starting: `tmux list-sessions 2>/dev/null | grep "^mc-"` ## Typical Debug Workflow -1. `~/Minecraft/Servers/start-server.sh 1.20.6-Vanilla` (background) -2. Wait for "Done" in server output -3. Build: `dotnet build $MCC_REPO/MinecraftClient.sln -c Release` -4. Run MCC: `cd $MCC_REPO && MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release -- CursorBot - localhost 2>&1` -5. RCON: `mc-rcon "op CursorBot"` -6. MCC cmd: `echo "inventory player list" >> $MCC_REPO/mcc_input.txt` -7. Read terminal file to see output -8. Kill MCC → rebuild → repeat -## Timing Reference +1. `tools/start-server.sh 1.20.6` (background, `block_until_ms: 0`) +2. Wait for "Done": `tmux capture-pane -t mc-1_20_6 -p -S -5` +3. Build: `dotnet build MinecraftClient.sln -c Release` +4. Run MCC: `MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release --no-build -- CursorBot - localhost 2>&1` (background, `block_until_ms: 0`) +5. `sleep 2`, read terminal to confirm join +6. RCON: `tools/mc-rcon.sh "op CursorBot"` +7. MCC cmd: `echo "inventory player list" >> mcc_input.txt` +8. `sleep 1`, read terminal for output +9. `pkill -f MinecraftClient` → rebuild → repeat + | Operation | Typical Duration | |-----------|-----------------| -| MCC startup → join server | ~1s | -| FileInput command → response | <500ms | +| MCC startup → join | ~1s | +| FileInput → response | <500ms | -## Official Minecraft Server Source (Decompiled) -`$MCC_REPO/MinecraftOfficial/` contains decompiled official server code for protocol reference. -When investigating protocol details (packet structure, field order, NBT format, etc.), -look at the corresponding version's decompiled source as authoritative reference. +## Tools + +All in `tools/`: + +| Script | Purpose | +|--------|---------| +| `start-server.sh ` | Start MC server in tmux | +| `mc-rcon.sh "cmd" [port] [pw]` | RCON command (default: 25575, test123) | +| `decompile.sh --version ` | Decompile MC version + download server.jar | +| `mcc-env.sh` | Source for shell helpers (`mc-start`, `mcc-build`, etc.) | + +`mcc-env.sh` exports `$MCC_REPO` and `$MCC_SERVERS` and defines convenience functions. Source it in interactive shells or `~/.bashrc`. In Cursor's non-interactive Shell, use the standalone scripts directly. + +## Decompiled Server Source + +`MinecraftOfficial/` contains decompiled official server/client code: + +```bash +tools/decompile.sh --version 1.21.1 # server (default) +tools/decompile.sh --version 1.21.1 --side CLIENT # client +``` + +Auto-downloads `MinecraftDecompiler.jar` if missing; downloads `server.jar` into `MinecraftOfficial/downloads//` for SERVER side. + +## Key Code Paths + +| Area | Files | +|------|-------| +| Protocol version map | `Protocol/ProtocolHandler.cs` | +| Packet palette (ID mapping) | `Protocol/Handlers/PacketPalettes/PacketPalette*.cs` | +| Core packet handling | `Protocol/Handlers/Protocol18.cs` | +| Data serialization | `Protocol/Handlers/DataTypes.cs` | +| Structured components (1.20.6+) | `Protocol/Handlers/StructuredComponents/` | +| Client logic | `McClient.cs` | +| Config phase packets | `Protocol/Handlers/ConfigurationPacketTypesIn.cs` / `Out.cs` | +| Console I/O library | `ConsoleInteractive/` | + +## Debugging Tips + +- Debug output: `DebugMessages = true` in `[Logging]` of `MinecraftClient.ini` +- Protocol version shown during connection: `Server version : X.XX.X (protocol vNNN)` +- Server `EncoderException` = protocol mismatch +- Packet reference: https://minecraft.wiki/w/Java_Edition_protocol/Packets +- Use `block_until_ms: 0` for long-running processes, read terminal files for output + +## Git Commits + +Commit at meaningful milestones. Messages in English with sufficient context. From d25f2f40ec4ad9f58fc66aff6c3400fa16fd2f89 Mon Sep 17 00:00:00 2001 From: breadbyte <14045257+breadbyte@users.noreply.github.com> Date: Sun, 22 Mar 2026 18:34:19 +0800 Subject: [PATCH 099/484] Update Github Actions to be more robust with releases (#2952) * Update build-and-release.yml --- .github/workflows/build-and-release.yml | 256 ++++++++++++++---------- 1 file changed, 152 insertions(+), 104 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 40a22587..dba44918 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -12,92 +12,17 @@ env: compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded" jobs: - build: - runs-on: ubuntu-latest - if: ${{ always() && needs.fetch-translations.result != 'failure' && needs.determine-build.result != 'skipped' }} - needs: [determine-build, fetch-translations] - timeout-minutes: 15 - strategy: - matrix: - target: [win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64] - + determine-build: + runs-on: ubuntu-slim + if: >- + ${{ + !contains(github.event.head_commit.message, 'skipci') && + !contains(github.event.pull_request.title, 'skipci') + }} steps: - - name: Checkout - uses: actions/checkout@v3 - if: ${{ always() && needs.fetch-translations.result == 'skipped' }} - with: - fetch-depth: 0 - submodules: 'true' - - - name: Get Current Date - run: | - echo date=$(date +'%Y%m%d') >> $GITHUB_ENV - echo date_dashed=$(date -u +'%Y-%m-%d') >> $GITHUB_ENV - - - name: Restore Translations (if available) - uses: actions/cache/restore@v3 - with: - path: ${{ github.workspace }}/* - key: "translation-${{ github.sha }}" - restore-keys: "translation-" - - - name: Setup Environment Variables (early) - run: | - echo project-path=${{ github.workspace }}/${{ env.PROJECT }} >> $GITHUB_ENV - echo file-ext=${{ (startsWith(matrix.target, 'win') && '.exe') || ' ' }} >> $GITHUB_ENV + - name: dummy action + run: "echo 'dummy action that checks if the build is to be skipped, if it is, this action does not run to break the entire build action'" - - name: Setup .NET SDK - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 10.0.x - - - name: Setup Environment Variables - run: | - echo target-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/${{ matrix.target }}/publish/ >> $GITHUB_ENV - echo assembly-info=${{ env.project-path }}/Properties/AssemblyInfo.cs >> $GITHUB_ENV - echo build-version-info=${{ env.date }}-${{ github.run_number }} >> $GITHUB_ENV - echo commit=$(echo ${{ github.sha }} | cut -c 1-7) >> $GITHUB_ENV - - - name: Setup Environment Variables (late) - run: | - echo built-executable-path=${{ env.target-out-path }}${{ env.PROJECT }}${{ env.file-ext }} >> $GITHUB_ENV - - - name: Set Version Info - run: | - echo '' >> ${{ env.assembly-info }} - echo "[assembly: AssemblyConfiguration(\"GitHub build ${{ github.run_number }}, built on ${{ env.date_dashed }} from commit ${{ env.commit }}\")]" >> ${{ env.assembly-info }} - sed -i -e 's|SentryDSN = "";|SentryDSN = "${{ secrets.SENTRY_DSN }}";|g' ${{ env.project-path }}/Program.cs - - - name: Build Target - run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r ${{ matrix.target }} ${{ env.compile-flags }} - env: - DOTNET_NOLOGO: true - - - name: Rename Binary - run: | - mv ${{ env.built-executable-path }} ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ (startsWith(matrix.target, 'win') && '.exe') || ' ' }} - - - name: Wait - # We wait before creating a release because we might run into a race condition - # while creating a new tag (as opposed to using the existing tag, if any) since we're running builds in parallel. - run: | - sleep 5s - - - name: Create Release - uses: ncipollo/release-action@v1.14.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - artifacts: ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ (startsWith(matrix.target, 'win') && '.exe') || ' ' }} - tag: ${{ format('{0}-{1}', env.date, github.run_number) }} - name: '${{ env.build-version-info }}: ${{ github.event.head_commit.message }}' - generateReleaseNotes: true - artifactErrorsFailBuild: true - allowUpdates: true - makeLatest: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - replacesArtifacts: false - fetch-translations: strategy: fail-fast: true @@ -116,13 +41,13 @@ jobs: key: "translation-${{ github.sha }}" lookup-only: true restore-keys: "translation-" - + - name: Checkout - uses: actions/checkout@v3 if: steps.cache-check.outputs.cache-hit != 'true' + uses: actions/checkout@v3 with: - fetch-depth: 0 - submodules: 'true' + fetch-depth: 0 + submodules: 'true' - name: Download translations from crowdin uses: crowdin/github-action@v1.6.0 @@ -148,20 +73,143 @@ jobs: with: path: ${{ github.workspace }}/* key: "translation-${{ github.sha }}" - - determine-build: - runs-on: ubuntu-latest - strategy: - fail-fast: true - if: >- - ${{ - !contains(github.event.head_commit.message, 'skipci') && - !contains(github.event.head_commit.message, '[skipci]') && - !contains(github.event.head_commit.message, 'skipci | ') && - !contains(github.event.pull_request.title, 'skipci') && - !contains(github.event.pull_request.title, '[skipci]') && - !contains(github.event.pull_request.title, 'skipci | ') - }} + + create-tag: + runs-on: ubuntu-slim + timeout-minutes: 5 # Wait 5 minutes in case of network issues/etc + needs: [determine-build] + if: ${{ needs.determine-build.result == 'success' }} steps: - - name: dummy action - run: "echo 'dummy action that checks if the build is to be skipped, if it is, this action does not run to break the entire build action'" + - id: make-tag + run: | + TAG="$(date -u +'%Y%m%d')-${{ github.run_number }}" + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "TAG=$TAG" >> $GITHUB_ENV + + - name: Create Release Tag + uses: actions/github-script@v7 + with: + script: | + const tag = process.env.TAG; + try { + await github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `refs/tags/${tag}`, + sha: context.sha + }); + } catch(error) { + if (error.message.includes('already exists')) { + console.log(`Tag ${tag} already exists`); + } else { + throw error; + } + } + outputs: + build-tag: ${{ steps.make-tag.outputs.tag }} + + build: + runs-on: ubuntu-latest + # Check if we're not skipping build, tag is created, and translations successfully fetched (or skipped) + if: ${{ needs.determine-build.result == 'success' && + needs.create-tag.result == 'success' && + (needs.fetch-translations.result == 'success' || needs.fetch-translations.result == 'skipped') + }} + needs: [determine-build, fetch-translations, create-tag] + timeout-minutes: 15 + strategy: + matrix: + target: [win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64] + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: 'true' + + - name: Get Current Date + run: | + echo date=$(date +'%Y%m%d') >> $GITHUB_ENV + echo date_dashed=$(date -u +'%Y-%m-%d') >> $GITHUB_ENV + + - name: Restore Translations (if available) + uses: actions/cache/restore@v3 + with: + path: ${{ github.workspace }}/* + key: "translation-${{ github.sha }}" + restore-keys: "translation-" + + - name: Setup Environment Variables (early) + run: | + echo project-path=${{ github.workspace }}/${{ env.PROJECT }} >> $GITHUB_ENV + echo file-ext=${{ (startsWith(matrix.target, 'win') && '.exe') || '' }} >> $GITHUB_ENV + + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Setup Environment Variables + run: | + echo target-out-path=${{ env.project-path }}/bin/Release/${{ env.target-version }}/${{ matrix.target }}/publish/ >> $GITHUB_ENV + echo assembly-info=${{ env.project-path }}/Properties/AssemblyInfo.cs >> $GITHUB_ENV + echo build-version-info=${{ needs.create-tag.outputs.build-tag }} >> $GITHUB_ENV + echo commit=$(echo ${{ github.sha }} | cut -c 1-7) >> $GITHUB_ENV + + - name: Setup Environment Variables (late) + run: | + echo built-executable-path=${{ env.target-out-path }}${{ env.PROJECT }}${{ env.file-ext }} >> $GITHUB_ENV + + - name: Set Version Info and Sentry Project (if applicable) + run: | + echo '' >> ${{ env.assembly-info }} + echo "[assembly: AssemblyConfiguration(\"GitHub build ${{ github.run_number }}, built on ${{ env.date_dashed }} from commit ${{ env.commit }}\")]" >> ${{ env.assembly-info }} + + - name: Inject Sentry DSN + if: ${{ github.repository == 'MCCTeam/Minecraft-Console-Client' }} + run: | + grep -q 'SentryDSN = "";' ${{ env.project-path }}/Program.cs || { echo "SentryDSN pattern not found in Program.cs"; exit 1; } + sed -i -e 's|SentryDSN = "";|SentryDSN = "${{ secrets.SENTRY_DSN }}";|g' ${{ env.project-path }}/Program.cs + + - name: Build Target + run: dotnet publish ${{ env.project-path }}.sln -f ${{ env.target-version }} -r ${{ matrix.target }} ${{ env.compile-flags }} + env: + DOTNET_NOLOGO: true + + - name: Rename Binary + run: | + mv ${{ env.built-executable-path }} ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ env.file-ext }} + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }} + path: ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ env.file-ext }} + if-no-files-found: error + + create-release: + runs-on: ubuntu-slim + needs: [create-tag, build] + if: ${{ needs.build.result == 'success' && needs.create-tag.result == 'success' }} + steps: + - name: Download All Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + merge-multiple: true + + - name: Create Release + uses: ncipollo/release-action@v1.14.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + artifacts: "artifacts/**/*" + tag: ${{ needs.create-tag.outputs.build-tag }} + name: '${{ needs.create-tag.outputs.build-tag }}: ${{ github.event.head_commit.message }}' + generateReleaseNotes: true + artifactErrorsFailBuild: true + allowUpdates: true + makeLatest: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + replacesArtifacts: true From 33fccf85b57aa2feddf24ad28718456453c5495e Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 12:45:52 +0100 Subject: [PATCH 100/484] Added changes from 2927 --- MinecraftClientGUI/Form1.Designer.cs | 132 +-- MinecraftClientGUI/Form1.cs | 989 +++++++++++++----- MinecraftClientGUI/MinecraftClient.cs | 109 +- MinecraftClientGUI/MinecraftClientGUI.csproj | 54 +- MinecraftClientGUI/Program.cs | 26 +- .../Properties/Resources.Designer.cs | 46 +- .../Properties/Settings.Designer.cs | 24 +- MinecraftClientGUI/app.config | 3 + MinecraftClientGUI/screenshot.png | Bin 0 -> 49804 bytes 9 files changed, 875 insertions(+), 508 deletions(-) create mode 100644 MinecraftClientGUI/app.config create mode 100644 MinecraftClientGUI/screenshot.png diff --git a/MinecraftClientGUI/Form1.Designer.cs b/MinecraftClientGUI/Form1.Designer.cs index ba2c948a..e31ea78b 100644 --- a/MinecraftClientGUI/Form1.Designer.cs +++ b/MinecraftClientGUI/Form1.Designer.cs @@ -28,146 +28,20 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); - this.groupBox_Login = new System.Windows.Forms.GroupBox(); - this.btn_connect = new System.Windows.Forms.Button(); - this.box_ip = new System.Windows.Forms.TextBox(); - this.box_password = new System.Windows.Forms.TextBox(); - this.box_Login = new System.Windows.Forms.TextBox(); - this.box_output = new System.Windows.Forms.RichTextBox(); - this.box_input = new System.Windows.Forms.TextBox(); - this.btn_send = new System.Windows.Forms.Button(); - this.btn_about = new System.Windows.Forms.Button(); - this.groupBox_Login.SuspendLayout(); + this.components = new System.ComponentModel.Container(); this.SuspendLayout(); // - // groupBox_Login - // - this.groupBox_Login.BackColor = System.Drawing.Color.Transparent; - this.groupBox_Login.Controls.Add(this.btn_connect); - this.groupBox_Login.Controls.Add(this.box_ip); - this.groupBox_Login.Controls.Add(this.box_password); - this.groupBox_Login.Controls.Add(this.box_Login); - this.groupBox_Login.Location = new System.Drawing.Point(13, 11); - this.groupBox_Login.Name = "groupBox_Login"; - this.groupBox_Login.Size = new System.Drawing.Size(564, 46); - this.groupBox_Login.TabIndex = 0; - this.groupBox_Login.TabStop = false; - this.groupBox_Login.Text = " "; - // - // btn_connect - // - this.btn_connect.Location = new System.Drawing.Point(513, 15); - this.btn_connect.Name = "btn_connect"; - this.btn_connect.Size = new System.Drawing.Size(40, 23); - this.btn_connect.TabIndex = 6; - this.btn_connect.Text = "Go!"; - this.btn_connect.UseVisualStyleBackColor = true; - this.btn_connect.Click += new System.EventHandler(this.btn_connect_Click); - // - // box_ip - // - this.box_ip.Location = new System.Drawing.Point(400, 17); - this.box_ip.Name = "box_ip"; - this.box_ip.Size = new System.Drawing.Size(100, 20); - this.box_ip.TabIndex = 5; - this.box_ip.KeyUp += new System.Windows.Forms.KeyEventHandler(this.loginBox_KeyUp); - // - // box_password - // - this.box_password.Location = new System.Drawing.Point(235, 17); - this.box_password.Name = "box_password"; - this.box_password.PasswordChar = '•'; - this.box_password.Size = new System.Drawing.Size(100, 20); - this.box_password.TabIndex = 3; - this.box_password.KeyUp += new System.Windows.Forms.KeyEventHandler(this.loginBox_KeyUp); - // - // box_Login - // - this.box_Login.Location = new System.Drawing.Point(67, 17); - this.box_Login.Name = "box_Login"; - this.box_Login.Size = new System.Drawing.Size(100, 20); - this.box_Login.TabIndex = 1; - this.box_Login.KeyUp += new System.Windows.Forms.KeyEventHandler(this.loginBox_KeyUp); - // - // box_output - // - this.box_output.Location = new System.Drawing.Point(13, 66); - this.box_output.Name = "box_output"; - this.box_output.ReadOnly = true; - this.box_output.Size = new System.Drawing.Size(564, 292); - this.box_output.TabIndex = 1; - this.box_output.Text = ""; - this.box_output.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.LinkClicked); - // - // box_input - // - this.box_input.AcceptsTab = true; - this.box_input.Location = new System.Drawing.Point(13, 365); - this.box_input.MaxLength = 100; - this.box_input.Multiline = true; - this.box_input.Name = "box_input"; - this.box_input.Size = new System.Drawing.Size(490, 20); - this.box_input.TabIndex = 2; - this.box_input.KeyDown += new System.Windows.Forms.KeyEventHandler(this.inputBox_KeyDown); - // - // btn_send - // - this.btn_send.Location = new System.Drawing.Point(509, 364); - this.btn_send.Name = "btn_send"; - this.btn_send.Size = new System.Drawing.Size(40, 22); - this.btn_send.TabIndex = 3; - this.btn_send.Text = "Send"; - this.btn_send.UseVisualStyleBackColor = true; - this.btn_send.Click += new System.EventHandler(this.btn_send_Click); - // - // btn_about - // - this.btn_about.Location = new System.Drawing.Point(555, 364); - this.btn_about.Name = "btn_about"; - this.btn_about.Size = new System.Drawing.Size(22, 22); - this.btn_about.TabIndex = 4; - this.btn_about.Text = "?"; - this.btn_about.UseVisualStyleBackColor = true; - this.btn_about.Click += new System.EventHandler(this.btn_about_Click); - // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.Control; - this.ClientSize = new System.Drawing.Size(589, 398); - this.Controls.Add(this.btn_about); - this.Controls.Add(this.btn_send); - this.Controls.Add(this.box_input); - this.Controls.Add(this.box_output); - this.Controls.Add(this.groupBox_Login); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; + this.ClientSize = new System.Drawing.Size(1100, 700); this.Name = "Form1"; + this.Text = "MCC Multibox Commander"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Minecraft Console Client GUI"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.onClose); - this.Load += new System.EventHandler(this.Form1_Load); - this.groupBox_Login.ResumeLayout(false); - this.groupBox_Login.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); - } #endregion - - private System.Windows.Forms.GroupBox groupBox_Login; - private System.Windows.Forms.Button btn_connect; - private System.Windows.Forms.TextBox box_ip; - private System.Windows.Forms.TextBox box_password; - private System.Windows.Forms.TextBox box_Login; - private System.Windows.Forms.RichTextBox box_output; - private System.Windows.Forms.TextBox box_input; - private System.Windows.Forms.Button btn_send; - private System.Windows.Forms.Button btn_about; } } - diff --git a/MinecraftClientGUI/Form1.cs b/MinecraftClientGUI/Form1.cs index 189cab59..60698982 100644 --- a/MinecraftClientGUI/Form1.cs +++ b/MinecraftClientGUI/Form1.cs @@ -1,337 +1,794 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; -using System.Text; -using System.Windows.Forms; +using System.Runtime.InteropServices; using System.Threading; +using System.Windows.Forms; namespace MinecraftClientGUI { - /// - /// The main graphical user interface - /// + static class Theme + { + public static Color BgDark = Color.FromArgb(15, 15, 18); + public static Color BgPanel = Color.FromArgb(22, 22, 28); + public static Color BgHeader = Color.FromArgb(28, 28, 36); + public static Color BgCard = Color.FromArgb(32, 32, 42); + public static Color BgInput = Color.FromArgb(20, 20, 26); + public static Color TabActive = Color.FromArgb(38, 38, 52); + public static Color TabInactive = Color.FromArgb(22, 22, 28); + public static Color Accent = Color.FromArgb(82, 130, 255); + public static Color AccentHover = Color.FromArgb(110, 155, 255); + public static Color AccentRed = Color.FromArgb(220, 70, 70); + public static Color AccentGreen = Color.FromArgb(60, 200, 100); + public static Color Text = Color.FromArgb(220, 220, 230); + public static Color TextDim = Color.FromArgb(120, 120, 140); + public static Color TextMuted = Color.FromArgb(70, 70, 90); + public static Color Border = Color.FromArgb(40, 40, 55); + } + + class DarkComboBox : ComboBox + { + public DarkComboBox() + { + DrawMode = DrawMode.OwnerDrawFixed; + FlatStyle = FlatStyle.Flat; + BackColor = Theme.BgInput; + ForeColor = Theme.Text; + Font = new Font("Segoe UI", 9f); + } + protected override void OnDrawItem(DrawItemEventArgs e) + { + if (e.Index < 0) return; + e.Graphics.FillRectangle( + new SolidBrush((e.State & DrawItemState.Selected) != 0 ? Theme.TabActive : Theme.BgInput), + e.Bounds); + TextRenderer.DrawText(e.Graphics, Items[e.Index].ToString(), Font, e.Bounds, + Theme.Text, TextFormatFlags.VerticalCenter | TextFormatFlags.Left); + } + } + + class FlatBtn : Button + { + private Color _back, _hover; + public FlatBtn(string text, Color back, Color? hover = null) + { + Text = text; + _back = back; + _hover = hover ?? ControlPaint.Light(back, 0.2f); + FlatStyle = FlatStyle.Flat; + FlatAppearance.BorderSize = 0; + BackColor = _back; + ForeColor = Theme.Text; + Font = new Font("Segoe UI", 9f, FontStyle.Bold); + Cursor = Cursors.Hand; + MouseEnter += (s, e) => BackColor = _hover; + MouseLeave += (s, e) => BackColor = _back; + } + } public partial class Form1 : Form { - private LinkedList previous = new LinkedList(); - private MinecraftClient Client; - private Thread t_clientread; - - #region Aero Glass Low-level Windows API - - [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] - public struct MARGINS + private const string SettingsFile = "settings_v3.txt"; + private const string MacrosFile = "macros.txt"; + private static readonly string[] DefaultSettingsContent = new[] { "", "", "" }; + private static readonly string[] DefaultMacrosContent = new[] { - public int Left; - public int Right; - public int Top; - public int Bottom; - } + "Creative|/gamemode creative|Gold", + "Survival|/gamemode survival|Gray", + "Hello|Hello everyone!|Green", + "Login|/login password123|Purple", + "Spawn|/spawn|Blue" + }; + private string currentLang = "en"; - [System.Runtime.InteropServices.DllImport("dwmapi.dll")] - public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins); + private Panel tabBar, contentArea, topPanel, bottomPanel, rightPanel; + private Label lblLogin, lblPass, lblIP, lblActive; + private DarkComboBox cmbLogin, cmbIP; + private TextBox txtPassword; + private FlatBtn btnAddBot; + private TextBox boxGlobalInput; + private FlatBtn btnGlobalSend; + private CheckBox chkSendToAll; + private Label lblMacrosTitle; + private FlowLayoutPanel macroPanel; + private FlatBtn btnEditMacros, btnRefreshMacros, btnLangSwitch; - #endregion + private List historyLogins = new List(); + private List historyIPs = new List(); + private List tabs = new List(); + private ConsoleTab activeTab = null; public Form1(string[] args) { InitializeComponent(); - if (args.Length > 0) { initClient(new MinecraftClient(args)); } + BuildUI(); + EnsureRuntimeFiles(); + LoadSettings(); + LoadMacros(); + UpdateLanguage(); + if (args.Length > 0) AddNewTab("Auto-Bot", args); + this.FormClosing += (s, e) => { foreach (var t in tabs.ToList()) t.CloseTab(); }; } - /// - /// Define some element properties and init Aero Glass if using Vista or newer - /// - - private void Form1_Load(object sender, EventArgs e) + private static void EnsureRuntimeFiles() { - box_output.ScrollBars = RichTextBoxScrollBars.None; - box_output.Font = new Font("Consolas", 8); - box_output.BackColor = Color.White; + EnsureFileExists(SettingsFile, DefaultSettingsContent); + EnsureFileExists(MacrosFile, DefaultMacrosContent); + } - if (Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor == 1) + private static void EnsureFileExists(string path, string[] defaultContent) + { + if (!File.Exists(path)) { - this.BackColor = Color.DarkMagenta; this.TransparencyKey = Color.DarkMagenta; - MARGINS marg = new MARGINS() { Left = -1, Right = -1, Top = -1, Bottom = -1 }; - DwmExtendFrameIntoClientArea(this.Handle, ref marg); + File.WriteAllLines(path, defaultContent); } } - /// - /// Launch the Minecraft Client by clicking the "Go!" button. - /// If a client is already running, it will be closed. - /// - - private void btn_connect_Click(object sender, EventArgs e) + private void BuildUI() { - if (Client != null) + this.Text = "MCC Multibox Commander"; + this.Size = new Size(1200, 780); + this.MinimumSize = new Size(900, 600); + this.BackColor = Theme.BgDark; + this.ForeColor = Theme.Text; + this.Font = new Font("Segoe UI", 9f); + this.StartPosition = FormStartPosition.CenterScreen; + + // TOP PANEL + topPanel = new Panel { Dock = DockStyle.Top, Height = 60, BackColor = Theme.BgHeader, Padding = new Padding(12, 0, 12, 0) }; + topPanel.Paint += PaintBottomBorder; + this.Controls.Add(topPanel); + + int y = 17; + lblLogin = MkLabel("Username / Email:", 10, 2); topPanel.Controls.Add(lblLogin); + cmbLogin = new DarkComboBox { Location = new Point(10, y), Size = new Size(195, 26) }; topPanel.Controls.Add(cmbLogin); + + lblPass = MkLabel("Password:", 215, 2); topPanel.Controls.Add(lblPass); + txtPassword = new TextBox { Location = new Point(215, y), Size = new Size(155, 26), BackColor = Theme.BgInput, ForeColor = Theme.Text, BorderStyle = BorderStyle.FixedSingle, UseSystemPasswordChar = true, Font = new Font("Segoe UI", 9f) }; + topPanel.Controls.Add(txtPassword); + + lblIP = MkLabel("Server IP:", 380, 2); topPanel.Controls.Add(lblIP); + cmbIP = new DarkComboBox { Location = new Point(380, y), Size = new Size(215, 26) }; topPanel.Controls.Add(cmbIP); + + btnAddBot = new FlatBtn("+ Add Account", Theme.Accent, Theme.AccentHover) { Location = new Point(608, y - 1), Size = new Size(148, 28) }; + btnAddBot.Click += BtnAddBot_Click; + topPanel.Controls.Add(btnAddBot); + + lblActive = new Label { Location = new Point(770, y), AutoSize = true, ForeColor = Theme.AccentGreen, Font = new Font("Segoe UI", 9f, FontStyle.Bold) }; + topPanel.Controls.Add(lblActive); + + var timer = new System.Windows.Forms.Timer { Interval = 1000 }; + timer.Tick += (s, e) => lblActive.Text = (currentLang == "en" ? "Active accounts: " : "Aktywne konta: ") + tabs.Count; + timer.Start(); + + // RIGHT PANEL + rightPanel = new Panel { Dock = DockStyle.Right, Width = 185, BackColor = Theme.BgPanel }; + rightPanel.Paint += PaintLeftBorder; + this.Controls.Add(rightPanel); + + // Language toggle - large button at the top + btnLangSwitch = new FlatBtn("PL", Color.FromArgb(45, 75, 145), Color.FromArgb(60, 100, 185)) { - Client.Close(); - t_clientread.Abort(); - box_output.Text = ""; - } - string username = box_Login.Text; - string password = box_password.Text; - string serverip = box_ip.Text; - if (password == "") { password = "-"; } - if (username != "" && serverip != "") - { - initClient(new MinecraftClient(username, password, serverip)); - } + Dock = DockStyle.Top, + Height = 36, + Font = new Font("Segoe UI", 11f, FontStyle.Bold), + ForeColor = Color.White + }; + btnLangSwitch.Click += (s, e) => { currentLang = currentLang == "en" ? "pl" : "en"; UpdateLanguage(); }; + rightPanel.Controls.Add(btnLangSwitch); + + // Macro header + var macroHeader = new Panel { Dock = DockStyle.Top, Height = 52, BackColor = Theme.BgPanel }; + macroHeader.Paint += PaintBottomBorder; + rightPanel.Controls.Add(macroHeader); + + lblMacrosTitle = new Label { Text = "Quick Actions", Location = new Point(8, 8), Size = new Size(169, 18), ForeColor = Theme.Text, Font = new Font("Segoe UI", 9f, FontStyle.Bold) }; + macroHeader.Controls.Add(lblMacrosTitle); + + btnEditMacros = new FlatBtn("Edit", Color.FromArgb(40, 40, 58)) { Location = new Point(8, 28), Size = new Size(76, 20), Font = new Font("Segoe UI", 8f, FontStyle.Bold) }; + btnEditMacros.Click += BtnEditMacros_Click; + macroHeader.Controls.Add(btnEditMacros); + + btnRefreshMacros = new FlatBtn("Reload", Color.FromArgb(40, 40, 58)) { Location = new Point(90, 28), Size = new Size(76, 20), Font = new Font("Segoe UI", 8f, FontStyle.Bold) }; + btnRefreshMacros.Click += (s, e) => LoadMacros(); + macroHeader.Controls.Add(btnRefreshMacros); + + macroPanel = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown, WrapContents = false, AutoScroll = true, BackColor = Theme.BgPanel, Padding = new Padding(8, 8, 0, 8) }; + rightPanel.Controls.Add(macroPanel); + + rightPanel.Controls.SetChildIndex(macroPanel, 0); + rightPanel.Controls.SetChildIndex(macroHeader, 1); + rightPanel.Controls.SetChildIndex(btnLangSwitch, 2); + + // BOTTOM PANEL + bottomPanel = new Panel { Dock = DockStyle.Bottom, Height = 40, BackColor = Theme.BgHeader, Padding = new Padding(6, 6, 6, 0) }; + bottomPanel.Paint += PaintTopBorder; + this.Controls.Add(bottomPanel); + + btnGlobalSend = new FlatBtn("Send", Color.FromArgb(50, 90, 160), Theme.Accent) { Dock = DockStyle.Right, Width = 80 }; + btnGlobalSend.Click += BtnGlobalSend_Click; + bottomPanel.Controls.Add(btnGlobalSend); + + chkSendToAll = new CheckBox { Text = "Send to all", Dock = DockStyle.Right, Width = 120, ForeColor = Color.FromArgb(255, 160, 90), Padding = new Padding(8, 0, 0, 0), Font = new Font("Segoe UI", 9f, FontStyle.Bold) }; + bottomPanel.Controls.Add(chkSendToAll); + + boxGlobalInput = new TextBox { Dock = DockStyle.Fill, BackColor = Theme.BgInput, ForeColor = Theme.Text, BorderStyle = BorderStyle.FixedSingle, Font = new Font("Consolas", 11f) }; + boxGlobalInput.KeyDown += (s, e) => { if (e.KeyCode == Keys.Enter) { BtnGlobalSend_Click(s, e); e.SuppressKeyPress = true; } }; + bottomPanel.Controls.Add(boxGlobalInput); + + // TAB BAR + tabBar = new Panel { Dock = DockStyle.Top, Height = 38, BackColor = Theme.BgPanel }; + tabBar.Paint += PaintBottomBorder; + this.Controls.Add(tabBar); + + // CONTENT AREA + contentArea = new Panel { Dock = DockStyle.Fill, BackColor = Theme.BgDark }; + this.Controls.Add(contentArea); + + this.Controls.SetChildIndex(contentArea, 0); + this.Controls.SetChildIndex(tabBar, 1); + this.Controls.SetChildIndex(bottomPanel, 2); + this.Controls.SetChildIndex(rightPanel, 3); + this.Controls.SetChildIndex(topPanel, 4); } - /// - /// Handle a new Minecraft Client - /// - /// Client to handle - - private void initClient(MinecraftClient client) + private void AddNewTab(string title, string[] args) { - Client = client; - t_clientread = new Thread(new ThreadStart(t_clientread_loop)); - t_clientread.Start(); - box_input.Select(); + var tab = new ConsoleTab(title, args, currentLang) { Dock = DockStyle.Fill }; + tabs.Add(tab); + contentArea.Controls.Add(tab); + RebuildTabBar(); + ActivateTab(tab); } - /// - /// Thread reading output from the Minecraft Client - /// - - private void t_clientread_loop() + private void ActivateTab(ConsoleTab tab) { - while (true && !Client.Disconnected) - { - printstring(Client.ReadLine()); - } + activeTab = tab; + foreach (Control c in contentArea.Controls) c.Visible = (c == tab); + RebuildTabBar(); } - /// - /// Print a Minecraft-Formatted string to the console area - /// - /// String to print - - private void printstring(string str) + private void RebuildTabBar() { - if (!String.IsNullOrEmpty(str)) + tabBar.Controls.Clear(); + int x = 4; + foreach (var tab in tabs) { - Color color = Color.Black; - FontStyle style = FontStyle.Regular; - string[] subs = str.Split('§'); - if (subs[0].Length > 0) { AppendTextBox(box_output, subs[0], Color.Black, FontStyle.Regular); } - for (int i = 1; i < subs.Length; i++) + var t = tab; + bool active = (t == activeTab); + + var btn = new Panel { Location = new Point(x, active ? 2 : 5), Size = new Size(148, active ? 32 : 27), BackColor = active ? Theme.TabActive : Theme.TabInactive, Cursor = Cursors.Hand }; + btn.Paint += (s, e) => { + if (t == activeTab) + e.Graphics.FillRectangle(new SolidBrush(Theme.Accent), 0, btn.Height - 2, btn.Width, 2); + }; + + var lbl = new Label { - if (subs[i].Length > 0) + Text = t.TabTitle, + Location = new Point(8, 0), + Size = new Size(108, 30), + ForeColor = active ? Theme.Text : Theme.TextDim, + Font = new Font("Segoe UI", 9f, active ? FontStyle.Bold : FontStyle.Regular), + TextAlign = ContentAlignment.MiddleLeft, + Cursor = Cursors.Hand + }; + lbl.Click += (s, e) => ActivateTab(t); + btn.Click += (s, e) => ActivateTab(t); + btn.Controls.Add(lbl); + + var btnX = new Label + { + Text = "x", + Location = new Point(120, 0), + Size = new Size(25, 30), + ForeColor = Theme.TextMuted, + Font = new Font("Segoe UI", 9f), + TextAlign = ContentAlignment.MiddleCenter, + Cursor = Cursors.Hand + }; + btnX.MouseEnter += (s, e) => btnX.ForeColor = Theme.AccentRed; + btnX.MouseLeave += (s, e) => btnX.ForeColor = Theme.TextMuted; + btnX.Click += (s, e) => { + t.CloseTab(); + tabs.Remove(t); + contentArea.Controls.Remove(t); + if (activeTab == t) { activeTab = tabs.LastOrDefault(); if (activeTab != null) ActivateTab(activeTab); } + RebuildTabBar(); + }; + btn.Controls.Add(btnX); + tabBar.Controls.Add(btn); + x += 152; + } + } + + private void UpdateLanguage() + { + bool en = currentLang == "en"; + btnLangSwitch.Text = en ? "Switch to PL" : "Switch to EN"; + lblLogin.Text = en ? "Username / Email:" : "Login / Email:"; + lblPass.Text = en ? "Password:" : "Haslo:"; + lblIP.Text = en ? "Server IP:" : "IP Serwera:"; + btnAddBot.Text = en ? "+ Add Account" : "+ Dodaj Konto"; + lblMacrosTitle.Text = en ? "Quick Actions" : "Szybkie Akcje"; + btnEditMacros.Text = en ? "Edit" : "Edytuj"; + btnRefreshMacros.Text = en ? "Reload" : "Odswiez"; + btnGlobalSend.Text = en ? "Send" : "Wyslij"; + chkSendToAll.Text = en ? "Send to all" : "Wyslij do wszystkich"; + foreach (var tab in tabs) tab.UpdateLang(currentLang); + } + + private void BtnEditMacros_Click(object sender, EventArgs e) + { + EnsureFileExists(MacrosFile, DefaultMacrosContent); + Process.Start("notepad.exe", MacrosFile); + } + + private void LoadMacros() + { + macroPanel.Controls.Clear(); + if (!File.Exists(MacrosFile)) return; + try + { + foreach (var line in File.ReadAllLines(MacrosFile)) + { + if (string.IsNullOrWhiteSpace(line)) continue; + var parts = line.Split('|'); + if (parts.Length >= 2) { - if (subs[i].Length > 1) - { - switch (subs[i][0]) - { - //Font colors - case '0': color = Color.Black; break; - case '1': color = Color.DarkBlue; break; - case '2': color = Color.DarkGreen; break; - case '3': color = Color.DarkCyan; break; - case '4': color = Color.DarkRed; break; - case '5': color = Color.DarkMagenta; break; - case '6': color = Color.DarkGoldenrod; break; - case '7': color = Color.DimGray; break; - case '8': color = Color.Gray; break; - case '9': color = Color.Blue; break; - case 'a': color = Color.Green; break; - case 'b': color = Color.CornflowerBlue; break; - case 'c': color = Color.Red; break; - case 'd': color = Color.Magenta; break; - case 'e': color = Color.Goldenrod; break; - - //White on white = invisible so use gray instead - case 'f': color = Color.DimGray; break; - - //Font styles. Can use several styles eg Bold + Underline - case 'l': style = style | FontStyle.Bold; break; - case 'm': style = style | FontStyle.Strikeout; break; - case 'n': style = style | FontStyle.Underline; break; - case 'o': style = style | FontStyle.Italic; break; - - //Reset font color & style - case 'r': color = Color.Black; style = FontStyle.Regular; break; - } - - AppendTextBox(box_output, subs[i].Substring(1, subs[i].Length - 1), color, style); - } + Color c = parts.Length > 2 ? Color.FromName(parts[2]) : Theme.Accent; + if (c.IsEmpty) c = Theme.Accent; + AddMacroBtn(parts[1], parts[0], c); } } - AppendTextBox(box_output, "\n", Color.Black, FontStyle.Regular); } - Console.ForegroundColor = ConsoleColor.Gray; + catch (Exception ex) { MessageBox.Show("Error loading macros: " + ex.Message); } } - /// - /// Append text to a RichTextBox with font customization - /// - /// Target RichTextBox - /// Text to add - /// Color of the text - /// Font style of the text - - private void AppendTextBox(RichTextBox box, string text, Color color, FontStyle style) + private void AddMacroBtn(string cmd, string label, Color color) { - if (InvokeRequired) + Color bg = Color.FromArgb(32, 32, 48); + Color hov = Color.FromArgb(44, 44, 64); + var btn = new Button { - this.Invoke(new Action(AppendTextBox), new object[] { box, text, color, style }); + Text = " " + label, + Width = macroPanel.Width - 22, + Height = 34, + FlatStyle = FlatStyle.Flat, + BackColor = bg, + ForeColor = Theme.Text, + Font = new Font("Segoe UI", 9f, FontStyle.Bold), + Cursor = Cursors.Hand, + Margin = new Padding(0, 0, 0, 4), + TextAlign = ContentAlignment.MiddleLeft, + Tag = color + }; + btn.FlatAppearance.BorderSize = 0; + btn.MouseEnter += (s, e) => btn.BackColor = hov; + btn.MouseLeave += (s, e) => btn.BackColor = bg; + btn.Paint += (s, e) => e.Graphics.FillRectangle(new SolidBrush(color), 0, 0, 4, btn.Height); + btn.Click += (s, e) => { + if (chkSendToAll.Checked) foreach (var tab in tabs) tab.Send(cmd); + else activeTab?.Send(cmd); + }; + macroPanel.Controls.Add(btn); + } + + private void BtnAddBot_Click(object sender, EventArgs e) + { + string user = cmbLogin.Text.Trim(), pass = txtPassword.Text.Trim(), ip = cmbIP.Text.Trim(); + if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(ip)) + { + MessageBox.Show(currentLang == "en" ? "Please enter username and IP!" : "Podaj login i IP serwera!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + SaveSettings(user, ip); + string tabTitle = user.Contains("@") ? user.Split('@')[0] : user; + AddNewTab(tabTitle, new[] { user, pass, ip }); + } + + private void BtnGlobalSend_Click(object sender, EventArgs e) + { + string cmd = boxGlobalInput.Text.Trim(); + if (string.IsNullOrEmpty(cmd)) return; + if (chkSendToAll.Checked) foreach (var tab in tabs) tab.Send(cmd); + else activeTab?.Send(cmd); + boxGlobalInput.Clear(); + } + + private void LoadSettings() + { + try + { + if (!File.Exists(SettingsFile)) return; + var lines = File.ReadAllLines(SettingsFile).ToList(); + while (lines.Count < 3) + { + lines.Add(string.Empty); + } + if (lines.Count > 0) txtPassword.Text = lines[0]; + if (lines.Count > 1) { historyLogins = lines[1].Split('|').ToList(); cmbLogin.Items.AddRange(historyLogins.ToArray()); if (cmbLogin.Items.Count > 0) cmbLogin.SelectedIndex = 0; } + if (lines.Count > 2) { historyIPs = lines[2].Split('|').ToList(); cmbIP.Items.AddRange(historyIPs.ToArray()); if (cmbIP.Items.Count > 0) cmbIP.SelectedIndex = 0; } + } + catch { } + } + + private void SaveSettings(string user, string ip) + { + historyLogins.Remove(user); historyLogins.Insert(0, user); if (historyLogins.Count > 10) historyLogins.RemoveAt(10); + historyIPs.Remove(ip); historyIPs.Insert(0, ip); if (historyIPs.Count > 10) historyIPs.RemoveAt(10); + cmbLogin.Items.Clear(); cmbLogin.Items.AddRange(historyLogins.ToArray()); cmbLogin.Text = user; + cmbIP.Items.Clear(); cmbIP.Items.AddRange(historyIPs.ToArray()); cmbIP.Text = ip; + try { File.WriteAllLines(SettingsFile, new[] { txtPassword.Text, string.Join("|", historyLogins), string.Join("|", historyIPs) }); } catch { } + } + + private void PaintBottomBorder(object sender, PaintEventArgs e) { var c = (Control)sender; e.Graphics.DrawLine(new Pen(Theme.Border), 0, c.Height - 1, c.Width, c.Height - 1); } + private void PaintTopBorder(object sender, PaintEventArgs e) { var c = (Control)sender; e.Graphics.DrawLine(new Pen(Theme.Border), 0, 0, c.Width, 0); } + private void PaintLeftBorder(object sender, PaintEventArgs e) { var c = (Control)sender; e.Graphics.DrawLine(new Pen(Theme.Border), 0, 0, 0, c.Height); } + private Label MkLabel(string text, int x, int y) => new Label { Text = text, Location = new Point(x, y), AutoSize = true, ForeColor = Theme.TextDim, Font = new Font("Segoe UI", 8f) }; + } + + // ===================================================== + // LINE TYPES (for filtering) + // ===================================================== + enum LineType { Chat, System, Error } + + struct LogLine + { + public string Raw; + public string Display; + public LineType Type; + public DateTime Time; + } + + public class ConsoleTab : Panel + { + private MinecraftClient Client; + private Thread t_read; + private RichTextBox boxOutput; + private Button btnDisconnect; + private Label lblStatus; + private Label lblTimer; + private CheckBox chkAutoScroll; + private bool autoScroll = true; + + private Button btnFilterAll, btnFilterChat, btnFilterSystem, btnFilterError; + private LineType? activeFilter = null; + + private List allLines = new List(); + private object logLock = new object(); + + private StreamWriter logWriter; + private DateTime connectedAt; + private System.Windows.Forms.Timer timerClock; + private bool isConnected = false; + + public string TabTitle { get; set; } + + [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam); + [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] + private static extern int SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList); + private const int WM_VSCROLL = 0x115, SB_BOTTOM = 7; + + public ConsoleTab(string title, string[] args, string lang) + { + this.TabTitle = title; + this.BackColor = Theme.BgDark; + + InitLogFile(title); + + // Top bar + var topBar = new Panel { Dock = DockStyle.Top, Height = 36, BackColor = Theme.BgCard }; + topBar.Paint += (s, e) => e.Graphics.DrawLine(new Pen(Theme.Border), 0, topBar.Height - 1, topBar.Width, topBar.Height - 1); + + btnDisconnect = new Button + { + Text = lang == "en" ? "Disconnect" : "Rozlacz", + Dock = DockStyle.Right, + Width = 105, + FlatStyle = FlatStyle.Flat, + BackColor = Color.FromArgb(160, 45, 45), + ForeColor = Color.White, + Font = new Font("Segoe UI", 9f, FontStyle.Bold), + Cursor = Cursors.Hand + }; + btnDisconnect.FlatAppearance.BorderSize = 0; + btnDisconnect.Click += (s, e) => CloseTab(); + topBar.Controls.Add(btnDisconnect); + + chkAutoScroll = new CheckBox + { + Text = "Auto-scroll", + Dock = DockStyle.Right, + Width = 95, + ForeColor = Theme.TextDim, + Font = new Font("Segoe UI", 8f), + Checked = true, + Padding = new Padding(0, 0, 12, 0) + }; + chkAutoScroll.CheckedChanged += (s, e) => autoScroll = chkAutoScroll.Checked; + topBar.Controls.Add(chkAutoScroll); + + lblTimer = new Label + { + Text = "00:00:00", + Dock = DockStyle.Right, + Width = 70, + ForeColor = Theme.TextDim, + Font = new Font("Consolas", 8f), + TextAlign = ContentAlignment.MiddleCenter + }; + topBar.Controls.Add(lblTimer); + + lblStatus = new Label + { + Text = " ● " + title, + Dock = DockStyle.Fill, + ForeColor = Theme.TextMuted, + Font = new Font("Segoe UI", 9f, FontStyle.Bold), + TextAlign = ContentAlignment.MiddleLeft + }; + topBar.Controls.Add(lblStatus); + this.Controls.Add(topBar); + + // Filter bar + var filterBar = new Panel { Dock = DockStyle.Top, Height = 30, BackColor = Theme.BgPanel }; + filterBar.Paint += (s, e) => e.Graphics.DrawLine(new Pen(Theme.Border), 0, filterBar.Height - 1, filterBar.Width, filterBar.Height - 1); + + btnFilterAll = MakeFilterBtn("All", null, filterBar, 4); + btnFilterChat = MakeFilterBtn("Chat", LineType.Chat, filterBar, 54); + btnFilterSystem = MakeFilterBtn("System", LineType.System, filterBar, 118); + btnFilterError = MakeFilterBtn("Errors", LineType.Error, filterBar, 192); + SetFilterActive(btnFilterAll); + this.Controls.Add(filterBar); + + // Console + boxOutput = new RichTextBox + { + Dock = DockStyle.Fill, + BackColor = Theme.BgDark, + ForeColor = Color.FromArgb(200, 200, 215), + Font = new Font("Consolas", 10f), + BorderStyle = BorderStyle.None, + ReadOnly = true, + ScrollBars = RichTextBoxScrollBars.Vertical + }; + var ctx = new ContextMenuStrip { BackColor = Theme.BgCard, ForeColor = Theme.Text }; + ctx.Items.Add("Disconnect / Close", null, (s, e) => CloseTab()); + ctx.Items.Add("Clear Console", null, (s, e) => { boxOutput.Clear(); lock (logLock) allLines.Clear(); }); + boxOutput.ContextMenuStrip = ctx; + this.Controls.Add(boxOutput); + + try { SetWindowTheme(boxOutput.Handle, "DarkMode_Explorer", null); } catch { } + + timerClock = new System.Windows.Forms.Timer { Interval = 1000 }; + timerClock.Tick += (s, e) => { + if (isConnected && !lblTimer.IsDisposed) + { + var elapsed = DateTime.Now - connectedAt; + lblTimer.Text = elapsed.ToString(@"hh\:mm\:ss"); + } + }; + timerClock.Start(); + + PrintSystem("Initializing...", LineType.System); + if (args.Length == 3) new Thread(() => InitClient(new MinecraftClient(args[0], args[1], args[2]))).Start(); + else new Thread(() => InitClient(new MinecraftClient(args))).Start(); + } + + private void InitLogFile(string title) + { + try + { + string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs"); + Directory.CreateDirectory(dir); + string safeName = string.Concat(title.Split(Path.GetInvalidFileNameChars())); + string date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm"); + string path = Path.Combine(dir, safeName + "_" + date + ".txt"); + logWriter = new StreamWriter(path, append: true, encoding: System.Text.Encoding.UTF8) { AutoFlush = true }; + logWriter.WriteLine("=== Session started: " + DateTime.Now + " | Account: " + title + " ==="); + } + catch { } + } + + private void WriteLog(string text, LineType type) + { + try { logWriter?.WriteLine("[" + DateTime.Now.ToString("HH:mm:ss") + "][" + type + "] " + text); } catch { } + } + + private Button MakeFilterBtn(string label, LineType? type, Panel parent, int x) + { + int w = label == "All" ? 44 : label == "System" ? 68 : 58; + var btn = new Button + { + Text = label, + Location = new Point(x, 4), + Size = new Size(w, 22), + FlatStyle = FlatStyle.Flat, + BackColor = Theme.BgCard, + ForeColor = Theme.TextDim, + Font = new Font("Segoe UI", 8f, FontStyle.Bold), + Cursor = Cursors.Hand + }; + btn.FlatAppearance.BorderSize = 1; + btn.FlatAppearance.BorderColor = Theme.Border; + btn.Click += (s, e) => { activeFilter = type; SetFilterActive(btn); RedrawFiltered(); }; + parent.Controls.Add(btn); + return btn; + } + + private void SetFilterActive(Button active) + { + foreach (var b in new[] { btnFilterAll, btnFilterChat, btnFilterSystem, btnFilterError }) + { + if (b == null) continue; + b.BackColor = b == active ? Theme.Accent : Theme.BgCard; + b.ForeColor = b == active ? Color.White : Theme.TextDim; + } + } + + private void RedrawFiltered() + { + InvokeUI(() => { + boxOutput.Clear(); + List snapshot; + lock (logLock) snapshot = new List(allLines); + foreach (var line in snapshot) + if (activeFilter == null || line.Type == activeFilter) + RenderLine(line); + if (autoScroll) SendMessage(boxOutput.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, IntPtr.Zero); + }); + } + + private void RenderLine(LogLine line) + { + if (line.Type == LineType.System || line.Type == LineType.Error) + { + boxOutput.SelectionColor = line.Type == LineType.Error ? Color.FromArgb(220, 80, 80) : Color.FromArgb(85, 85, 105); + boxOutput.AppendText(line.Display + "\n"); } else { - box.SelectionStart = box.TextLength; - box.SelectionLength = 0; - box.SelectionColor = color; - box.SelectionFont = new Font(box.Font, style); - box.AppendText(text); - box.SelectionColor = box.ForeColor; - box.SelectionStart = box.Text.Length; - box.ScrollToCaret(); - } - } - - /// - /// Properly disconnect the client when clicking the [X] close button - /// - - protected void onClose(object sender, EventArgs e) - { - if (t_clientread != null) { t_clientread.Abort(); } - if (Client != null) { new Thread(new ThreadStart(Client.Close)).Start(); } - } - - /// - /// Allows an Enter keypress in "Login", "Password" or "Server IP" box to be considered as a click on the "Go!" button - /// - /// - /// - - public void loginBox_KeyUp(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.Enter) - { - btn_connect_Click(sender, e); - e.Handled = true; - } - } - - /// - /// Handle special functions in the input box : send with Enter key, command history and tab-complete - /// - /// - /// - - public void inputBox_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.Enter) - { - btn_send_Click(sender, e); - e.Handled = true; - } - else if (e.KeyCode == Keys.Down) - { - if (previous.Count > 0) + string[] subs = line.Raw.Split('\u00a7'); + boxOutput.SelectionColor = Color.FromArgb(200, 200, 215); + if (subs.Length > 0) boxOutput.AppendText(subs[0]); + for (int i = 1; i < subs.Length; i++) { - box_input.Text = previous.First.Value; - previous.AddLast(box_input.Text); - previous.RemoveFirst(); - box_input.Select(box_input.Text.Length, 0); - } - e.Handled = true; - } - else if (e.KeyCode == Keys.Up) - { - if (previous.Count > 0) - { - box_input.Text = previous.Last.Value; - previous.AddFirst(box_input.Text); - previous.RemoveLast(); - box_input.Select(box_input.Text.Length, 0); - } - e.Handled = true; - } - else if (e.KeyCode == Keys.Tab) - { - if (box_input.SelectionStart > 0) - { - string behind_cursor = box_input.Text.Substring(0, box_input.SelectionStart); - string after_cursor = box_input.Text.Substring(box_input.SelectionStart); - string[] behind_temp = behind_cursor.Split(' '); - string autocomplete = Client.tabAutoComplete(behind_temp[behind_temp.Length - 1]); - if (!String.IsNullOrEmpty(autocomplete)) + if (subs[i].Length > 1) { - behind_temp[behind_temp.Length - 1] = autocomplete; - behind_cursor = String.Join(" ", behind_temp); - box_input.Text = behind_cursor + after_cursor; - box_input.SelectionStart = behind_cursor.Length; + boxOutput.SelectionColor = GetColor(subs[i][0]); + boxOutput.SelectionFont = GetFont(subs[i][0], boxOutput.Font); + boxOutput.AppendText(subs[i].Substring(1)); } } - e.SuppressKeyPress = true; - e.Handled = true; + boxOutput.AppendText("\n"); } } - /// - /// Send the input in the input box, if any, by pressing the "Send" button. - /// Handle "/quit" command to properly disconnect and close the GUI. - /// + public void UpdateLang(string lang) { if (btnDisconnect != null) btnDisconnect.Text = lang == "en" ? "Disconnect" : "Rozlacz"; } - private void btn_send_Click(object sender, EventArgs e) + private void InitClient(MinecraftClient client) { - if (Client != null) + Client = client; + t_read = new Thread(ReadLoop) { IsBackground = true }; + t_read.Start(); + connectedAt = DateTime.Now; + isConnected = true; + InvokeUI(() => { + lblStatus.Text = " ● " + TabTitle; + lblStatus.ForeColor = Color.FromArgb(100, 210, 130); + PrintSystem("Connected.", LineType.System); + }); + } + + private void ReadLoop() + { + try { - if (box_input.Text.Trim().ToLower() == "/quit") + while (Client != null && !Client.Disconnected) { - Close(); - } - else - { - Client.SendText(box_input.Text); - previous.AddLast(box_input.Text); - box_input.Text = ""; + string line = Client.ReadLine(); + if (!string.IsNullOrEmpty(line)) PrintChat(line); } } - } - - /// - /// Draw text on glass pane without ClearType, only black pixels - /// - - protected override void OnPaint(PaintEventArgs e) - { - e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; - e.Graphics.DrawString("Login Details", this.Font, Brushes.Black, 20, 11); - e.Graphics.DrawString("Username:", this.Font, Brushes.Black, 20, 31); - e.Graphics.DrawString("Password:", this.Font, Brushes.Black, 191, 31); - e.Graphics.DrawString("Server IP:", this.Font, Brushes.Black, 355, 31); - } - - /// - /// Show the "About" message box, open the official topic in an internet browser if the user press OK. - /// - - private void btn_about_Click(object sender, EventArgs e) - { - if (MessageBox.Show("MCC GUI version 1.0 - (c) 2013 ORelio\nAllows to send commands to any Minecraft server\nand receive text messages in a fast and easy way.\n\nPress OK to visit the official topic on Minecraft Forums.", - "About Minecraft Console Client", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK) + catch (ThreadAbortException) { - System.Diagnostics.Process.Start("http://www.minecraftforum.net/topic/1314800-/"); + } + catch (Exception ex) { InvokeUI(() => PrintSystem("Error: " + ex.Message, LineType.Error)); } + finally + { + isConnected = false; + InvokeUI(() => { + PrintSystem("Disconnected.", LineType.Error); + if (lblStatus != null) { lblStatus.Text = " ● " + TabTitle; lblStatus.ForeColor = Color.FromArgb(220, 80, 80); } + }); } } - /// - /// Open a link located in the console window - /// - - private void LinkClicked(object sender, LinkClickedEventArgs e) + public void Send(string text) { - try { System.Diagnostics.Process.Start(e.LinkText); } - catch (Exception ex) { MessageBox.Show("An error occured while opening the link :\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } + if (Client != null && !Client.Disconnected) + { + Client.SendText(text); + InvokeUI(() => PrintSystem("> " + text, LineType.System, Color.FromArgb(100, 180, 255))); + } + } + + public void CloseTab() + { + try + { + isConnected = false; + timerClock?.Stop(); + logWriter?.WriteLine("=== Session ended: " + DateTime.Now + " ==="); + logWriter?.Close(); + if (Client != null) { Client.Close(); Client = null; } + if (t_read != null && t_read.IsAlive) { t_read.Abort(); t_read = null; } + } + catch { } + } + + private void PrintSystem(string text, LineType type, Color? color = null) + { + string prefix = type == LineType.Error ? "[ERR] " : "[SYS] "; + Color c = color ?? (type == LineType.Error ? Color.FromArgb(220, 80, 80) : Color.FromArgb(85, 85, 105)); + var entry = new LogLine { Raw = prefix + text, Display = prefix + text, Type = type, Time = DateTime.Now }; + lock (logLock) allLines.Add(entry); + WriteLog(text, type); + InvokeUI(() => { + if (activeFilter == null || activeFilter == type) + { + boxOutput.SelectionColor = c; + boxOutput.AppendText(entry.Display + "\n"); + if (autoScroll) SendMessage(boxOutput.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, IntPtr.Zero); + } + }); + } + + private void PrintChat(string raw) + { + string plain = System.Text.RegularExpressions.Regex.Replace(raw, @"§.", ""); + var entry = new LogLine { Raw = raw, Display = plain, Type = LineType.Chat, Time = DateTime.Now }; + lock (logLock) allLines.Add(entry); + WriteLog(plain, LineType.Chat); + InvokeUI(() => { + if (activeFilter == null || activeFilter == LineType.Chat) + { + boxOutput.SuspendLayout(); + RenderLine(entry); + if (autoScroll) SendMessage(boxOutput.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, IntPtr.Zero); + boxOutput.ResumeLayout(); + } + }); + } + + private void InvokeUI(Action a) { if (!boxOutput.IsDisposed) { if (boxOutput.InvokeRequired) try { boxOutput.Invoke(a); } catch { } else a(); } } + private Font GetFont(char c, Font f) => c == 'l' ? new Font(f, FontStyle.Bold) : f; + private Color GetColor(char c) + { + switch (c) + { + case '0': return Color.FromArgb(20, 20, 20); + case '1': return Color.FromArgb(85, 85, 255); + case '2': return Color.FromArgb(85, 200, 85); + case '3': return Color.FromArgb(85, 220, 220); + case '4': return Color.FromArgb(220, 85, 85); + case '5': return Color.FromArgb(200, 85, 200); + case '6': return Color.FromArgb(255, 180, 30); + case '7': return Color.Silver; + case '8': return Color.FromArgb(120, 120, 140); + case '9': return Color.FromArgb(100, 130, 255); + case 'a': return Color.FromArgb(85, 255, 85); + case 'b': return Color.FromArgb(85, 255, 255); + case 'c': return Color.FromArgb(255, 85, 85); + case 'd': return Color.FromArgb(255, 130, 255); + case 'e': return Color.FromArgb(255, 255, 85); + case 'f': return Color.White; + default: return Color.FromArgb(200, 200, 215); + } } } } diff --git a/MinecraftClientGUI/MinecraftClient.cs b/MinecraftClientGUI/MinecraftClient.cs index abf9b4ef..fb070136 100644 --- a/MinecraftClientGUI/MinecraftClient.cs +++ b/MinecraftClientGUI/MinecraftClient.cs @@ -24,33 +24,18 @@ namespace MinecraftClientGUI private Process Client; private Thread Reader; - /// - /// Start a client using command-line arguments - /// - /// Arguments to pass - public MinecraftClient(string[] args) { initClient("\"" + String.Join("\" \"", args) + "\" BasicIO"); } - /// - /// Start the client using username, password and server IP - /// - /// Username or email - /// Password for the given username - /// Server IP to join - public MinecraftClient(string username, string password, string serverip) { + // If the password is empty, pass an empty string to support Microsoft/Browser login + if (password == null) password = ""; initClient('"' + username + "\" \"" + password + "\" \"" + serverip + "\" BasicIO"); } - /// - /// Inner function for launching the external console application - /// - /// Arguments to pass - private void initClient(string arguments) { if (File.Exists(ExePath)) @@ -59,7 +44,10 @@ namespace MinecraftClientGUI Client.StartInfo.FileName = ExePath; Client.StartInfo.Arguments = arguments; Client.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; - Client.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage); + + // FIX: Forcing UTF-8 fixes Polish characters and colors + Client.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; + Client.StartInfo.UseShellExecute = false; Client.StartInfo.RedirectStandardOutput = true; Client.StartInfo.RedirectStandardInput = true; @@ -69,66 +57,58 @@ namespace MinecraftClientGUI Reader = new Thread(new ThreadStart(t_reader)); Reader.Start(); } - else throw new FileNotFoundException("Cannot find Minecraft Client Executable!", ExePath); + else throw new FileNotFoundException("Nie znaleziono pliku MinecraftClient.exe!", ExePath); } - /// - /// Thread for reading output and app messages from the console - /// - private void t_reader() { while (true) { try { - string line = ""; - while (line.Trim() == "") + if (Client.HasExited) { disconnected = true; break; } + + string line = Client.StandardOutput.ReadLine(); + if (line != null) { - line = Client.StandardOutput.ReadLine() + Client.MainWindowTitle; - if (line.Length > 0) + if (line.Trim() != "") { - if (line == "Server was successfuly joined.") { disconnected = false; } - if (line == "You have left the server.") { disconnected = true; } - if (line[0] == (char)0x00) + if (line.Contains("Server was successfuly joined")) { disconnected = false; } + if (line.Contains("You have left the server")) { disconnected = true; } + + if (line.Length > 0 && line[0] == (char)0x00) { - //App message from the console string[] command = line.Substring(1).Split((char)0x00); - switch (command[0].ToLower()) + if (command[0].ToLower() == "autocomplete") { - case "autocomplete": - if (command.Length > 1) { tabAutoCompleteBuffer.AddLast(command[1]); } - else tabAutoCompleteBuffer.AddLast(""); - break; + if (command.Length > 1) { tabAutoCompleteBuffer.AddLast(command[1]); } + else tabAutoCompleteBuffer.AddLast(""); } } - else OutputBuffer.AddLast(line); + else + { + OutputBuffer.AddLast(line); + } } } + else { Thread.Sleep(10); } // Small pause to avoid overloading the CPU } - catch (NullReferenceException) { break; } + catch (Exception) { break; } } } - /// - /// Get the first queuing output line to print - /// - /// - public string ReadLine() { - while (OutputBuffer.Count < 1) { } + while (OutputBuffer.Count < 1) + { + if (disconnected) return ""; + Thread.Sleep(10); // Save CPU while waiting for data + } string line = OutputBuffer.First.Value; OutputBuffer.RemoveFirst(); return line; } - /// - /// Complete a playername or a command, usually by pressing the TAB key - /// - /// Text to complete - /// Returns an autocompletion for the provided text - public string tabAutoComplete(string text_behindcursor) { tabAutoCompleteBuffer.Clear(); @@ -136,7 +116,12 @@ namespace MinecraftClientGUI { text_behindcursor = text_behindcursor.Trim(); SendText((char)0x00 + "autocomplete" + (char)0x00 + text_behindcursor); - int maxwait = 30; while (tabAutoCompleteBuffer.Count < 1 && maxwait > 0) { Thread.Sleep(100); maxwait--; } + int maxwait = 30; + while (tabAutoCompleteBuffer.Count < 1 && maxwait > 0) + { + Thread.Sleep(100); + maxwait--; + } if (tabAutoCompleteBuffer.Count > 0) { string text_completed = tabAutoCompleteBuffer.First.Value; @@ -148,14 +133,9 @@ namespace MinecraftClientGUI else return ""; } - /// - /// Send a message or a command to the server - /// - /// Text to send - public void SendText(string text) { - if (text != null) + if (text != null && !Client.HasExited) { text = text.Replace("\t", ""); text = text.Replace("\r", ""); @@ -168,17 +148,16 @@ namespace MinecraftClientGUI } } - /// - /// Properly disconnect from the server and dispose the client - /// - public void Close() { - Client.StandardInput.WriteLine("/quit"); - if (Reader.IsAlive) { Reader.Abort(); } - if (!Client.WaitForExit(3000)) + if (!Client.HasExited) { - try { Client.Kill(); } catch { } + Client.StandardInput.WriteLine("/quit"); + if (Reader.IsAlive) { Reader.Abort(); } + if (!Client.WaitForExit(2000)) + { + try { Client.Kill(); } catch { } + } } } } diff --git a/MinecraftClientGUI/MinecraftClientGUI.csproj b/MinecraftClientGUI/MinecraftClientGUI.csproj index ce8642c4..1066164e 100644 --- a/MinecraftClientGUI/MinecraftClientGUI.csproj +++ b/MinecraftClientGUI/MinecraftClientGUI.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,9 +10,26 @@ Properties MinecraftClientGUI MinecraftClientGUI - v4.0 - Client + v4.8 + + 512 + false + C:\Users\Admin\Desktop\publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 3 + 1.0.0.%2a + false + true + true x86 @@ -23,6 +40,7 @@ DEBUG;TRACE prompt 4 + false x86 @@ -32,10 +50,23 @@ TRACE prompt 4 + false AppIcon.ico + + 4C76A63F11DB91E010AF3039521927BEB537A320 + + + MinecraftClientGUI_TemporaryKey.pfx + + + true + + + true + @@ -69,7 +100,10 @@ True Resources.resx + True + + SettingsSingleFileGenerator Settings.Designer.cs @@ -83,6 +117,18 @@ + + + False + Microsoft .NET Framework 4.8 %28x86 i x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + - \ No newline at end of file + diff --git a/MinecraftClientGUI/Program.cs b/MinecraftClientGUI/Program.cs index 45876950..dd080198 100644 --- a/MinecraftClientGUI/Program.cs +++ b/MinecraftClientGUI/Program.cs @@ -1,12 +1,13 @@ using System; -using System.Collections.Generic; -using System.Linq; +using System.Diagnostics; using System.Windows.Forms; namespace MinecraftClientGUI { static class Program { + private const string ReleasesUrl = "https://github.com/MCCTeam/Minecraft-Console-Client/releases"; + /// /// Minecraft Console Client GUI by ORelio (c) 2013. /// Allows to use Minecraft Console Client in a more user friendly interface @@ -18,7 +19,26 @@ namespace MinecraftClientGUI { if (!System.IO.File.Exists(MinecraftClient.ExePath)) { - MessageBox.Show("File not found: " + MinecraftClient.ExePath, "Minecraft client not found", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult result = MessageBox.Show( + "File not found: " + MinecraftClient.ExePath + Environment.NewLine + Environment.NewLine + + "Place MinecraftClient.exe in the same folder as MinecraftClientGUI.exe." + Environment.NewLine + Environment.NewLine + + "Download MinecraftClient.exe from:" + Environment.NewLine + + ReleasesUrl + Environment.NewLine + Environment.NewLine + + "Open the releases page now?", + "Minecraft client not found", + MessageBoxButtons.YesNo, + MessageBoxIcon.Error); + + if (result == DialogResult.Yes) + { + try + { + Process.Start(new ProcessStartInfo(ReleasesUrl) { UseShellExecute = true }); + } + catch + { + } + } } else { diff --git a/MinecraftClientGUI/Properties/Resources.Designer.cs b/MinecraftClientGUI/Properties/Resources.Designer.cs index 9b33fcd6..a32a90af 100644 --- a/MinecraftClientGUI/Properties/Resources.Designer.cs +++ b/MinecraftClientGUI/Properties/Resources.Designer.cs @@ -1,17 +1,17 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18046 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace MinecraftClientGUI.Properties -{ - - +namespace MinecraftClientGUI.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,51 +19,43 @@ namespace MinecraftClientGUI.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftClientGUI.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } diff --git a/MinecraftClientGUI/Properties/Settings.Designer.cs b/MinecraftClientGUI/Properties/Settings.Designer.cs index 52f889e8..e41b8583 100644 --- a/MinecraftClientGUI/Properties/Settings.Designer.cs +++ b/MinecraftClientGUI/Properties/Settings.Designer.cs @@ -1,28 +1,24 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18046 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace MinecraftClientGUI.Properties -{ - - +namespace MinecraftClientGUI.Properties { + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { + + public static Settings Default { + get { return defaultInstance; } } diff --git a/MinecraftClientGUI/app.config b/MinecraftClientGUI/app.config new file mode 100644 index 00000000..3e0e37cf --- /dev/null +++ b/MinecraftClientGUI/app.config @@ -0,0 +1,3 @@ + + + diff --git a/MinecraftClientGUI/screenshot.png b/MinecraftClientGUI/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6684c44336b2da8f5e7c2c3836240be1482f1494 GIT binary patch literal 49804 zcmdSB2UJtp_dgm7Dk9*Bii&`hBGp1KQLqeB2c$`f2myfr(xoIpL75Q+mC&0}0jZ&P z63ZYEN)Ut)s)`{%2!TKX>F?sqe1GNpTfg^T>%Fz!dUvg?Bsce-yU#xR?DP5Ty-)tI zvAQO{`^at(2qbRy>t$OINCXN3Z42ME12`jnAS(%Y+Y)Mf%>-20e{>%BvfbyB)PnZFp=UWy- zcK?1c?yhLYBc)?{Z{xHsQQs%OEcDgIUnxEP%SrKJyAyLSN0Ty!Mh_TcuG13gHhw(TpgZIn(Dmyo#vR4=*7(E z{Xnf6FV|4g`iZoIG7pDzW~*MdzO&UmyD^rey-f839`vZ$*9pNq|m1eA?=}*TWVR{8v#!-!@=mkT|l=l^{Aw*q=4I_^f zA6zH%Y~#}bCI)W!rJ>aEOe5t+9!8In@#%Y4Pb{H{QcsUcj>g*!PEU7pJ9y{$Y_r+O z2nFTU;i1m3=7TC2{YnJn(0OZwpV?gQ-PZdEIK}HaQIES`pdQ&X5i`GgDk$8dptxgf zt^PNCFhiA-{4lwdb`ZZtAL`O#y7wGG$_KOarw4J=+5-5x{soDQ${7Re49ZqQHh0^>XccW z?I{o1#Hw%z+}|jzQ0&=RKKGO1W7`~7`lqpVeuK#x&(nlCF|(vQQN1Aue1>26fs5~Lt`yrBJrS*n6~H?e&ai^-_ZoK8 zd44*ZdKT;>RBwH$iw*4uL;7#FIyh9gt6eh|1T#*y3sr?Hoe0(H507dT%k{71hkUzI zvlVV{J4hm4FbsX_SCAk-*9LnR|Ku{$a_Eoa-58|f4gB}@Z0=_xw9|Zr@}jBYd*x5 zII=bFfZ`$sa1-Hrae+g)ZRsxnSuCf)Adse#Y_?VQl01#6xIS@G1tTd8lG%X#e9l;;EUO$yuxvM?S)-Z|Z3hgj~Leg@uPo@@&TfnE>dx`1vi z4bp{$MV*O-g>*>}$jMLtvaHS|#BO5E9Cr%LI0-(X;!wWK`6e&$Xr3MOCw~q?w%&+T z&f~sWg%aq3%2*0gK(NiKrdtaxj~K5UWq*S3?Mq;XPCl%G+#}4?YO;(N@j-$j-mR51 zM*L2QDjms8iKaGL8MF6CeNIB6!zP-3947qQ)alM`fhbSB(}1(@w=Lo(qkPbdDS{>* z89M9qwzm$7w=ih2I6o7?jc5+YEC^@o4rhhB{8_0CG8b+ol0jqEI6}te==`*lf&G7X z<7oJo-^}8CKlCKxm=!NH5bPet3|KJJjV*0ivOVW%9KiG=@!w0PKOi}gs{9gbj0>VV zXI`XLgYV59WDDYP$EJnf$qYWhO^F`cfh<3OU${G5wWUM`pS|pmSf@Rp<_r4B=!Z3yiW}Q(Tb*L%*|57`->zUeQL&mS{n;%V_KT2ac$xlsbHmtAKyqzTEY)Y4+l@RGg_np5! z3g$eO&ye@>SX>wIPOzuoKHcla@Z2^wRETy^@_%qyO0%W2&tE4&%cE4|S1pTY#UH!( zjwfq?>O4h7$~hB-d!Rc3#ceE!f-(f;ik>ZXIfxVut$!x^OYyKKeTkNo!ogXak-Mg& zDTwbkCCN1c{^x4OzMJQ~#wmmO-D|48f1r3CK$if!2PN^g47_?_B$ z@OWBd!vt-pa>odCwjdA`Fg6rQoLN81gpEgcR2wL)*0!o8$hNjSL?qApMD_*>(b&aN zc=%!|^yAt$cb&%Gs_@13+L@8i9WCaWgV5t--$|wBoUV8P(-T*u#@`zyJQ>d;K#E zn0L2?UudG_VhvbLvb~Y>L~LH{H)ZP=<0(chb-41Bz)t8k3!ONo?9lsSmHn=qjj=V^ z^WYQ}R5-WMGn`vzA*26pm@*f!7Tj3L9TV4Q-kS`a44yx`5WQp=@YauAnaaIMu+Nx> zoQYWElWk;hb>A2^C=9I5w=m$M$`BQc)SnV&2)JFkbH?c=RqBJK*?2TH& z;}1dR<{mvA+64{Y3(J}b95^BdEt@UpYRyy!%&#OL!7s!}wOF+zOQd<;ufPPn zyGh(Sx(2z`S;2E>DW{Yj#&62izVewUI#f&-1zh*qbil$uz!UQvz_(^Zvwu#tkz%2nceZEC?6isiH^5%g!RuhO<~_*M*@;hqU!md0NstDTKU=9i}jz0-B*;7 z$fm+qfQgQo;Tm&zf{~e{X@NNLwWDMDDV3ksw}U`UVRJXH5alyoC+lBdVy_jGTZJ1b zh3958q@`28vZ&%>P|t7vXYCxd>5PI{l49a+D9xW+D3&m(Kyz{yFaq?Ew%Y} zsP;@%=VaW?#IlHqPnziRfRDesDe}i2El0!#W{LZ%#iZJ-I5(@3=QdbxjQP)JqCz)D*2ZC3(z6fI!BajM_~Z=cbkaalfj3`6^Hx*-Xeq zo3FXHUL;ie`aP@x#hHD^W&WquGgaaI>iuiTJzGI7SA?ZUg{IIfcBQTaYN%J7RE+EueRrVZZ8}nKZuo8bfcI7brXh z^ar{n`jn#afE;nwl7mQ?i*_rfNP;fb&OZyh(E@*R6*3(>#J4|8z-s zr6Qj(nthQ_;g4TOS2F4sw2c5Lm~AfPB94a1AIirzq`u_lo&t0NirX@eYkL|mFu!R; zuGYGr?;@Q>zamTauQ!~d0w{2O4yW=3J^pTatv+x2B<1Zc=oS!Y#~a}T?Optgvy&0m z3uazZFC^xN<_xzkagNHn`80nfZUe=gcIp)+YAs77%Y}2Mc9jN_=l$`gRbzTKq zbM!*;`GdL>>jnDjr4@!5ZfOZM3d?J#ET6Bl0(!L+!;|GqI^#Hb%UJE!$DxXlRiHnY7}5ff*ZbfXx>d!3sR0RYxpD52`_+g0a_J{znW+Wy;8v%XWv*1oTgO&TSO zpPstY#i>S{)*<^)4>{CCAO6{4s)1pk35kr}$T$07PxphZlLiRZY^TBGRrls^j~vPL z(>hgZ35~OC+b!iXJ2Lvo&5Pyrgk~)^JUy{2D+v>A7qQsQ$j!*)25qxjg&Cd}y=gg_ zQ#&x68hM+D6-jFMYEx+iaWdq(cYw)Tu!g!Paly z^F9#aW6_4(I6N3Purff1PnMZ{T>w^eWg5$1*Pl@`r38xHV-Q&5)PQj2hA1%K7qJqF%ZbSE{dKP@7>D(95z%d!R!px~(cKo_uG7Bek%MhcB}U zpOcEBA!5h)PT`tfAxH@(UGtK|@(d~36+3gkV5h8(ycGTAyH%-JZPjT9nGVm{c1obj zv&BDR?Snfaea#=-x>Yu%2!m8vGy$;9g**Ps8bNtyQMZE#sWv^|1s7OdegdTh+2~;X z6e3RIus*5}e4WPCjo7#5)oCtYKSH6}D6z%@i0rMe2KBH7ru=m_?rV?iwH421-@6AE ztc8Z}nnZE>zk-QND+9IYX;Z8xpC-xham0;;$I~%SxW?a-uq|cF+yTCACCvXptjty} z^j7}6FN;jSe93jElE70i%e{DjRDwY11;3b(Dy!v%Bb`478*py1KYhyPkGCHG_m4%3 zQ5beUua~yiy)!;$J20 zg5LiIT&(ix2;QA%;k;g~@ghkA>(n3fZ9e3~ANirBZC^v0mkI8t&SUf)t#rHXBs%p% zSUZvK>Mit+ZY|v0*HtL((GWR7YAp(A*Z<$zJ&ez+y0%9dfwWZrY8+pv?y9NUEIVu>=(4ErXld&v0*|A^`gkIyPOV+iDlPw2}EPT zn>j*|abTL^%3NAuaLU4Wq8zHD;~IAP4$gnu>Uyd$+<(Ip%r!B=#dn{5+!>O zt(slLM8htr-g}xheAbVDCUrNoHUb$kLHlqFb;a?C3d*ukz3ahf*_VUc^)12|(j4$D zAKOx-Dl9SBYz&G*tjcG z-DssI(}Qif?NA?gS$!bz64w0=UEVs#^z6)Y-F<$1$zV&11@WwqH?X3ZA&4iGKWnGd zXRLiBbzCFo$JBT#WDa}KZtTTNB-tFaG*xmTzGar}#W(zdUW}V!STlSi3y~S@u9zzb zR(O7BpmfxHqR>GC`~ysR)V5e{>pa!zF@EjqQPdMfR9}PoUB`BPz{HyMCjCbmtzp27 zRCdwIt_uwu>0JHMo9dY1P%#^ehWV1q-1?~H5qCz70(<>W$mQEYwtL+7xg~6Wvcz1r26uGQ3ZClT!xx43Y6m7G1TZ%C%^%$cj)|RCr z1%1}Sa;duPW7=-wVxh+7*f3q_rOhjiEO-F z6)?_P4cN!1Zn^|hMbQ#F8{~}|KCEo%Y(N1J`^v|}nw+7p%of1BCE+S?%#>h{9_Nmo z!yYK6ebt3wBQSs_9fhx*W@KB#&6ir1nihF8Ki>LB_Lvq##~b!x`xhpeA7&qktaUXd3Z!>7n!MjE0#E-9cnL1zmA|F#d_5C|CgDTf}Wyuf*DGqH~stoGR zBkFmEZW~U5XcV-C)*AM^s;q`ijl5>K+fypn>xMVCM(1|M3 z==MttEs*VHyu$%+wHv*746BG+6&jzBgbP|3&j~q5L28@o-s=+bc!V{A5?Y!9`K9^8 zP^WD(KOdL;1Udf%V5n&SeX-u}Z+&yRQxyZyJfyP>P?eqdg#P*Ah8Hm$a(UE0uY zMDV6ICE)l`V>c_(()MQb*|e>*i}&*2p0!`=_trTi)S&n3I&blJ6vZt!3ut0r(swU~ z{~VLMO8&e_(c+8`-S;~_5Yk0zqhvezW!7ffdb|q#g0C!gU?x*VvipOj!VY42DhFRV zwDmvujKYY!fm0JI@p|+y; zrOy0P6KAPPZxv!M9c6e3ekY}Ed2Z3C{<^lugQ>+0F?ySZ+iwMJ+V2acupATT;=r+d z3D{(HS#&?%q4k`$q)vdWQ3G`<6N{KQ|3jfRzVL*M=W)-5@cYi~ zoEos^`-N$IYb0x%UF3lZsHt-#(;wF><>&1py`OWhtcy?@GJX~Nf~6)rg)B{04DEKP zf0R5<^p0gO5L;{X3xqDsgyi*A;VB)#b?~!3N^nqzR?e%>rljwsqlSCy?|XbTZ|11D z)-HbzGh1%WNMhiS!D zN-mkgag7(}r#Y|QOym(n*>dgq6$b?t0n@jrO+)}sh4tH@%h@Sxdj7APF0UStE*D3Cmjk3r={1%60!Ka`W{3huheGbcaa(v7|V<~nP78pNb{yr4uUs@xPX(#mImyG z>E0au{;pDc@?>O|kUg{Gjn!z*_QviE8CIiO(`uy=n|ezr=V9(Qn%Gu!x%jn7BX4uc zo6Z;2(D8$B;IRtwE=cpO?eP0k3h1L%*ya9fKkP8|Wzfmh58<4dkusPlRI%g?O3Ol1 zX15m&Cp~r;?>+uYQ(3LlbQ(l0;P75uo$(J}!vlA5TfVbIa4#|nk9*(aK7diTLgbxw z{TAlo-T^V}Goy?5lnv{@RfzgdyPQOYe{fx&ux%}*wp{oN$@;vp8QC5%-H-jcySO{j z3i*J?&$8}Lalj37hyO{pDMxbd*Y8M1V62WhIdyQwd{D(3T8wTD-@3F!WuvahiQdROP|HT%Q8XOi z-el;qiMnL6v-lD&$Q9}77=5SCC=0vJW(^+hJd=zxKuDP?K=mSY@sn{E~w*O0DuSljX6M7!3bRq)n$r z>bsnt07w}vrQ`&PpEWMLf)L(yXtaZ@0iBBTJ&CI53l!5VN%?LtF7d_LEa^VLMv~GM zQ1vcHMvdIV^#&w>uI>IA?O`29b<|u^N>V>!j1sx1lvMebl=3FdsxrVuCrq4g-TU{8 z0S5Kx+W*PL)%yXqAr5e{<0uh;%zZupgvWrK;CUOR9)Ok=Bb3B0JQe-P-JS>~0fO=~ zYITwOMPifsYsw|m98&y8OrUF-=S-ZRNNonTE^>eJM~lN~)lYx?!@m9@kpIRSfk*xi zT=M^mvktjYvm!r6X_6|NlKX%w*W*ACm{q_x{1AE9RZ18~a+$H(`3Q z4Z_&YZvX2u9bt2npOL`U0Z!WW1Y6sA^!vp zu~=$rkhw>;ba-VUm5BGT(lr$b5{6Uj8Fh?mn=E)9f0e3YoiTkPH&34*`%~{NXan>j zmrO&lF$^T~*h4UqGZKjxAq-O-?#=uB=n-;b7~9yDv0rDW)58fXxpwoOjA|rDhpqDq zyS5Q)mv1aMJc*=!XO@#i9GKPO~uA9W=^V8MnIVG!I2^GdIz1V(%@26Eo#XS4$ zk4hHDDjb(?CcOJOeLw^Dle?f`1$iL_DV3_W0QMAv(yD{t?g#;8N`W$`f7jZW-U zEDtw`aKBMj@C*QMg3(*)HVq1q;ib;-mbn$j&H{yLchb6!igntx;j=R?Dt+wY9}=?2 zQeMYOahG%o*xney>n7U-JlW-~Xr1VH7NZ{(5FK>m7)Ms>P4v=q7wlpVZ&4HqhqCHJ zdE+XMJw8^3ulK*=G?)x@P886MSDpaDE2*tQoMQfS;#rDD<4XrHWYc`(0_QF(aXCB5 z^1{=W@~L}SjKvKMSVD>>(wdZAr zzykks3Q`~3+g2(PYQi%wj#OIlt>gmJww=--G%MV}k2`Ng2J?IYBdIQY|7OlcZB~r} zyIvqlfcx!{*;_^-8F$_+L0GorIl177bGKL~S(XK<(ohciLxvaTpdt2L(#zb??& zl=Y%c7!V%gF^q&Kgp`;QlE{rnvNCuzJq$_%7pnO8RTpP_;sh^wA91meAE5=PBzFOL zw+a-(pRdDmDc>Z8?l%eIFfnMsT@%uDYAe>yu>#>}T*YsMPD061z0<22z84pGX5;7X zmlpFv3oIVkPg>!n@%k#BmUFH10X2Cx4P%|jcH<&*05oq(k3TJ=&PF7EzVyWjiXQVx z0jJ%K=nZ>&Fnr#MO;rTD2@vE%4a%9?gjL9a(MMC;(Au8DZ8JtsCA@XIu7H_G^>l>A z>KN<)JPw0|u5D(&XY+q6bH?18hDbX$kAbwsv^6-S#@Y9N`v#}NAT*nX{itXY5~Bdq zjd5p3M7_wq)>I*x(0HQj!!YCVO^8y@b<+J&H8F|Sn5OKiE-5+kLV8DkXcPK|Qtm=Z zpFAuorNp>*L@Yw)5vJ169^1q~4Z1gkXK5VCiQ)ZGNNsinhG}6iFNFU6H6xOeJC1V< zC|s|sc=4qqST#y=zp4AU&+B;SS`$`rzJ_!jRaqtuf!!P)(B!}$KyurmXBJuWu3ml& zVTmB)8+&raeQRx2DagQ-w$*3s7gaDxQbyW3iWvyG#mds+;to3WBP^x_Sht#faVSlf zp{d(;bEFmiUcBHrw-zB-3?Mn|!g@YzxE+H>I7S2r1G1W*7(v@%hg>)&YC0Df53hOG zd%jf#`z+rYF~TvD3QTC6WRX!&`4?84wtS53{FwIp&({i$Qw(WrMqOzCuaJTjRdz|S zo2sI$n{nhJ{ToSm6Hz&RTpeW@Yhf%P%;#4}q?JxOvaF{$W+b78 zPyxbSrsKuH8#-ohImPmVwpbbjrwG35FcP7R3SUPJ?}Bc_zKnkbODpC6vS6!}z0+E7 z%dC;YZ%%IEFL=t$IQ`;MSpB}-`8d~(kdbvB4}Cp=zKPlm)qwL0dLWRfyx16~b2k-d zFke2%bPdGHMj_n#Ncfi>=T8%vzHStmydS-ErwT)*xc=qW!w3!xqR<*U9Tj{!jPg<=|`Q$r{M-u1K3w z(k-QfuNFdM0~S~(1D1@~URi*zAfL79mUrJMA9+~ANy1v`Q=-h*uRwYR-Z%&r5G^ME za%@+X#1eq^ZVLHLc3whYLF-I5Z(kU-C)31lC@qX=g8M8lYzv44Z|i10Ra3=$kJKGE+SKBASX_FxwbMW zFT#SISv@COxdS?`&*@bmpVnx$?LRuSdys6B==V-(Z54p8Akf?nAn@+?+Jxk5=CCsI zl6u%1H|&G+y3`Pas}FaPx^Q1&IPSOq@-XOO{O$QU8}UOA|M7U6ApIn&jS4eakc8hTs#&#f&9X`6t5^U%EVSDXLK$3h#2pz?{ZXkI{GXVqF; z#yF2UNc3rTQ#9HvV+0OW*&rqE`9^b@C$s2IQ&7VXC zRFjQ`E$Q6w$9+I`&E_$5O=>~By}3kG)&}z7n}>xw z8kVHC&L-ARVC-OD!gdL{{EM?|?1f-DRU;$STDK%DKVr>35-%-x&uIzH z4~?hD!@p5~yoPWd9mTHqh0K@Qk(~&79jieZ;0qKD<1_O2x~;oPXL=|%^f;yKT@+ky zG8HAopD~H~1>Z3GU;A-U+LbwuRF*t?Zp)l=$lwb9W%$ar@gHAOt<>}A*_V}KzEvPk zK=50?pSmGl=Q4Lv%maMa^vL&p_z0PQm%q+!U*?ohT(5lV=!LiZ@-_r(kKVV@koHS^ z_HE9%9nDNh`4>Cs>}RoG^ApJfMnUQ3*2Zc#JDV0{6Myt5IQ5%2yCnx6Mk;Zwo?kn~ zUj?)DJJmt?TPYcqnYlUu`0ItFj{-7`xC}hiiYEP@S6+iWX#U14dbXaFptr z;(BL=JN$Xj0UtP}26+s7`Yh1xnMgGed(F6@KA=If3&_p%s#WF>t3W4dVpfRHF+lQQ zn@+cHnN_-2kXhq3O-g=Po;Y;q7|XY4QNx0Cq**Wtd9ESPDR28WSo`D8UmV3e+dj$R z1u3de_yg00@2NQf&f_M|vKB2crI`5I$0Iw!oSj$hHTYcs3(m34CTI65Xdzqmn{*=$ zb{eo2nc~E*WDmlw@|hd!oyoN!gW^YD*g9lF-`WxAz0~Fe=0(49eV7)5?5z@C+K;aX3hcnotqZ0h4QM zP(@kBn?x!k5`jEoNgMpqISm=jaZvsDa1TUvjjb^LkG~v6T!R?AB%`%>5%0fK3>y9}C$T1} zAT5RtzbqjyfO(id5JYvPRi%KV<0oDu)XlRq+FEcx4TOxrA2tnjwD;`>KS)}v#*QCP zwNUU?$H6M5DLsspUhi_KP8B7-qvFvR_GMd5-J!8UO1%=wa=)YBg66Qe_#`}%tD>K@ zIvlgAVDZ*%*U8D@Ml4l7cLh@XuKi0{*)Y|1V8Qs>R47wR*6JUZbYEbr5lMaERp4}B zqKE>%xf|*al;xG{;5$>}Sf-2@cGej)dBJahptR$MmQE||56Ad%=_Z$bb2cM^kY{x< z-_3x?{#G>X9HO;R6%F%zqJ^?-P+#VmHE7;(Rw^^CdGM=}KQbb|A>vWZ;Z{FwnMU!l zpaIBta%E+>V|!_I;j_4VhNM3DerD{HtJeK0HzO+h6~^ld^|QtTQkkd;StE-=8`~&V zt0K1x(sT@S+MzkOfi&O2I^&R+$lgGYXGi^kT(|M{pcFO$bj2lymOt}1+JSWFyXuMQ zuL@eiP>mR8uI zF*~t}f1r+Ic&p@z8mb<$mD!Te{o-yz9)JF8QIc^{YTbX^W9Y7j zORH)hZ|Gvk7r0fiuWzMY=zm=F|NhDa$}|pA8dvyV7Suf3f9kC+kPiD8I`=e>ttPHkG=mSfKdKwsbdcm()(FmVDRF z_X(9VnhtY8en3(g2*%}3)kjoJ{BhL<9>T_MG2eWk(nBZp|KR~~f1E%C7@Ig>5JxZG zd-&g;{(ttPWvvM*iX8;uwH&<}d*k5woe1ickSQsRGr5uTw1RZ5JTI3w^2w)*jPpYv zE=%x6lE`M(vDgX0%9W_Q1b;F>%x8U(3=@y)_qb?PfHO zFk^nKLJ&^I8;^auqx_A?+p^&_1p7NA)@rJ4zW7J37MbzeLqG$6*Rx1nQ5ug;sJWAU z^-+y{?9*JNmF|sjQ<9?KaZQLMXh^8>-OK$I37z{+8M0xW7P?_K-hE`e&%ilNt#u|bzIwO_&PK7>GF|~CDc!pt z{^8l4dC`bYWG{MEOy%Li)bgWGqn$2U?`?hYMmxF`9yq&;$I*eVb{ z_C0bKuP@&t{Mv)O-XGn6YWVW!K{h$|vzJaoNn@oDG-N+076RoNap$FX+YOgc>X2 zpr%eT42ApDj*!_bgqD(~`A3etbTxIKhOgDPb zygmPQgXZ1%(My0gYVUVeis|nN;kR1ea%tQ7*NlyW0sxntjF|0Xm=ck;4zMXm4-zp_ zMt)F{dvPzZpgcVES(fHGS)^i3l497`Avn_7RUu6VYyJsK@lpZnE#s} zcs5;%@N81CJbha4+Y?*x&B@i+*zoCy!NWBX!_I|gf8srkf)qY510(Fgb$i|b-c#Q~HmZ2f6l2BNpVj0s5>P_(b!`Ifx;j`W8gjjY_6y=> zzVNZjPF>_+%}V+C8Mbefpod1_7+P%oFHQs4L!A);7_EE7GiSM%}#qx}iK|GOf5zG15a#(hcs@5Up{DyNRzni!eRV1_xj5EhA)#j6xJd~Y z`V~W-#;pz21LaqO9u=~PeOMD&$#-UdfC$QXU#o-g85n)Y z6!)@QF`PBcNB-bWXPlOVS{~yPg&RSPUfJ~?A^r6F$S$Y`N?5}#WUSd~q?Tzz)U5TH zFg-oJ%6LaEC#2a=ARe;H5&eL;AzG0W*DA^Et2_a`3?2gk<_)~wdlL>|OjAa^dY zac0MIgnG}OHixNQ^)V$CV^_pNfaE~=-hqXS4I?ZOZ|VbSSB2vI=msFhfz zja6xi--0kE%KH{`+ftH-j5!_w@qnqgA0y&!mz7&@wUUa)x>w#5Ue;q8!g)k;DU;Gw zQv8Ogju2qFdBavVE`Ewe!n*Rj3m5y6gLJQ1)zW&Qw9&6x{>8C~<|R#_xZ)*k2Qc7i zJxe$@_uNrc>+WPpS^Sab%OOf?qTaaLb8g~1reb;8bgSUDUTavz<}`h2kbVN-F2jy| zGda9m69oc9$81#Y1RN_H0|r&KDLj5^9eN2P?jn2{NYWc8`+K)V9m;)JrEmu>kew$4 z{+g4;x=zxWJ*_!eg`Z=7Z@*g6U-j|sTNwEP+B5Ha6oWV)ZT5OG6^ z8bFDnlIs-RP7}exb9xoG(*h1`#$AB@G|G{q7qwTfg_>m^+5>gWS6DY%F=No|2&x$+ ztBYVE>&-BOmR5Xv(7q|X9N$NULW^>-R+*USmZntGg3dc?75w-n( zqb70GMZH$x67sn`@7;E^fv6oRY-lLbJvy)4C145O{PfVKLi%h*+)lf=s&QwfjL?htp&w-mC?kql z$TU>CXFAta;s%p_DS!2o?Bf;%Qbcbnsee-i7q3}rpz49h_)UrO7+Y*!T%`GfAgrUr z1k;{TNfW5iRu^V|ykH@|nW}HCPzh9iryvXVUdV3C~R{q2?h3VLz z-R|Ajxs+#Lw~E2D9uFU1JT@-v>Y05b@E@Q>62oVJh1QED`>@h!!*~%}L2+!c==^N4?qJ z9Jt;WEgig;4(^QPZOdK$*rR^S8k~@Rl>iSL!7B`7fpjqTa|Y>S_^MV2V&9=0xC=x% zBX4s)PrO?(3}Y=SQw?yXveWrB*i}n|ewIkllvrz?2NV6wVSB8Kh4C)bCymmJ|?`}&h zCt;Wo&V_oL4$?Mr^%sf1;I)D1X!fI@*?5EPQUelF{R_ahB!J22{S6Amf5t{5wkzcF z|HR+BSO#pC0Vq(2>EAfL)Q0sYHD9UBA#a;%vuCni^;+!6-@9HimHtBrwZCEa)60L| z2W(TS6Zs4CzkCiTCFN&bZBoO}Dh(hayYFvw4s`M0->C2Ezxa~s*w4arz%+gZlmV0x z6dgxharwLO{s<7WU<0=SRW5gu(557LZnb=dJN*bLcsVc&68Yv7hB&DZBRO?ECwhsB z>3ZLrY&jncAx*Kx;-P`Epo%$Lsl2MBNHOV@iHgqoB9+;1mPw{@cxf?E5{%p{a2}om$-l z?Kb?jn}lX8NL9Q(Y`|p?ChX;`KV)4VLwRB#>M^~EE3?V1P}{%%QmEt*D?rh-Oe}7oLvuRVvdG=c+YFnFWNR?(?qU(!mOVubKE_6ealQ0x?HB8 z%~6x@;VQY-A`GGt)%G>%MufW7NcyB1vL*12D*7B;7Ee^YYowAd3W3;%E>HTbM|~zF z=V#ClKgs%&_p{^g?g2)s_GvG^2%Rea1~yt8-}=ljq4z;`=`%GNQ9kgr=dYX#Fc%=r5hxbyr$E#if}>LcTIGl5wJ)~0w{obx+3zfihtjpwz4 z4)i9|h_~;?bkd!&46Iz_c)O6wRm^qI=Cb=@fFv(5SqL{-JWH7Pz?cwYq^OB=LcUJ_ zNg1j(i>B0o?GwKf*wP)IjBt1Fpu+F_QJCP#&QETtZfR$#0g#0M

!ZuZAIW4s!W8GHAdE(NxA{+RZvJ@+Fuj2sNCU9Zk)}Vrn>c#Cvn_x3 z(x;MzlZ>Au2I@HgSjqz%ZIi^BaO3SPx{Yx;;euT04{atZPH$W-cfz6W+v;myaRy@ll6Q}2tUH8wSDSH*5tkd=^YvFL>)4rFP#L`J6Jr3 z+M$!SamUZIN=pKLu}ZvU-(ttor98c4Dyd?K*knF)o5vd_Vld)k1;!dswp z^;0B*FIWscBx4$#jFjjIe)MrTOrirz{gPz%VRVqkIqu7DSsO3Nim_wM4exRsI;K5Q z;5=NyJwG#XuJyOs-W4?&sCJAXp!sl;!A_lx^T1!9$XZuY`Z!s-t>BHHjw(J(5NGT(;ugR*_4KS-pmjY0&e!TX zcXax=&TgDlS7#Y`{I6G7_U)KXSl5-Et}|2$q<{75JyFQDR+o$~{XK5l(g#K28()5i zw+qmJ>oD|*Trs<6C`-ibs+7rff-bQ~v%^H)!svoQ`An#PrYAHRQ$)R2;XkmKq<)Hv z)_bKD8JKymKLwV$slB)>wjs^Jj6YzCK@{sX?mKETuV+SF@x%Mic-n}ctF4+9#N_+V zyZDB=pLtgrjK2&P=i^f*%f!56U28^!<@sy;2Xl$n_TG7S#qnL%5K4@wICQzL%+Z)2 zt~uuNKqXtsH#Ib_#mCYAz_zT52<4I+)I-LowGT~RQf|*@J%yfkNpo#|p^-~=&onc5 zqS~82Rj8#mX3W~qq=^xillU`w&~b8rTYa3J~&O?Iq6HpOWGFS%d&o1 zt7&Hcp-K5vPASOF<>aow3LyPlBsJ?o17*LZQVWf^qXybFUoPlT{w z+rd-zrx&L^NIEIT^v#ld5^J72{K0K9vhdXKTT;6W7o2mkIM14e7JmK%SY;`YBO!3A zdG}e`HNfr$T(js2G$d}jGXB&sveYz!H`hz+HCER>+7q zN?!v9J8FDme?~_^d=K~hxe+%XDIb3W65!6~W`}_pKYF%#O4dn2)%$(8oq|_i*>(o{ z8Kj?Nc#$Z%e2sMmfz{IlLI`2h!L7Wft`=i-zfH8c2Hm>*%EVyh*e%|V8=kV-i@JkF zqS>p_rb_NYn06H}NG293m_Rw+E7$P|Em{+l3o-hXrJQA)-&klmIA))i-1=a$qWye) zSSx+4@{+wn&r@74ioaW6Ywy)S#`o}gZI~&I^h9Iv8P&!I>tM&bmNY}ekb6>%?_~R> zt)TU-0*W>ts|4pGR1fa1G~2dB9_8DoV_i6UC*zS!&}=z&T^Gi8h#)TNG8oRYZT8XV z>->X-DnkOH+NMyM5gpVcj7!;Uu*G*lTIcF?wQzQ!lINu4;@AP#y@@NYmM`gr4Aaz6 z9|aSu7uJ^4r)Y4BknYI6K?Dcw(P;OuZZJZPqurQO)zg#gj!&xJ=Ty0MYjqLQlbR{H zoEs7!u&dvgw=Kov6y&dVnKwea!Y(@&KayF}t#4kSw^6q>f(QRt5KkfIIThbWcwI25 zu~&R2>GEFoYG821%FsgC!_7^<&gTWkBt6%!N7K_save0hEEc|_3msf|=M?Ty2bRGZ z6ENo@p2quwS;%rpLKQ+7U zp-w37a<{R@Caq>5wm1y2Yi)}?$j*LHCP&sRtiYDT3>?2v&68>PC;S9FLgk`IPOVh4 zXYKt~VTaMOQxaa-nW>d_TAAE!}Rpz&e!Aj&L6Jc_68v-m#3AcBX6+Jip|KCM;B^h|#R zaU5M-z$N1TO`q}F%JK$TC_4v7D&!DhE27*EL(39|Jqy`+OI4Al4C~}Jg1~t{1manQ zqvE1o7L+Ktg1`uuJ1=EKgf3&fF>UitI@x|7s1=aHpXGx4Ry*5W;UCPLi(5s$;HwDd z>D3;eFg%RneX+OlEV5C#5K^WOn>gQIlb<=w5;_Q)1hp&{}jh(R?9U6|nR&M9TAe?c0^_x;9$~ z>bCd2QA|K#uk7DzZ<{9=iEZoX6p@UUL#fwyhGMa~%G1tyuv49{Jv(Wh>%@r0Sp5lmpJHR#Oa1qWrp$$}qG!Hz8yRYiYL zpq9TP3z&&HlNN7O`mT(oE@e~08~2~-A!7X6w-SrLBz|L_ievt$bO8o!+GjQG{Xd1B zE`ll~Ekd}z$~*2Boo1=SdAmv70gQ2@^Wm=zZdsZq3g!xMlU&AXf~2#0v&vy(=MHVn zD_SBOyJ(76)TkCdLoRwZZ)6SG%||&q!8##{HRV8L<&nb&qVXuqiWk}$ndV%9T?&-? z(eeG?4Vj;iM4X`*E2ZQKXvG=}QLJ#ISAONGK=U8a95 z2hMs9CddRr9w1<_Sm6Goz^je==Cf-`uErm1px~`J(+=%|pYW0}BTvjQ78{Qd`e)fN zhLtkYLD);U{6pgd43st&C~X2}hBG8PkagvtNuVw8?_#`Pzzs*nfqx1OFXicwMk!Bl zaKI}%GBH|!c-rB6amqf9Se1Ozi_dOGTav#{tOV-t0-Bt!Yt_|`I~MuzM}7N+7Ck|_ zp1&|o!6Aiwgd1=371GaxG3?<^8a(XsL`Pz;OGx21-y&a#L(~KsMO{)j+e2#=EHm&8 z>>j&T-b|yE)F80mRGnS@;ijW=ZBqfHxFafl+1m(10z7H$&B zvFUdx$1LRkF9e+mEs*6j&h!`c5yxh*Hr1~2e&2&bJU-W*0CbuskbYBXU5UuQ!f_3K zPK-r#HT^t!o1v=~ywzTh<9XlE`AYEt`;piRyk)+gw?@l`{m4RzCQQq=qjZ+HCriZB zdLymxK3)%I+IK;Ro_o+}kA3dojmDRhgGT4jg{BgJ>aKN89h&V-tVFa{uMB1|W)@!} zwxx|+Okbr?k4%pxg4piFk{`u~w29Ol{6QwpcWOiwoqJ9GL53W4xL~eFhR`bYs}oK> zmTt!$dme|?tz{%uD8XPyee}l2hTeXSf9ZwC7FkVFuIW#MSop%@miG z*4Yb@7?#YYzj^Zl-vBjAojm4hzjZM4Bdf=WAGNp6f> zWH@}%vjt^L!4G+hhCOvJ-Z-7HJLb(dtZQ>zbQ4#2ehJSZsk|V95(qLw61Bg{X(uCp zJjh)j^lc)!o)qV%oux)VzC(n9d0H`A?l-gAGe^R_{9PrdOpxqtmq1?Dj9_wekcZ6Q6Bbev7Y!qf#&{T19E5 zTg==hodRlh!~L6vKbPw7%1d;9Mzf$6K5lPJ4F79$(^xB_MV_2ofmq(wk)%HVFtHt{>=T_y6nmrUB0F$4>me&4$qlYJfN2qELVpQ%xhOb>u z`%B6S*{XB>y|ZHN$rzrt&cbk3S#6MWHwM%)`azgfB%H&zut#Ue*i#E7%acmOjz-mh zY(O+WE~9VM9PsBd&Bugy1`-#GYbD^g;00=Rp2oA6j5fli;(HYsr;vK?2YFAInj|Bq zGp_Iaa}B?($@Hd-xasK`o=;y8lp?bt=eU^mg807TWH`$Hl}n--HZAjN;OcN>C-g>s z?M6zSnl>CAP_MC=gvD0X)-eGdMscl-oaIktjTZ?p;i9^}>rG$yj7M;rp1qnf2Olp} zV_W_Fw&c&79MCacF&VX=jm7nF!+X%Gu_HGDFJ%D8IBx~B%(t?3Q5-F%g>u@Wlu=M*Ey|7Oo|CEsY_ zqRaN!Dh>Z=W#7a#rgwo7;;4LCF27=ECB&z-*jLvvJgl5jIOQHXSjc2=-nB%nKPY*! z@UDs|#}BH!g{D!D7JY54W6uL8Bo5mWfg_V)-K8e?E#zV>kotIm*^ubHgtMOiFS!0c z6kO|_0P{Lh=*7)>Ag55n0r1`Xa)p53_ao_OH%N+Q=X3cH(@Hz!_`MpMfv$%^gl$jU z4(o=`a%D;P-a!5T6wy+hw(>~HEn|7QUA!;2;KAPk_f-@op`wTXsdDTh?2Mj>P|*7u zXJQH#zq1_TSy1%?lAega7OrH+pS6?nH#hSStv*dF+o5+9d{Pha3x)&-W)FKQgNp{C z{!O0qKXR9UWmJD$L>$8JFY~wn|*%>O_I-GB2IRfj>@=1H{Y&$hjs|oEiy(?9O zR=JHd-nRbW?uy7Ng+;>N`)jcDFiTODI=u(dow;=zuR2UkeW0la=1yXJv|4Jv6k0xg zvCS+kL#7{=ZwWOWG*bT7lecYzSVVm}wEUg!aQlheNh6tF zfJ1;8W4^@Xj}#kXH+!s2F;TqQsaCq!Zck2;>SN^N!6r3^pM)N+u1EIeozWd!4n?ax zKJU`ZUwIY}Vw*sp^k?_NKT^Wha&Kw4m_8I*o1qG!HK`IW~9GIf{C9v=kQzcb}?>Cx^z`v{k7c3q3-5qvm_xNz~6tK6T& zyjxiz=X4@&UQX@OU74AnVj&`j9S*^&2{nIA*2je{abCG)j7_3zrX$xDV`s<>MEl3{ zo9j_ejuI|!I_S`pBcF&FVQ)_jM?#W+5m65VUAsY>62M!_^2&K0qntP1M*V8r?{oFQ zn{3V$!*>&WnBmQZ<%nG#l;!M(truX4O1-y;`4_UkAwMxzf2{TFK*$*x>~s!WJYjpJ zOzI>bN1wo*8RuCI)+0Pw+q1Uyy1G6CodD@4Ml0LT8Pk+|{E7Y=ui(!VX9v9e;~D8& zLo8XVLQ4s_ZdyZPn0)IH-RdtLF_{;Qomy#^JDn;Pt~4PzUUAkgmEP*)8eE9(JteAl zq4{2H(>V7afzd$Wxnm?DBN`RtNk z<62~FqGE*44r!Q)Q)n8O>P~g+VOYZOeEnmE&6Kdl{k|HuwI^&4%S}gXqL$IrRhG$$ z1DX_G79wl`L!gAuuE=8-!fCx?Qc3;>07^hHG)b6GWYv@cwk0)S4c{#wyQN3ATfm>4 z1?JEL+8e*w92{Dw{s}#d6yt&WQe9tE@2vepRZ-aVOmdm{6R|8}C1h$P;1aLM4S;66 z_0sPtoxG#;DNA^y(lr^SmY~@QJ_|kLwtI0nU|OfVrET8`o>j}%CH4!k7|l}s$|7#a z@SJwBGEtIGGP)4|c=7Yd`P#EW+1aqMBJpmbnx@9*QrPvLs(#mp>Q@6%j~z`00#UgH ziiuL-O5H>Yb@pABm)~&Q7t`x&8(ks5jrL6*m0p=#$?hx}SxhZf;<+<>csCtoE?I3^ zJFDjw@YZV&a|XMPGM@sBEW07plnH}j&sYFf0&U<^;D|WJs_+dl;4~dgY>ql9FH9SJ zO9JPit%dfAcRp_Ah$fms>4PrdDIh~eyFC3Rt;ow#?54Z-` zhAfq84dz-O41DonoE!LN)PrD6coGoQK%DyoDSP+w?T?$ji|1&YyUPMDJP)_@ZuTon zf)I6$tND%VpkaB}Bvb>Rw9U)fRzs%9*p{eFdbmhrQaT6{P<$%EcNX?7`INgBwWTH_ zdI}4ru2WZAbB*2c)~{6URhs}sz_W`^8TN)%Zz$)!XNh5S1%e>^9t=3 zn)5$hCQx%WWcbw&Pa{isA(g)FWt;@qHn`8l=Gendyn=+a2hie2$oY*+nOX|U-hkvn z={L!_a|&dhW|*!HM_o75Lfnv#DH!}|n4T`8Yy8JxUq+ag6kjQBbL+85;*Bo5HCahJ za{C$5SMrzZr18ctq2^95*M3Z!eoBg0p5V1OHAZQ^R~XZ0iz4544hU8bo$8q{SL^pG zRN2slHO+;%4mAXV^-}k`ej~CW?4Mnwg_H)w}+Wc4AC2QTDt!FS#1LJt!pxFx}T_e@uqSsWH2YD}u zsQ>J`H{v=i(ok56O;w>UJnda<8$!F9IBzvq3KEu&DMbuuDU_h0#|${3N)LIkDSDJ7 zs@c9J)au1}y=g^iX7SNV&d;{>5ABfZjTCEb((9;2TCU98d28qMA`bNYAp@MD;@+w$x<71J zBU@><%Y_%;QHf)#o>!R`a!DzW%uN6)1ne-#~v$679wH0-xx^aS=j|&e^~YUXu4urLUu5d2p&P2zBE{ z|Ca6gU>JdG@OR)G60lousks1T8upQj$=1q$N>tMR4rPl2HABS_ndJtC3|;WPf$6#! zOlZTmjS}!l?+G_ZZqd(|`xm!8erI6sM!!rtAC9{Gi3MPDJopergLH&7ZCtEUYO#3;vfzWLeKlxDyh@ZeowI}W@}W7wHm z?6#u!Zzmt30x?`DxjEbgE)BwPxi|nb$AF^zOZLV@?l3=WHFz=(2&63N(-WHT80z@9u^ zkndX9a}QxNKAh1=GP?ETe3QwD3F+kH!Lf|ajklfTxAs#Y%ufWFfDaenZVEpSe?Q|a zG%)C#Vp;s<=hbdHYt7A`+l25ZJpQCjdbBs^-Gj2DiicW9y6lSE?D8l}*Gs$3D8UjD zx1w9&>&Zx?mI_AVxsG=HtctaPmDJ`TZw5N{7?dy66SHaKWrlKTfaDI_d!!vmBcUky zf{)t`R*bW&P1Jvu&PBKs6`h>jQHX>lM%UPf&x}QtQW$#y4z|1@O>A1VqR z)puAH`U|Mc?EGE~!C8?%X3Q*xuRE6EJ_~jA{8Y9iz(t1QWgekk|c1MoaN^ znV-}5jEpQNr$VJ$sPdn`V}tT|jjl7^#Co<|NL3cc^tL_ATwHRl7vP|;(|5XKa0A0g z2E+_~wn!1Vj>KkTVJq*d1J*Xq6rnLSlo&pb8tkkYAgU9$S2qZp*l% zsZ+FWc-PzBQ}n9Lj-22XUpuK!=rSqeqqUpIwyddqoMTl6WRO@Hd_b@fd5%^{7n~lgx*av&QW*V&fL8HJ!{P99u%Ic zxIRw$EE?;^8|EPd*->cl5NipCJp-|n_8PIRw=d70F(07Qu-XHO1U)FB;hCMUKxhF%{DMkhhU=t zPpmR~(|0H7h{mL)2OxfI%?PNSd@60kpX~d1D2}JeMF=@~qb9`><>@XWTBCe7B>W)= z98DxsjvZ-z3m5g_$f@bNu6b;39ityugR@TeX{#{$2{AHvEA#P{Wl<|>KMy7(E9c&3aW_rSzb2@Dhc9}2%4yw@?A|!ile9kP$!HI%)}K4w z6;0Zx%I}Rg_pO|i=h`V*IPhcksJ7_s?-SDv=x~|GXF7+Xh&=rS__dMdVI8joho+SI z8PiYpnxT(YUac>-zc)6@9#Nq`TI~9J%;C(B*8KP@=3uTb$B${$f%W%SGy@wn+Ds%z z=Yxwr1{mC~&er)IavWeq8Cr6`7!5;b`Rg(^_W3Y31xHX8JBPTRu%nMO%K9&kjMMDo zU?|RV`PDMU{|-COU{co+MKqQ$CitKiCy4TXk;4HMfeo(w3Sd|<2za-?)e7e;#YO^q z6PDt&>Gq0be+0t5A0a*x7M7htafp18NV9KiyASgOb z8V7F$KPbIrba7jICU&u})RU^~mS$o)UX=s_!p4_Fau}?z&>*WH1{e{jQl7@6F*F)F zF;(vUj9_A_MY^!r0iHS=c;=#0I1b-#=~mt5WAuHk%u05A7C;koC9fzIqS(rA>nHFDHTvY~q^yAWda~cWeoMAX8vCK;3#nV=|gAw~tDvXokR{c@y#nE$0 z%5mF*Rpf8Lvi(<#xw6f)dii$yGmbzf_Hgw{S`-^fP}@WmHOr+uENCX$E28rA-4{}Q zotvJQkGEZ9i~Vtw=s+dbb+8-Orr(neRU9yYnXPRVw-Rhzx&)hq^oQHK4wT-;xQx2; z@4%Z0#2D-H8{Y|k&{Cy$%C6VX+WM|!*w;HVd+*g{bP-{r4t6P`fHQtCj*xP$fnYU+7*<{sHF7xEp~OE zTmR7NVRD%Jm@Z~A=pqJNtL*%jGkM0tJC0Yv zFiegg01c=%mc}DHz3HABQ_a=VmMdS50>uc~L1T87T^?vk4%+;IagjJ$f^k9X3nt7& z#~Q~@B6t9$czNPS<~^}3sXZ{O`EKo0wPtEDd6lqx5;gh8do&~hSG4H|uUWkdr7sll zJeQ#kCPb^E=565Dd_Ln3W7eM%rH6Hd=T!VvR{B%xhi`lzteh+gVC^<7Pv&VQzMr69 zFN={9H`v*VY-R6GprFl+_8UwZ9uQ5~T!uQ(Lgf>`?QS^Z*uC`74_Ah{;6kVPs~VZC zFz}D{jl;^nWp0DfLTn$C_9e?mRdb0u4vNl{ ztg~JS2VgQCAZ)&@qDI1A=tM>nZ00<1?yI*ZAKzN4h@zrem@+rKQs&am9T%|XQSgG; z-wt7ho?;B+;qd+C7jWcEsfMPGMC3z|mPUomynkHTT~a<1web!<^j9omaNk|5_Y>NM z`w?xOV-~r$`s~}@GSjQzpA|mq072uIGo1k8uTKUHxg9v~)(yOTvllEoIO~@E)}HF} z7QAJZlv^c}2SpEi4QNxUg)>Ce`w=d=B>Ogyq+VlPjU%DzO(-tD>Y7FX@J+v^nN8A) zJK~|sr6Yr%>r}rkD9Cv{5+Ycx38i_SeR>PKuI173CAhOCxIX&zWLeu%_4t!8v`?LL zRN$L|QBQ<$$p^r0^c>z17iWredeCliRZy~cHdLoOKq4u;?gcNL@o(ehjntp!dyvI_rD0Ehe5!h~@Z-~;Ao=lXNFX7dQxa+mUsdJ|e~lb` ze53?q$Xt$@m5=`7vv7P%)|UXnHXcKpE|-8tLVaq)WUvn7XZ*bJPfr5%k!{zM@&g*M=_A=G#JkF8h)PjXZg8*rCluS(f3Z`#J;Olxz0FxaO z%6W|)c#5%|lwW%KM_ z9LgtY;9BCg?bJ9G!AAw=0>(+cuVcC%W{Ga)1j@tG0s8!DzM?=bNghE?1*SiL?s&8Zh#0 zc~3)Mx#KaF7==X?6^|TVrkU6mFY4OfD|h`CvkpX?i&kfF1IT-=+KY>Q#gkA^_M&E` zJ3xhn^H!x|ZB&2$bG-n49n#6yd$#2kohKe=KAHR;8uq1Lh=EWczwxIm?7FAkhb!}x zp#X{Gl!+O$o#ph#FD^T+32L)z0}zvRm;=yNEwzC=nx(D22^#PhPOfxi`RN>Wpg{=Y zToE`WQFCYdrowUhvNMm3v6LGXqBcIGj>#SI=|0+KD=8ilLWf&-Ve&KUNdp_Z$-Yy2 zCFT4UbtyTEi{z8%y+;&TGaJM@VZMMe0V%HixQsqfz#k@yec8&CUYJ9v;tvVqh|daMtb zyi@>dno1*fZnYY_A0f@Q?;}j0IpL}VmHX@S2~&yWv==)b)WoJ2;i?L@=nx>uQ0ojH z=ptG_-A6V#en__bLZHxYahQiu?u*>wJ07RPPT{1Ds2Mt#kaC_ zNEgdQ*bCHz7c4X+P$mhy;cvM6SRhOvlkZ^0VbsFj*h^r4Q5V?w7wFyd0F+b4YI;Rh z**7?QWT(F?T-tu4PX6)6B^di^S_l3aNC%Zk)x^`jK+0rE?v8`ZXkx`TIblg5=)!gs zXPN4aRD5^YI!uKehIu!-OQ^H~->HeJ`^{miZ`M;>;-HuP|JmgWEG{GuIYlvBIgvyoQm z(D1!ivWL+JN_3QVGcZdge!d?6xdI|HM7sXn8Sd-^4pH3yi4Ye1bp^J|KI?$3m(06+7N zN{Tdgw>%{xI1HMo$N}mNp8CapZ=13++okkXf6c3wL$AQKjZEXx0iBqyW70gMk+P@h{RV<#s$+c1IpK#S~5Pv@U~XH50VsX~nIzDg z2yyN^q+dO5n}#QqJ8yX@`IM2-1-E91;u~uIj$YB2spKo8`WoS16b@&$@AaL19@``* z1aBQ)3;1T?8D=jsyyHXbUJDt)A54ePv_U~KMIb>Zr%k}6ajHu*`zXpNmY)8X%{p=h zH{fB5m$~2oAo+O@(XJF-C9LXw z;5q(c|1L!M>qP}vTwGY4XEOY3<=mW~%R0u&ci^e?!K$ehNg3|3+WV#(NnwqK*?+%% z|LNq!N-+{nXT>za)p*Q|F=%{Bou3PSf{6byy30IXYGb*NwPUPKvzEnv!kYHWulM;0 zS>)I6pKku}f|`!@gL9?kLHEsFZ=WA0oc10p*bULy(kFpf8*nz<*q;|*61Su14d4N$ zG7yNjQ|Z1}q1Aq^9DV7vuI;!w1xeyP?bfTN*7<2c^71=j$z>xZrUA2CJO31}S<(N# ziX1yNUIdznY&vJBE&Ab!aM!G=FT^-LIZf8|hy!hS#JOioLj*_$j@@P)dp-!T^L9b# zf8+1&92JenCO*4$eUcLoc$VYA5tDTv`fyW^7YUOl{GgxLxkm^d$QAsV{#pgLIeiGK z#?2m|j-dxW_T9hx*ra&OrH}#XlQjMV$eDs|;tUa%-O9+jvyZTK;L&&IDG^E)Xcw>*6RSqiec*bvp4_LbZKn4g>x$DY+sRlQE<{@UApftkBw zjf!JB^i4QU@#%U9rG>QjA z@%Px~D7|rig1pJ zLEC8R)O-i0IuX>2>$*L1yrzS{Uw5}rz3^Q4hd#@B?Zh!NjZqn_NVZYm)LZesxeH;9 zSAP|?<~xD_f+@g&e@`{|d40|E4k~PT8OU*ca|gN%0FP$&t#C4wjf(o;p7!b>+B zj0^4&3Y0*cRkhbqDAw*v)11#QK^hkh_GQ2LVdC%BBkbYcq|jiSTN^?$U#eOv+lh(Z zTsPj!$6x0JMNpLYc(gwVc6hDlJ?ENOGrw%^8)%CN|2UO4cES@@jJv0%i?`D{Pkg$5xpeAZ;XhaYU;pz-ui0m1E*=(t@n_w?mnt zjz3IXblpxsL>w-}%$A$-u4^}4+2_<#9Z*Ar`pw2oiB#}SI!`@raCCU8s4#YT9dV)4 zaDPYCC~SWydd>oxe9dGw6k8_jKYARH4zonqE>Nq5oDK;V&4tT|L22@NsUGmRADys;jD~+sk`)WhBdDo!w=5z!D@Nfq8 z<-G4XKfdxK6GFCVHNWV~GcvGLvx;2&fISV*=WAiZcFconrb2P1d!5VGjz0}M{|TbV zmHfQ!R>a%2Qs7)a=(+bj%nYxoO`@56)tHV=S;H^QS2`MRuLxGm`_Y&n!Z-Hn=347e z`FL^Vex>ezzOdFXc)zwiQ6RHb^9~H4cH`ON_Xr3>>qZ#*+QaxAc8WhFqZ(jwM843l z@XGTZ=6(pg=eO#@FUdMIjp^kV(ZqP|WmZ}&scA63UKN~tvD)>_3lJl2U5fvc%&4u{l4JDr+bn;1@$MM7${Iz4KyIyGf|F(1ZNFP1B> z2Ms!CR0S+WE# zF)q`#q#j=Q&ff*%UHZSy$K{FH8fnhown!ETRIxl0_P6WgnFjp#AOFk3B_>*U7}T57 z`&-Jwwwp>+Tr0egF7wM#tMg)!HVUTcii8iF3|y^Uxyx^n;JO%akAK6B0Pxv=rY&rE zh_Knk$9R=*A_~y0s&{Pv?%O5UZxeWz7fi)J^0>aS%CkDnpY&A}iU*M5W?O9;09`y_xeH6{}HfRs3b@hkAoCju>|d2YaJj5~WY zr&Q8cz6SKnvvHFP2-xv#%DI=w-?P@mbpY^Q`*0`&l3Ge>FoOT1hFnSRGTvfg`+?E3 z=F*+3r3NdV6-!DBpZop&v8z6mD_Kf86r7FTH>>?Ok%I&vw@$Ao zxnxo!i(_$$p~&TQ3+Lr@XdY8NN|_waM-bS&kEK)#GAjB8!!&z>GX-X6#qtV4chW}35`DNvGtpY)*2#(Bg60t$4&VeeuU zYaj@7o1d^h#s=~)EqUONaPM&}fuM-4Bq&bn_lVvwy_-G41WLs3@a#I+1^-zk<3Fbl z!kOspp%bI?tjJ^mYD3F2MD z0;bugMo{LT|0}P^^%AyRzf4-HS-VBgWBaep6hKoSY(wJz?os;Ru~yFVz`bYVEX25f zzn}!La=k`&|HGLH8d?2|`*P%wrCX|tnaR_z=gD7p*G#j&#&PR1dm|xY!WirDz!q21 z-%K!TrvBx(_b)%l|3|xGA^0CS5!3iXYZ!Jw!V$Nhr55(fviw6Qh5ukX;}2Djs*uXw z9_JQQYB}Whi48t*WIbl?z?Z}!3GVfk*3IW5I7Bn>DpW5o`!C%m4GI-%u$N|>43n;^ z7QiFT$~NW*lAs(!>|u#JJpX%cQAc zE!m+o$27C4SUO6j}cZePdq$^i9%+8dpP> zPd+0GPsAi1dP~?5;1EUQ&emQR$vCSeBe zT4e91E@5ES@cVQ~UbJDsd=l#?3m}Y_83ksOM30KsLz}QCVN|rpf$p z?QZ#=WxDgv4ecR=0mX9Vl~?W-g(l6>>jZzB6~*+B9@mj|NW)4>!=U`caOrH;5(7sS zC&l$CO+txc%X=uBHj8=qIM(>Qwt&}hR)ml?ABs71Luz|K3)SW-1;~O@#Kxgkk=tOt zA>HroZh-i9EmvVD8BIbh`M9dqgYpG_;p`+|s89_xRa1tfeqG1Jo3~@*Mk3l(+t0s` zD&yB~quptWev+bm0o$|kU`9sx1=rP{43vdWN^YvhG5VZNJ}WQ}Dr6pI&~V&xdq%x! z^@C31CV`R$3N*~AW|<;^9nBXYOnDlOTe$FMsqw$AkhFcV%q=?VjtGy@);+W%e2R#L z)r=M?(iuW938881m!z=id-!2r8Pwd`T!;$P|^MeBPdSqq*iclZfes$*K8 zmYlzqzwh0Q)fr{}Hv-(P+OyD42vBDqr3UddcHS{%^>J(O>z}U+6LlFJa{cyKPfP4+ zv*^UaYW=G725%T;Tu#I61p;yms73K!#*KHt>8ETiDYP~n0vu#Gdv=*Rg|2Uzl1gPl zT@)q#fSOZxBm0WUO%G0aXF3YcB_J4hNqFn*J4tPZ=Ue|!Lbvi<9Kv|Oy+8bZefg0u z;lZn=JZ&Qa2gB!K$4|C%l0DXuKjsi6wU3*E0at=}BSR(TD=@PCZp%9ZCGu|lw;lAV<0R`wzv&nnC$(6G* z{09f2(Q7F;2lupSZWd07B&TEB;^IGCIdqWUm>}3k99$R~%H6afN@b~C5zgUnvW_y2 zz`6Q1ILIySiEG+d%U7?)wkajdaf1iw-=(&t)k4@Qdex{F^^7-~WnSvOF<$^^HYp@b z;H|9I68dFVWLXRk`IwPXGgPe9UV_c>n&=^!2q+Gu(^#`P0g~PS8$RJPKjoee52Rv- zPa1>Jmc6@~JubaQ9xa(ouxxtAr2j4+FqTRBS_Z+R62^W=We(n7=%y5ed&OnaY^? zhCFc`K!+)!o$baRB5vql%dex(y2kjMC9CU8Rx8n)l7}Oj`dj-?P*OGZ?eqE6%Wf`L z)2`0=5VFODn~LFNF~|WLZu#%*(;0;$GHvHoHvEvDKSK)dB1jfhj}T* zeQ`F~kxJFSZj^_|q+haCBKoX#@nfX9e7MRuT<9qR6w8dbR1qwlU7wq za83=wnGuPC*}Mn*bEj&MuzOOj$yqLA`sJNo0V-`Jo&>D7Rf>vN|3y@erh4|~@Ky|^ zpT02g<;KFO2br8^>~rkK@i%ii(7Hi0?_`=fpmeBw0a~Om1}G$G(xGVBNy3pAk_xT# zU~czYizhLua=6Z3)0AhaBy+uy6FBr*%?jEyo%F~YW~w62_A>4=eNYSe7-3YViy$g% z3*u*KrONVsl9P5jQTUdVTyLQT)S3DklQWdn1LOZFE@?a4DZa;lL;~d00Ud zd&HqV2uBo>ijnTu;~e~|;$RD)BYSfh)jx!>6}<5@`HQn>l)vn{C6lbv*-v%5@|GUG z=0APz^#of8HYkf3DFEn5VHoUtA$c>E-mX+nw(8bso@jJ^I8bs?wh6iKrT?Wj$=(0C!`XR9LcAKlYP19x1Qqse! z<9PlYv1Q0AsR0$vb6KF=djxOEFOZ(v+Zp}lJEg3?DH1R?Ci0I!^c7;j__(cl>iXKM zj}cVp=)AAe`jw6uLwtzVe|%h!so2_lGDn{L!>BzA>Hj_-J7N;#WLaspCyu=qnL>iKKSBh8{N~Wm-3xuZJC0R7RE;iNlFjg z=8Yw9$Av$agp=WlDWzMkYwjw|vq$DodE`%Qanj^CyHmH}P~l7hKj_gcm@}xcD80`H zahb3-!PAaW8$09p*_d}=4ZbNW%ODlzluBw9<4lsDq1ViTuI{>aauJx={kNQYM)to? z3^}a}H0pS-aldyhdq7Of9+I-m4%kJjv(U*T>A)~l@RN>00psSEEU6=^dYTda7z zP4iKDft2+27fxYW>zM{K6a#}*tCn;@?>yED&m-LYCO^cAgBSvR>0w8eP$PYNUW^A?l>D*$yjF| zQ;rgq&gHZ-rgse_sHF2&z0kZOMO%1+2oPe{E#JM%O-yzV``*)_^UVLDIQCK8-y%0W zs3!Wy$nF1~^8awk3;hjcV#c^&O^cNy$1an~OMm3k%L)ZZ<(JXb3OEDBM+fuc3#ykk zcvRD+!Qm7;c!RQ&vQ##AVA0_oS+1K{?aa9!IWayMxbhD)cf;NP{?N~F>tvYYwGyUq+Uw%s;d#O>+ z(#TcfL+JHu3kkwMuNV_LP6?CntejAt2Xo_rwv5l^K!9w7kVvl8|3C_O>vRcJ@*E+3 z4lP$q(EHHca0zq}bT*u0HW#~dSCz}KC!=3PH>pi~bn|dGq<;t2XK!+7p5u?CIC{vy z$sg@aeSGkq^z41jg)yn*F!HFPkgLh*=<0Qoij&-BEZ3D;7|*)z;`Y1=Ch7{sd7k45 z1g(Gya7ePv{+Or}F$&gBpxxMmewT*-(cX22HI;7bacqMQHbzk)U||piL8S=@DAfjn z1&EY@7#K_fN=T3z6$M8GMhqZbKxrWf1WAApKo~>=1QkOFp{NWs1!;j0f_EqA%$f6? z^W1Zud(VCDkNLaV`Plp0>s$4G*D8Tpx`F8VHxb=rCAxp_tV?LE?~wtZ*aDzP#M(%U zQI-)7R({CD$vt2qIxh-J_86IaSH)#w)1b@4(KSkqYslx1_7dF-qGs73iITv8ric08V$3+Jp<=&Ig{n5cfbf7{Y zTq%sLnTH(pq39g995@!mc6^HSD!)Kb?>Ue2jU6u9Ok|v7FC0)LrHI}V0bot6Pg05dP3jqR zw<#=BM|hHf2PVa~X8|*LcxrVcr;rrItINB)LIB!^lO^t4Z#~f5CIE6E8bHjwTHYxO zr?mDjIrqtK0gd;yPF7dk2tnL(dH}xw+w>ysD3iI~mtRE)(&x>8ycWzXQJ@bI?S9za zea>lhX)Q3*DbTKw8JSK_m`+f5T?}+R^ZkXG+hzgoZB}!NNT%%2h)i|%Tf5wMutaPP zi8WMC7nrBter4Oj2)3f**{z)wB5%7Dthr9|1-}>}P z1MfkkB38!1=fuBbvNI0PbV}zAL|UWaSA^vow-4uoBryHs;Nu;AngF$Zr1eALS&`Z! zm?TI1b}=+-GJg~=CQjyv1;1z}JYvWQZcE;<{yr=~Di2oat2|xEdiGe(i)I)6^0^d4 zo;JIWMrjK3FuVbniv~vi&v6~A*ip$My$M=k>j%sA=tEf4umSu_t=U1E$%g^uN0G&k z{Rj2VZ6b^VtoI{U{T#iT8rLD#{_HRiFk}O2HXmy69PmB;mTHVQfR-lKtO_0A^c^r& zjiul=tOon}aWaCPMw}|Pt$8^{SjR*-&G@$TB$ROvxfAWvFCY`-Dn=orZlHBzVmz@d zRU98eXU1^C3;Oq9U4NR8BXuH4|jfeK&x6b7zqp zgqor?t!kg>j5ostM4a=*b)0;;uIc18DCZdUWqEs6#LhSy8_Lz+d;WxCSMl+k41`!5D~O#2;vDr#?OPiXb(;+`E&{VooPJ(T@c`Q#LCHpA~# zU+Eq3FZgx(h@RmU&j7ODBVIz0GJSrG24=Rj+gZ3E{mq}<$Df|Td)RR>4nUx7Aa~&5 z1_Qa|4x`G5Jy83(Z3A3QqpaHmvZ6)6SR{$5WLeyJ$c}TIEml*cYsLJVGS-m38QAu!u5;R?Dv-ZILIirr4}>dP2T0N zTPd$}{>2cX*^ScHWpps)?no+y7_t9{i}vE`^QH4S2t!9Teh>rOa)#J zbZWx6qiA}1sFryEAZLMU*6-V#Tl-i~UQdjuJT|Td;OsBpwr9&fOmN_HuU6Dtp;X=z zTC(Xb9WfGc!jjsTdPl4{2l7zovhGrZI`q%&J@-Xf?q3h?-JF`U`0mOJ2ZusV#`(Fe zS9H<#_f=x^Ijmxf7C*NX<8~`}Mq{!FJM=!9^kBH;v!byoqBoL-NaoB^ z{Msk(WE~9EN?T`GVVpB~o^Yy3ccap9Db(z#5tcky*q^Mqm7ZoWu8T-+nIFDx!9H$^ zH09e$+PFd4E|_mpvs|^NRz59r00>!f#w~o7*NcK#RGdG=p^LtwSFw{2&765#T3KoR zJl}Bqp-421Sy3uuQy*27Dna9obRonDvb(aSL4S6j`%V(} z=HhAa_FwabjQ->VDygl3yxM*P_~7g#hxE>8K+EhN{z3%wVU2c~Z-ZfS*I_PpbTPtv zqD^OS!V%wtISvNz^1;hsjc+EEdpw`H>5R6E8VC!iXPgp~InO@efc$2GxN_bS%*pQ4 z&JlRvn{@brx4Ie(R!9c&?MaE9@#Az@xdheX%{KX*7A^?EfT;q-7^&ZJGzCCCbAdsP z-`4A~btL-;Hf>IIp$y2CSJ!P_*fNQ+TXIuZmhwh{89`(3pW6_u5R+Zf6X5Cgw~-NG z7fQ9}$fiGi+y|!OZ}!#6$|KcMKjZ(T=o|Njb6|HY$%CwNkUcvXo!Oq;d^ztf9NUzM zdopY!E2G^w@ulQ^a(iTc&gDz}X>X0pXnp(GRh5oHL}shlXFEWbeyPoP`J=6JDq}b& zbc$WwUga?fXNR1)SOCy5Fw>7*WhuayY9oAvyH0}XPzKe@MkTZaLJ(_A&)O;n>+zluEe0DUQhl~TgdwTW+sq0sx&)6(Ft?kn3(3!>E>&yO^I+%&dz(W zLb|M!a3{^4zAsz@jn%XeFDsGTI!ZCLP|b1XlvPxK(VvS>($wYAEq+pLSio;?W6>bi6%tSs``aKn@yAc#tVR zEyi6QX6UmIE=9X8f+dgsM&jxc`_j?8M&|32Y=Er8ao+Sct^Odmsyjf3e71A{Deg?v zpo=N1Ga}#KX?Bxt3J(P|B#mc!7?z*xRMELjVkEB|GA{VQ3uXH`y&5`(pgE9BH{a~= zt+l&}Je`oVlmkrzf?jD&c*R@;SYh85=f?OwSSAV%@lm=_6R??}J{YRS*w?*C{zkI@ z+aOiR!L%}B3O+wU?RJIhwvq=C>o3HR?vNAT>-P>+)D*xm>%r9SnY))!Fk`erVW&Ja zLKEtqbM;H1D-9T&B>i7jPi_{M2Qt~+M`Lgu-$QXujq1dQ)q@e2A`*qIqWty<*xSeN zqRXSANhd~95j!`?9gTQ?<j4B^X-)Dfma<1l7>w|Y3%p!HGPANDI<>-Byx^?3bWYZo;tT=S8|^ee(G z64~Xx#?SAnce)2hy!KxfE2ozK{MY=^c)xuQ^uU+kck``#P8?s@oc*nz66YmQ=DYg6t5)eNZ2@Tn0EqkZW7yCmC`Q(zuTpcdiANptXWVv zp}f}@(_sy5XFIkZI$VboaGz>rR@W}P2%n{mr9FUYt8%kDY6+3TA>$+v#Hb&W>>q?U z(mvVjoT(}OesJxj=f-`@zhlMLD&9(&zLONl7rd#nRNQXTuc0`fvAP&Ry6}ziHMp+b z8lpl1^BB5S*U6C#(r3M0Pm24*?u;wP<&DLk8;&6qMrZ|IhmvoXVJc9eu`<>&>b@$P0T^N})<>L9* z-rRdn_%rE5mIAchbgGKfb^jSxxyZq~9yabuJ4L1<(Hm@R`A7L4hRRTrWvJHUQTD$e zn);v5NBRC#CvXeyA0@rM+rTvKoXU83zk4r7o}@YW?q**ao^=6>h(9u7)ot?(^i;`$ zrD=V@o>rjLx_;#&y)Xs z#P_G|Ga}$~c72h5m<_w>N&!r##2|sVu5=)mH+RFB@kETT@DW#OTluEIcVCYW4LHwJ zR)pf%&oV(cekMi1MlFcom)U=xI$$v#nuSbsbVR=kYx`84^&Q7xZ;ici=Y102o5_vi zVG%a$#WZ|K*+4E7dHYz{bbVzei9cgv0yd#SsLRL~iSs61bu~TWR#YJfLnIl=({xR)TrQzoaMQCuwMeW$t@ktV2T()zyBN<72!@|#G-~^EI zLXd(#;J`l0l8LuE*NQnnJGh)ywp?OFP1Dmr6aj+XeLUZr3B?7Q@Ev6G?veZbeF93l9a8?-1r?+n=QB)#>m4UKy%@9+%6+h^ z&DYNyCp(H&vZKh>Q=Es$2>CV}p|9*^#$?A2fU2u@6c!b#@f4bL7RJa8?+w;ElcRA-_#b zn%LI9SjDfr-0o1m!yGWt>Nf0H?Rh)k2G2F)MnOIrdZfr)o=}aRm?;C|>#EW1ZLz&s zGUE@pU!Kuc?9sa<&cm+}W9u&(CLl+2*jEdGW7{TZ!EU<$nOrUQ&r(<5fMqT($coKB zA@zc!2|}Oa*vxnhs_9n)UjO~iq>hbH${uOJB=rm)?Q}#N|NTSw;x)oL>?qh6mHF_H zPtV&4qaR{awJCk`Ie`;R)acHgTmJNOm^GU^zUUINC>l?4_6T`eBkYDL&^|S+r@zU| z)>yli8q+x{j#8q-Fk!ZPAtrCj&#PP)6G*Sk0;2qDxXF{*3820GRjA;Q<{ulI4ViD{ z2bsFT*c9_nYc??EeK^705v^0>J=f#;$HtJg=#dlR!G6em2pBA~ZeKgNNX^oUP7l7ri<|#}R9dfAHc&idrDazzbTitEMJ% zP{xFCi0DJA37u$;L{)|R8oEU;oHN9p5%lD0P=hQ(_^qHplhwA$obMdBG;ESm5j~^H zYV^KYH_@=Fq$cBYb3h7Aus~&mHP?zHf#aFEJRlU^_h^yjZA))ajRsaS0y`!nj!LEL#tcU2F1M^=jO)0iYJ6kdxnU9-rYL@TvaWO*SFw#sx@52;-lc7GeRl;IwhUs z!QaA6iao0879P*IF=;v*p*yvf#NsE-uZxdA!P_bw`Ai&)2R3jVPY}OpZ=p{Ow;+cx zZ%jQ@VYj=UAHV&ZBe~2Kz2O-5Fx6%8195%IXT0}ll9+mv94dLP6y``)vP{`d_0kbH zdX)0rS^e_VtV|N>7fCB~Fw>;p(Z7-#)r;E0e*)Tk$r}8f?U$EM)ZldOcWv%CmLVya zoKeI$MY<&zRE|@l99LsR0W=Mcd>KVQxN*^1r%OmM5w>L~D`GOt>7A>t2|Yu2!NEzV z0>cK+v!c6@A-WSN58VI~pb5g|UBBG^l+nsjk~iR`hc=MZzd08f(kGoDtW} zP*~LAu-XM?LAF+ysvoe%8C|-t0Y=j$uc@BJaD8#Rc;u~+*Joqc7(gzo2G6LsrsJCx zYmPaR%>v+eH$!(Sf7wS|9{lOL^8UF=R!dIv(p`5+Aj3YCrBMWv5I7n?HbbR5s~EX0 z4*%R|&u*GcQq3wt=V~Xd?yJRVoo8wBbs%g`m$k_*x=Kyhrzygn;G~BM%G!0Imx8eT z)tt_`TVvh5Yg6L3K|XN?f7=~HCuSXXQR$~pdlnuDjB>SpRhMQ!>c2-=V@%@mXs_pIAk@j{WNCCRu+@rZCAQ@-w zh8J~Az7_Et(KAQbizBz}pMWN;AHd4yn@)=+>z89Z zRKh=%dtYc)jhy=s$i=JfQ-svOega+k8tKTCW4ROdN2#t;w~;D4Ph)45knlg$Zf}=N z@17nvjp1W6qyLGX9NL1eMUE({0t<90|E^!lDYYoyR1R&})Us|4_*4DRhOfFf)twAG zlNvUg#QI+HQ3}sUxBOiT3kjNiu0xTS(V@Umj%2wsC0M@WceNkNi9gkXQk^>r{JM5F z2}dwJFx?`p@SZ;N`wA7;+iFR{pBE2Nt~T`rwuu9@oZZ7RLFK?*rLTTB7zWIBY#M99 jqe?i>Z3*D_x-PEQP%a>6jt<~~8^1YWZEr=e@Vxb3lWQ`p literal 0 HcmV?d00001 From e3d3a86ac23b3301f0a82f3ef4bff12d9dd33efe Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 17:50:57 +0800 Subject: [PATCH 101/484] feat: add 26.1 palette files and new enum values Add item, block, entity, and entity metadata palettes for Minecraft 26.1. New enums: GoldenDandelion (item/block), PottedGoldenDandelion (block), CatSoundVariant, CowSoundVariant, PigSoundVariant, ChickenSoundVariant (entity metadata). Update gen_entity_metadata_palette.py FIELD_TO_ENUM mapping for the new sound variant types. Made-with: Cursor --- .../Inventory/ItemPalettes/ItemPalette261.cs | 1524 +++++++++++ MinecraftClient/Inventory/ItemType.cs | 1 + .../Mapping/BlockPalettes/Palette261.cs | 2354 +++++++++++++++++ MinecraftClient/Mapping/EntityMetaDataType.cs | 16 + .../EntityMetadataPalette261.cs | 58 + .../EntityPalettes/EntityPalette261.cs | 175 ++ MinecraftClient/Mapping/Material.cs | 2 + tools/gen_entity_metadata_palette.py | 14 +- 8 files changed, 4139 insertions(+), 5 deletions(-) create mode 100644 MinecraftClient/Inventory/ItemPalettes/ItemPalette261.cs create mode 100644 MinecraftClient/Mapping/BlockPalettes/Palette261.cs create mode 100644 MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette261.cs create mode 100644 MinecraftClient/Mapping/EntityPalettes/EntityPalette261.cs diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette261.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette261.cs new file mode 100644 index 00000000..4acbe644 --- /dev/null +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette261.cs @@ -0,0 +1,1524 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Inventory.ItemPalettes +{ + public class ItemPalette261 : ItemPalette + { + private static readonly Dictionary mappings = new(); + + static ItemPalette261() + { + mappings[0] = ItemType.Air; + mappings[1] = ItemType.Stone; + mappings[2] = ItemType.Granite; + mappings[3] = ItemType.PolishedGranite; + mappings[4] = ItemType.Diorite; + mappings[5] = ItemType.PolishedDiorite; + mappings[6] = ItemType.Andesite; + mappings[7] = ItemType.PolishedAndesite; + mappings[8] = ItemType.Deepslate; + mappings[9] = ItemType.CobbledDeepslate; + mappings[10] = ItemType.PolishedDeepslate; + mappings[11] = ItemType.Calcite; + mappings[12] = ItemType.Tuff; + mappings[13] = ItemType.TuffSlab; + mappings[14] = ItemType.TuffStairs; + mappings[15] = ItemType.TuffWall; + mappings[16] = ItemType.ChiseledTuff; + mappings[17] = ItemType.PolishedTuff; + mappings[18] = ItemType.PolishedTuffSlab; + mappings[19] = ItemType.PolishedTuffStairs; + mappings[20] = ItemType.PolishedTuffWall; + mappings[21] = ItemType.TuffBricks; + mappings[22] = ItemType.TuffBrickSlab; + mappings[23] = ItemType.TuffBrickStairs; + mappings[24] = ItemType.TuffBrickWall; + mappings[25] = ItemType.ChiseledTuffBricks; + mappings[26] = ItemType.DripstoneBlock; + mappings[27] = ItemType.GrassBlock; + mappings[28] = ItemType.Dirt; + mappings[29] = ItemType.CoarseDirt; + mappings[30] = ItemType.Podzol; + mappings[31] = ItemType.RootedDirt; + mappings[32] = ItemType.Mud; + mappings[33] = ItemType.CrimsonNylium; + mappings[34] = ItemType.WarpedNylium; + mappings[35] = ItemType.Cobblestone; + mappings[36] = ItemType.OakPlanks; + mappings[37] = ItemType.SprucePlanks; + mappings[38] = ItemType.BirchPlanks; + mappings[39] = ItemType.JunglePlanks; + mappings[40] = ItemType.AcaciaPlanks; + mappings[41] = ItemType.CherryPlanks; + mappings[42] = ItemType.DarkOakPlanks; + mappings[43] = ItemType.PaleOakPlanks; + mappings[44] = ItemType.MangrovePlanks; + mappings[45] = ItemType.BambooPlanks; + mappings[46] = ItemType.CrimsonPlanks; + mappings[47] = ItemType.WarpedPlanks; + mappings[48] = ItemType.BambooMosaic; + mappings[49] = ItemType.OakSapling; + mappings[50] = ItemType.SpruceSapling; + mappings[51] = ItemType.BirchSapling; + mappings[52] = ItemType.JungleSapling; + mappings[53] = ItemType.AcaciaSapling; + mappings[54] = ItemType.CherrySapling; + mappings[55] = ItemType.DarkOakSapling; + mappings[56] = ItemType.PaleOakSapling; + mappings[57] = ItemType.MangrovePropagule; + mappings[58] = ItemType.Bedrock; + mappings[59] = ItemType.Sand; + mappings[60] = ItemType.SuspiciousSand; + mappings[61] = ItemType.SuspiciousGravel; + mappings[62] = ItemType.RedSand; + mappings[63] = ItemType.Gravel; + mappings[64] = ItemType.CoalOre; + mappings[65] = ItemType.DeepslateCoalOre; + mappings[66] = ItemType.IronOre; + mappings[67] = ItemType.DeepslateIronOre; + mappings[68] = ItemType.CopperOre; + mappings[69] = ItemType.DeepslateCopperOre; + mappings[70] = ItemType.GoldOre; + mappings[71] = ItemType.DeepslateGoldOre; + mappings[72] = ItemType.RedstoneOre; + mappings[73] = ItemType.DeepslateRedstoneOre; + mappings[74] = ItemType.EmeraldOre; + mappings[75] = ItemType.DeepslateEmeraldOre; + mappings[76] = ItemType.LapisOre; + mappings[77] = ItemType.DeepslateLapisOre; + mappings[78] = ItemType.DiamondOre; + mappings[79] = ItemType.DeepslateDiamondOre; + mappings[80] = ItemType.NetherGoldOre; + mappings[81] = ItemType.NetherQuartzOre; + mappings[82] = ItemType.AncientDebris; + mappings[83] = ItemType.CoalBlock; + mappings[84] = ItemType.RawIronBlock; + mappings[85] = ItemType.RawCopperBlock; + mappings[86] = ItemType.RawGoldBlock; + mappings[87] = ItemType.HeavyCore; + mappings[88] = ItemType.AmethystBlock; + mappings[89] = ItemType.BuddingAmethyst; + mappings[90] = ItemType.IronBlock; + mappings[91] = ItemType.CopperBlock; + mappings[92] = ItemType.GoldBlock; + mappings[93] = ItemType.DiamondBlock; + mappings[94] = ItemType.NetheriteBlock; + mappings[95] = ItemType.ExposedCopper; + mappings[96] = ItemType.WeatheredCopper; + mappings[97] = ItemType.OxidizedCopper; + mappings[98] = ItemType.ChiseledCopper; + mappings[99] = ItemType.ExposedChiseledCopper; + mappings[100] = ItemType.WeatheredChiseledCopper; + mappings[101] = ItemType.OxidizedChiseledCopper; + mappings[102] = ItemType.CutCopper; + mappings[103] = ItemType.ExposedCutCopper; + mappings[104] = ItemType.WeatheredCutCopper; + mappings[105] = ItemType.OxidizedCutCopper; + mappings[106] = ItemType.CutCopperStairs; + mappings[107] = ItemType.ExposedCutCopperStairs; + mappings[108] = ItemType.WeatheredCutCopperStairs; + mappings[109] = ItemType.OxidizedCutCopperStairs; + mappings[110] = ItemType.CutCopperSlab; + mappings[111] = ItemType.ExposedCutCopperSlab; + mappings[112] = ItemType.WeatheredCutCopperSlab; + mappings[113] = ItemType.OxidizedCutCopperSlab; + mappings[114] = ItemType.WaxedCopperBlock; + mappings[115] = ItemType.WaxedExposedCopper; + mappings[116] = ItemType.WaxedWeatheredCopper; + mappings[117] = ItemType.WaxedOxidizedCopper; + mappings[118] = ItemType.WaxedChiseledCopper; + mappings[119] = ItemType.WaxedExposedChiseledCopper; + mappings[120] = ItemType.WaxedWeatheredChiseledCopper; + mappings[121] = ItemType.WaxedOxidizedChiseledCopper; + mappings[122] = ItemType.WaxedCutCopper; + mappings[123] = ItemType.WaxedExposedCutCopper; + mappings[124] = ItemType.WaxedWeatheredCutCopper; + mappings[125] = ItemType.WaxedOxidizedCutCopper; + mappings[126] = ItemType.WaxedCutCopperStairs; + mappings[127] = ItemType.WaxedExposedCutCopperStairs; + mappings[128] = ItemType.WaxedWeatheredCutCopperStairs; + mappings[129] = ItemType.WaxedOxidizedCutCopperStairs; + mappings[130] = ItemType.WaxedCutCopperSlab; + mappings[131] = ItemType.WaxedExposedCutCopperSlab; + mappings[132] = ItemType.WaxedWeatheredCutCopperSlab; + mappings[133] = ItemType.WaxedOxidizedCutCopperSlab; + mappings[134] = ItemType.OakLog; + mappings[135] = ItemType.SpruceLog; + mappings[136] = ItemType.BirchLog; + mappings[137] = ItemType.JungleLog; + mappings[138] = ItemType.AcaciaLog; + mappings[139] = ItemType.CherryLog; + mappings[140] = ItemType.PaleOakLog; + mappings[141] = ItemType.DarkOakLog; + mappings[142] = ItemType.MangroveLog; + mappings[143] = ItemType.MangroveRoots; + mappings[144] = ItemType.MuddyMangroveRoots; + mappings[145] = ItemType.CrimsonStem; + mappings[146] = ItemType.WarpedStem; + mappings[147] = ItemType.BambooBlock; + mappings[148] = ItemType.StrippedOakLog; + mappings[149] = ItemType.StrippedSpruceLog; + mappings[150] = ItemType.StrippedBirchLog; + mappings[151] = ItemType.StrippedJungleLog; + mappings[152] = ItemType.StrippedAcaciaLog; + mappings[153] = ItemType.StrippedCherryLog; + mappings[154] = ItemType.StrippedDarkOakLog; + mappings[155] = ItemType.StrippedPaleOakLog; + mappings[156] = ItemType.StrippedMangroveLog; + mappings[157] = ItemType.StrippedCrimsonStem; + mappings[158] = ItemType.StrippedWarpedStem; + mappings[159] = ItemType.StrippedOakWood; + mappings[160] = ItemType.StrippedSpruceWood; + mappings[161] = ItemType.StrippedBirchWood; + mappings[162] = ItemType.StrippedJungleWood; + mappings[163] = ItemType.StrippedAcaciaWood; + mappings[164] = ItemType.StrippedCherryWood; + mappings[165] = ItemType.StrippedDarkOakWood; + mappings[166] = ItemType.StrippedPaleOakWood; + mappings[167] = ItemType.StrippedMangroveWood; + mappings[168] = ItemType.StrippedCrimsonHyphae; + mappings[169] = ItemType.StrippedWarpedHyphae; + mappings[170] = ItemType.StrippedBambooBlock; + mappings[171] = ItemType.OakWood; + mappings[172] = ItemType.SpruceWood; + mappings[173] = ItemType.BirchWood; + mappings[174] = ItemType.JungleWood; + mappings[175] = ItemType.AcaciaWood; + mappings[176] = ItemType.CherryWood; + mappings[177] = ItemType.PaleOakWood; + mappings[178] = ItemType.DarkOakWood; + mappings[179] = ItemType.MangroveWood; + mappings[180] = ItemType.CrimsonHyphae; + mappings[181] = ItemType.WarpedHyphae; + mappings[182] = ItemType.OakLeaves; + mappings[183] = ItemType.SpruceLeaves; + mappings[184] = ItemType.BirchLeaves; + mappings[185] = ItemType.JungleLeaves; + mappings[186] = ItemType.AcaciaLeaves; + mappings[187] = ItemType.CherryLeaves; + mappings[188] = ItemType.DarkOakLeaves; + mappings[189] = ItemType.PaleOakLeaves; + mappings[190] = ItemType.MangroveLeaves; + mappings[191] = ItemType.AzaleaLeaves; + mappings[192] = ItemType.FloweringAzaleaLeaves; + mappings[193] = ItemType.Sponge; + mappings[194] = ItemType.WetSponge; + mappings[195] = ItemType.Glass; + mappings[196] = ItemType.TintedGlass; + mappings[197] = ItemType.LapisBlock; + mappings[198] = ItemType.Sandstone; + mappings[199] = ItemType.ChiseledSandstone; + mappings[200] = ItemType.CutSandstone; + mappings[201] = ItemType.Cobweb; + mappings[202] = ItemType.ShortGrass; + mappings[203] = ItemType.Fern; + mappings[204] = ItemType.Bush; + mappings[205] = ItemType.Azalea; + mappings[206] = ItemType.FloweringAzalea; + mappings[207] = ItemType.DeadBush; + mappings[208] = ItemType.FireflyBush; + mappings[209] = ItemType.ShortDryGrass; + mappings[210] = ItemType.TallDryGrass; + mappings[211] = ItemType.Seagrass; + mappings[212] = ItemType.SeaPickle; + mappings[213] = ItemType.WhiteWool; + mappings[214] = ItemType.OrangeWool; + mappings[215] = ItemType.MagentaWool; + mappings[216] = ItemType.LightBlueWool; + mappings[217] = ItemType.YellowWool; + mappings[218] = ItemType.LimeWool; + mappings[219] = ItemType.PinkWool; + mappings[220] = ItemType.GrayWool; + mappings[221] = ItemType.LightGrayWool; + mappings[222] = ItemType.CyanWool; + mappings[223] = ItemType.PurpleWool; + mappings[224] = ItemType.BlueWool; + mappings[225] = ItemType.BrownWool; + mappings[226] = ItemType.GreenWool; + mappings[227] = ItemType.RedWool; + mappings[228] = ItemType.BlackWool; + mappings[229] = ItemType.Dandelion; + mappings[230] = ItemType.GoldenDandelion; + mappings[231] = ItemType.OpenEyeblossom; + mappings[232] = ItemType.ClosedEyeblossom; + mappings[233] = ItemType.Poppy; + mappings[234] = ItemType.BlueOrchid; + mappings[235] = ItemType.Allium; + mappings[236] = ItemType.AzureBluet; + mappings[237] = ItemType.RedTulip; + mappings[238] = ItemType.OrangeTulip; + mappings[239] = ItemType.WhiteTulip; + mappings[240] = ItemType.PinkTulip; + mappings[241] = ItemType.OxeyeDaisy; + mappings[242] = ItemType.Cornflower; + mappings[243] = ItemType.LilyOfTheValley; + mappings[244] = ItemType.WitherRose; + mappings[245] = ItemType.Torchflower; + mappings[246] = ItemType.PitcherPlant; + mappings[247] = ItemType.SporeBlossom; + mappings[248] = ItemType.BrownMushroom; + mappings[249] = ItemType.RedMushroom; + mappings[250] = ItemType.CrimsonFungus; + mappings[251] = ItemType.WarpedFungus; + mappings[252] = ItemType.CrimsonRoots; + mappings[253] = ItemType.WarpedRoots; + mappings[254] = ItemType.NetherSprouts; + mappings[255] = ItemType.WeepingVines; + mappings[256] = ItemType.TwistingVines; + mappings[257] = ItemType.SugarCane; + mappings[258] = ItemType.Kelp; + mappings[259] = ItemType.PinkPetals; + mappings[260] = ItemType.Wildflowers; + mappings[261] = ItemType.LeafLitter; + mappings[262] = ItemType.MossCarpet; + mappings[263] = ItemType.MossBlock; + mappings[264] = ItemType.PaleMossCarpet; + mappings[265] = ItemType.PaleHangingMoss; + mappings[266] = ItemType.PaleMossBlock; + mappings[267] = ItemType.HangingRoots; + mappings[268] = ItemType.BigDripleaf; + mappings[269] = ItemType.SmallDripleaf; + mappings[270] = ItemType.Bamboo; + mappings[271] = ItemType.OakSlab; + mappings[272] = ItemType.SpruceSlab; + mappings[273] = ItemType.BirchSlab; + mappings[274] = ItemType.JungleSlab; + mappings[275] = ItemType.AcaciaSlab; + mappings[276] = ItemType.CherrySlab; + mappings[277] = ItemType.DarkOakSlab; + mappings[278] = ItemType.PaleOakSlab; + mappings[279] = ItemType.MangroveSlab; + mappings[280] = ItemType.BambooSlab; + mappings[281] = ItemType.BambooMosaicSlab; + mappings[282] = ItemType.CrimsonSlab; + mappings[283] = ItemType.WarpedSlab; + mappings[284] = ItemType.StoneSlab; + mappings[285] = ItemType.SmoothStoneSlab; + mappings[286] = ItemType.SandstoneSlab; + mappings[287] = ItemType.CutSandstoneSlab; + mappings[288] = ItemType.PetrifiedOakSlab; + mappings[289] = ItemType.CobblestoneSlab; + mappings[290] = ItemType.BrickSlab; + mappings[291] = ItemType.StoneBrickSlab; + mappings[292] = ItemType.MudBrickSlab; + mappings[293] = ItemType.NetherBrickSlab; + mappings[294] = ItemType.QuartzSlab; + mappings[295] = ItemType.RedSandstoneSlab; + mappings[296] = ItemType.CutRedSandstoneSlab; + mappings[297] = ItemType.PurpurSlab; + mappings[298] = ItemType.PrismarineSlab; + mappings[299] = ItemType.PrismarineBrickSlab; + mappings[300] = ItemType.DarkPrismarineSlab; + mappings[301] = ItemType.SmoothQuartz; + mappings[302] = ItemType.SmoothRedSandstone; + mappings[303] = ItemType.SmoothSandstone; + mappings[304] = ItemType.SmoothStone; + mappings[305] = ItemType.Bricks; + mappings[306] = ItemType.AcaciaShelf; + mappings[307] = ItemType.BambooShelf; + mappings[308] = ItemType.BirchShelf; + mappings[309] = ItemType.CherryShelf; + mappings[310] = ItemType.CrimsonShelf; + mappings[311] = ItemType.DarkOakShelf; + mappings[312] = ItemType.JungleShelf; + mappings[313] = ItemType.MangroveShelf; + mappings[314] = ItemType.OakShelf; + mappings[315] = ItemType.PaleOakShelf; + mappings[316] = ItemType.SpruceShelf; + mappings[317] = ItemType.WarpedShelf; + mappings[318] = ItemType.Bookshelf; + mappings[319] = ItemType.ChiseledBookshelf; + mappings[320] = ItemType.DecoratedPot; + mappings[321] = ItemType.MossyCobblestone; + mappings[322] = ItemType.Obsidian; + mappings[323] = ItemType.Torch; + mappings[324] = ItemType.EndRod; + mappings[325] = ItemType.ChorusPlant; + mappings[326] = ItemType.ChorusFlower; + mappings[327] = ItemType.PurpurBlock; + mappings[328] = ItemType.PurpurPillar; + mappings[329] = ItemType.PurpurStairs; + mappings[330] = ItemType.Spawner; + mappings[331] = ItemType.CreakingHeart; + mappings[332] = ItemType.Chest; + mappings[333] = ItemType.CraftingTable; + mappings[334] = ItemType.Farmland; + mappings[335] = ItemType.Furnace; + mappings[336] = ItemType.Ladder; + mappings[337] = ItemType.CobblestoneStairs; + mappings[338] = ItemType.Snow; + mappings[339] = ItemType.Ice; + mappings[340] = ItemType.SnowBlock; + mappings[341] = ItemType.Cactus; + mappings[342] = ItemType.CactusFlower; + mappings[343] = ItemType.Clay; + mappings[344] = ItemType.Jukebox; + mappings[345] = ItemType.OakFence; + mappings[346] = ItemType.SpruceFence; + mappings[347] = ItemType.BirchFence; + mappings[348] = ItemType.JungleFence; + mappings[349] = ItemType.AcaciaFence; + mappings[350] = ItemType.CherryFence; + mappings[351] = ItemType.DarkOakFence; + mappings[352] = ItemType.PaleOakFence; + mappings[353] = ItemType.MangroveFence; + mappings[354] = ItemType.BambooFence; + mappings[355] = ItemType.CrimsonFence; + mappings[356] = ItemType.WarpedFence; + mappings[357] = ItemType.Pumpkin; + mappings[358] = ItemType.CarvedPumpkin; + mappings[359] = ItemType.JackOLantern; + mappings[360] = ItemType.Netherrack; + mappings[361] = ItemType.SoulSand; + mappings[362] = ItemType.SoulSoil; + mappings[363] = ItemType.Basalt; + mappings[364] = ItemType.PolishedBasalt; + mappings[365] = ItemType.SmoothBasalt; + mappings[366] = ItemType.SoulTorch; + mappings[367] = ItemType.CopperTorch; + mappings[368] = ItemType.Glowstone; + mappings[369] = ItemType.InfestedStone; + mappings[370] = ItemType.InfestedCobblestone; + mappings[371] = ItemType.InfestedStoneBricks; + mappings[372] = ItemType.InfestedMossyStoneBricks; + mappings[373] = ItemType.InfestedCrackedStoneBricks; + mappings[374] = ItemType.InfestedChiseledStoneBricks; + mappings[375] = ItemType.InfestedDeepslate; + mappings[376] = ItemType.StoneBricks; + mappings[377] = ItemType.MossyStoneBricks; + mappings[378] = ItemType.CrackedStoneBricks; + mappings[379] = ItemType.ChiseledStoneBricks; + mappings[380] = ItemType.PackedMud; + mappings[381] = ItemType.MudBricks; + mappings[382] = ItemType.DeepslateBricks; + mappings[383] = ItemType.CrackedDeepslateBricks; + mappings[384] = ItemType.DeepslateTiles; + mappings[385] = ItemType.CrackedDeepslateTiles; + mappings[386] = ItemType.ChiseledDeepslate; + mappings[387] = ItemType.ReinforcedDeepslate; + mappings[388] = ItemType.BrownMushroomBlock; + mappings[389] = ItemType.RedMushroomBlock; + mappings[390] = ItemType.MushroomStem; + mappings[391] = ItemType.IronBars; + mappings[392] = ItemType.CopperBars; + mappings[393] = ItemType.ExposedCopperBars; + mappings[394] = ItemType.WeatheredCopperBars; + mappings[395] = ItemType.OxidizedCopperBars; + mappings[396] = ItemType.WaxedCopperBars; + mappings[397] = ItemType.WaxedExposedCopperBars; + mappings[398] = ItemType.WaxedWeatheredCopperBars; + mappings[399] = ItemType.WaxedOxidizedCopperBars; + mappings[400] = ItemType.IronChain; + mappings[401] = ItemType.CopperChain; + mappings[402] = ItemType.ExposedCopperChain; + mappings[403] = ItemType.WeatheredCopperChain; + mappings[404] = ItemType.OxidizedCopperChain; + mappings[405] = ItemType.WaxedCopperChain; + mappings[406] = ItemType.WaxedExposedCopperChain; + mappings[407] = ItemType.WaxedWeatheredCopperChain; + mappings[408] = ItemType.WaxedOxidizedCopperChain; + mappings[409] = ItemType.GlassPane; + mappings[410] = ItemType.Melon; + mappings[411] = ItemType.Vine; + mappings[412] = ItemType.GlowLichen; + mappings[413] = ItemType.ResinClump; + mappings[414] = ItemType.ResinBlock; + mappings[415] = ItemType.ResinBricks; + mappings[416] = ItemType.ResinBrickStairs; + mappings[417] = ItemType.ResinBrickSlab; + mappings[418] = ItemType.ResinBrickWall; + mappings[419] = ItemType.ChiseledResinBricks; + mappings[420] = ItemType.BrickStairs; + mappings[421] = ItemType.StoneBrickStairs; + mappings[422] = ItemType.MudBrickStairs; + mappings[423] = ItemType.Mycelium; + mappings[424] = ItemType.LilyPad; + mappings[425] = ItemType.NetherBricks; + mappings[426] = ItemType.CrackedNetherBricks; + mappings[427] = ItemType.ChiseledNetherBricks; + mappings[428] = ItemType.NetherBrickFence; + mappings[429] = ItemType.NetherBrickStairs; + mappings[430] = ItemType.Sculk; + mappings[431] = ItemType.SculkVein; + mappings[432] = ItemType.SculkCatalyst; + mappings[433] = ItemType.SculkShrieker; + mappings[434] = ItemType.EnchantingTable; + mappings[435] = ItemType.EndPortalFrame; + mappings[436] = ItemType.EndStone; + mappings[437] = ItemType.EndStoneBricks; + mappings[438] = ItemType.DragonEgg; + mappings[439] = ItemType.SandstoneStairs; + mappings[440] = ItemType.EnderChest; + mappings[441] = ItemType.EmeraldBlock; + mappings[442] = ItemType.OakStairs; + mappings[443] = ItemType.SpruceStairs; + mappings[444] = ItemType.BirchStairs; + mappings[445] = ItemType.JungleStairs; + mappings[446] = ItemType.AcaciaStairs; + mappings[447] = ItemType.CherryStairs; + mappings[448] = ItemType.DarkOakStairs; + mappings[449] = ItemType.PaleOakStairs; + mappings[450] = ItemType.MangroveStairs; + mappings[451] = ItemType.BambooStairs; + mappings[452] = ItemType.BambooMosaicStairs; + mappings[453] = ItemType.CrimsonStairs; + mappings[454] = ItemType.WarpedStairs; + mappings[455] = ItemType.CommandBlock; + mappings[456] = ItemType.Beacon; + mappings[457] = ItemType.CobblestoneWall; + mappings[458] = ItemType.MossyCobblestoneWall; + mappings[459] = ItemType.BrickWall; + mappings[460] = ItemType.PrismarineWall; + mappings[461] = ItemType.RedSandstoneWall; + mappings[462] = ItemType.MossyStoneBrickWall; + mappings[463] = ItemType.GraniteWall; + mappings[464] = ItemType.StoneBrickWall; + mappings[465] = ItemType.MudBrickWall; + mappings[466] = ItemType.NetherBrickWall; + mappings[467] = ItemType.AndesiteWall; + mappings[468] = ItemType.RedNetherBrickWall; + mappings[469] = ItemType.SandstoneWall; + mappings[470] = ItemType.EndStoneBrickWall; + mappings[471] = ItemType.DioriteWall; + mappings[472] = ItemType.BlackstoneWall; + mappings[473] = ItemType.PolishedBlackstoneWall; + mappings[474] = ItemType.PolishedBlackstoneBrickWall; + mappings[475] = ItemType.CobbledDeepslateWall; + mappings[476] = ItemType.PolishedDeepslateWall; + mappings[477] = ItemType.DeepslateBrickWall; + mappings[478] = ItemType.DeepslateTileWall; + mappings[479] = ItemType.Anvil; + mappings[480] = ItemType.ChippedAnvil; + mappings[481] = ItemType.DamagedAnvil; + mappings[482] = ItemType.ChiseledQuartzBlock; + mappings[483] = ItemType.QuartzBlock; + mappings[484] = ItemType.QuartzBricks; + mappings[485] = ItemType.QuartzPillar; + mappings[486] = ItemType.QuartzStairs; + mappings[487] = ItemType.WhiteTerracotta; + mappings[488] = ItemType.OrangeTerracotta; + mappings[489] = ItemType.MagentaTerracotta; + mappings[490] = ItemType.LightBlueTerracotta; + mappings[491] = ItemType.YellowTerracotta; + mappings[492] = ItemType.LimeTerracotta; + mappings[493] = ItemType.PinkTerracotta; + mappings[494] = ItemType.GrayTerracotta; + mappings[495] = ItemType.LightGrayTerracotta; + mappings[496] = ItemType.CyanTerracotta; + mappings[497] = ItemType.PurpleTerracotta; + mappings[498] = ItemType.BlueTerracotta; + mappings[499] = ItemType.BrownTerracotta; + mappings[500] = ItemType.GreenTerracotta; + mappings[501] = ItemType.RedTerracotta; + mappings[502] = ItemType.BlackTerracotta; + mappings[503] = ItemType.Barrier; + mappings[504] = ItemType.Light; + mappings[505] = ItemType.HayBlock; + mappings[506] = ItemType.WhiteCarpet; + mappings[507] = ItemType.OrangeCarpet; + mappings[508] = ItemType.MagentaCarpet; + mappings[509] = ItemType.LightBlueCarpet; + mappings[510] = ItemType.YellowCarpet; + mappings[511] = ItemType.LimeCarpet; + mappings[512] = ItemType.PinkCarpet; + mappings[513] = ItemType.GrayCarpet; + mappings[514] = ItemType.LightGrayCarpet; + mappings[515] = ItemType.CyanCarpet; + mappings[516] = ItemType.PurpleCarpet; + mappings[517] = ItemType.BlueCarpet; + mappings[518] = ItemType.BrownCarpet; + mappings[519] = ItemType.GreenCarpet; + mappings[520] = ItemType.RedCarpet; + mappings[521] = ItemType.BlackCarpet; + mappings[522] = ItemType.Terracotta; + mappings[523] = ItemType.PackedIce; + mappings[524] = ItemType.DirtPath; + mappings[525] = ItemType.Sunflower; + mappings[526] = ItemType.Lilac; + mappings[527] = ItemType.RoseBush; + mappings[528] = ItemType.Peony; + mappings[529] = ItemType.TallGrass; + mappings[530] = ItemType.LargeFern; + mappings[531] = ItemType.WhiteStainedGlass; + mappings[532] = ItemType.OrangeStainedGlass; + mappings[533] = ItemType.MagentaStainedGlass; + mappings[534] = ItemType.LightBlueStainedGlass; + mappings[535] = ItemType.YellowStainedGlass; + mappings[536] = ItemType.LimeStainedGlass; + mappings[537] = ItemType.PinkStainedGlass; + mappings[538] = ItemType.GrayStainedGlass; + mappings[539] = ItemType.LightGrayStainedGlass; + mappings[540] = ItemType.CyanStainedGlass; + mappings[541] = ItemType.PurpleStainedGlass; + mappings[542] = ItemType.BlueStainedGlass; + mappings[543] = ItemType.BrownStainedGlass; + mappings[544] = ItemType.GreenStainedGlass; + mappings[545] = ItemType.RedStainedGlass; + mappings[546] = ItemType.BlackStainedGlass; + mappings[547] = ItemType.WhiteStainedGlassPane; + mappings[548] = ItemType.OrangeStainedGlassPane; + mappings[549] = ItemType.MagentaStainedGlassPane; + mappings[550] = ItemType.LightBlueStainedGlassPane; + mappings[551] = ItemType.YellowStainedGlassPane; + mappings[552] = ItemType.LimeStainedGlassPane; + mappings[553] = ItemType.PinkStainedGlassPane; + mappings[554] = ItemType.GrayStainedGlassPane; + mappings[555] = ItemType.LightGrayStainedGlassPane; + mappings[556] = ItemType.CyanStainedGlassPane; + mappings[557] = ItemType.PurpleStainedGlassPane; + mappings[558] = ItemType.BlueStainedGlassPane; + mappings[559] = ItemType.BrownStainedGlassPane; + mappings[560] = ItemType.GreenStainedGlassPane; + mappings[561] = ItemType.RedStainedGlassPane; + mappings[562] = ItemType.BlackStainedGlassPane; + mappings[563] = ItemType.Prismarine; + mappings[564] = ItemType.PrismarineBricks; + mappings[565] = ItemType.DarkPrismarine; + mappings[566] = ItemType.PrismarineStairs; + mappings[567] = ItemType.PrismarineBrickStairs; + mappings[568] = ItemType.DarkPrismarineStairs; + mappings[569] = ItemType.SeaLantern; + mappings[570] = ItemType.RedSandstone; + mappings[571] = ItemType.ChiseledRedSandstone; + mappings[572] = ItemType.CutRedSandstone; + mappings[573] = ItemType.RedSandstoneStairs; + mappings[574] = ItemType.RepeatingCommandBlock; + mappings[575] = ItemType.ChainCommandBlock; + mappings[576] = ItemType.MagmaBlock; + mappings[577] = ItemType.NetherWartBlock; + mappings[578] = ItemType.WarpedWartBlock; + mappings[579] = ItemType.RedNetherBricks; + mappings[580] = ItemType.BoneBlock; + mappings[581] = ItemType.StructureVoid; + mappings[582] = ItemType.ShulkerBox; + mappings[583] = ItemType.WhiteShulkerBox; + mappings[584] = ItemType.OrangeShulkerBox; + mappings[585] = ItemType.MagentaShulkerBox; + mappings[586] = ItemType.LightBlueShulkerBox; + mappings[587] = ItemType.YellowShulkerBox; + mappings[588] = ItemType.LimeShulkerBox; + mappings[589] = ItemType.PinkShulkerBox; + mappings[590] = ItemType.GrayShulkerBox; + mappings[591] = ItemType.LightGrayShulkerBox; + mappings[592] = ItemType.CyanShulkerBox; + mappings[593] = ItemType.PurpleShulkerBox; + mappings[594] = ItemType.BlueShulkerBox; + mappings[595] = ItemType.BrownShulkerBox; + mappings[596] = ItemType.GreenShulkerBox; + mappings[597] = ItemType.RedShulkerBox; + mappings[598] = ItemType.BlackShulkerBox; + mappings[599] = ItemType.WhiteGlazedTerracotta; + mappings[600] = ItemType.OrangeGlazedTerracotta; + mappings[601] = ItemType.MagentaGlazedTerracotta; + mappings[602] = ItemType.LightBlueGlazedTerracotta; + mappings[603] = ItemType.YellowGlazedTerracotta; + mappings[604] = ItemType.LimeGlazedTerracotta; + mappings[605] = ItemType.PinkGlazedTerracotta; + mappings[606] = ItemType.GrayGlazedTerracotta; + mappings[607] = ItemType.LightGrayGlazedTerracotta; + mappings[608] = ItemType.CyanGlazedTerracotta; + mappings[609] = ItemType.PurpleGlazedTerracotta; + mappings[610] = ItemType.BlueGlazedTerracotta; + mappings[611] = ItemType.BrownGlazedTerracotta; + mappings[612] = ItemType.GreenGlazedTerracotta; + mappings[613] = ItemType.RedGlazedTerracotta; + mappings[614] = ItemType.BlackGlazedTerracotta; + mappings[615] = ItemType.WhiteConcrete; + mappings[616] = ItemType.OrangeConcrete; + mappings[617] = ItemType.MagentaConcrete; + mappings[618] = ItemType.LightBlueConcrete; + mappings[619] = ItemType.YellowConcrete; + mappings[620] = ItemType.LimeConcrete; + mappings[621] = ItemType.PinkConcrete; + mappings[622] = ItemType.GrayConcrete; + mappings[623] = ItemType.LightGrayConcrete; + mappings[624] = ItemType.CyanConcrete; + mappings[625] = ItemType.PurpleConcrete; + mappings[626] = ItemType.BlueConcrete; + mappings[627] = ItemType.BrownConcrete; + mappings[628] = ItemType.GreenConcrete; + mappings[629] = ItemType.RedConcrete; + mappings[630] = ItemType.BlackConcrete; + mappings[631] = ItemType.WhiteConcretePowder; + mappings[632] = ItemType.OrangeConcretePowder; + mappings[633] = ItemType.MagentaConcretePowder; + mappings[634] = ItemType.LightBlueConcretePowder; + mappings[635] = ItemType.YellowConcretePowder; + mappings[636] = ItemType.LimeConcretePowder; + mappings[637] = ItemType.PinkConcretePowder; + mappings[638] = ItemType.GrayConcretePowder; + mappings[639] = ItemType.LightGrayConcretePowder; + mappings[640] = ItemType.CyanConcretePowder; + mappings[641] = ItemType.PurpleConcretePowder; + mappings[642] = ItemType.BlueConcretePowder; + mappings[643] = ItemType.BrownConcretePowder; + mappings[644] = ItemType.GreenConcretePowder; + mappings[645] = ItemType.RedConcretePowder; + mappings[646] = ItemType.BlackConcretePowder; + mappings[647] = ItemType.TurtleEgg; + mappings[648] = ItemType.SnifferEgg; + mappings[649] = ItemType.DriedGhast; + mappings[650] = ItemType.DeadTubeCoralBlock; + mappings[651] = ItemType.DeadBrainCoralBlock; + mappings[652] = ItemType.DeadBubbleCoralBlock; + mappings[653] = ItemType.DeadFireCoralBlock; + mappings[654] = ItemType.DeadHornCoralBlock; + mappings[655] = ItemType.TubeCoralBlock; + mappings[656] = ItemType.BrainCoralBlock; + mappings[657] = ItemType.BubbleCoralBlock; + mappings[658] = ItemType.FireCoralBlock; + mappings[659] = ItemType.HornCoralBlock; + mappings[660] = ItemType.TubeCoral; + mappings[661] = ItemType.BrainCoral; + mappings[662] = ItemType.BubbleCoral; + mappings[663] = ItemType.FireCoral; + mappings[664] = ItemType.HornCoral; + mappings[665] = ItemType.DeadBrainCoral; + mappings[666] = ItemType.DeadBubbleCoral; + mappings[667] = ItemType.DeadFireCoral; + mappings[668] = ItemType.DeadHornCoral; + mappings[669] = ItemType.DeadTubeCoral; + mappings[670] = ItemType.TubeCoralFan; + mappings[671] = ItemType.BrainCoralFan; + mappings[672] = ItemType.BubbleCoralFan; + mappings[673] = ItemType.FireCoralFan; + mappings[674] = ItemType.HornCoralFan; + mappings[675] = ItemType.DeadTubeCoralFan; + mappings[676] = ItemType.DeadBrainCoralFan; + mappings[677] = ItemType.DeadBubbleCoralFan; + mappings[678] = ItemType.DeadFireCoralFan; + mappings[679] = ItemType.DeadHornCoralFan; + mappings[680] = ItemType.BlueIce; + mappings[681] = ItemType.Conduit; + mappings[682] = ItemType.PolishedGraniteStairs; + mappings[683] = ItemType.SmoothRedSandstoneStairs; + mappings[684] = ItemType.MossyStoneBrickStairs; + mappings[685] = ItemType.PolishedDioriteStairs; + mappings[686] = ItemType.MossyCobblestoneStairs; + mappings[687] = ItemType.EndStoneBrickStairs; + mappings[688] = ItemType.StoneStairs; + mappings[689] = ItemType.SmoothSandstoneStairs; + mappings[690] = ItemType.SmoothQuartzStairs; + mappings[691] = ItemType.GraniteStairs; + mappings[692] = ItemType.AndesiteStairs; + mappings[693] = ItemType.RedNetherBrickStairs; + mappings[694] = ItemType.PolishedAndesiteStairs; + mappings[695] = ItemType.DioriteStairs; + mappings[696] = ItemType.CobbledDeepslateStairs; + mappings[697] = ItemType.PolishedDeepslateStairs; + mappings[698] = ItemType.DeepslateBrickStairs; + mappings[699] = ItemType.DeepslateTileStairs; + mappings[700] = ItemType.PolishedGraniteSlab; + mappings[701] = ItemType.SmoothRedSandstoneSlab; + mappings[702] = ItemType.MossyStoneBrickSlab; + mappings[703] = ItemType.PolishedDioriteSlab; + mappings[704] = ItemType.MossyCobblestoneSlab; + mappings[705] = ItemType.EndStoneBrickSlab; + mappings[706] = ItemType.SmoothSandstoneSlab; + mappings[707] = ItemType.SmoothQuartzSlab; + mappings[708] = ItemType.GraniteSlab; + mappings[709] = ItemType.AndesiteSlab; + mappings[710] = ItemType.RedNetherBrickSlab; + mappings[711] = ItemType.PolishedAndesiteSlab; + mappings[712] = ItemType.DioriteSlab; + mappings[713] = ItemType.CobbledDeepslateSlab; + mappings[714] = ItemType.PolishedDeepslateSlab; + mappings[715] = ItemType.DeepslateBrickSlab; + mappings[716] = ItemType.DeepslateTileSlab; + mappings[717] = ItemType.Scaffolding; + mappings[718] = ItemType.Redstone; + mappings[719] = ItemType.RedstoneTorch; + mappings[720] = ItemType.RedstoneBlock; + mappings[721] = ItemType.Repeater; + mappings[722] = ItemType.Comparator; + mappings[723] = ItemType.Piston; + mappings[724] = ItemType.StickyPiston; + mappings[725] = ItemType.SlimeBlock; + mappings[726] = ItemType.HoneyBlock; + mappings[727] = ItemType.Observer; + mappings[728] = ItemType.Hopper; + mappings[729] = ItemType.Dispenser; + mappings[730] = ItemType.Dropper; + mappings[731] = ItemType.Lectern; + mappings[732] = ItemType.Target; + mappings[733] = ItemType.Lever; + mappings[734] = ItemType.LightningRod; + mappings[735] = ItemType.ExposedLightningRod; + mappings[736] = ItemType.WeatheredLightningRod; + mappings[737] = ItemType.OxidizedLightningRod; + mappings[738] = ItemType.WaxedLightningRod; + mappings[739] = ItemType.WaxedExposedLightningRod; + mappings[740] = ItemType.WaxedWeatheredLightningRod; + mappings[741] = ItemType.WaxedOxidizedLightningRod; + mappings[742] = ItemType.DaylightDetector; + mappings[743] = ItemType.SculkSensor; + mappings[744] = ItemType.CalibratedSculkSensor; + mappings[745] = ItemType.TripwireHook; + mappings[746] = ItemType.TrappedChest; + mappings[747] = ItemType.Tnt; + mappings[748] = ItemType.RedstoneLamp; + mappings[749] = ItemType.NoteBlock; + mappings[750] = ItemType.StoneButton; + mappings[751] = ItemType.PolishedBlackstoneButton; + mappings[752] = ItemType.OakButton; + mappings[753] = ItemType.SpruceButton; + mappings[754] = ItemType.BirchButton; + mappings[755] = ItemType.JungleButton; + mappings[756] = ItemType.AcaciaButton; + mappings[757] = ItemType.CherryButton; + mappings[758] = ItemType.DarkOakButton; + mappings[759] = ItemType.PaleOakButton; + mappings[760] = ItemType.MangroveButton; + mappings[761] = ItemType.BambooButton; + mappings[762] = ItemType.CrimsonButton; + mappings[763] = ItemType.WarpedButton; + mappings[764] = ItemType.StonePressurePlate; + mappings[765] = ItemType.PolishedBlackstonePressurePlate; + mappings[766] = ItemType.LightWeightedPressurePlate; + mappings[767] = ItemType.HeavyWeightedPressurePlate; + mappings[768] = ItemType.OakPressurePlate; + mappings[769] = ItemType.SprucePressurePlate; + mappings[770] = ItemType.BirchPressurePlate; + mappings[771] = ItemType.JunglePressurePlate; + mappings[772] = ItemType.AcaciaPressurePlate; + mappings[773] = ItemType.CherryPressurePlate; + mappings[774] = ItemType.DarkOakPressurePlate; + mappings[775] = ItemType.PaleOakPressurePlate; + mappings[776] = ItemType.MangrovePressurePlate; + mappings[777] = ItemType.BambooPressurePlate; + mappings[778] = ItemType.CrimsonPressurePlate; + mappings[779] = ItemType.WarpedPressurePlate; + mappings[780] = ItemType.IronDoor; + mappings[781] = ItemType.OakDoor; + mappings[782] = ItemType.SpruceDoor; + mappings[783] = ItemType.BirchDoor; + mappings[784] = ItemType.JungleDoor; + mappings[785] = ItemType.AcaciaDoor; + mappings[786] = ItemType.CherryDoor; + mappings[787] = ItemType.DarkOakDoor; + mappings[788] = ItemType.PaleOakDoor; + mappings[789] = ItemType.MangroveDoor; + mappings[790] = ItemType.BambooDoor; + mappings[791] = ItemType.CrimsonDoor; + mappings[792] = ItemType.WarpedDoor; + mappings[793] = ItemType.CopperDoor; + mappings[794] = ItemType.ExposedCopperDoor; + mappings[795] = ItemType.WeatheredCopperDoor; + mappings[796] = ItemType.OxidizedCopperDoor; + mappings[797] = ItemType.WaxedCopperDoor; + mappings[798] = ItemType.WaxedExposedCopperDoor; + mappings[799] = ItemType.WaxedWeatheredCopperDoor; + mappings[800] = ItemType.WaxedOxidizedCopperDoor; + mappings[801] = ItemType.IronTrapdoor; + mappings[802] = ItemType.OakTrapdoor; + mappings[803] = ItemType.SpruceTrapdoor; + mappings[804] = ItemType.BirchTrapdoor; + mappings[805] = ItemType.JungleTrapdoor; + mappings[806] = ItemType.AcaciaTrapdoor; + mappings[807] = ItemType.CherryTrapdoor; + mappings[808] = ItemType.DarkOakTrapdoor; + mappings[809] = ItemType.PaleOakTrapdoor; + mappings[810] = ItemType.MangroveTrapdoor; + mappings[811] = ItemType.BambooTrapdoor; + mappings[812] = ItemType.CrimsonTrapdoor; + mappings[813] = ItemType.WarpedTrapdoor; + mappings[814] = ItemType.CopperTrapdoor; + mappings[815] = ItemType.ExposedCopperTrapdoor; + mappings[816] = ItemType.WeatheredCopperTrapdoor; + mappings[817] = ItemType.OxidizedCopperTrapdoor; + mappings[818] = ItemType.WaxedCopperTrapdoor; + mappings[819] = ItemType.WaxedExposedCopperTrapdoor; + mappings[820] = ItemType.WaxedWeatheredCopperTrapdoor; + mappings[821] = ItemType.WaxedOxidizedCopperTrapdoor; + mappings[822] = ItemType.OakFenceGate; + mappings[823] = ItemType.SpruceFenceGate; + mappings[824] = ItemType.BirchFenceGate; + mappings[825] = ItemType.JungleFenceGate; + mappings[826] = ItemType.AcaciaFenceGate; + mappings[827] = ItemType.CherryFenceGate; + mappings[828] = ItemType.DarkOakFenceGate; + mappings[829] = ItemType.PaleOakFenceGate; + mappings[830] = ItemType.MangroveFenceGate; + mappings[831] = ItemType.BambooFenceGate; + mappings[832] = ItemType.CrimsonFenceGate; + mappings[833] = ItemType.WarpedFenceGate; + mappings[834] = ItemType.PoweredRail; + mappings[835] = ItemType.DetectorRail; + mappings[836] = ItemType.Rail; + mappings[837] = ItemType.ActivatorRail; + mappings[838] = ItemType.Saddle; + mappings[839] = ItemType.WhiteHarness; + mappings[840] = ItemType.OrangeHarness; + mappings[841] = ItemType.MagentaHarness; + mappings[842] = ItemType.LightBlueHarness; + mappings[843] = ItemType.YellowHarness; + mappings[844] = ItemType.LimeHarness; + mappings[845] = ItemType.PinkHarness; + mappings[846] = ItemType.GrayHarness; + mappings[847] = ItemType.LightGrayHarness; + mappings[848] = ItemType.CyanHarness; + mappings[849] = ItemType.PurpleHarness; + mappings[850] = ItemType.BlueHarness; + mappings[851] = ItemType.BrownHarness; + mappings[852] = ItemType.GreenHarness; + mappings[853] = ItemType.RedHarness; + mappings[854] = ItemType.BlackHarness; + mappings[855] = ItemType.Minecart; + mappings[856] = ItemType.ChestMinecart; + mappings[857] = ItemType.FurnaceMinecart; + mappings[858] = ItemType.TntMinecart; + mappings[859] = ItemType.HopperMinecart; + mappings[860] = ItemType.CarrotOnAStick; + mappings[861] = ItemType.WarpedFungusOnAStick; + mappings[862] = ItemType.PhantomMembrane; + mappings[863] = ItemType.Elytra; + mappings[864] = ItemType.OakBoat; + mappings[865] = ItemType.OakChestBoat; + mappings[866] = ItemType.SpruceBoat; + mappings[867] = ItemType.SpruceChestBoat; + mappings[868] = ItemType.BirchBoat; + mappings[869] = ItemType.BirchChestBoat; + mappings[870] = ItemType.JungleBoat; + mappings[871] = ItemType.JungleChestBoat; + mappings[872] = ItemType.AcaciaBoat; + mappings[873] = ItemType.AcaciaChestBoat; + mappings[874] = ItemType.CherryBoat; + mappings[875] = ItemType.CherryChestBoat; + mappings[876] = ItemType.DarkOakBoat; + mappings[877] = ItemType.DarkOakChestBoat; + mappings[878] = ItemType.PaleOakBoat; + mappings[879] = ItemType.PaleOakChestBoat; + mappings[880] = ItemType.MangroveBoat; + mappings[881] = ItemType.MangroveChestBoat; + mappings[882] = ItemType.BambooRaft; + mappings[883] = ItemType.BambooChestRaft; + mappings[884] = ItemType.StructureBlock; + mappings[885] = ItemType.Jigsaw; + mappings[886] = ItemType.TestBlock; + mappings[887] = ItemType.TestInstanceBlock; + mappings[888] = ItemType.TurtleHelmet; + mappings[889] = ItemType.TurtleScute; + mappings[890] = ItemType.ArmadilloScute; + mappings[891] = ItemType.WolfArmor; + mappings[892] = ItemType.FlintAndSteel; + mappings[893] = ItemType.Bowl; + mappings[894] = ItemType.Apple; + mappings[895] = ItemType.Bow; + mappings[896] = ItemType.Arrow; + mappings[897] = ItemType.Coal; + mappings[898] = ItemType.Charcoal; + mappings[899] = ItemType.Diamond; + mappings[900] = ItemType.Emerald; + mappings[901] = ItemType.LapisLazuli; + mappings[902] = ItemType.Quartz; + mappings[903] = ItemType.AmethystShard; + mappings[904] = ItemType.RawIron; + mappings[905] = ItemType.IronIngot; + mappings[906] = ItemType.RawCopper; + mappings[907] = ItemType.CopperIngot; + mappings[908] = ItemType.RawGold; + mappings[909] = ItemType.GoldIngot; + mappings[910] = ItemType.NetheriteIngot; + mappings[911] = ItemType.NetheriteScrap; + mappings[912] = ItemType.WoodenSword; + mappings[913] = ItemType.WoodenShovel; + mappings[914] = ItemType.WoodenPickaxe; + mappings[915] = ItemType.WoodenAxe; + mappings[916] = ItemType.WoodenHoe; + mappings[917] = ItemType.CopperSword; + mappings[918] = ItemType.CopperShovel; + mappings[919] = ItemType.CopperPickaxe; + mappings[920] = ItemType.CopperAxe; + mappings[921] = ItemType.CopperHoe; + mappings[922] = ItemType.StoneSword; + mappings[923] = ItemType.StoneShovel; + mappings[924] = ItemType.StonePickaxe; + mappings[925] = ItemType.StoneAxe; + mappings[926] = ItemType.StoneHoe; + mappings[927] = ItemType.GoldenSword; + mappings[928] = ItemType.GoldenShovel; + mappings[929] = ItemType.GoldenPickaxe; + mappings[930] = ItemType.GoldenAxe; + mappings[931] = ItemType.GoldenHoe; + mappings[932] = ItemType.IronSword; + mappings[933] = ItemType.IronShovel; + mappings[934] = ItemType.IronPickaxe; + mappings[935] = ItemType.IronAxe; + mappings[936] = ItemType.IronHoe; + mappings[937] = ItemType.DiamondSword; + mappings[938] = ItemType.DiamondShovel; + mappings[939] = ItemType.DiamondPickaxe; + mappings[940] = ItemType.DiamondAxe; + mappings[941] = ItemType.DiamondHoe; + mappings[942] = ItemType.NetheriteSword; + mappings[943] = ItemType.NetheriteShovel; + mappings[944] = ItemType.NetheritePickaxe; + mappings[945] = ItemType.NetheriteAxe; + mappings[946] = ItemType.NetheriteHoe; + mappings[947] = ItemType.Stick; + mappings[948] = ItemType.MushroomStew; + mappings[949] = ItemType.String; + mappings[950] = ItemType.Feather; + mappings[951] = ItemType.Gunpowder; + mappings[952] = ItemType.WheatSeeds; + mappings[953] = ItemType.Wheat; + mappings[954] = ItemType.Bread; + mappings[955] = ItemType.LeatherHelmet; + mappings[956] = ItemType.LeatherChestplate; + mappings[957] = ItemType.LeatherLeggings; + mappings[958] = ItemType.LeatherBoots; + mappings[959] = ItemType.CopperHelmet; + mappings[960] = ItemType.CopperChestplate; + mappings[961] = ItemType.CopperLeggings; + mappings[962] = ItemType.CopperBoots; + mappings[963] = ItemType.ChainmailHelmet; + mappings[964] = ItemType.ChainmailChestplate; + mappings[965] = ItemType.ChainmailLeggings; + mappings[966] = ItemType.ChainmailBoots; + mappings[967] = ItemType.IronHelmet; + mappings[968] = ItemType.IronChestplate; + mappings[969] = ItemType.IronLeggings; + mappings[970] = ItemType.IronBoots; + mappings[971] = ItemType.DiamondHelmet; + mappings[972] = ItemType.DiamondChestplate; + mappings[973] = ItemType.DiamondLeggings; + mappings[974] = ItemType.DiamondBoots; + mappings[975] = ItemType.GoldenHelmet; + mappings[976] = ItemType.GoldenChestplate; + mappings[977] = ItemType.GoldenLeggings; + mappings[978] = ItemType.GoldenBoots; + mappings[979] = ItemType.NetheriteHelmet; + mappings[980] = ItemType.NetheriteChestplate; + mappings[981] = ItemType.NetheriteLeggings; + mappings[982] = ItemType.NetheriteBoots; + mappings[983] = ItemType.Flint; + mappings[984] = ItemType.Porkchop; + mappings[985] = ItemType.CookedPorkchop; + mappings[986] = ItemType.Painting; + mappings[987] = ItemType.GoldenApple; + mappings[988] = ItemType.EnchantedGoldenApple; + mappings[989] = ItemType.OakSign; + mappings[990] = ItemType.SpruceSign; + mappings[991] = ItemType.BirchSign; + mappings[992] = ItemType.JungleSign; + mappings[993] = ItemType.AcaciaSign; + mappings[994] = ItemType.CherrySign; + mappings[995] = ItemType.DarkOakSign; + mappings[996] = ItemType.PaleOakSign; + mappings[997] = ItemType.MangroveSign; + mappings[998] = ItemType.BambooSign; + mappings[999] = ItemType.CrimsonSign; + mappings[1000] = ItemType.WarpedSign; + mappings[1001] = ItemType.OakHangingSign; + mappings[1002] = ItemType.SpruceHangingSign; + mappings[1003] = ItemType.BirchHangingSign; + mappings[1004] = ItemType.JungleHangingSign; + mappings[1005] = ItemType.AcaciaHangingSign; + mappings[1006] = ItemType.CherryHangingSign; + mappings[1007] = ItemType.DarkOakHangingSign; + mappings[1008] = ItemType.PaleOakHangingSign; + mappings[1009] = ItemType.MangroveHangingSign; + mappings[1010] = ItemType.BambooHangingSign; + mappings[1011] = ItemType.CrimsonHangingSign; + mappings[1012] = ItemType.WarpedHangingSign; + mappings[1013] = ItemType.Bucket; + mappings[1014] = ItemType.WaterBucket; + mappings[1015] = ItemType.LavaBucket; + mappings[1016] = ItemType.PowderSnowBucket; + mappings[1017] = ItemType.Snowball; + mappings[1018] = ItemType.Leather; + mappings[1019] = ItemType.MilkBucket; + mappings[1020] = ItemType.PufferfishBucket; + mappings[1021] = ItemType.SalmonBucket; + mappings[1022] = ItemType.CodBucket; + mappings[1023] = ItemType.TropicalFishBucket; + mappings[1024] = ItemType.AxolotlBucket; + mappings[1025] = ItemType.TadpoleBucket; + mappings[1026] = ItemType.Brick; + mappings[1027] = ItemType.ClayBall; + mappings[1028] = ItemType.DriedKelpBlock; + mappings[1029] = ItemType.Paper; + mappings[1030] = ItemType.Book; + mappings[1031] = ItemType.SlimeBall; + mappings[1032] = ItemType.Egg; + mappings[1033] = ItemType.BlueEgg; + mappings[1034] = ItemType.BrownEgg; + mappings[1035] = ItemType.Compass; + mappings[1036] = ItemType.RecoveryCompass; + mappings[1037] = ItemType.Bundle; + mappings[1038] = ItemType.WhiteBundle; + mappings[1039] = ItemType.OrangeBundle; + mappings[1040] = ItemType.MagentaBundle; + mappings[1041] = ItemType.LightBlueBundle; + mappings[1042] = ItemType.YellowBundle; + mappings[1043] = ItemType.LimeBundle; + mappings[1044] = ItemType.PinkBundle; + mappings[1045] = ItemType.GrayBundle; + mappings[1046] = ItemType.LightGrayBundle; + mappings[1047] = ItemType.CyanBundle; + mappings[1048] = ItemType.PurpleBundle; + mappings[1049] = ItemType.BlueBundle; + mappings[1050] = ItemType.BrownBundle; + mappings[1051] = ItemType.GreenBundle; + mappings[1052] = ItemType.RedBundle; + mappings[1053] = ItemType.BlackBundle; + mappings[1054] = ItemType.FishingRod; + mappings[1055] = ItemType.Clock; + mappings[1056] = ItemType.Spyglass; + mappings[1057] = ItemType.GlowstoneDust; + mappings[1058] = ItemType.Cod; + mappings[1059] = ItemType.Salmon; + mappings[1060] = ItemType.TropicalFish; + mappings[1061] = ItemType.Pufferfish; + mappings[1062] = ItemType.CookedCod; + mappings[1063] = ItemType.CookedSalmon; + mappings[1064] = ItemType.InkSac; + mappings[1065] = ItemType.GlowInkSac; + mappings[1066] = ItemType.CocoaBeans; + mappings[1067] = ItemType.WhiteDye; + mappings[1068] = ItemType.OrangeDye; + mappings[1069] = ItemType.MagentaDye; + mappings[1070] = ItemType.LightBlueDye; + mappings[1071] = ItemType.YellowDye; + mappings[1072] = ItemType.LimeDye; + mappings[1073] = ItemType.PinkDye; + mappings[1074] = ItemType.GrayDye; + mappings[1075] = ItemType.LightGrayDye; + mappings[1076] = ItemType.CyanDye; + mappings[1077] = ItemType.PurpleDye; + mappings[1078] = ItemType.BlueDye; + mappings[1079] = ItemType.BrownDye; + mappings[1080] = ItemType.GreenDye; + mappings[1081] = ItemType.RedDye; + mappings[1082] = ItemType.BlackDye; + mappings[1083] = ItemType.BoneMeal; + mappings[1084] = ItemType.Bone; + mappings[1085] = ItemType.Sugar; + mappings[1086] = ItemType.Cake; + mappings[1087] = ItemType.WhiteBed; + mappings[1088] = ItemType.OrangeBed; + mappings[1089] = ItemType.MagentaBed; + mappings[1090] = ItemType.LightBlueBed; + mappings[1091] = ItemType.YellowBed; + mappings[1092] = ItemType.LimeBed; + mappings[1093] = ItemType.PinkBed; + mappings[1094] = ItemType.GrayBed; + mappings[1095] = ItemType.LightGrayBed; + mappings[1096] = ItemType.CyanBed; + mappings[1097] = ItemType.PurpleBed; + mappings[1098] = ItemType.BlueBed; + mappings[1099] = ItemType.BrownBed; + mappings[1100] = ItemType.GreenBed; + mappings[1101] = ItemType.RedBed; + mappings[1102] = ItemType.BlackBed; + mappings[1103] = ItemType.Cookie; + mappings[1104] = ItemType.Crafter; + mappings[1105] = ItemType.FilledMap; + mappings[1106] = ItemType.Shears; + mappings[1107] = ItemType.MelonSlice; + mappings[1108] = ItemType.DriedKelp; + mappings[1109] = ItemType.PumpkinSeeds; + mappings[1110] = ItemType.MelonSeeds; + mappings[1111] = ItemType.Beef; + mappings[1112] = ItemType.CookedBeef; + mappings[1113] = ItemType.Chicken; + mappings[1114] = ItemType.CookedChicken; + mappings[1115] = ItemType.RottenFlesh; + mappings[1116] = ItemType.EnderPearl; + mappings[1117] = ItemType.BlazeRod; + mappings[1118] = ItemType.GhastTear; + mappings[1119] = ItemType.GoldNugget; + mappings[1120] = ItemType.NetherWart; + mappings[1121] = ItemType.GlassBottle; + mappings[1122] = ItemType.Potion; + mappings[1123] = ItemType.SpiderEye; + mappings[1124] = ItemType.FermentedSpiderEye; + mappings[1125] = ItemType.BlazePowder; + mappings[1126] = ItemType.MagmaCream; + mappings[1127] = ItemType.BrewingStand; + mappings[1128] = ItemType.Cauldron; + mappings[1129] = ItemType.EnderEye; + mappings[1130] = ItemType.GlisteringMelonSlice; + mappings[1131] = ItemType.ChickenSpawnEgg; + mappings[1132] = ItemType.CowSpawnEgg; + mappings[1133] = ItemType.PigSpawnEgg; + mappings[1134] = ItemType.SheepSpawnEgg; + mappings[1135] = ItemType.CamelSpawnEgg; + mappings[1136] = ItemType.DonkeySpawnEgg; + mappings[1137] = ItemType.HorseSpawnEgg; + mappings[1138] = ItemType.MuleSpawnEgg; + mappings[1139] = ItemType.CatSpawnEgg; + mappings[1140] = ItemType.ParrotSpawnEgg; + mappings[1141] = ItemType.WolfSpawnEgg; + mappings[1142] = ItemType.ArmadilloSpawnEgg; + mappings[1143] = ItemType.BatSpawnEgg; + mappings[1144] = ItemType.BeeSpawnEgg; + mappings[1145] = ItemType.FoxSpawnEgg; + mappings[1146] = ItemType.GoatSpawnEgg; + mappings[1147] = ItemType.LlamaSpawnEgg; + mappings[1148] = ItemType.OcelotSpawnEgg; + mappings[1149] = ItemType.PandaSpawnEgg; + mappings[1150] = ItemType.PolarBearSpawnEgg; + mappings[1151] = ItemType.RabbitSpawnEgg; + mappings[1152] = ItemType.AxolotlSpawnEgg; + mappings[1153] = ItemType.CodSpawnEgg; + mappings[1154] = ItemType.DolphinSpawnEgg; + mappings[1155] = ItemType.FrogSpawnEgg; + mappings[1156] = ItemType.GlowSquidSpawnEgg; + mappings[1157] = ItemType.NautilusSpawnEgg; + mappings[1158] = ItemType.PufferfishSpawnEgg; + mappings[1159] = ItemType.SalmonSpawnEgg; + mappings[1160] = ItemType.SquidSpawnEgg; + mappings[1161] = ItemType.TadpoleSpawnEgg; + mappings[1162] = ItemType.TropicalFishSpawnEgg; + mappings[1163] = ItemType.TurtleSpawnEgg; + mappings[1164] = ItemType.AllaySpawnEgg; + mappings[1165] = ItemType.MooshroomSpawnEgg; + mappings[1166] = ItemType.SnifferSpawnEgg; + mappings[1167] = ItemType.CopperGolemSpawnEgg; + mappings[1168] = ItemType.IronGolemSpawnEgg; + mappings[1169] = ItemType.SnowGolemSpawnEgg; + mappings[1170] = ItemType.TraderLlamaSpawnEgg; + mappings[1171] = ItemType.VillagerSpawnEgg; + mappings[1172] = ItemType.WanderingTraderSpawnEgg; + mappings[1173] = ItemType.BoggedSpawnEgg; + mappings[1174] = ItemType.CamelHuskSpawnEgg; + mappings[1175] = ItemType.DrownedSpawnEgg; + mappings[1176] = ItemType.HuskSpawnEgg; + mappings[1177] = ItemType.ParchedSpawnEgg; + mappings[1178] = ItemType.SkeletonSpawnEgg; + mappings[1179] = ItemType.SkeletonHorseSpawnEgg; + mappings[1180] = ItemType.StraySpawnEgg; + mappings[1181] = ItemType.WitherSpawnEgg; + mappings[1182] = ItemType.WitherSkeletonSpawnEgg; + mappings[1183] = ItemType.ZombieSpawnEgg; + mappings[1184] = ItemType.ZombieHorseSpawnEgg; + mappings[1185] = ItemType.ZombieNautilusSpawnEgg; + mappings[1186] = ItemType.ZombieVillagerSpawnEgg; + mappings[1187] = ItemType.CaveSpiderSpawnEgg; + mappings[1188] = ItemType.SpiderSpawnEgg; + mappings[1189] = ItemType.BreezeSpawnEgg; + mappings[1190] = ItemType.CreakingSpawnEgg; + mappings[1191] = ItemType.CreeperSpawnEgg; + mappings[1192] = ItemType.ElderGuardianSpawnEgg; + mappings[1193] = ItemType.GuardianSpawnEgg; + mappings[1194] = ItemType.PhantomSpawnEgg; + mappings[1195] = ItemType.SilverfishSpawnEgg; + mappings[1196] = ItemType.SlimeSpawnEgg; + mappings[1197] = ItemType.WardenSpawnEgg; + mappings[1198] = ItemType.WitchSpawnEgg; + mappings[1199] = ItemType.EvokerSpawnEgg; + mappings[1200] = ItemType.PillagerSpawnEgg; + mappings[1201] = ItemType.RavagerSpawnEgg; + mappings[1202] = ItemType.VindicatorSpawnEgg; + mappings[1203] = ItemType.VexSpawnEgg; + mappings[1204] = ItemType.BlazeSpawnEgg; + mappings[1205] = ItemType.GhastSpawnEgg; + mappings[1206] = ItemType.HappyGhastSpawnEgg; + mappings[1207] = ItemType.HoglinSpawnEgg; + mappings[1208] = ItemType.MagmaCubeSpawnEgg; + mappings[1209] = ItemType.PiglinSpawnEgg; + mappings[1210] = ItemType.PiglinBruteSpawnEgg; + mappings[1211] = ItemType.StriderSpawnEgg; + mappings[1212] = ItemType.ZoglinSpawnEgg; + mappings[1213] = ItemType.ZombifiedPiglinSpawnEgg; + mappings[1214] = ItemType.EnderDragonSpawnEgg; + mappings[1215] = ItemType.EndermanSpawnEgg; + mappings[1216] = ItemType.EndermiteSpawnEgg; + mappings[1217] = ItemType.ShulkerSpawnEgg; + mappings[1218] = ItemType.ExperienceBottle; + mappings[1219] = ItemType.FireCharge; + mappings[1220] = ItemType.WindCharge; + mappings[1221] = ItemType.WritableBook; + mappings[1222] = ItemType.WrittenBook; + mappings[1223] = ItemType.BreezeRod; + mappings[1224] = ItemType.Mace; + mappings[1225] = ItemType.ItemFrame; + mappings[1226] = ItemType.GlowItemFrame; + mappings[1227] = ItemType.FlowerPot; + mappings[1228] = ItemType.Carrot; + mappings[1229] = ItemType.Potato; + mappings[1230] = ItemType.BakedPotato; + mappings[1231] = ItemType.PoisonousPotato; + mappings[1232] = ItemType.Map; + mappings[1233] = ItemType.GoldenCarrot; + mappings[1234] = ItemType.SkeletonSkull; + mappings[1235] = ItemType.WitherSkeletonSkull; + mappings[1236] = ItemType.PlayerHead; + mappings[1237] = ItemType.ZombieHead; + mappings[1238] = ItemType.CreeperHead; + mappings[1239] = ItemType.DragonHead; + mappings[1240] = ItemType.PiglinHead; + mappings[1241] = ItemType.NetherStar; + mappings[1242] = ItemType.PumpkinPie; + mappings[1243] = ItemType.FireworkRocket; + mappings[1244] = ItemType.FireworkStar; + mappings[1245] = ItemType.EnchantedBook; + mappings[1246] = ItemType.NetherBrick; + mappings[1247] = ItemType.ResinBrick; + mappings[1248] = ItemType.PrismarineShard; + mappings[1249] = ItemType.PrismarineCrystals; + mappings[1250] = ItemType.Rabbit; + mappings[1251] = ItemType.CookedRabbit; + mappings[1252] = ItemType.RabbitStew; + mappings[1253] = ItemType.RabbitFoot; + mappings[1254] = ItemType.RabbitHide; + mappings[1255] = ItemType.ArmorStand; + mappings[1256] = ItemType.CopperHorseArmor; + mappings[1257] = ItemType.IronHorseArmor; + mappings[1258] = ItemType.GoldenHorseArmor; + mappings[1259] = ItemType.DiamondHorseArmor; + mappings[1260] = ItemType.NetheriteHorseArmor; + mappings[1261] = ItemType.LeatherHorseArmor; + mappings[1262] = ItemType.Lead; + mappings[1263] = ItemType.NameTag; + mappings[1264] = ItemType.CommandBlockMinecart; + mappings[1265] = ItemType.Mutton; + mappings[1266] = ItemType.CookedMutton; + mappings[1267] = ItemType.WhiteBanner; + mappings[1268] = ItemType.OrangeBanner; + mappings[1269] = ItemType.MagentaBanner; + mappings[1270] = ItemType.LightBlueBanner; + mappings[1271] = ItemType.YellowBanner; + mappings[1272] = ItemType.LimeBanner; + mappings[1273] = ItemType.PinkBanner; + mappings[1274] = ItemType.GrayBanner; + mappings[1275] = ItemType.LightGrayBanner; + mappings[1276] = ItemType.CyanBanner; + mappings[1277] = ItemType.PurpleBanner; + mappings[1278] = ItemType.BlueBanner; + mappings[1279] = ItemType.BrownBanner; + mappings[1280] = ItemType.GreenBanner; + mappings[1281] = ItemType.RedBanner; + mappings[1282] = ItemType.BlackBanner; + mappings[1283] = ItemType.EndCrystal; + mappings[1284] = ItemType.ChorusFruit; + mappings[1285] = ItemType.PoppedChorusFruit; + mappings[1286] = ItemType.TorchflowerSeeds; + mappings[1287] = ItemType.PitcherPod; + mappings[1288] = ItemType.Beetroot; + mappings[1289] = ItemType.BeetrootSeeds; + mappings[1290] = ItemType.BeetrootSoup; + mappings[1291] = ItemType.DragonBreath; + mappings[1292] = ItemType.SplashPotion; + mappings[1293] = ItemType.SpectralArrow; + mappings[1294] = ItemType.TippedArrow; + mappings[1295] = ItemType.LingeringPotion; + mappings[1296] = ItemType.Shield; + mappings[1297] = ItemType.WoodenSpear; + mappings[1298] = ItemType.StoneSpear; + mappings[1299] = ItemType.CopperSpear; + mappings[1300] = ItemType.IronSpear; + mappings[1301] = ItemType.GoldenSpear; + mappings[1302] = ItemType.DiamondSpear; + mappings[1303] = ItemType.NetheriteSpear; + mappings[1304] = ItemType.TotemOfUndying; + mappings[1305] = ItemType.ShulkerShell; + mappings[1306] = ItemType.IronNugget; + mappings[1307] = ItemType.CopperNugget; + mappings[1308] = ItemType.KnowledgeBook; + mappings[1309] = ItemType.DebugStick; + mappings[1310] = ItemType.MusicDisc13; + mappings[1311] = ItemType.MusicDiscCat; + mappings[1312] = ItemType.MusicDiscBlocks; + mappings[1313] = ItemType.MusicDiscChirp; + mappings[1314] = ItemType.MusicDiscCreator; + mappings[1315] = ItemType.MusicDiscCreatorMusicBox; + mappings[1316] = ItemType.MusicDiscFar; + mappings[1317] = ItemType.MusicDiscLavaChicken; + mappings[1318] = ItemType.MusicDiscMall; + mappings[1319] = ItemType.MusicDiscMellohi; + mappings[1320] = ItemType.MusicDiscStal; + mappings[1321] = ItemType.MusicDiscStrad; + mappings[1322] = ItemType.MusicDiscWard; + mappings[1323] = ItemType.MusicDisc11; + mappings[1324] = ItemType.MusicDiscWait; + mappings[1325] = ItemType.MusicDiscOtherside; + mappings[1326] = ItemType.MusicDiscRelic; + mappings[1327] = ItemType.MusicDisc5; + mappings[1328] = ItemType.MusicDiscPigstep; + mappings[1329] = ItemType.MusicDiscPrecipice; + mappings[1330] = ItemType.MusicDiscTears; + mappings[1331] = ItemType.DiscFragment5; + mappings[1332] = ItemType.Trident; + mappings[1333] = ItemType.NautilusShell; + mappings[1334] = ItemType.IronNautilusArmor; + mappings[1335] = ItemType.GoldenNautilusArmor; + mappings[1336] = ItemType.DiamondNautilusArmor; + mappings[1337] = ItemType.NetheriteNautilusArmor; + mappings[1338] = ItemType.CopperNautilusArmor; + mappings[1339] = ItemType.HeartOfTheSea; + mappings[1340] = ItemType.Crossbow; + mappings[1341] = ItemType.SuspiciousStew; + mappings[1342] = ItemType.Loom; + mappings[1343] = ItemType.FlowerBannerPattern; + mappings[1344] = ItemType.CreeperBannerPattern; + mappings[1345] = ItemType.SkullBannerPattern; + mappings[1346] = ItemType.MojangBannerPattern; + mappings[1347] = ItemType.GlobeBannerPattern; + mappings[1348] = ItemType.PiglinBannerPattern; + mappings[1349] = ItemType.FlowBannerPattern; + mappings[1350] = ItemType.GusterBannerPattern; + mappings[1351] = ItemType.FieldMasonedBannerPattern; + mappings[1352] = ItemType.BordureIndentedBannerPattern; + mappings[1353] = ItemType.GoatHorn; + mappings[1354] = ItemType.Composter; + mappings[1355] = ItemType.Barrel; + mappings[1356] = ItemType.Smoker; + mappings[1357] = ItemType.BlastFurnace; + mappings[1358] = ItemType.CartographyTable; + mappings[1359] = ItemType.FletchingTable; + mappings[1360] = ItemType.Grindstone; + mappings[1361] = ItemType.SmithingTable; + mappings[1362] = ItemType.Stonecutter; + mappings[1363] = ItemType.Bell; + mappings[1364] = ItemType.Lantern; + mappings[1365] = ItemType.SoulLantern; + mappings[1366] = ItemType.CopperLantern; + mappings[1367] = ItemType.ExposedCopperLantern; + mappings[1368] = ItemType.WeatheredCopperLantern; + mappings[1369] = ItemType.OxidizedCopperLantern; + mappings[1370] = ItemType.WaxedCopperLantern; + mappings[1371] = ItemType.WaxedExposedCopperLantern; + mappings[1372] = ItemType.WaxedWeatheredCopperLantern; + mappings[1373] = ItemType.WaxedOxidizedCopperLantern; + mappings[1374] = ItemType.SweetBerries; + mappings[1375] = ItemType.GlowBerries; + mappings[1376] = ItemType.Campfire; + mappings[1377] = ItemType.SoulCampfire; + mappings[1378] = ItemType.Shroomlight; + mappings[1379] = ItemType.Honeycomb; + mappings[1380] = ItemType.BeeNest; + mappings[1381] = ItemType.Beehive; + mappings[1382] = ItemType.HoneyBottle; + mappings[1383] = ItemType.HoneycombBlock; + mappings[1384] = ItemType.Lodestone; + mappings[1385] = ItemType.CryingObsidian; + mappings[1386] = ItemType.Blackstone; + mappings[1387] = ItemType.BlackstoneSlab; + mappings[1388] = ItemType.BlackstoneStairs; + mappings[1389] = ItemType.GildedBlackstone; + mappings[1390] = ItemType.PolishedBlackstone; + mappings[1391] = ItemType.PolishedBlackstoneSlab; + mappings[1392] = ItemType.PolishedBlackstoneStairs; + mappings[1393] = ItemType.ChiseledPolishedBlackstone; + mappings[1394] = ItemType.PolishedBlackstoneBricks; + mappings[1395] = ItemType.PolishedBlackstoneBrickSlab; + mappings[1396] = ItemType.PolishedBlackstoneBrickStairs; + mappings[1397] = ItemType.CrackedPolishedBlackstoneBricks; + mappings[1398] = ItemType.RespawnAnchor; + mappings[1399] = ItemType.Candle; + mappings[1400] = ItemType.WhiteCandle; + mappings[1401] = ItemType.OrangeCandle; + mappings[1402] = ItemType.MagentaCandle; + mappings[1403] = ItemType.LightBlueCandle; + mappings[1404] = ItemType.YellowCandle; + mappings[1405] = ItemType.LimeCandle; + mappings[1406] = ItemType.PinkCandle; + mappings[1407] = ItemType.GrayCandle; + mappings[1408] = ItemType.LightGrayCandle; + mappings[1409] = ItemType.CyanCandle; + mappings[1410] = ItemType.PurpleCandle; + mappings[1411] = ItemType.BlueCandle; + mappings[1412] = ItemType.BrownCandle; + mappings[1413] = ItemType.GreenCandle; + mappings[1414] = ItemType.RedCandle; + mappings[1415] = ItemType.BlackCandle; + mappings[1416] = ItemType.SmallAmethystBud; + mappings[1417] = ItemType.MediumAmethystBud; + mappings[1418] = ItemType.LargeAmethystBud; + mappings[1419] = ItemType.AmethystCluster; + mappings[1420] = ItemType.PointedDripstone; + mappings[1421] = ItemType.OchreFroglight; + mappings[1422] = ItemType.VerdantFroglight; + mappings[1423] = ItemType.PearlescentFroglight; + mappings[1424] = ItemType.Frogspawn; + mappings[1425] = ItemType.EchoShard; + mappings[1426] = ItemType.Brush; + mappings[1427] = ItemType.NetheriteUpgradeSmithingTemplate; + mappings[1428] = ItemType.SentryArmorTrimSmithingTemplate; + mappings[1429] = ItemType.DuneArmorTrimSmithingTemplate; + mappings[1430] = ItemType.CoastArmorTrimSmithingTemplate; + mappings[1431] = ItemType.WildArmorTrimSmithingTemplate; + mappings[1432] = ItemType.WardArmorTrimSmithingTemplate; + mappings[1433] = ItemType.EyeArmorTrimSmithingTemplate; + mappings[1434] = ItemType.VexArmorTrimSmithingTemplate; + mappings[1435] = ItemType.TideArmorTrimSmithingTemplate; + mappings[1436] = ItemType.SnoutArmorTrimSmithingTemplate; + mappings[1437] = ItemType.RibArmorTrimSmithingTemplate; + mappings[1438] = ItemType.SpireArmorTrimSmithingTemplate; + mappings[1439] = ItemType.WayfinderArmorTrimSmithingTemplate; + mappings[1440] = ItemType.ShaperArmorTrimSmithingTemplate; + mappings[1441] = ItemType.SilenceArmorTrimSmithingTemplate; + mappings[1442] = ItemType.RaiserArmorTrimSmithingTemplate; + mappings[1443] = ItemType.HostArmorTrimSmithingTemplate; + mappings[1444] = ItemType.FlowArmorTrimSmithingTemplate; + mappings[1445] = ItemType.BoltArmorTrimSmithingTemplate; + mappings[1446] = ItemType.AnglerPotterySherd; + mappings[1447] = ItemType.ArcherPotterySherd; + mappings[1448] = ItemType.ArmsUpPotterySherd; + mappings[1449] = ItemType.BladePotterySherd; + mappings[1450] = ItemType.BrewerPotterySherd; + mappings[1451] = ItemType.BurnPotterySherd; + mappings[1452] = ItemType.DangerPotterySherd; + mappings[1453] = ItemType.ExplorerPotterySherd; + mappings[1454] = ItemType.FlowPotterySherd; + mappings[1455] = ItemType.FriendPotterySherd; + mappings[1456] = ItemType.GusterPotterySherd; + mappings[1457] = ItemType.HeartPotterySherd; + mappings[1458] = ItemType.HeartbreakPotterySherd; + mappings[1459] = ItemType.HowlPotterySherd; + mappings[1460] = ItemType.MinerPotterySherd; + mappings[1461] = ItemType.MournerPotterySherd; + mappings[1462] = ItemType.PlentyPotterySherd; + mappings[1463] = ItemType.PrizePotterySherd; + mappings[1464] = ItemType.ScrapePotterySherd; + mappings[1465] = ItemType.SheafPotterySherd; + mappings[1466] = ItemType.ShelterPotterySherd; + mappings[1467] = ItemType.SkullPotterySherd; + mappings[1468] = ItemType.SnortPotterySherd; + mappings[1469] = ItemType.CopperGrate; + mappings[1470] = ItemType.ExposedCopperGrate; + mappings[1471] = ItemType.WeatheredCopperGrate; + mappings[1472] = ItemType.OxidizedCopperGrate; + mappings[1473] = ItemType.WaxedCopperGrate; + mappings[1474] = ItemType.WaxedExposedCopperGrate; + mappings[1475] = ItemType.WaxedWeatheredCopperGrate; + mappings[1476] = ItemType.WaxedOxidizedCopperGrate; + mappings[1477] = ItemType.CopperBulb; + mappings[1478] = ItemType.ExposedCopperBulb; + mappings[1479] = ItemType.WeatheredCopperBulb; + mappings[1480] = ItemType.OxidizedCopperBulb; + mappings[1481] = ItemType.WaxedCopperBulb; + mappings[1482] = ItemType.WaxedExposedCopperBulb; + mappings[1483] = ItemType.WaxedWeatheredCopperBulb; + mappings[1484] = ItemType.WaxedOxidizedCopperBulb; + mappings[1485] = ItemType.CopperChest; + mappings[1486] = ItemType.ExposedCopperChest; + mappings[1487] = ItemType.WeatheredCopperChest; + mappings[1488] = ItemType.OxidizedCopperChest; + mappings[1489] = ItemType.WaxedCopperChest; + mappings[1490] = ItemType.WaxedExposedCopperChest; + mappings[1491] = ItemType.WaxedWeatheredCopperChest; + mappings[1492] = ItemType.WaxedOxidizedCopperChest; + mappings[1493] = ItemType.CopperGolemStatue; + mappings[1494] = ItemType.ExposedCopperGolemStatue; + mappings[1495] = ItemType.WeatheredCopperGolemStatue; + mappings[1496] = ItemType.OxidizedCopperGolemStatue; + mappings[1497] = ItemType.WaxedCopperGolemStatue; + mappings[1498] = ItemType.WaxedExposedCopperGolemStatue; + mappings[1499] = ItemType.WaxedWeatheredCopperGolemStatue; + mappings[1500] = ItemType.WaxedOxidizedCopperGolemStatue; + mappings[1501] = ItemType.TrialSpawner; + mappings[1502] = ItemType.TrialKey; + mappings[1503] = ItemType.OminousTrialKey; + mappings[1504] = ItemType.Vault; + mappings[1505] = ItemType.OminousBottle; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index 96d629ce..aaff1d72 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -578,6 +578,7 @@ namespace MinecraftClient.Inventory GoldenAxe, GoldenBoots, GoldenCarrot, + GoldenDandelion, GoldenChestplate, GoldenHelmet, GoldenHoe, diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette261.cs b/MinecraftClient/Mapping/BlockPalettes/Palette261.cs new file mode 100644 index 00000000..5a2b7ac0 --- /dev/null +++ b/MinecraftClient/Mapping/BlockPalettes/Palette261.cs @@ -0,0 +1,2354 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.BlockPalettes +{ + public class Palette261 : BlockPalette + { + private static readonly Dictionary materials = new(); + + static Palette261() + { + for (int i = 0; i <= 0; i++) + materials[i] = Material.Air; + for (int i = 1; i <= 1; i++) + materials[i] = Material.Stone; + for (int i = 2; i <= 2; i++) + materials[i] = Material.Granite; + for (int i = 3; i <= 3; i++) + materials[i] = Material.PolishedGranite; + for (int i = 4; i <= 4; i++) + materials[i] = Material.Diorite; + for (int i = 5; i <= 5; i++) + materials[i] = Material.PolishedDiorite; + for (int i = 6; i <= 6; i++) + materials[i] = Material.Andesite; + for (int i = 7; i <= 7; i++) + materials[i] = Material.PolishedAndesite; + for (int i = 8; i <= 9; i++) + materials[i] = Material.GrassBlock; + for (int i = 10; i <= 10; i++) + materials[i] = Material.Dirt; + for (int i = 11; i <= 11; i++) + materials[i] = Material.CoarseDirt; + for (int i = 12; i <= 13; i++) + materials[i] = Material.Podzol; + for (int i = 14; i <= 14; i++) + materials[i] = Material.Cobblestone; + for (int i = 15; i <= 15; i++) + materials[i] = Material.OakPlanks; + for (int i = 16; i <= 16; i++) + materials[i] = Material.SprucePlanks; + for (int i = 17; i <= 17; i++) + materials[i] = Material.BirchPlanks; + for (int i = 18; i <= 18; i++) + materials[i] = Material.JunglePlanks; + for (int i = 19; i <= 19; i++) + materials[i] = Material.AcaciaPlanks; + for (int i = 20; i <= 20; i++) + materials[i] = Material.CherryPlanks; + for (int i = 21; i <= 21; i++) + materials[i] = Material.DarkOakPlanks; + for (int i = 22; i <= 24; i++) + materials[i] = Material.PaleOakWood; + for (int i = 25; i <= 25; i++) + materials[i] = Material.PaleOakPlanks; + for (int i = 26; i <= 26; i++) + materials[i] = Material.MangrovePlanks; + for (int i = 27; i <= 27; i++) + materials[i] = Material.BambooPlanks; + for (int i = 28; i <= 28; i++) + materials[i] = Material.BambooMosaic; + for (int i = 29; i <= 30; i++) + materials[i] = Material.OakSapling; + for (int i = 31; i <= 32; i++) + materials[i] = Material.SpruceSapling; + for (int i = 33; i <= 34; i++) + materials[i] = Material.BirchSapling; + for (int i = 35; i <= 36; i++) + materials[i] = Material.JungleSapling; + for (int i = 37; i <= 38; i++) + materials[i] = Material.AcaciaSapling; + for (int i = 39; i <= 40; i++) + materials[i] = Material.CherrySapling; + for (int i = 41; i <= 42; i++) + materials[i] = Material.DarkOakSapling; + for (int i = 43; i <= 44; i++) + materials[i] = Material.PaleOakSapling; + for (int i = 45; i <= 84; i++) + materials[i] = Material.MangrovePropagule; + for (int i = 85; i <= 85; i++) + materials[i] = Material.Bedrock; + for (int i = 86; i <= 101; i++) + materials[i] = Material.Water; + for (int i = 102; i <= 117; i++) + materials[i] = Material.Lava; + for (int i = 118; i <= 118; i++) + materials[i] = Material.Sand; + for (int i = 119; i <= 122; i++) + materials[i] = Material.SuspiciousSand; + for (int i = 123; i <= 123; i++) + materials[i] = Material.RedSand; + for (int i = 124; i <= 124; i++) + materials[i] = Material.Gravel; + for (int i = 125; i <= 128; i++) + materials[i] = Material.SuspiciousGravel; + for (int i = 129; i <= 129; i++) + materials[i] = Material.GoldOre; + for (int i = 130; i <= 130; i++) + materials[i] = Material.DeepslateGoldOre; + for (int i = 131; i <= 131; i++) + materials[i] = Material.IronOre; + for (int i = 132; i <= 132; i++) + materials[i] = Material.DeepslateIronOre; + for (int i = 133; i <= 133; i++) + materials[i] = Material.CoalOre; + for (int i = 134; i <= 134; i++) + materials[i] = Material.DeepslateCoalOre; + for (int i = 135; i <= 135; i++) + materials[i] = Material.NetherGoldOre; + for (int i = 136; i <= 138; i++) + materials[i] = Material.OakLog; + for (int i = 139; i <= 141; i++) + materials[i] = Material.SpruceLog; + for (int i = 142; i <= 144; i++) + materials[i] = Material.BirchLog; + for (int i = 145; i <= 147; i++) + materials[i] = Material.JungleLog; + for (int i = 148; i <= 150; i++) + materials[i] = Material.AcaciaLog; + for (int i = 151; i <= 153; i++) + materials[i] = Material.CherryLog; + for (int i = 154; i <= 156; i++) + materials[i] = Material.DarkOakLog; + for (int i = 157; i <= 159; i++) + materials[i] = Material.PaleOakLog; + for (int i = 160; i <= 162; i++) + materials[i] = Material.MangroveLog; + for (int i = 163; i <= 164; i++) + materials[i] = Material.MangroveRoots; + for (int i = 165; i <= 167; i++) + materials[i] = Material.MuddyMangroveRoots; + for (int i = 168; i <= 170; i++) + materials[i] = Material.BambooBlock; + for (int i = 171; i <= 173; i++) + materials[i] = Material.StrippedSpruceLog; + for (int i = 174; i <= 176; i++) + materials[i] = Material.StrippedBirchLog; + for (int i = 177; i <= 179; i++) + materials[i] = Material.StrippedJungleLog; + for (int i = 180; i <= 182; i++) + materials[i] = Material.StrippedAcaciaLog; + for (int i = 183; i <= 185; i++) + materials[i] = Material.StrippedCherryLog; + for (int i = 186; i <= 188; i++) + materials[i] = Material.StrippedDarkOakLog; + for (int i = 189; i <= 191; i++) + materials[i] = Material.StrippedPaleOakLog; + for (int i = 192; i <= 194; i++) + materials[i] = Material.StrippedOakLog; + for (int i = 195; i <= 197; i++) + materials[i] = Material.StrippedMangroveLog; + for (int i = 198; i <= 200; i++) + materials[i] = Material.StrippedBambooBlock; + for (int i = 201; i <= 203; i++) + materials[i] = Material.OakWood; + for (int i = 204; i <= 206; i++) + materials[i] = Material.SpruceWood; + for (int i = 207; i <= 209; i++) + materials[i] = Material.BirchWood; + for (int i = 210; i <= 212; i++) + materials[i] = Material.JungleWood; + for (int i = 213; i <= 215; i++) + materials[i] = Material.AcaciaWood; + for (int i = 216; i <= 218; i++) + materials[i] = Material.CherryWood; + for (int i = 219; i <= 221; i++) + materials[i] = Material.DarkOakWood; + for (int i = 222; i <= 224; i++) + materials[i] = Material.MangroveWood; + for (int i = 225; i <= 227; i++) + materials[i] = Material.StrippedOakWood; + for (int i = 228; i <= 230; i++) + materials[i] = Material.StrippedSpruceWood; + for (int i = 231; i <= 233; i++) + materials[i] = Material.StrippedBirchWood; + for (int i = 234; i <= 236; i++) + materials[i] = Material.StrippedJungleWood; + for (int i = 237; i <= 239; i++) + materials[i] = Material.StrippedAcaciaWood; + for (int i = 240; i <= 242; i++) + materials[i] = Material.StrippedCherryWood; + for (int i = 243; i <= 245; i++) + materials[i] = Material.StrippedDarkOakWood; + for (int i = 246; i <= 248; i++) + materials[i] = Material.StrippedPaleOakWood; + for (int i = 249; i <= 251; i++) + materials[i] = Material.StrippedMangroveWood; + for (int i = 252; i <= 279; i++) + materials[i] = Material.OakLeaves; + for (int i = 280; i <= 307; i++) + materials[i] = Material.SpruceLeaves; + for (int i = 308; i <= 335; i++) + materials[i] = Material.BirchLeaves; + for (int i = 336; i <= 363; i++) + materials[i] = Material.JungleLeaves; + for (int i = 364; i <= 391; i++) + materials[i] = Material.AcaciaLeaves; + for (int i = 392; i <= 419; i++) + materials[i] = Material.CherryLeaves; + for (int i = 420; i <= 447; i++) + materials[i] = Material.DarkOakLeaves; + for (int i = 448; i <= 475; i++) + materials[i] = Material.PaleOakLeaves; + for (int i = 476; i <= 503; i++) + materials[i] = Material.MangroveLeaves; + for (int i = 504; i <= 531; i++) + materials[i] = Material.AzaleaLeaves; + for (int i = 532; i <= 559; i++) + materials[i] = Material.FloweringAzaleaLeaves; + for (int i = 560; i <= 560; i++) + materials[i] = Material.Sponge; + for (int i = 561; i <= 561; i++) + materials[i] = Material.WetSponge; + for (int i = 562; i <= 562; i++) + materials[i] = Material.Glass; + for (int i = 563; i <= 563; i++) + materials[i] = Material.LapisOre; + for (int i = 564; i <= 564; i++) + materials[i] = Material.DeepslateLapisOre; + for (int i = 565; i <= 565; i++) + materials[i] = Material.LapisBlock; + for (int i = 566; i <= 577; i++) + materials[i] = Material.Dispenser; + for (int i = 578; i <= 578; i++) + materials[i] = Material.Sandstone; + for (int i = 579; i <= 579; i++) + materials[i] = Material.ChiseledSandstone; + for (int i = 580; i <= 580; i++) + materials[i] = Material.CutSandstone; + for (int i = 581; i <= 1930; i++) + materials[i] = Material.NoteBlock; + for (int i = 1931; i <= 1946; i++) + materials[i] = Material.WhiteBed; + for (int i = 1947; i <= 1962; i++) + materials[i] = Material.OrangeBed; + for (int i = 1963; i <= 1978; i++) + materials[i] = Material.MagentaBed; + for (int i = 1979; i <= 1994; i++) + materials[i] = Material.LightBlueBed; + for (int i = 1995; i <= 2010; i++) + materials[i] = Material.YellowBed; + for (int i = 2011; i <= 2026; i++) + materials[i] = Material.LimeBed; + for (int i = 2027; i <= 2042; i++) + materials[i] = Material.PinkBed; + for (int i = 2043; i <= 2058; i++) + materials[i] = Material.GrayBed; + for (int i = 2059; i <= 2074; i++) + materials[i] = Material.LightGrayBed; + for (int i = 2075; i <= 2090; i++) + materials[i] = Material.CyanBed; + for (int i = 2091; i <= 2106; i++) + materials[i] = Material.PurpleBed; + for (int i = 2107; i <= 2122; i++) + materials[i] = Material.BlueBed; + for (int i = 2123; i <= 2138; i++) + materials[i] = Material.BrownBed; + for (int i = 2139; i <= 2154; i++) + materials[i] = Material.GreenBed; + for (int i = 2155; i <= 2170; i++) + materials[i] = Material.RedBed; + for (int i = 2171; i <= 2186; i++) + materials[i] = Material.BlackBed; + for (int i = 2187; i <= 2210; i++) + materials[i] = Material.PoweredRail; + for (int i = 2211; i <= 2234; i++) + materials[i] = Material.DetectorRail; + for (int i = 2235; i <= 2246; i++) + materials[i] = Material.StickyPiston; + for (int i = 2247; i <= 2247; i++) + materials[i] = Material.Cobweb; + for (int i = 2248; i <= 2248; i++) + materials[i] = Material.ShortGrass; + for (int i = 2249; i <= 2249; i++) + materials[i] = Material.Fern; + for (int i = 2250; i <= 2250; i++) + materials[i] = Material.DeadBush; + for (int i = 2251; i <= 2251; i++) + materials[i] = Material.Bush; + for (int i = 2252; i <= 2252; i++) + materials[i] = Material.ShortDryGrass; + for (int i = 2253; i <= 2253; i++) + materials[i] = Material.TallDryGrass; + for (int i = 2254; i <= 2254; i++) + materials[i] = Material.Seagrass; + for (int i = 2255; i <= 2256; i++) + materials[i] = Material.TallSeagrass; + for (int i = 2257; i <= 2268; i++) + materials[i] = Material.Piston; + for (int i = 2269; i <= 2292; i++) + materials[i] = Material.PistonHead; + for (int i = 2293; i <= 2293; i++) + materials[i] = Material.WhiteWool; + for (int i = 2294; i <= 2294; i++) + materials[i] = Material.OrangeWool; + for (int i = 2295; i <= 2295; i++) + materials[i] = Material.MagentaWool; + for (int i = 2296; i <= 2296; i++) + materials[i] = Material.LightBlueWool; + for (int i = 2297; i <= 2297; i++) + materials[i] = Material.YellowWool; + for (int i = 2298; i <= 2298; i++) + materials[i] = Material.LimeWool; + for (int i = 2299; i <= 2299; i++) + materials[i] = Material.PinkWool; + for (int i = 2300; i <= 2300; i++) + materials[i] = Material.GrayWool; + for (int i = 2301; i <= 2301; i++) + materials[i] = Material.LightGrayWool; + for (int i = 2302; i <= 2302; i++) + materials[i] = Material.CyanWool; + for (int i = 2303; i <= 2303; i++) + materials[i] = Material.PurpleWool; + for (int i = 2304; i <= 2304; i++) + materials[i] = Material.BlueWool; + for (int i = 2305; i <= 2305; i++) + materials[i] = Material.BrownWool; + for (int i = 2306; i <= 2306; i++) + materials[i] = Material.GreenWool; + for (int i = 2307; i <= 2307; i++) + materials[i] = Material.RedWool; + for (int i = 2308; i <= 2308; i++) + materials[i] = Material.BlackWool; + for (int i = 2309; i <= 2320; i++) + materials[i] = Material.MovingPiston; + for (int i = 2321; i <= 2321; i++) + materials[i] = Material.Dandelion; + for (int i = 2322; i <= 2322; i++) + materials[i] = Material.GoldenDandelion; + for (int i = 2323; i <= 2323; i++) + materials[i] = Material.Torchflower; + for (int i = 2324; i <= 2324; i++) + materials[i] = Material.Poppy; + for (int i = 2325; i <= 2325; i++) + materials[i] = Material.BlueOrchid; + for (int i = 2326; i <= 2326; i++) + materials[i] = Material.Allium; + for (int i = 2327; i <= 2327; i++) + materials[i] = Material.AzureBluet; + for (int i = 2328; i <= 2328; i++) + materials[i] = Material.RedTulip; + for (int i = 2329; i <= 2329; i++) + materials[i] = Material.OrangeTulip; + for (int i = 2330; i <= 2330; i++) + materials[i] = Material.WhiteTulip; + for (int i = 2331; i <= 2331; i++) + materials[i] = Material.PinkTulip; + for (int i = 2332; i <= 2332; i++) + materials[i] = Material.OxeyeDaisy; + for (int i = 2333; i <= 2333; i++) + materials[i] = Material.Cornflower; + for (int i = 2334; i <= 2334; i++) + materials[i] = Material.WitherRose; + for (int i = 2335; i <= 2335; i++) + materials[i] = Material.LilyOfTheValley; + for (int i = 2336; i <= 2336; i++) + materials[i] = Material.BrownMushroom; + for (int i = 2337; i <= 2337; i++) + materials[i] = Material.RedMushroom; + for (int i = 2338; i <= 2338; i++) + materials[i] = Material.GoldBlock; + for (int i = 2339; i <= 2339; i++) + materials[i] = Material.IronBlock; + for (int i = 2340; i <= 2340; i++) + materials[i] = Material.Bricks; + for (int i = 2341; i <= 2342; i++) + materials[i] = Material.Tnt; + for (int i = 2343; i <= 2343; i++) + materials[i] = Material.Bookshelf; + for (int i = 2344; i <= 2599; i++) + materials[i] = Material.ChiseledBookshelf; + for (int i = 2600; i <= 2663; i++) + materials[i] = Material.AcaciaShelf; + for (int i = 2664; i <= 2727; i++) + materials[i] = Material.BambooShelf; + for (int i = 2728; i <= 2791; i++) + materials[i] = Material.BirchShelf; + for (int i = 2792; i <= 2855; i++) + materials[i] = Material.CherryShelf; + for (int i = 2856; i <= 2919; i++) + materials[i] = Material.CrimsonShelf; + for (int i = 2920; i <= 2983; i++) + materials[i] = Material.DarkOakShelf; + for (int i = 2984; i <= 3047; i++) + materials[i] = Material.JungleShelf; + for (int i = 3048; i <= 3111; i++) + materials[i] = Material.MangroveShelf; + for (int i = 3112; i <= 3175; i++) + materials[i] = Material.OakShelf; + for (int i = 3176; i <= 3239; i++) + materials[i] = Material.PaleOakShelf; + for (int i = 3240; i <= 3303; i++) + materials[i] = Material.SpruceShelf; + for (int i = 3304; i <= 3367; i++) + materials[i] = Material.WarpedShelf; + for (int i = 3368; i <= 3368; i++) + materials[i] = Material.MossyCobblestone; + for (int i = 3369; i <= 3369; i++) + materials[i] = Material.Obsidian; + for (int i = 3370; i <= 3370; i++) + materials[i] = Material.Torch; + for (int i = 3371; i <= 3374; i++) + materials[i] = Material.WallTorch; + for (int i = 3375; i <= 3886; i++) + materials[i] = Material.Fire; + for (int i = 3887; i <= 3887; i++) + materials[i] = Material.SoulFire; + for (int i = 3888; i <= 3888; i++) + materials[i] = Material.Spawner; + for (int i = 3889; i <= 3906; i++) + materials[i] = Material.CreakingHeart; + for (int i = 3907; i <= 3986; i++) + materials[i] = Material.OakStairs; + for (int i = 3987; i <= 4010; i++) + materials[i] = Material.Chest; + for (int i = 4011; i <= 5306; i++) + materials[i] = Material.RedstoneWire; + for (int i = 5307; i <= 5307; i++) + materials[i] = Material.DiamondOre; + for (int i = 5308; i <= 5308; i++) + materials[i] = Material.DeepslateDiamondOre; + for (int i = 5309; i <= 5309; i++) + materials[i] = Material.DiamondBlock; + for (int i = 5310; i <= 5310; i++) + materials[i] = Material.CraftingTable; + for (int i = 5311; i <= 5318; i++) + materials[i] = Material.Wheat; + for (int i = 5319; i <= 5326; i++) + materials[i] = Material.Farmland; + for (int i = 5327; i <= 5334; i++) + materials[i] = Material.Furnace; + for (int i = 5335; i <= 5366; i++) + materials[i] = Material.OakSign; + for (int i = 5367; i <= 5398; i++) + materials[i] = Material.SpruceSign; + for (int i = 5399; i <= 5430; i++) + materials[i] = Material.BirchSign; + for (int i = 5431; i <= 5462; i++) + materials[i] = Material.AcaciaSign; + for (int i = 5463; i <= 5494; i++) + materials[i] = Material.CherrySign; + for (int i = 5495; i <= 5526; i++) + materials[i] = Material.JungleSign; + for (int i = 5527; i <= 5558; i++) + materials[i] = Material.DarkOakSign; + for (int i = 5559; i <= 5590; i++) + materials[i] = Material.PaleOakSign; + for (int i = 5591; i <= 5622; i++) + materials[i] = Material.MangroveSign; + for (int i = 5623; i <= 5654; i++) + materials[i] = Material.BambooSign; + for (int i = 5655; i <= 5718; i++) + materials[i] = Material.OakDoor; + for (int i = 5719; i <= 5726; i++) + materials[i] = Material.Ladder; + for (int i = 5727; i <= 5746; i++) + materials[i] = Material.Rail; + for (int i = 5747; i <= 5826; i++) + materials[i] = Material.CobblestoneStairs; + for (int i = 5827; i <= 5834; i++) + materials[i] = Material.OakWallSign; + for (int i = 5835; i <= 5842; i++) + materials[i] = Material.SpruceWallSign; + for (int i = 5843; i <= 5850; i++) + materials[i] = Material.BirchWallSign; + for (int i = 5851; i <= 5858; i++) + materials[i] = Material.AcaciaWallSign; + for (int i = 5859; i <= 5866; i++) + materials[i] = Material.CherryWallSign; + for (int i = 5867; i <= 5874; i++) + materials[i] = Material.JungleWallSign; + for (int i = 5875; i <= 5882; i++) + materials[i] = Material.DarkOakWallSign; + for (int i = 5883; i <= 5890; i++) + materials[i] = Material.PaleOakWallSign; + for (int i = 5891; i <= 5898; i++) + materials[i] = Material.MangroveWallSign; + for (int i = 5899; i <= 5906; i++) + materials[i] = Material.BambooWallSign; + for (int i = 5907; i <= 5970; i++) + materials[i] = Material.OakHangingSign; + for (int i = 5971; i <= 6034; i++) + materials[i] = Material.SpruceHangingSign; + for (int i = 6035; i <= 6098; i++) + materials[i] = Material.BirchHangingSign; + for (int i = 6099; i <= 6162; i++) + materials[i] = Material.AcaciaHangingSign; + for (int i = 6163; i <= 6226; i++) + materials[i] = Material.CherryHangingSign; + for (int i = 6227; i <= 6290; i++) + materials[i] = Material.JungleHangingSign; + for (int i = 6291; i <= 6354; i++) + materials[i] = Material.DarkOakHangingSign; + for (int i = 6355; i <= 6418; i++) + materials[i] = Material.PaleOakHangingSign; + for (int i = 6419; i <= 6482; i++) + materials[i] = Material.CrimsonHangingSign; + for (int i = 6483; i <= 6546; i++) + materials[i] = Material.WarpedHangingSign; + for (int i = 6547; i <= 6610; i++) + materials[i] = Material.MangroveHangingSign; + for (int i = 6611; i <= 6674; i++) + materials[i] = Material.BambooHangingSign; + for (int i = 6675; i <= 6682; i++) + materials[i] = Material.OakWallHangingSign; + for (int i = 6683; i <= 6690; i++) + materials[i] = Material.SpruceWallHangingSign; + for (int i = 6691; i <= 6698; i++) + materials[i] = Material.BirchWallHangingSign; + for (int i = 6699; i <= 6706; i++) + materials[i] = Material.AcaciaWallHangingSign; + for (int i = 6707; i <= 6714; i++) + materials[i] = Material.CherryWallHangingSign; + for (int i = 6715; i <= 6722; i++) + materials[i] = Material.JungleWallHangingSign; + for (int i = 6723; i <= 6730; i++) + materials[i] = Material.DarkOakWallHangingSign; + for (int i = 6731; i <= 6738; i++) + materials[i] = Material.PaleOakWallHangingSign; + for (int i = 6739; i <= 6746; i++) + materials[i] = Material.MangroveWallHangingSign; + for (int i = 6747; i <= 6754; i++) + materials[i] = Material.CrimsonWallHangingSign; + for (int i = 6755; i <= 6762; i++) + materials[i] = Material.WarpedWallHangingSign; + for (int i = 6763; i <= 6770; i++) + materials[i] = Material.BambooWallHangingSign; + for (int i = 6771; i <= 6794; i++) + materials[i] = Material.Lever; + for (int i = 6795; i <= 6796; i++) + materials[i] = Material.StonePressurePlate; + for (int i = 6797; i <= 6860; i++) + materials[i] = Material.IronDoor; + for (int i = 6861; i <= 6862; i++) + materials[i] = Material.OakPressurePlate; + for (int i = 6863; i <= 6864; i++) + materials[i] = Material.SprucePressurePlate; + for (int i = 6865; i <= 6866; i++) + materials[i] = Material.BirchPressurePlate; + for (int i = 6867; i <= 6868; i++) + materials[i] = Material.JunglePressurePlate; + for (int i = 6869; i <= 6870; i++) + materials[i] = Material.AcaciaPressurePlate; + for (int i = 6871; i <= 6872; i++) + materials[i] = Material.CherryPressurePlate; + for (int i = 6873; i <= 6874; i++) + materials[i] = Material.DarkOakPressurePlate; + for (int i = 6875; i <= 6876; i++) + materials[i] = Material.PaleOakPressurePlate; + for (int i = 6877; i <= 6878; i++) + materials[i] = Material.MangrovePressurePlate; + for (int i = 6879; i <= 6880; i++) + materials[i] = Material.BambooPressurePlate; + for (int i = 6881; i <= 6882; i++) + materials[i] = Material.RedstoneOre; + for (int i = 6883; i <= 6884; i++) + materials[i] = Material.DeepslateRedstoneOre; + for (int i = 6885; i <= 6886; i++) + materials[i] = Material.RedstoneTorch; + for (int i = 6887; i <= 6894; i++) + materials[i] = Material.RedstoneWallTorch; + for (int i = 6895; i <= 6918; i++) + materials[i] = Material.StoneButton; + for (int i = 6919; i <= 6926; i++) + materials[i] = Material.Snow; + for (int i = 6927; i <= 6927; i++) + materials[i] = Material.Ice; + for (int i = 6928; i <= 6928; i++) + materials[i] = Material.SnowBlock; + for (int i = 6929; i <= 6944; i++) + materials[i] = Material.Cactus; + for (int i = 6945; i <= 6945; i++) + materials[i] = Material.CactusFlower; + for (int i = 6946; i <= 6946; i++) + materials[i] = Material.Clay; + for (int i = 6947; i <= 6962; i++) + materials[i] = Material.SugarCane; + for (int i = 6963; i <= 6964; i++) + materials[i] = Material.Jukebox; + for (int i = 6965; i <= 6996; i++) + materials[i] = Material.OakFence; + for (int i = 6997; i <= 6997; i++) + materials[i] = Material.Netherrack; + for (int i = 6998; i <= 6998; i++) + materials[i] = Material.SoulSand; + for (int i = 6999; i <= 6999; i++) + materials[i] = Material.SoulSoil; + for (int i = 7000; i <= 7002; i++) + materials[i] = Material.Basalt; + for (int i = 7003; i <= 7005; i++) + materials[i] = Material.PolishedBasalt; + for (int i = 7006; i <= 7006; i++) + materials[i] = Material.SoulTorch; + for (int i = 7007; i <= 7010; i++) + materials[i] = Material.SoulWallTorch; + for (int i = 7011; i <= 7011; i++) + materials[i] = Material.CopperTorch; + for (int i = 7012; i <= 7015; i++) + materials[i] = Material.CopperWallTorch; + for (int i = 7016; i <= 7016; i++) + materials[i] = Material.Glowstone; + for (int i = 7017; i <= 7018; i++) + materials[i] = Material.NetherPortal; + for (int i = 7019; i <= 7022; i++) + materials[i] = Material.CarvedPumpkin; + for (int i = 7023; i <= 7026; i++) + materials[i] = Material.JackOLantern; + for (int i = 7027; i <= 7033; i++) + materials[i] = Material.Cake; + for (int i = 7034; i <= 7097; i++) + materials[i] = Material.Repeater; + for (int i = 7098; i <= 7098; i++) + materials[i] = Material.WhiteStainedGlass; + for (int i = 7099; i <= 7099; i++) + materials[i] = Material.OrangeStainedGlass; + for (int i = 7100; i <= 7100; i++) + materials[i] = Material.MagentaStainedGlass; + for (int i = 7101; i <= 7101; i++) + materials[i] = Material.LightBlueStainedGlass; + for (int i = 7102; i <= 7102; i++) + materials[i] = Material.YellowStainedGlass; + for (int i = 7103; i <= 7103; i++) + materials[i] = Material.LimeStainedGlass; + for (int i = 7104; i <= 7104; i++) + materials[i] = Material.PinkStainedGlass; + for (int i = 7105; i <= 7105; i++) + materials[i] = Material.GrayStainedGlass; + for (int i = 7106; i <= 7106; i++) + materials[i] = Material.LightGrayStainedGlass; + for (int i = 7107; i <= 7107; i++) + materials[i] = Material.CyanStainedGlass; + for (int i = 7108; i <= 7108; i++) + materials[i] = Material.PurpleStainedGlass; + for (int i = 7109; i <= 7109; i++) + materials[i] = Material.BlueStainedGlass; + for (int i = 7110; i <= 7110; i++) + materials[i] = Material.BrownStainedGlass; + for (int i = 7111; i <= 7111; i++) + materials[i] = Material.GreenStainedGlass; + for (int i = 7112; i <= 7112; i++) + materials[i] = Material.RedStainedGlass; + for (int i = 7113; i <= 7113; i++) + materials[i] = Material.BlackStainedGlass; + for (int i = 7114; i <= 7177; i++) + materials[i] = Material.OakTrapdoor; + for (int i = 7178; i <= 7241; i++) + materials[i] = Material.SpruceTrapdoor; + for (int i = 7242; i <= 7305; i++) + materials[i] = Material.BirchTrapdoor; + for (int i = 7306; i <= 7369; i++) + materials[i] = Material.JungleTrapdoor; + for (int i = 7370; i <= 7433; i++) + materials[i] = Material.AcaciaTrapdoor; + for (int i = 7434; i <= 7497; i++) + materials[i] = Material.CherryTrapdoor; + for (int i = 7498; i <= 7561; i++) + materials[i] = Material.DarkOakTrapdoor; + for (int i = 7562; i <= 7625; i++) + materials[i] = Material.PaleOakTrapdoor; + for (int i = 7626; i <= 7689; i++) + materials[i] = Material.MangroveTrapdoor; + for (int i = 7690; i <= 7753; i++) + materials[i] = Material.BambooTrapdoor; + for (int i = 7754; i <= 7754; i++) + materials[i] = Material.StoneBricks; + for (int i = 7755; i <= 7755; i++) + materials[i] = Material.MossyStoneBricks; + for (int i = 7756; i <= 7756; i++) + materials[i] = Material.CrackedStoneBricks; + for (int i = 7757; i <= 7757; i++) + materials[i] = Material.ChiseledStoneBricks; + for (int i = 7758; i <= 7758; i++) + materials[i] = Material.PackedMud; + for (int i = 7759; i <= 7759; i++) + materials[i] = Material.MudBricks; + for (int i = 7760; i <= 7760; i++) + materials[i] = Material.InfestedStone; + for (int i = 7761; i <= 7761; i++) + materials[i] = Material.InfestedCobblestone; + for (int i = 7762; i <= 7762; i++) + materials[i] = Material.InfestedStoneBricks; + for (int i = 7763; i <= 7763; i++) + materials[i] = Material.InfestedMossyStoneBricks; + for (int i = 7764; i <= 7764; i++) + materials[i] = Material.InfestedCrackedStoneBricks; + for (int i = 7765; i <= 7765; i++) + materials[i] = Material.InfestedChiseledStoneBricks; + for (int i = 7766; i <= 7829; i++) + materials[i] = Material.BrownMushroomBlock; + for (int i = 7830; i <= 7893; i++) + materials[i] = Material.RedMushroomBlock; + for (int i = 7894; i <= 7957; i++) + materials[i] = Material.MushroomStem; + for (int i = 7958; i <= 7989; i++) + materials[i] = Material.IronBars; + for (int i = 7990; i <= 8021; i++) + materials[i] = Material.CopperBars; + for (int i = 8022; i <= 8053; i++) + materials[i] = Material.ExposedCopperBars; + for (int i = 8054; i <= 8085; i++) + materials[i] = Material.WeatheredCopperBars; + for (int i = 8086; i <= 8117; i++) + materials[i] = Material.OxidizedCopperBars; + for (int i = 8118; i <= 8149; i++) + materials[i] = Material.WaxedCopperBars; + for (int i = 8150; i <= 8181; i++) + materials[i] = Material.WaxedExposedCopperBars; + for (int i = 8182; i <= 8213; i++) + materials[i] = Material.WaxedWeatheredCopperBars; + for (int i = 8214; i <= 8245; i++) + materials[i] = Material.WaxedOxidizedCopperBars; + for (int i = 8246; i <= 8251; i++) + materials[i] = Material.IronChain; + for (int i = 8252; i <= 8257; i++) + materials[i] = Material.CopperChain; + for (int i = 8258; i <= 8263; i++) + materials[i] = Material.ExposedCopperChain; + for (int i = 8264; i <= 8269; i++) + materials[i] = Material.WeatheredCopperChain; + for (int i = 8270; i <= 8275; i++) + materials[i] = Material.OxidizedCopperChain; + for (int i = 8276; i <= 8281; i++) + materials[i] = Material.WaxedCopperChain; + for (int i = 8282; i <= 8287; i++) + materials[i] = Material.WaxedExposedCopperChain; + for (int i = 8288; i <= 8293; i++) + materials[i] = Material.WaxedWeatheredCopperChain; + for (int i = 8294; i <= 8299; i++) + materials[i] = Material.WaxedOxidizedCopperChain; + for (int i = 8300; i <= 8331; i++) + materials[i] = Material.GlassPane; + for (int i = 8332; i <= 8332; i++) + materials[i] = Material.Pumpkin; + for (int i = 8333; i <= 8333; i++) + materials[i] = Material.Melon; + for (int i = 8334; i <= 8337; i++) + materials[i] = Material.AttachedPumpkinStem; + for (int i = 8338; i <= 8341; i++) + materials[i] = Material.AttachedMelonStem; + for (int i = 8342; i <= 8349; i++) + materials[i] = Material.PumpkinStem; + for (int i = 8350; i <= 8357; i++) + materials[i] = Material.MelonStem; + for (int i = 8358; i <= 8389; i++) + materials[i] = Material.Vine; + for (int i = 8390; i <= 8517; i++) + materials[i] = Material.GlowLichen; + for (int i = 8518; i <= 8645; i++) + materials[i] = Material.ResinClump; + for (int i = 8646; i <= 8677; i++) + materials[i] = Material.OakFenceGate; + for (int i = 8678; i <= 8757; i++) + materials[i] = Material.BrickStairs; + for (int i = 8758; i <= 8837; i++) + materials[i] = Material.StoneBrickStairs; + for (int i = 8838; i <= 8917; i++) + materials[i] = Material.MudBrickStairs; + for (int i = 8918; i <= 8919; i++) + materials[i] = Material.Mycelium; + for (int i = 8920; i <= 8920; i++) + materials[i] = Material.LilyPad; + for (int i = 8921; i <= 8921; i++) + materials[i] = Material.ResinBlock; + for (int i = 8922; i <= 8922; i++) + materials[i] = Material.ResinBricks; + for (int i = 8923; i <= 9002; i++) + materials[i] = Material.ResinBrickStairs; + for (int i = 9003; i <= 9008; i++) + materials[i] = Material.ResinBrickSlab; + for (int i = 9009; i <= 9332; i++) + materials[i] = Material.ResinBrickWall; + for (int i = 9333; i <= 9333; i++) + materials[i] = Material.ChiseledResinBricks; + for (int i = 9334; i <= 9334; i++) + materials[i] = Material.NetherBricks; + for (int i = 9335; i <= 9366; i++) + materials[i] = Material.NetherBrickFence; + for (int i = 9367; i <= 9446; i++) + materials[i] = Material.NetherBrickStairs; + for (int i = 9447; i <= 9450; i++) + materials[i] = Material.NetherWart; + for (int i = 9451; i <= 9451; i++) + materials[i] = Material.EnchantingTable; + for (int i = 9452; i <= 9459; i++) + materials[i] = Material.BrewingStand; + for (int i = 9460; i <= 9460; i++) + materials[i] = Material.Cauldron; + for (int i = 9461; i <= 9463; i++) + materials[i] = Material.WaterCauldron; + for (int i = 9464; i <= 9464; i++) + materials[i] = Material.LavaCauldron; + for (int i = 9465; i <= 9467; i++) + materials[i] = Material.PowderSnowCauldron; + for (int i = 9468; i <= 9468; i++) + materials[i] = Material.EndPortal; + for (int i = 9469; i <= 9476; i++) + materials[i] = Material.EndPortalFrame; + for (int i = 9477; i <= 9477; i++) + materials[i] = Material.EndStone; + for (int i = 9478; i <= 9478; i++) + materials[i] = Material.DragonEgg; + for (int i = 9479; i <= 9480; i++) + materials[i] = Material.RedstoneLamp; + for (int i = 9481; i <= 9492; i++) + materials[i] = Material.Cocoa; + for (int i = 9493; i <= 9572; i++) + materials[i] = Material.SandstoneStairs; + for (int i = 9573; i <= 9573; i++) + materials[i] = Material.EmeraldOre; + for (int i = 9574; i <= 9574; i++) + materials[i] = Material.DeepslateEmeraldOre; + for (int i = 9575; i <= 9582; i++) + materials[i] = Material.EnderChest; + for (int i = 9583; i <= 9598; i++) + materials[i] = Material.TripwireHook; + for (int i = 9599; i <= 9726; i++) + materials[i] = Material.Tripwire; + for (int i = 9727; i <= 9727; i++) + materials[i] = Material.EmeraldBlock; + for (int i = 9728; i <= 9807; i++) + materials[i] = Material.SpruceStairs; + for (int i = 9808; i <= 9887; i++) + materials[i] = Material.BirchStairs; + for (int i = 9888; i <= 9967; i++) + materials[i] = Material.JungleStairs; + for (int i = 9968; i <= 9979; i++) + materials[i] = Material.CommandBlock; + for (int i = 9980; i <= 9980; i++) + materials[i] = Material.Beacon; + for (int i = 9981; i <= 10304; i++) + materials[i] = Material.CobblestoneWall; + for (int i = 10305; i <= 10628; i++) + materials[i] = Material.MossyCobblestoneWall; + for (int i = 10629; i <= 10629; i++) + materials[i] = Material.FlowerPot; + for (int i = 10630; i <= 10630; i++) + materials[i] = Material.PottedTorchflower; + for (int i = 10631; i <= 10631; i++) + materials[i] = Material.PottedOakSapling; + for (int i = 10632; i <= 10632; i++) + materials[i] = Material.PottedSpruceSapling; + for (int i = 10633; i <= 10633; i++) + materials[i] = Material.PottedBirchSapling; + for (int i = 10634; i <= 10634; i++) + materials[i] = Material.PottedJungleSapling; + for (int i = 10635; i <= 10635; i++) + materials[i] = Material.PottedAcaciaSapling; + for (int i = 10636; i <= 10636; i++) + materials[i] = Material.PottedCherrySapling; + for (int i = 10637; i <= 10637; i++) + materials[i] = Material.PottedDarkOakSapling; + for (int i = 10638; i <= 10638; i++) + materials[i] = Material.PottedPaleOakSapling; + for (int i = 10639; i <= 10639; i++) + materials[i] = Material.PottedMangrovePropagule; + for (int i = 10640; i <= 10640; i++) + materials[i] = Material.PottedFern; + for (int i = 10641; i <= 10641; i++) + materials[i] = Material.PottedDandelion; + for (int i = 10642; i <= 10642; i++) + materials[i] = Material.PottedGoldenDandelion; + for (int i = 10643; i <= 10643; i++) + materials[i] = Material.PottedPoppy; + for (int i = 10644; i <= 10644; i++) + materials[i] = Material.PottedBlueOrchid; + for (int i = 10645; i <= 10645; i++) + materials[i] = Material.PottedAllium; + for (int i = 10646; i <= 10646; i++) + materials[i] = Material.PottedAzureBluet; + for (int i = 10647; i <= 10647; i++) + materials[i] = Material.PottedRedTulip; + for (int i = 10648; i <= 10648; i++) + materials[i] = Material.PottedOrangeTulip; + for (int i = 10649; i <= 10649; i++) + materials[i] = Material.PottedWhiteTulip; + for (int i = 10650; i <= 10650; i++) + materials[i] = Material.PottedPinkTulip; + for (int i = 10651; i <= 10651; i++) + materials[i] = Material.PottedOxeyeDaisy; + for (int i = 10652; i <= 10652; i++) + materials[i] = Material.PottedCornflower; + for (int i = 10653; i <= 10653; i++) + materials[i] = Material.PottedLilyOfTheValley; + for (int i = 10654; i <= 10654; i++) + materials[i] = Material.PottedWitherRose; + for (int i = 10655; i <= 10655; i++) + materials[i] = Material.PottedRedMushroom; + for (int i = 10656; i <= 10656; i++) + materials[i] = Material.PottedBrownMushroom; + for (int i = 10657; i <= 10657; i++) + materials[i] = Material.PottedDeadBush; + for (int i = 10658; i <= 10658; i++) + materials[i] = Material.PottedCactus; + for (int i = 10659; i <= 10666; i++) + materials[i] = Material.Carrots; + for (int i = 10667; i <= 10674; i++) + materials[i] = Material.Potatoes; + for (int i = 10675; i <= 10698; i++) + materials[i] = Material.OakButton; + for (int i = 10699; i <= 10722; i++) + materials[i] = Material.SpruceButton; + for (int i = 10723; i <= 10746; i++) + materials[i] = Material.BirchButton; + for (int i = 10747; i <= 10770; i++) + materials[i] = Material.JungleButton; + for (int i = 10771; i <= 10794; i++) + materials[i] = Material.AcaciaButton; + for (int i = 10795; i <= 10818; i++) + materials[i] = Material.CherryButton; + for (int i = 10819; i <= 10842; i++) + materials[i] = Material.DarkOakButton; + for (int i = 10843; i <= 10866; i++) + materials[i] = Material.PaleOakButton; + for (int i = 10867; i <= 10890; i++) + materials[i] = Material.MangroveButton; + for (int i = 10891; i <= 10914; i++) + materials[i] = Material.BambooButton; + for (int i = 10915; i <= 10946; i++) + materials[i] = Material.SkeletonSkull; + for (int i = 10947; i <= 10954; i++) + materials[i] = Material.SkeletonWallSkull; + for (int i = 10955; i <= 10986; i++) + materials[i] = Material.WitherSkeletonSkull; + for (int i = 10987; i <= 10994; i++) + materials[i] = Material.WitherSkeletonWallSkull; + for (int i = 10995; i <= 11026; i++) + materials[i] = Material.ZombieHead; + for (int i = 11027; i <= 11034; i++) + materials[i] = Material.ZombieWallHead; + for (int i = 11035; i <= 11066; i++) + materials[i] = Material.PlayerHead; + for (int i = 11067; i <= 11074; i++) + materials[i] = Material.PlayerWallHead; + for (int i = 11075; i <= 11106; i++) + materials[i] = Material.CreeperHead; + for (int i = 11107; i <= 11114; i++) + materials[i] = Material.CreeperWallHead; + for (int i = 11115; i <= 11146; i++) + materials[i] = Material.DragonHead; + for (int i = 11147; i <= 11154; i++) + materials[i] = Material.DragonWallHead; + for (int i = 11155; i <= 11186; i++) + materials[i] = Material.PiglinHead; + for (int i = 11187; i <= 11194; i++) + materials[i] = Material.PiglinWallHead; + for (int i = 11195; i <= 11198; i++) + materials[i] = Material.Anvil; + for (int i = 11199; i <= 11202; i++) + materials[i] = Material.ChippedAnvil; + for (int i = 11203; i <= 11206; i++) + materials[i] = Material.DamagedAnvil; + for (int i = 11207; i <= 11230; i++) + materials[i] = Material.TrappedChest; + for (int i = 11231; i <= 11246; i++) + materials[i] = Material.LightWeightedPressurePlate; + for (int i = 11247; i <= 11262; i++) + materials[i] = Material.HeavyWeightedPressurePlate; + for (int i = 11263; i <= 11278; i++) + materials[i] = Material.Comparator; + for (int i = 11279; i <= 11310; i++) + materials[i] = Material.DaylightDetector; + for (int i = 11311; i <= 11311; i++) + materials[i] = Material.RedstoneBlock; + for (int i = 11312; i <= 11312; i++) + materials[i] = Material.NetherQuartzOre; + for (int i = 11313; i <= 11322; i++) + materials[i] = Material.Hopper; + for (int i = 11323; i <= 11323; i++) + materials[i] = Material.QuartzBlock; + for (int i = 11324; i <= 11324; i++) + materials[i] = Material.ChiseledQuartzBlock; + for (int i = 11325; i <= 11327; i++) + materials[i] = Material.QuartzPillar; + for (int i = 11328; i <= 11407; i++) + materials[i] = Material.QuartzStairs; + for (int i = 11408; i <= 11431; i++) + materials[i] = Material.ActivatorRail; + for (int i = 11432; i <= 11443; i++) + materials[i] = Material.Dropper; + for (int i = 11444; i <= 11444; i++) + materials[i] = Material.WhiteTerracotta; + for (int i = 11445; i <= 11445; i++) + materials[i] = Material.OrangeTerracotta; + for (int i = 11446; i <= 11446; i++) + materials[i] = Material.MagentaTerracotta; + for (int i = 11447; i <= 11447; i++) + materials[i] = Material.LightBlueTerracotta; + for (int i = 11448; i <= 11448; i++) + materials[i] = Material.YellowTerracotta; + for (int i = 11449; i <= 11449; i++) + materials[i] = Material.LimeTerracotta; + for (int i = 11450; i <= 11450; i++) + materials[i] = Material.PinkTerracotta; + for (int i = 11451; i <= 11451; i++) + materials[i] = Material.GrayTerracotta; + for (int i = 11452; i <= 11452; i++) + materials[i] = Material.LightGrayTerracotta; + for (int i = 11453; i <= 11453; i++) + materials[i] = Material.CyanTerracotta; + for (int i = 11454; i <= 11454; i++) + materials[i] = Material.PurpleTerracotta; + for (int i = 11455; i <= 11455; i++) + materials[i] = Material.BlueTerracotta; + for (int i = 11456; i <= 11456; i++) + materials[i] = Material.BrownTerracotta; + for (int i = 11457; i <= 11457; i++) + materials[i] = Material.GreenTerracotta; + for (int i = 11458; i <= 11458; i++) + materials[i] = Material.RedTerracotta; + for (int i = 11459; i <= 11459; i++) + materials[i] = Material.BlackTerracotta; + for (int i = 11460; i <= 11491; i++) + materials[i] = Material.WhiteStainedGlassPane; + for (int i = 11492; i <= 11523; i++) + materials[i] = Material.OrangeStainedGlassPane; + for (int i = 11524; i <= 11555; i++) + materials[i] = Material.MagentaStainedGlassPane; + for (int i = 11556; i <= 11587; i++) + materials[i] = Material.LightBlueStainedGlassPane; + for (int i = 11588; i <= 11619; i++) + materials[i] = Material.YellowStainedGlassPane; + for (int i = 11620; i <= 11651; i++) + materials[i] = Material.LimeStainedGlassPane; + for (int i = 11652; i <= 11683; i++) + materials[i] = Material.PinkStainedGlassPane; + for (int i = 11684; i <= 11715; i++) + materials[i] = Material.GrayStainedGlassPane; + for (int i = 11716; i <= 11747; i++) + materials[i] = Material.LightGrayStainedGlassPane; + for (int i = 11748; i <= 11779; i++) + materials[i] = Material.CyanStainedGlassPane; + for (int i = 11780; i <= 11811; i++) + materials[i] = Material.PurpleStainedGlassPane; + for (int i = 11812; i <= 11843; i++) + materials[i] = Material.BlueStainedGlassPane; + for (int i = 11844; i <= 11875; i++) + materials[i] = Material.BrownStainedGlassPane; + for (int i = 11876; i <= 11907; i++) + materials[i] = Material.GreenStainedGlassPane; + for (int i = 11908; i <= 11939; i++) + materials[i] = Material.RedStainedGlassPane; + for (int i = 11940; i <= 11971; i++) + materials[i] = Material.BlackStainedGlassPane; + for (int i = 11972; i <= 12051; i++) + materials[i] = Material.AcaciaStairs; + for (int i = 12052; i <= 12131; i++) + materials[i] = Material.CherryStairs; + for (int i = 12132; i <= 12211; i++) + materials[i] = Material.DarkOakStairs; + for (int i = 12212; i <= 12291; i++) + materials[i] = Material.PaleOakStairs; + for (int i = 12292; i <= 12371; i++) + materials[i] = Material.MangroveStairs; + for (int i = 12372; i <= 12451; i++) + materials[i] = Material.BambooStairs; + for (int i = 12452; i <= 12531; i++) + materials[i] = Material.BambooMosaicStairs; + for (int i = 12532; i <= 12532; i++) + materials[i] = Material.SlimeBlock; + for (int i = 12533; i <= 12534; i++) + materials[i] = Material.Barrier; + for (int i = 12535; i <= 12566; i++) + materials[i] = Material.Light; + for (int i = 12567; i <= 12630; i++) + materials[i] = Material.IronTrapdoor; + for (int i = 12631; i <= 12631; i++) + materials[i] = Material.Prismarine; + for (int i = 12632; i <= 12632; i++) + materials[i] = Material.PrismarineBricks; + for (int i = 12633; i <= 12633; i++) + materials[i] = Material.DarkPrismarine; + for (int i = 12634; i <= 12713; i++) + materials[i] = Material.PrismarineStairs; + for (int i = 12714; i <= 12793; i++) + materials[i] = Material.PrismarineBrickStairs; + for (int i = 12794; i <= 12873; i++) + materials[i] = Material.DarkPrismarineStairs; + for (int i = 12874; i <= 12879; i++) + materials[i] = Material.PrismarineSlab; + for (int i = 12880; i <= 12885; i++) + materials[i] = Material.PrismarineBrickSlab; + for (int i = 12886; i <= 12891; i++) + materials[i] = Material.DarkPrismarineSlab; + for (int i = 12892; i <= 12892; i++) + materials[i] = Material.SeaLantern; + for (int i = 12893; i <= 12895; i++) + materials[i] = Material.HayBlock; + for (int i = 12896; i <= 12896; i++) + materials[i] = Material.WhiteCarpet; + for (int i = 12897; i <= 12897; i++) + materials[i] = Material.OrangeCarpet; + for (int i = 12898; i <= 12898; i++) + materials[i] = Material.MagentaCarpet; + for (int i = 12899; i <= 12899; i++) + materials[i] = Material.LightBlueCarpet; + for (int i = 12900; i <= 12900; i++) + materials[i] = Material.YellowCarpet; + for (int i = 12901; i <= 12901; i++) + materials[i] = Material.LimeCarpet; + for (int i = 12902; i <= 12902; i++) + materials[i] = Material.PinkCarpet; + for (int i = 12903; i <= 12903; i++) + materials[i] = Material.GrayCarpet; + for (int i = 12904; i <= 12904; i++) + materials[i] = Material.LightGrayCarpet; + for (int i = 12905; i <= 12905; i++) + materials[i] = Material.CyanCarpet; + for (int i = 12906; i <= 12906; i++) + materials[i] = Material.PurpleCarpet; + for (int i = 12907; i <= 12907; i++) + materials[i] = Material.BlueCarpet; + for (int i = 12908; i <= 12908; i++) + materials[i] = Material.BrownCarpet; + for (int i = 12909; i <= 12909; i++) + materials[i] = Material.GreenCarpet; + for (int i = 12910; i <= 12910; i++) + materials[i] = Material.RedCarpet; + for (int i = 12911; i <= 12911; i++) + materials[i] = Material.BlackCarpet; + for (int i = 12912; i <= 12912; i++) + materials[i] = Material.Terracotta; + for (int i = 12913; i <= 12913; i++) + materials[i] = Material.CoalBlock; + for (int i = 12914; i <= 12914; i++) + materials[i] = Material.PackedIce; + for (int i = 12915; i <= 12916; i++) + materials[i] = Material.Sunflower; + for (int i = 12917; i <= 12918; i++) + materials[i] = Material.Lilac; + for (int i = 12919; i <= 12920; i++) + materials[i] = Material.RoseBush; + for (int i = 12921; i <= 12922; i++) + materials[i] = Material.Peony; + for (int i = 12923; i <= 12924; i++) + materials[i] = Material.TallGrass; + for (int i = 12925; i <= 12926; i++) + materials[i] = Material.LargeFern; + for (int i = 12927; i <= 12942; i++) + materials[i] = Material.WhiteBanner; + for (int i = 12943; i <= 12958; i++) + materials[i] = Material.OrangeBanner; + for (int i = 12959; i <= 12974; i++) + materials[i] = Material.MagentaBanner; + for (int i = 12975; i <= 12990; i++) + materials[i] = Material.LightBlueBanner; + for (int i = 12991; i <= 13006; i++) + materials[i] = Material.YellowBanner; + for (int i = 13007; i <= 13022; i++) + materials[i] = Material.LimeBanner; + for (int i = 13023; i <= 13038; i++) + materials[i] = Material.PinkBanner; + for (int i = 13039; i <= 13054; i++) + materials[i] = Material.GrayBanner; + for (int i = 13055; i <= 13070; i++) + materials[i] = Material.LightGrayBanner; + for (int i = 13071; i <= 13086; i++) + materials[i] = Material.CyanBanner; + for (int i = 13087; i <= 13102; i++) + materials[i] = Material.PurpleBanner; + for (int i = 13103; i <= 13118; i++) + materials[i] = Material.BlueBanner; + for (int i = 13119; i <= 13134; i++) + materials[i] = Material.BrownBanner; + for (int i = 13135; i <= 13150; i++) + materials[i] = Material.GreenBanner; + for (int i = 13151; i <= 13166; i++) + materials[i] = Material.RedBanner; + for (int i = 13167; i <= 13182; i++) + materials[i] = Material.BlackBanner; + for (int i = 13183; i <= 13186; i++) + materials[i] = Material.WhiteWallBanner; + for (int i = 13187; i <= 13190; i++) + materials[i] = Material.OrangeWallBanner; + for (int i = 13191; i <= 13194; i++) + materials[i] = Material.MagentaWallBanner; + for (int i = 13195; i <= 13198; i++) + materials[i] = Material.LightBlueWallBanner; + for (int i = 13199; i <= 13202; i++) + materials[i] = Material.YellowWallBanner; + for (int i = 13203; i <= 13206; i++) + materials[i] = Material.LimeWallBanner; + for (int i = 13207; i <= 13210; i++) + materials[i] = Material.PinkWallBanner; + for (int i = 13211; i <= 13214; i++) + materials[i] = Material.GrayWallBanner; + for (int i = 13215; i <= 13218; i++) + materials[i] = Material.LightGrayWallBanner; + for (int i = 13219; i <= 13222; i++) + materials[i] = Material.CyanWallBanner; + for (int i = 13223; i <= 13226; i++) + materials[i] = Material.PurpleWallBanner; + for (int i = 13227; i <= 13230; i++) + materials[i] = Material.BlueWallBanner; + for (int i = 13231; i <= 13234; i++) + materials[i] = Material.BrownWallBanner; + for (int i = 13235; i <= 13238; i++) + materials[i] = Material.GreenWallBanner; + for (int i = 13239; i <= 13242; i++) + materials[i] = Material.RedWallBanner; + for (int i = 13243; i <= 13246; i++) + materials[i] = Material.BlackWallBanner; + for (int i = 13247; i <= 13247; i++) + materials[i] = Material.RedSandstone; + for (int i = 13248; i <= 13248; i++) + materials[i] = Material.ChiseledRedSandstone; + for (int i = 13249; i <= 13249; i++) + materials[i] = Material.CutRedSandstone; + for (int i = 13250; i <= 13329; i++) + materials[i] = Material.RedSandstoneStairs; + for (int i = 13330; i <= 13335; i++) + materials[i] = Material.OakSlab; + for (int i = 13336; i <= 13341; i++) + materials[i] = Material.SpruceSlab; + for (int i = 13342; i <= 13347; i++) + materials[i] = Material.BirchSlab; + for (int i = 13348; i <= 13353; i++) + materials[i] = Material.JungleSlab; + for (int i = 13354; i <= 13359; i++) + materials[i] = Material.AcaciaSlab; + for (int i = 13360; i <= 13365; i++) + materials[i] = Material.CherrySlab; + for (int i = 13366; i <= 13371; i++) + materials[i] = Material.DarkOakSlab; + for (int i = 13372; i <= 13377; i++) + materials[i] = Material.PaleOakSlab; + for (int i = 13378; i <= 13383; i++) + materials[i] = Material.MangroveSlab; + for (int i = 13384; i <= 13389; i++) + materials[i] = Material.BambooSlab; + for (int i = 13390; i <= 13395; i++) + materials[i] = Material.BambooMosaicSlab; + for (int i = 13396; i <= 13401; i++) + materials[i] = Material.StoneSlab; + for (int i = 13402; i <= 13407; i++) + materials[i] = Material.SmoothStoneSlab; + for (int i = 13408; i <= 13413; i++) + materials[i] = Material.SandstoneSlab; + for (int i = 13414; i <= 13419; i++) + materials[i] = Material.CutSandstoneSlab; + for (int i = 13420; i <= 13425; i++) + materials[i] = Material.PetrifiedOakSlab; + for (int i = 13426; i <= 13431; i++) + materials[i] = Material.CobblestoneSlab; + for (int i = 13432; i <= 13437; i++) + materials[i] = Material.BrickSlab; + for (int i = 13438; i <= 13443; i++) + materials[i] = Material.StoneBrickSlab; + for (int i = 13444; i <= 13449; i++) + materials[i] = Material.MudBrickSlab; + for (int i = 13450; i <= 13455; i++) + materials[i] = Material.NetherBrickSlab; + for (int i = 13456; i <= 13461; i++) + materials[i] = Material.QuartzSlab; + for (int i = 13462; i <= 13467; i++) + materials[i] = Material.RedSandstoneSlab; + for (int i = 13468; i <= 13473; i++) + materials[i] = Material.CutRedSandstoneSlab; + for (int i = 13474; i <= 13479; i++) + materials[i] = Material.PurpurSlab; + for (int i = 13480; i <= 13480; i++) + materials[i] = Material.SmoothStone; + for (int i = 13481; i <= 13481; i++) + materials[i] = Material.SmoothSandstone; + for (int i = 13482; i <= 13482; i++) + materials[i] = Material.SmoothQuartz; + for (int i = 13483; i <= 13483; i++) + materials[i] = Material.SmoothRedSandstone; + for (int i = 13484; i <= 13515; i++) + materials[i] = Material.SpruceFenceGate; + for (int i = 13516; i <= 13547; i++) + materials[i] = Material.BirchFenceGate; + for (int i = 13548; i <= 13579; i++) + materials[i] = Material.JungleFenceGate; + for (int i = 13580; i <= 13611; i++) + materials[i] = Material.AcaciaFenceGate; + for (int i = 13612; i <= 13643; i++) + materials[i] = Material.CherryFenceGate; + for (int i = 13644; i <= 13675; i++) + materials[i] = Material.DarkOakFenceGate; + for (int i = 13676; i <= 13707; i++) + materials[i] = Material.PaleOakFenceGate; + for (int i = 13708; i <= 13739; i++) + materials[i] = Material.MangroveFenceGate; + for (int i = 13740; i <= 13771; i++) + materials[i] = Material.BambooFenceGate; + for (int i = 13772; i <= 13803; i++) + materials[i] = Material.SpruceFence; + for (int i = 13804; i <= 13835; i++) + materials[i] = Material.BirchFence; + for (int i = 13836; i <= 13867; i++) + materials[i] = Material.JungleFence; + for (int i = 13868; i <= 13899; i++) + materials[i] = Material.AcaciaFence; + for (int i = 13900; i <= 13931; i++) + materials[i] = Material.CherryFence; + for (int i = 13932; i <= 13963; i++) + materials[i] = Material.DarkOakFence; + for (int i = 13964; i <= 13995; i++) + materials[i] = Material.PaleOakFence; + for (int i = 13996; i <= 14027; i++) + materials[i] = Material.MangroveFence; + for (int i = 14028; i <= 14059; i++) + materials[i] = Material.BambooFence; + for (int i = 14060; i <= 14123; i++) + materials[i] = Material.SpruceDoor; + for (int i = 14124; i <= 14187; i++) + materials[i] = Material.BirchDoor; + for (int i = 14188; i <= 14251; i++) + materials[i] = Material.JungleDoor; + for (int i = 14252; i <= 14315; i++) + materials[i] = Material.AcaciaDoor; + for (int i = 14316; i <= 14379; i++) + materials[i] = Material.CherryDoor; + for (int i = 14380; i <= 14443; i++) + materials[i] = Material.DarkOakDoor; + for (int i = 14444; i <= 14507; i++) + materials[i] = Material.PaleOakDoor; + for (int i = 14508; i <= 14571; i++) + materials[i] = Material.MangroveDoor; + for (int i = 14572; i <= 14635; i++) + materials[i] = Material.BambooDoor; + for (int i = 14636; i <= 14641; i++) + materials[i] = Material.EndRod; + for (int i = 14642; i <= 14705; i++) + materials[i] = Material.ChorusPlant; + for (int i = 14706; i <= 14711; i++) + materials[i] = Material.ChorusFlower; + for (int i = 14712; i <= 14712; i++) + materials[i] = Material.PurpurBlock; + for (int i = 14713; i <= 14715; i++) + materials[i] = Material.PurpurPillar; + for (int i = 14716; i <= 14795; i++) + materials[i] = Material.PurpurStairs; + for (int i = 14796; i <= 14796; i++) + materials[i] = Material.EndStoneBricks; + for (int i = 14797; i <= 14798; i++) + materials[i] = Material.TorchflowerCrop; + for (int i = 14799; i <= 14808; i++) + materials[i] = Material.PitcherCrop; + for (int i = 14809; i <= 14810; i++) + materials[i] = Material.PitcherPlant; + for (int i = 14811; i <= 14814; i++) + materials[i] = Material.Beetroots; + for (int i = 14815; i <= 14815; i++) + materials[i] = Material.DirtPath; + for (int i = 14816; i <= 14816; i++) + materials[i] = Material.EndGateway; + for (int i = 14817; i <= 14828; i++) + materials[i] = Material.RepeatingCommandBlock; + for (int i = 14829; i <= 14840; i++) + materials[i] = Material.ChainCommandBlock; + for (int i = 14841; i <= 14844; i++) + materials[i] = Material.FrostedIce; + for (int i = 14845; i <= 14845; i++) + materials[i] = Material.MagmaBlock; + for (int i = 14846; i <= 14846; i++) + materials[i] = Material.NetherWartBlock; + for (int i = 14847; i <= 14847; i++) + materials[i] = Material.RedNetherBricks; + for (int i = 14848; i <= 14850; i++) + materials[i] = Material.BoneBlock; + for (int i = 14851; i <= 14851; i++) + materials[i] = Material.StructureVoid; + for (int i = 14852; i <= 14863; i++) + materials[i] = Material.Observer; + for (int i = 14864; i <= 14869; i++) + materials[i] = Material.ShulkerBox; + for (int i = 14870; i <= 14875; i++) + materials[i] = Material.WhiteShulkerBox; + for (int i = 14876; i <= 14881; i++) + materials[i] = Material.OrangeShulkerBox; + for (int i = 14882; i <= 14887; i++) + materials[i] = Material.MagentaShulkerBox; + for (int i = 14888; i <= 14893; i++) + materials[i] = Material.LightBlueShulkerBox; + for (int i = 14894; i <= 14899; i++) + materials[i] = Material.YellowShulkerBox; + for (int i = 14900; i <= 14905; i++) + materials[i] = Material.LimeShulkerBox; + for (int i = 14906; i <= 14911; i++) + materials[i] = Material.PinkShulkerBox; + for (int i = 14912; i <= 14917; i++) + materials[i] = Material.GrayShulkerBox; + for (int i = 14918; i <= 14923; i++) + materials[i] = Material.LightGrayShulkerBox; + for (int i = 14924; i <= 14929; i++) + materials[i] = Material.CyanShulkerBox; + for (int i = 14930; i <= 14935; i++) + materials[i] = Material.PurpleShulkerBox; + for (int i = 14936; i <= 14941; i++) + materials[i] = Material.BlueShulkerBox; + for (int i = 14942; i <= 14947; i++) + materials[i] = Material.BrownShulkerBox; + for (int i = 14948; i <= 14953; i++) + materials[i] = Material.GreenShulkerBox; + for (int i = 14954; i <= 14959; i++) + materials[i] = Material.RedShulkerBox; + for (int i = 14960; i <= 14965; i++) + materials[i] = Material.BlackShulkerBox; + for (int i = 14966; i <= 14969; i++) + materials[i] = Material.WhiteGlazedTerracotta; + for (int i = 14970; i <= 14973; i++) + materials[i] = Material.OrangeGlazedTerracotta; + for (int i = 14974; i <= 14977; i++) + materials[i] = Material.MagentaGlazedTerracotta; + for (int i = 14978; i <= 14981; i++) + materials[i] = Material.LightBlueGlazedTerracotta; + for (int i = 14982; i <= 14985; i++) + materials[i] = Material.YellowGlazedTerracotta; + for (int i = 14986; i <= 14989; i++) + materials[i] = Material.LimeGlazedTerracotta; + for (int i = 14990; i <= 14993; i++) + materials[i] = Material.PinkGlazedTerracotta; + for (int i = 14994; i <= 14997; i++) + materials[i] = Material.GrayGlazedTerracotta; + for (int i = 14998; i <= 15001; i++) + materials[i] = Material.LightGrayGlazedTerracotta; + for (int i = 15002; i <= 15005; i++) + materials[i] = Material.CyanGlazedTerracotta; + for (int i = 15006; i <= 15009; i++) + materials[i] = Material.PurpleGlazedTerracotta; + for (int i = 15010; i <= 15013; i++) + materials[i] = Material.BlueGlazedTerracotta; + for (int i = 15014; i <= 15017; i++) + materials[i] = Material.BrownGlazedTerracotta; + for (int i = 15018; i <= 15021; i++) + materials[i] = Material.GreenGlazedTerracotta; + for (int i = 15022; i <= 15025; i++) + materials[i] = Material.RedGlazedTerracotta; + for (int i = 15026; i <= 15029; i++) + materials[i] = Material.BlackGlazedTerracotta; + for (int i = 15030; i <= 15030; i++) + materials[i] = Material.WhiteConcrete; + for (int i = 15031; i <= 15031; i++) + materials[i] = Material.OrangeConcrete; + for (int i = 15032; i <= 15032; i++) + materials[i] = Material.MagentaConcrete; + for (int i = 15033; i <= 15033; i++) + materials[i] = Material.LightBlueConcrete; + for (int i = 15034; i <= 15034; i++) + materials[i] = Material.YellowConcrete; + for (int i = 15035; i <= 15035; i++) + materials[i] = Material.LimeConcrete; + for (int i = 15036; i <= 15036; i++) + materials[i] = Material.PinkConcrete; + for (int i = 15037; i <= 15037; i++) + materials[i] = Material.GrayConcrete; + for (int i = 15038; i <= 15038; i++) + materials[i] = Material.LightGrayConcrete; + for (int i = 15039; i <= 15039; i++) + materials[i] = Material.CyanConcrete; + for (int i = 15040; i <= 15040; i++) + materials[i] = Material.PurpleConcrete; + for (int i = 15041; i <= 15041; i++) + materials[i] = Material.BlueConcrete; + for (int i = 15042; i <= 15042; i++) + materials[i] = Material.BrownConcrete; + for (int i = 15043; i <= 15043; i++) + materials[i] = Material.GreenConcrete; + for (int i = 15044; i <= 15044; i++) + materials[i] = Material.RedConcrete; + for (int i = 15045; i <= 15045; i++) + materials[i] = Material.BlackConcrete; + for (int i = 15046; i <= 15046; i++) + materials[i] = Material.WhiteConcretePowder; + for (int i = 15047; i <= 15047; i++) + materials[i] = Material.OrangeConcretePowder; + for (int i = 15048; i <= 15048; i++) + materials[i] = Material.MagentaConcretePowder; + for (int i = 15049; i <= 15049; i++) + materials[i] = Material.LightBlueConcretePowder; + for (int i = 15050; i <= 15050; i++) + materials[i] = Material.YellowConcretePowder; + for (int i = 15051; i <= 15051; i++) + materials[i] = Material.LimeConcretePowder; + for (int i = 15052; i <= 15052; i++) + materials[i] = Material.PinkConcretePowder; + for (int i = 15053; i <= 15053; i++) + materials[i] = Material.GrayConcretePowder; + for (int i = 15054; i <= 15054; i++) + materials[i] = Material.LightGrayConcretePowder; + for (int i = 15055; i <= 15055; i++) + materials[i] = Material.CyanConcretePowder; + for (int i = 15056; i <= 15056; i++) + materials[i] = Material.PurpleConcretePowder; + for (int i = 15057; i <= 15057; i++) + materials[i] = Material.BlueConcretePowder; + for (int i = 15058; i <= 15058; i++) + materials[i] = Material.BrownConcretePowder; + for (int i = 15059; i <= 15059; i++) + materials[i] = Material.GreenConcretePowder; + for (int i = 15060; i <= 15060; i++) + materials[i] = Material.RedConcretePowder; + for (int i = 15061; i <= 15061; i++) + materials[i] = Material.BlackConcretePowder; + for (int i = 15062; i <= 15087; i++) + materials[i] = Material.Kelp; + for (int i = 15088; i <= 15088; i++) + materials[i] = Material.KelpPlant; + for (int i = 15089; i <= 15089; i++) + materials[i] = Material.DriedKelpBlock; + for (int i = 15090; i <= 15101; i++) + materials[i] = Material.TurtleEgg; + for (int i = 15102; i <= 15104; i++) + materials[i] = Material.SnifferEgg; + for (int i = 15105; i <= 15136; i++) + materials[i] = Material.DriedGhast; + for (int i = 15137; i <= 15137; i++) + materials[i] = Material.DeadTubeCoralBlock; + for (int i = 15138; i <= 15138; i++) + materials[i] = Material.DeadBrainCoralBlock; + for (int i = 15139; i <= 15139; i++) + materials[i] = Material.DeadBubbleCoralBlock; + for (int i = 15140; i <= 15140; i++) + materials[i] = Material.DeadFireCoralBlock; + for (int i = 15141; i <= 15141; i++) + materials[i] = Material.DeadHornCoralBlock; + for (int i = 15142; i <= 15142; i++) + materials[i] = Material.TubeCoralBlock; + for (int i = 15143; i <= 15143; i++) + materials[i] = Material.BrainCoralBlock; + for (int i = 15144; i <= 15144; i++) + materials[i] = Material.BubbleCoralBlock; + for (int i = 15145; i <= 15145; i++) + materials[i] = Material.FireCoralBlock; + for (int i = 15146; i <= 15146; i++) + materials[i] = Material.HornCoralBlock; + for (int i = 15147; i <= 15148; i++) + materials[i] = Material.DeadTubeCoral; + for (int i = 15149; i <= 15150; i++) + materials[i] = Material.DeadBrainCoral; + for (int i = 15151; i <= 15152; i++) + materials[i] = Material.DeadBubbleCoral; + for (int i = 15153; i <= 15154; i++) + materials[i] = Material.DeadFireCoral; + for (int i = 15155; i <= 15156; i++) + materials[i] = Material.DeadHornCoral; + for (int i = 15157; i <= 15158; i++) + materials[i] = Material.TubeCoral; + for (int i = 15159; i <= 15160; i++) + materials[i] = Material.BrainCoral; + for (int i = 15161; i <= 15162; i++) + materials[i] = Material.BubbleCoral; + for (int i = 15163; i <= 15164; i++) + materials[i] = Material.FireCoral; + for (int i = 15165; i <= 15166; i++) + materials[i] = Material.HornCoral; + for (int i = 15167; i <= 15168; i++) + materials[i] = Material.DeadTubeCoralFan; + for (int i = 15169; i <= 15170; i++) + materials[i] = Material.DeadBrainCoralFan; + for (int i = 15171; i <= 15172; i++) + materials[i] = Material.DeadBubbleCoralFan; + for (int i = 15173; i <= 15174; i++) + materials[i] = Material.DeadFireCoralFan; + for (int i = 15175; i <= 15176; i++) + materials[i] = Material.DeadHornCoralFan; + for (int i = 15177; i <= 15178; i++) + materials[i] = Material.TubeCoralFan; + for (int i = 15179; i <= 15180; i++) + materials[i] = Material.BrainCoralFan; + for (int i = 15181; i <= 15182; i++) + materials[i] = Material.BubbleCoralFan; + for (int i = 15183; i <= 15184; i++) + materials[i] = Material.FireCoralFan; + for (int i = 15185; i <= 15186; i++) + materials[i] = Material.HornCoralFan; + for (int i = 15187; i <= 15194; i++) + materials[i] = Material.DeadTubeCoralWallFan; + for (int i = 15195; i <= 15202; i++) + materials[i] = Material.DeadBrainCoralWallFan; + for (int i = 15203; i <= 15210; i++) + materials[i] = Material.DeadBubbleCoralWallFan; + for (int i = 15211; i <= 15218; i++) + materials[i] = Material.DeadFireCoralWallFan; + for (int i = 15219; i <= 15226; i++) + materials[i] = Material.DeadHornCoralWallFan; + for (int i = 15227; i <= 15234; i++) + materials[i] = Material.TubeCoralWallFan; + for (int i = 15235; i <= 15242; i++) + materials[i] = Material.BrainCoralWallFan; + for (int i = 15243; i <= 15250; i++) + materials[i] = Material.BubbleCoralWallFan; + for (int i = 15251; i <= 15258; i++) + materials[i] = Material.FireCoralWallFan; + for (int i = 15259; i <= 15266; i++) + materials[i] = Material.HornCoralWallFan; + for (int i = 15267; i <= 15274; i++) + materials[i] = Material.SeaPickle; + for (int i = 15275; i <= 15275; i++) + materials[i] = Material.BlueIce; + for (int i = 15276; i <= 15277; i++) + materials[i] = Material.Conduit; + for (int i = 15278; i <= 15278; i++) + materials[i] = Material.BambooSapling; + for (int i = 15279; i <= 15290; i++) + materials[i] = Material.Bamboo; + for (int i = 15291; i <= 15291; i++) + materials[i] = Material.PottedBamboo; + for (int i = 15292; i <= 15292; i++) + materials[i] = Material.VoidAir; + for (int i = 15293; i <= 15293; i++) + materials[i] = Material.CaveAir; + for (int i = 15294; i <= 15295; i++) + materials[i] = Material.BubbleColumn; + for (int i = 15296; i <= 15375; i++) + materials[i] = Material.PolishedGraniteStairs; + for (int i = 15376; i <= 15455; i++) + materials[i] = Material.SmoothRedSandstoneStairs; + for (int i = 15456; i <= 15535; i++) + materials[i] = Material.MossyStoneBrickStairs; + for (int i = 15536; i <= 15615; i++) + materials[i] = Material.PolishedDioriteStairs; + for (int i = 15616; i <= 15695; i++) + materials[i] = Material.MossyCobblestoneStairs; + for (int i = 15696; i <= 15775; i++) + materials[i] = Material.EndStoneBrickStairs; + for (int i = 15776; i <= 15855; i++) + materials[i] = Material.StoneStairs; + for (int i = 15856; i <= 15935; i++) + materials[i] = Material.SmoothSandstoneStairs; + for (int i = 15936; i <= 16015; i++) + materials[i] = Material.SmoothQuartzStairs; + for (int i = 16016; i <= 16095; i++) + materials[i] = Material.GraniteStairs; + for (int i = 16096; i <= 16175; i++) + materials[i] = Material.AndesiteStairs; + for (int i = 16176; i <= 16255; i++) + materials[i] = Material.RedNetherBrickStairs; + for (int i = 16256; i <= 16335; i++) + materials[i] = Material.PolishedAndesiteStairs; + for (int i = 16336; i <= 16415; i++) + materials[i] = Material.DioriteStairs; + for (int i = 16416; i <= 16421; i++) + materials[i] = Material.PolishedGraniteSlab; + for (int i = 16422; i <= 16427; i++) + materials[i] = Material.SmoothRedSandstoneSlab; + for (int i = 16428; i <= 16433; i++) + materials[i] = Material.MossyStoneBrickSlab; + for (int i = 16434; i <= 16439; i++) + materials[i] = Material.PolishedDioriteSlab; + for (int i = 16440; i <= 16445; i++) + materials[i] = Material.MossyCobblestoneSlab; + for (int i = 16446; i <= 16451; i++) + materials[i] = Material.EndStoneBrickSlab; + for (int i = 16452; i <= 16457; i++) + materials[i] = Material.SmoothSandstoneSlab; + for (int i = 16458; i <= 16463; i++) + materials[i] = Material.SmoothQuartzSlab; + for (int i = 16464; i <= 16469; i++) + materials[i] = Material.GraniteSlab; + for (int i = 16470; i <= 16475; i++) + materials[i] = Material.AndesiteSlab; + for (int i = 16476; i <= 16481; i++) + materials[i] = Material.RedNetherBrickSlab; + for (int i = 16482; i <= 16487; i++) + materials[i] = Material.PolishedAndesiteSlab; + for (int i = 16488; i <= 16493; i++) + materials[i] = Material.DioriteSlab; + for (int i = 16494; i <= 16817; i++) + materials[i] = Material.BrickWall; + for (int i = 16818; i <= 17141; i++) + materials[i] = Material.PrismarineWall; + for (int i = 17142; i <= 17465; i++) + materials[i] = Material.RedSandstoneWall; + for (int i = 17466; i <= 17789; i++) + materials[i] = Material.MossyStoneBrickWall; + for (int i = 17790; i <= 18113; i++) + materials[i] = Material.GraniteWall; + for (int i = 18114; i <= 18437; i++) + materials[i] = Material.StoneBrickWall; + for (int i = 18438; i <= 18761; i++) + materials[i] = Material.MudBrickWall; + for (int i = 18762; i <= 19085; i++) + materials[i] = Material.NetherBrickWall; + for (int i = 19086; i <= 19409; i++) + materials[i] = Material.AndesiteWall; + for (int i = 19410; i <= 19733; i++) + materials[i] = Material.RedNetherBrickWall; + for (int i = 19734; i <= 20057; i++) + materials[i] = Material.SandstoneWall; + for (int i = 20058; i <= 20381; i++) + materials[i] = Material.EndStoneBrickWall; + for (int i = 20382; i <= 20705; i++) + materials[i] = Material.DioriteWall; + for (int i = 20706; i <= 20737; i++) + materials[i] = Material.Scaffolding; + for (int i = 20738; i <= 20741; i++) + materials[i] = Material.Loom; + for (int i = 20742; i <= 20753; i++) + materials[i] = Material.Barrel; + for (int i = 20754; i <= 20761; i++) + materials[i] = Material.Smoker; + for (int i = 20762; i <= 20769; i++) + materials[i] = Material.BlastFurnace; + for (int i = 20770; i <= 20770; i++) + materials[i] = Material.CartographyTable; + for (int i = 20771; i <= 20771; i++) + materials[i] = Material.FletchingTable; + for (int i = 20772; i <= 20783; i++) + materials[i] = Material.Grindstone; + for (int i = 20784; i <= 20799; i++) + materials[i] = Material.Lectern; + for (int i = 20800; i <= 20800; i++) + materials[i] = Material.SmithingTable; + for (int i = 20801; i <= 20804; i++) + materials[i] = Material.Stonecutter; + for (int i = 20805; i <= 20836; i++) + materials[i] = Material.Bell; + for (int i = 20837; i <= 20840; i++) + materials[i] = Material.Lantern; + for (int i = 20841; i <= 20844; i++) + materials[i] = Material.SoulLantern; + for (int i = 20845; i <= 20848; i++) + materials[i] = Material.CopperLantern; + for (int i = 20849; i <= 20852; i++) + materials[i] = Material.ExposedCopperLantern; + for (int i = 20853; i <= 20856; i++) + materials[i] = Material.WeatheredCopperLantern; + for (int i = 20857; i <= 20860; i++) + materials[i] = Material.OxidizedCopperLantern; + for (int i = 20861; i <= 20864; i++) + materials[i] = Material.WaxedCopperLantern; + for (int i = 20865; i <= 20868; i++) + materials[i] = Material.WaxedExposedCopperLantern; + for (int i = 20869; i <= 20872; i++) + materials[i] = Material.WaxedWeatheredCopperLantern; + for (int i = 20873; i <= 20876; i++) + materials[i] = Material.WaxedOxidizedCopperLantern; + for (int i = 20877; i <= 20908; i++) + materials[i] = Material.Campfire; + for (int i = 20909; i <= 20940; i++) + materials[i] = Material.SoulCampfire; + for (int i = 20941; i <= 20944; i++) + materials[i] = Material.SweetBerryBush; + for (int i = 20945; i <= 20947; i++) + materials[i] = Material.WarpedStem; + for (int i = 20948; i <= 20950; i++) + materials[i] = Material.StrippedWarpedStem; + for (int i = 20951; i <= 20953; i++) + materials[i] = Material.WarpedHyphae; + for (int i = 20954; i <= 20956; i++) + materials[i] = Material.StrippedWarpedHyphae; + for (int i = 20957; i <= 20957; i++) + materials[i] = Material.WarpedNylium; + for (int i = 20958; i <= 20958; i++) + materials[i] = Material.WarpedFungus; + for (int i = 20959; i <= 20959; i++) + materials[i] = Material.WarpedWartBlock; + for (int i = 20960; i <= 20960; i++) + materials[i] = Material.WarpedRoots; + for (int i = 20961; i <= 20961; i++) + materials[i] = Material.NetherSprouts; + for (int i = 20962; i <= 20964; i++) + materials[i] = Material.CrimsonStem; + for (int i = 20965; i <= 20967; i++) + materials[i] = Material.StrippedCrimsonStem; + for (int i = 20968; i <= 20970; i++) + materials[i] = Material.CrimsonHyphae; + for (int i = 20971; i <= 20973; i++) + materials[i] = Material.StrippedCrimsonHyphae; + for (int i = 20974; i <= 20974; i++) + materials[i] = Material.CrimsonNylium; + for (int i = 20975; i <= 20975; i++) + materials[i] = Material.CrimsonFungus; + for (int i = 20976; i <= 20976; i++) + materials[i] = Material.Shroomlight; + for (int i = 20977; i <= 21002; i++) + materials[i] = Material.WeepingVines; + for (int i = 21003; i <= 21003; i++) + materials[i] = Material.WeepingVinesPlant; + for (int i = 21004; i <= 21029; i++) + materials[i] = Material.TwistingVines; + for (int i = 21030; i <= 21030; i++) + materials[i] = Material.TwistingVinesPlant; + for (int i = 21031; i <= 21031; i++) + materials[i] = Material.CrimsonRoots; + for (int i = 21032; i <= 21032; i++) + materials[i] = Material.CrimsonPlanks; + for (int i = 21033; i <= 21033; i++) + materials[i] = Material.WarpedPlanks; + for (int i = 21034; i <= 21039; i++) + materials[i] = Material.CrimsonSlab; + for (int i = 21040; i <= 21045; i++) + materials[i] = Material.WarpedSlab; + for (int i = 21046; i <= 21047; i++) + materials[i] = Material.CrimsonPressurePlate; + for (int i = 21048; i <= 21049; i++) + materials[i] = Material.WarpedPressurePlate; + for (int i = 21050; i <= 21081; i++) + materials[i] = Material.CrimsonFence; + for (int i = 21082; i <= 21113; i++) + materials[i] = Material.WarpedFence; + for (int i = 21114; i <= 21177; i++) + materials[i] = Material.CrimsonTrapdoor; + for (int i = 21178; i <= 21241; i++) + materials[i] = Material.WarpedTrapdoor; + for (int i = 21242; i <= 21273; i++) + materials[i] = Material.CrimsonFenceGate; + for (int i = 21274; i <= 21305; i++) + materials[i] = Material.WarpedFenceGate; + for (int i = 21306; i <= 21385; i++) + materials[i] = Material.CrimsonStairs; + for (int i = 21386; i <= 21465; i++) + materials[i] = Material.WarpedStairs; + for (int i = 21466; i <= 21489; i++) + materials[i] = Material.CrimsonButton; + for (int i = 21490; i <= 21513; i++) + materials[i] = Material.WarpedButton; + for (int i = 21514; i <= 21577; i++) + materials[i] = Material.CrimsonDoor; + for (int i = 21578; i <= 21641; i++) + materials[i] = Material.WarpedDoor; + for (int i = 21642; i <= 21673; i++) + materials[i] = Material.CrimsonSign; + for (int i = 21674; i <= 21705; i++) + materials[i] = Material.WarpedSign; + for (int i = 21706; i <= 21713; i++) + materials[i] = Material.CrimsonWallSign; + for (int i = 21714; i <= 21721; i++) + materials[i] = Material.WarpedWallSign; + for (int i = 21722; i <= 21725; i++) + materials[i] = Material.StructureBlock; + for (int i = 21726; i <= 21737; i++) + materials[i] = Material.Jigsaw; + for (int i = 21738; i <= 21741; i++) + materials[i] = Material.TestBlock; + for (int i = 21742; i <= 21742; i++) + materials[i] = Material.TestInstanceBlock; + for (int i = 21743; i <= 21751; i++) + materials[i] = Material.Composter; + for (int i = 21752; i <= 21767; i++) + materials[i] = Material.Target; + for (int i = 21768; i <= 21791; i++) + materials[i] = Material.BeeNest; + for (int i = 21792; i <= 21815; i++) + materials[i] = Material.Beehive; + for (int i = 21816; i <= 21816; i++) + materials[i] = Material.HoneyBlock; + for (int i = 21817; i <= 21817; i++) + materials[i] = Material.HoneycombBlock; + for (int i = 21818; i <= 21818; i++) + materials[i] = Material.NetheriteBlock; + for (int i = 21819; i <= 21819; i++) + materials[i] = Material.AncientDebris; + for (int i = 21820; i <= 21820; i++) + materials[i] = Material.CryingObsidian; + for (int i = 21821; i <= 21825; i++) + materials[i] = Material.RespawnAnchor; + for (int i = 21826; i <= 21826; i++) + materials[i] = Material.PottedCrimsonFungus; + for (int i = 21827; i <= 21827; i++) + materials[i] = Material.PottedWarpedFungus; + for (int i = 21828; i <= 21828; i++) + materials[i] = Material.PottedCrimsonRoots; + for (int i = 21829; i <= 21829; i++) + materials[i] = Material.PottedWarpedRoots; + for (int i = 21830; i <= 21830; i++) + materials[i] = Material.Lodestone; + for (int i = 21831; i <= 21831; i++) + materials[i] = Material.Blackstone; + for (int i = 21832; i <= 21911; i++) + materials[i] = Material.BlackstoneStairs; + for (int i = 21912; i <= 22235; i++) + materials[i] = Material.BlackstoneWall; + for (int i = 22236; i <= 22241; i++) + materials[i] = Material.BlackstoneSlab; + for (int i = 22242; i <= 22242; i++) + materials[i] = Material.PolishedBlackstone; + for (int i = 22243; i <= 22243; i++) + materials[i] = Material.PolishedBlackstoneBricks; + for (int i = 22244; i <= 22244; i++) + materials[i] = Material.CrackedPolishedBlackstoneBricks; + for (int i = 22245; i <= 22245; i++) + materials[i] = Material.ChiseledPolishedBlackstone; + for (int i = 22246; i <= 22251; i++) + materials[i] = Material.PolishedBlackstoneBrickSlab; + for (int i = 22252; i <= 22331; i++) + materials[i] = Material.PolishedBlackstoneBrickStairs; + for (int i = 22332; i <= 22655; i++) + materials[i] = Material.PolishedBlackstoneBrickWall; + for (int i = 22656; i <= 22656; i++) + materials[i] = Material.GildedBlackstone; + for (int i = 22657; i <= 22736; i++) + materials[i] = Material.PolishedBlackstoneStairs; + for (int i = 22737; i <= 22742; i++) + materials[i] = Material.PolishedBlackstoneSlab; + for (int i = 22743; i <= 22744; i++) + materials[i] = Material.PolishedBlackstonePressurePlate; + for (int i = 22745; i <= 22768; i++) + materials[i] = Material.PolishedBlackstoneButton; + for (int i = 22769; i <= 23092; i++) + materials[i] = Material.PolishedBlackstoneWall; + for (int i = 23093; i <= 23093; i++) + materials[i] = Material.ChiseledNetherBricks; + for (int i = 23094; i <= 23094; i++) + materials[i] = Material.CrackedNetherBricks; + for (int i = 23095; i <= 23095; i++) + materials[i] = Material.QuartzBricks; + for (int i = 23096; i <= 23111; i++) + materials[i] = Material.Candle; + for (int i = 23112; i <= 23127; i++) + materials[i] = Material.WhiteCandle; + for (int i = 23128; i <= 23143; i++) + materials[i] = Material.OrangeCandle; + for (int i = 23144; i <= 23159; i++) + materials[i] = Material.MagentaCandle; + for (int i = 23160; i <= 23175; i++) + materials[i] = Material.LightBlueCandle; + for (int i = 23176; i <= 23191; i++) + materials[i] = Material.YellowCandle; + for (int i = 23192; i <= 23207; i++) + materials[i] = Material.LimeCandle; + for (int i = 23208; i <= 23223; i++) + materials[i] = Material.PinkCandle; + for (int i = 23224; i <= 23239; i++) + materials[i] = Material.GrayCandle; + for (int i = 23240; i <= 23255; i++) + materials[i] = Material.LightGrayCandle; + for (int i = 23256; i <= 23271; i++) + materials[i] = Material.CyanCandle; + for (int i = 23272; i <= 23287; i++) + materials[i] = Material.PurpleCandle; + for (int i = 23288; i <= 23303; i++) + materials[i] = Material.BlueCandle; + for (int i = 23304; i <= 23319; i++) + materials[i] = Material.BrownCandle; + for (int i = 23320; i <= 23335; i++) + materials[i] = Material.GreenCandle; + for (int i = 23336; i <= 23351; i++) + materials[i] = Material.RedCandle; + for (int i = 23352; i <= 23367; i++) + materials[i] = Material.BlackCandle; + for (int i = 23368; i <= 23369; i++) + materials[i] = Material.CandleCake; + for (int i = 23370; i <= 23371; i++) + materials[i] = Material.WhiteCandleCake; + for (int i = 23372; i <= 23373; i++) + materials[i] = Material.OrangeCandleCake; + for (int i = 23374; i <= 23375; i++) + materials[i] = Material.MagentaCandleCake; + for (int i = 23376; i <= 23377; i++) + materials[i] = Material.LightBlueCandleCake; + for (int i = 23378; i <= 23379; i++) + materials[i] = Material.YellowCandleCake; + for (int i = 23380; i <= 23381; i++) + materials[i] = Material.LimeCandleCake; + for (int i = 23382; i <= 23383; i++) + materials[i] = Material.PinkCandleCake; + for (int i = 23384; i <= 23385; i++) + materials[i] = Material.GrayCandleCake; + for (int i = 23386; i <= 23387; i++) + materials[i] = Material.LightGrayCandleCake; + for (int i = 23388; i <= 23389; i++) + materials[i] = Material.CyanCandleCake; + for (int i = 23390; i <= 23391; i++) + materials[i] = Material.PurpleCandleCake; + for (int i = 23392; i <= 23393; i++) + materials[i] = Material.BlueCandleCake; + for (int i = 23394; i <= 23395; i++) + materials[i] = Material.BrownCandleCake; + for (int i = 23396; i <= 23397; i++) + materials[i] = Material.GreenCandleCake; + for (int i = 23398; i <= 23399; i++) + materials[i] = Material.RedCandleCake; + for (int i = 23400; i <= 23401; i++) + materials[i] = Material.BlackCandleCake; + for (int i = 23402; i <= 23402; i++) + materials[i] = Material.AmethystBlock; + for (int i = 23403; i <= 23403; i++) + materials[i] = Material.BuddingAmethyst; + for (int i = 23404; i <= 23415; i++) + materials[i] = Material.AmethystCluster; + for (int i = 23416; i <= 23427; i++) + materials[i] = Material.LargeAmethystBud; + for (int i = 23428; i <= 23439; i++) + materials[i] = Material.MediumAmethystBud; + for (int i = 23440; i <= 23451; i++) + materials[i] = Material.SmallAmethystBud; + for (int i = 23452; i <= 23452; i++) + materials[i] = Material.Tuff; + for (int i = 23453; i <= 23458; i++) + materials[i] = Material.TuffSlab; + for (int i = 23459; i <= 23538; i++) + materials[i] = Material.TuffStairs; + for (int i = 23539; i <= 23862; i++) + materials[i] = Material.TuffWall; + for (int i = 23863; i <= 23863; i++) + materials[i] = Material.PolishedTuff; + for (int i = 23864; i <= 23869; i++) + materials[i] = Material.PolishedTuffSlab; + for (int i = 23870; i <= 23949; i++) + materials[i] = Material.PolishedTuffStairs; + for (int i = 23950; i <= 24273; i++) + materials[i] = Material.PolishedTuffWall; + for (int i = 24274; i <= 24274; i++) + materials[i] = Material.ChiseledTuff; + for (int i = 24275; i <= 24275; i++) + materials[i] = Material.TuffBricks; + for (int i = 24276; i <= 24281; i++) + materials[i] = Material.TuffBrickSlab; + for (int i = 24282; i <= 24361; i++) + materials[i] = Material.TuffBrickStairs; + for (int i = 24362; i <= 24685; i++) + materials[i] = Material.TuffBrickWall; + for (int i = 24686; i <= 24686; i++) + materials[i] = Material.ChiseledTuffBricks; + for (int i = 24687; i <= 24687; i++) + materials[i] = Material.Calcite; + for (int i = 24688; i <= 24688; i++) + materials[i] = Material.TintedGlass; + for (int i = 24689; i <= 24689; i++) + materials[i] = Material.PowderSnow; + for (int i = 24690; i <= 24785; i++) + materials[i] = Material.SculkSensor; + for (int i = 24786; i <= 25169; i++) + materials[i] = Material.CalibratedSculkSensor; + for (int i = 25170; i <= 25170; i++) + materials[i] = Material.Sculk; + for (int i = 25171; i <= 25298; i++) + materials[i] = Material.SculkVein; + for (int i = 25299; i <= 25300; i++) + materials[i] = Material.SculkCatalyst; + for (int i = 25301; i <= 25308; i++) + materials[i] = Material.SculkShrieker; + for (int i = 25309; i <= 25309; i++) + materials[i] = Material.CopperBlock; + for (int i = 25310; i <= 25310; i++) + materials[i] = Material.ExposedCopper; + for (int i = 25311; i <= 25311; i++) + materials[i] = Material.WeatheredCopper; + for (int i = 25312; i <= 25312; i++) + materials[i] = Material.OxidizedCopper; + for (int i = 25313; i <= 25313; i++) + materials[i] = Material.CopperOre; + for (int i = 25314; i <= 25314; i++) + materials[i] = Material.DeepslateCopperOre; + for (int i = 25315; i <= 25315; i++) + materials[i] = Material.OxidizedCutCopper; + for (int i = 25316; i <= 25316; i++) + materials[i] = Material.WeatheredCutCopper; + for (int i = 25317; i <= 25317; i++) + materials[i] = Material.ExposedCutCopper; + for (int i = 25318; i <= 25318; i++) + materials[i] = Material.CutCopper; + for (int i = 25319; i <= 25319; i++) + materials[i] = Material.OxidizedChiseledCopper; + for (int i = 25320; i <= 25320; i++) + materials[i] = Material.WeatheredChiseledCopper; + for (int i = 25321; i <= 25321; i++) + materials[i] = Material.ExposedChiseledCopper; + for (int i = 25322; i <= 25322; i++) + materials[i] = Material.ChiseledCopper; + for (int i = 25323; i <= 25323; i++) + materials[i] = Material.WaxedOxidizedChiseledCopper; + for (int i = 25324; i <= 25324; i++) + materials[i] = Material.WaxedWeatheredChiseledCopper; + for (int i = 25325; i <= 25325; i++) + materials[i] = Material.WaxedExposedChiseledCopper; + for (int i = 25326; i <= 25326; i++) + materials[i] = Material.WaxedChiseledCopper; + for (int i = 25327; i <= 25406; i++) + materials[i] = Material.OxidizedCutCopperStairs; + for (int i = 25407; i <= 25486; i++) + materials[i] = Material.WeatheredCutCopperStairs; + for (int i = 25487; i <= 25566; i++) + materials[i] = Material.ExposedCutCopperStairs; + for (int i = 25567; i <= 25646; i++) + materials[i] = Material.CutCopperStairs; + for (int i = 25647; i <= 25652; i++) + materials[i] = Material.OxidizedCutCopperSlab; + for (int i = 25653; i <= 25658; i++) + materials[i] = Material.WeatheredCutCopperSlab; + for (int i = 25659; i <= 25664; i++) + materials[i] = Material.ExposedCutCopperSlab; + for (int i = 25665; i <= 25670; i++) + materials[i] = Material.CutCopperSlab; + for (int i = 25671; i <= 25671; i++) + materials[i] = Material.WaxedCopperBlock; + for (int i = 25672; i <= 25672; i++) + materials[i] = Material.WaxedWeatheredCopper; + for (int i = 25673; i <= 25673; i++) + materials[i] = Material.WaxedExposedCopper; + for (int i = 25674; i <= 25674; i++) + materials[i] = Material.WaxedOxidizedCopper; + for (int i = 25675; i <= 25675; i++) + materials[i] = Material.WaxedOxidizedCutCopper; + for (int i = 25676; i <= 25676; i++) + materials[i] = Material.WaxedWeatheredCutCopper; + for (int i = 25677; i <= 25677; i++) + materials[i] = Material.WaxedExposedCutCopper; + for (int i = 25678; i <= 25678; i++) + materials[i] = Material.WaxedCutCopper; + for (int i = 25679; i <= 25758; i++) + materials[i] = Material.WaxedOxidizedCutCopperStairs; + for (int i = 25759; i <= 25838; i++) + materials[i] = Material.WaxedWeatheredCutCopperStairs; + for (int i = 25839; i <= 25918; i++) + materials[i] = Material.WaxedExposedCutCopperStairs; + for (int i = 25919; i <= 25998; i++) + materials[i] = Material.WaxedCutCopperStairs; + for (int i = 25999; i <= 26004; i++) + materials[i] = Material.WaxedOxidizedCutCopperSlab; + for (int i = 26005; i <= 26010; i++) + materials[i] = Material.WaxedWeatheredCutCopperSlab; + for (int i = 26011; i <= 26016; i++) + materials[i] = Material.WaxedExposedCutCopperSlab; + for (int i = 26017; i <= 26022; i++) + materials[i] = Material.WaxedCutCopperSlab; + for (int i = 26023; i <= 26086; i++) + materials[i] = Material.CopperDoor; + for (int i = 26087; i <= 26150; i++) + materials[i] = Material.ExposedCopperDoor; + for (int i = 26151; i <= 26214; i++) + materials[i] = Material.OxidizedCopperDoor; + for (int i = 26215; i <= 26278; i++) + materials[i] = Material.WeatheredCopperDoor; + for (int i = 26279; i <= 26342; i++) + materials[i] = Material.WaxedCopperDoor; + for (int i = 26343; i <= 26406; i++) + materials[i] = Material.WaxedExposedCopperDoor; + for (int i = 26407; i <= 26470; i++) + materials[i] = Material.WaxedOxidizedCopperDoor; + for (int i = 26471; i <= 26534; i++) + materials[i] = Material.WaxedWeatheredCopperDoor; + for (int i = 26535; i <= 26598; i++) + materials[i] = Material.CopperTrapdoor; + for (int i = 26599; i <= 26662; i++) + materials[i] = Material.ExposedCopperTrapdoor; + for (int i = 26663; i <= 26726; i++) + materials[i] = Material.OxidizedCopperTrapdoor; + for (int i = 26727; i <= 26790; i++) + materials[i] = Material.WeatheredCopperTrapdoor; + for (int i = 26791; i <= 26854; i++) + materials[i] = Material.WaxedCopperTrapdoor; + for (int i = 26855; i <= 26918; i++) + materials[i] = Material.WaxedExposedCopperTrapdoor; + for (int i = 26919; i <= 26982; i++) + materials[i] = Material.WaxedOxidizedCopperTrapdoor; + for (int i = 26983; i <= 27046; i++) + materials[i] = Material.WaxedWeatheredCopperTrapdoor; + for (int i = 27047; i <= 27048; i++) + materials[i] = Material.CopperGrate; + for (int i = 27049; i <= 27050; i++) + materials[i] = Material.ExposedCopperGrate; + for (int i = 27051; i <= 27052; i++) + materials[i] = Material.WeatheredCopperGrate; + for (int i = 27053; i <= 27054; i++) + materials[i] = Material.OxidizedCopperGrate; + for (int i = 27055; i <= 27056; i++) + materials[i] = Material.WaxedCopperGrate; + for (int i = 27057; i <= 27058; i++) + materials[i] = Material.WaxedExposedCopperGrate; + for (int i = 27059; i <= 27060; i++) + materials[i] = Material.WaxedWeatheredCopperGrate; + for (int i = 27061; i <= 27062; i++) + materials[i] = Material.WaxedOxidizedCopperGrate; + for (int i = 27063; i <= 27066; i++) + materials[i] = Material.CopperBulb; + for (int i = 27067; i <= 27070; i++) + materials[i] = Material.ExposedCopperBulb; + for (int i = 27071; i <= 27074; i++) + materials[i] = Material.WeatheredCopperBulb; + for (int i = 27075; i <= 27078; i++) + materials[i] = Material.OxidizedCopperBulb; + for (int i = 27079; i <= 27082; i++) + materials[i] = Material.WaxedCopperBulb; + for (int i = 27083; i <= 27086; i++) + materials[i] = Material.WaxedExposedCopperBulb; + for (int i = 27087; i <= 27090; i++) + materials[i] = Material.WaxedWeatheredCopperBulb; + for (int i = 27091; i <= 27094; i++) + materials[i] = Material.WaxedOxidizedCopperBulb; + for (int i = 27095; i <= 27118; i++) + materials[i] = Material.CopperChest; + for (int i = 27119; i <= 27142; i++) + materials[i] = Material.ExposedCopperChest; + for (int i = 27143; i <= 27166; i++) + materials[i] = Material.WeatheredCopperChest; + for (int i = 27167; i <= 27190; i++) + materials[i] = Material.OxidizedCopperChest; + for (int i = 27191; i <= 27214; i++) + materials[i] = Material.WaxedCopperChest; + for (int i = 27215; i <= 27238; i++) + materials[i] = Material.WaxedExposedCopperChest; + for (int i = 27239; i <= 27262; i++) + materials[i] = Material.WaxedWeatheredCopperChest; + for (int i = 27263; i <= 27286; i++) + materials[i] = Material.WaxedOxidizedCopperChest; + for (int i = 27287; i <= 27318; i++) + materials[i] = Material.CopperGolemStatue; + for (int i = 27319; i <= 27350; i++) + materials[i] = Material.ExposedCopperGolemStatue; + for (int i = 27351; i <= 27382; i++) + materials[i] = Material.WeatheredCopperGolemStatue; + for (int i = 27383; i <= 27414; i++) + materials[i] = Material.OxidizedCopperGolemStatue; + for (int i = 27415; i <= 27446; i++) + materials[i] = Material.WaxedCopperGolemStatue; + for (int i = 27447; i <= 27478; i++) + materials[i] = Material.WaxedExposedCopperGolemStatue; + for (int i = 27479; i <= 27510; i++) + materials[i] = Material.WaxedWeatheredCopperGolemStatue; + for (int i = 27511; i <= 27542; i++) + materials[i] = Material.WaxedOxidizedCopperGolemStatue; + for (int i = 27543; i <= 27566; i++) + materials[i] = Material.LightningRod; + for (int i = 27567; i <= 27590; i++) + materials[i] = Material.ExposedLightningRod; + for (int i = 27591; i <= 27614; i++) + materials[i] = Material.WeatheredLightningRod; + for (int i = 27615; i <= 27638; i++) + materials[i] = Material.OxidizedLightningRod; + for (int i = 27639; i <= 27662; i++) + materials[i] = Material.WaxedLightningRod; + for (int i = 27663; i <= 27686; i++) + materials[i] = Material.WaxedExposedLightningRod; + for (int i = 27687; i <= 27710; i++) + materials[i] = Material.WaxedWeatheredLightningRod; + for (int i = 27711; i <= 27734; i++) + materials[i] = Material.WaxedOxidizedLightningRod; + for (int i = 27735; i <= 27754; i++) + materials[i] = Material.PointedDripstone; + for (int i = 27755; i <= 27755; i++) + materials[i] = Material.DripstoneBlock; + for (int i = 27756; i <= 27807; i++) + materials[i] = Material.CaveVines; + for (int i = 27808; i <= 27809; i++) + materials[i] = Material.CaveVinesPlant; + for (int i = 27810; i <= 27810; i++) + materials[i] = Material.SporeBlossom; + for (int i = 27811; i <= 27811; i++) + materials[i] = Material.Azalea; + for (int i = 27812; i <= 27812; i++) + materials[i] = Material.FloweringAzalea; + for (int i = 27813; i <= 27813; i++) + materials[i] = Material.MossCarpet; + for (int i = 27814; i <= 27829; i++) + materials[i] = Material.PinkPetals; + for (int i = 27830; i <= 27845; i++) + materials[i] = Material.Wildflowers; + for (int i = 27846; i <= 27861; i++) + materials[i] = Material.LeafLitter; + for (int i = 27862; i <= 27862; i++) + materials[i] = Material.MossBlock; + for (int i = 27863; i <= 27894; i++) + materials[i] = Material.BigDripleaf; + for (int i = 27895; i <= 27902; i++) + materials[i] = Material.BigDripleafStem; + for (int i = 27903; i <= 27918; i++) + materials[i] = Material.SmallDripleaf; + for (int i = 27919; i <= 27920; i++) + materials[i] = Material.HangingRoots; + for (int i = 27921; i <= 27921; i++) + materials[i] = Material.RootedDirt; + for (int i = 27922; i <= 27922; i++) + materials[i] = Material.Mud; + for (int i = 27923; i <= 27925; i++) + materials[i] = Material.Deepslate; + for (int i = 27926; i <= 27926; i++) + materials[i] = Material.CobbledDeepslate; + for (int i = 27927; i <= 28006; i++) + materials[i] = Material.CobbledDeepslateStairs; + for (int i = 28007; i <= 28012; i++) + materials[i] = Material.CobbledDeepslateSlab; + for (int i = 28013; i <= 28336; i++) + materials[i] = Material.CobbledDeepslateWall; + for (int i = 28337; i <= 28337; i++) + materials[i] = Material.PolishedDeepslate; + for (int i = 28338; i <= 28417; i++) + materials[i] = Material.PolishedDeepslateStairs; + for (int i = 28418; i <= 28423; i++) + materials[i] = Material.PolishedDeepslateSlab; + for (int i = 28424; i <= 28747; i++) + materials[i] = Material.PolishedDeepslateWall; + for (int i = 28748; i <= 28748; i++) + materials[i] = Material.DeepslateTiles; + for (int i = 28749; i <= 28828; i++) + materials[i] = Material.DeepslateTileStairs; + for (int i = 28829; i <= 28834; i++) + materials[i] = Material.DeepslateTileSlab; + for (int i = 28835; i <= 29158; i++) + materials[i] = Material.DeepslateTileWall; + for (int i = 29159; i <= 29159; i++) + materials[i] = Material.DeepslateBricks; + for (int i = 29160; i <= 29239; i++) + materials[i] = Material.DeepslateBrickStairs; + for (int i = 29240; i <= 29245; i++) + materials[i] = Material.DeepslateBrickSlab; + for (int i = 29246; i <= 29569; i++) + materials[i] = Material.DeepslateBrickWall; + for (int i = 29570; i <= 29570; i++) + materials[i] = Material.ChiseledDeepslate; + for (int i = 29571; i <= 29571; i++) + materials[i] = Material.CrackedDeepslateBricks; + for (int i = 29572; i <= 29572; i++) + materials[i] = Material.CrackedDeepslateTiles; + for (int i = 29573; i <= 29575; i++) + materials[i] = Material.InfestedDeepslate; + for (int i = 29576; i <= 29576; i++) + materials[i] = Material.SmoothBasalt; + for (int i = 29577; i <= 29577; i++) + materials[i] = Material.RawIronBlock; + for (int i = 29578; i <= 29578; i++) + materials[i] = Material.RawCopperBlock; + for (int i = 29579; i <= 29579; i++) + materials[i] = Material.RawGoldBlock; + for (int i = 29580; i <= 29580; i++) + materials[i] = Material.PottedAzaleaBush; + for (int i = 29581; i <= 29581; i++) + materials[i] = Material.PottedFloweringAzaleaBush; + for (int i = 29582; i <= 29584; i++) + materials[i] = Material.OchreFroglight; + for (int i = 29585; i <= 29587; i++) + materials[i] = Material.VerdantFroglight; + for (int i = 29588; i <= 29590; i++) + materials[i] = Material.PearlescentFroglight; + for (int i = 29591; i <= 29591; i++) + materials[i] = Material.Frogspawn; + for (int i = 29592; i <= 29592; i++) + materials[i] = Material.ReinforcedDeepslate; + for (int i = 29593; i <= 29608; i++) + materials[i] = Material.DecoratedPot; + for (int i = 29609; i <= 29656; i++) + materials[i] = Material.Crafter; + for (int i = 29657; i <= 29668; i++) + materials[i] = Material.TrialSpawner; + for (int i = 29669; i <= 29700; i++) + materials[i] = Material.Vault; + for (int i = 29701; i <= 29702; i++) + materials[i] = Material.HeavyCore; + for (int i = 29703; i <= 29703; i++) + materials[i] = Material.PaleMossBlock; + for (int i = 29704; i <= 29865; i++) + materials[i] = Material.PaleMossCarpet; + for (int i = 29866; i <= 29867; i++) + materials[i] = Material.PaleHangingMoss; + for (int i = 29868; i <= 29868; i++) + materials[i] = Material.OpenEyeblossom; + for (int i = 29869; i <= 29869; i++) + materials[i] = Material.ClosedEyeblossom; + for (int i = 29870; i <= 29870; i++) + materials[i] = Material.PottedOpenEyeblossom; + for (int i = 29871; i <= 29871; i++) + materials[i] = Material.PottedClosedEyeblossom; + for (int i = 29872; i <= 29872; i++) + materials[i] = Material.FireflyBush; + } + + protected override Dictionary GetDict() + { + return materials; + } + } +} diff --git a/MinecraftClient/Mapping/EntityMetaDataType.cs b/MinecraftClient/Mapping/EntityMetaDataType.cs index f5c70b7b..5d89f185 100644 --- a/MinecraftClient/Mapping/EntityMetaDataType.cs +++ b/MinecraftClient/Mapping/EntityMetaDataType.cs @@ -57,10 +57,18 @@ public enum EntityMetaDataType ///

CatVariant, /// + /// VarInt (1.21.5+) + /// + CatSoundVariant, + /// /// VarInt (1.20.6+) /// CowVariant, /// + /// VarInt (1.21.5+) + /// + CowSoundVariant, + /// /// VarInt (1.20.6+) /// WolfVariant, @@ -76,8 +84,16 @@ public enum EntityMetaDataType /// /// VarInt (1.21.5+) /// + PigSoundVariant, + /// + /// VarInt (1.21.5+) + /// ChickenVariant, /// + /// VarInt (1.21.5+) + /// + ChickenSoundVariant, + /// /// String + Position /// GlobalPosition, diff --git a/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette261.cs b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette261.cs new file mode 100644 index 00000000..d604b464 --- /dev/null +++ b/MinecraftClient/Mapping/EntityMetadataPalettes/EntityMetadataPalette261.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityMetadataPalettes; + +public class EntityMetadataPalette261 : EntityMetadataPalette +{ + private readonly Dictionary entityMetadataMappings = new() + { + { 0, EntityMetaDataType.Byte }, + { 1, EntityMetaDataType.VarInt }, + { 2, EntityMetaDataType.VarLong }, + { 3, EntityMetaDataType.Float }, + { 4, EntityMetaDataType.String }, + { 5, EntityMetaDataType.Chat }, + { 6, EntityMetaDataType.OptionalChat }, + { 7, EntityMetaDataType.Slot }, + { 8, EntityMetaDataType.Boolean }, + { 9, EntityMetaDataType.Rotation }, + { 10, EntityMetaDataType.Position }, + { 11, EntityMetaDataType.OptionalPosition }, + { 12, EntityMetaDataType.Direction }, + { 13, EntityMetaDataType.OptionalLivingEntityReference }, + { 14, EntityMetaDataType.BlockId }, + { 15, EntityMetaDataType.OptionalBlockId }, + { 16, EntityMetaDataType.Particle }, + { 17, EntityMetaDataType.Particles }, + { 18, EntityMetaDataType.VillagerData }, + { 19, EntityMetaDataType.OptionalVarInt }, + { 20, EntityMetaDataType.Pose }, + { 21, EntityMetaDataType.CatVariant }, + { 22, EntityMetaDataType.CatSoundVariant }, + { 23, EntityMetaDataType.CowVariant }, + { 24, EntityMetaDataType.CowSoundVariant }, + { 25, EntityMetaDataType.WolfVariant }, + { 26, EntityMetaDataType.WolfSoundVariant }, + { 27, EntityMetaDataType.FrogVariant }, + { 28, EntityMetaDataType.PigVariant }, + { 29, EntityMetaDataType.PigSoundVariant }, + { 30, EntityMetaDataType.ChickenVariant }, + { 31, EntityMetaDataType.ChickenSoundVariant }, + { 32, EntityMetaDataType.ZombieNautilusVariant }, + { 33, EntityMetaDataType.OptionalGlobalPosition }, + { 34, EntityMetaDataType.PaintingVariant }, + { 35, EntityMetaDataType.SnifferState }, + { 36, EntityMetaDataType.ArmadilloState }, + { 37, EntityMetaDataType.CopperGolemState }, + { 38, EntityMetaDataType.WeatheringCopperState }, + { 39, EntityMetaDataType.Vector3 }, + { 40, EntityMetaDataType.Quaternion }, + { 41, EntityMetaDataType.ResolvableProfile }, + { 42, EntityMetaDataType.HumanoidArm }, + }; + + public override Dictionary GetEntityMetadataMappingsList() + { + return entityMetadataMappings; + } +} diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette261.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette261.cs new file mode 100644 index 00000000..a33d0b3b --- /dev/null +++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette261.cs @@ -0,0 +1,175 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping.EntityPalettes +{ + public class EntityPalette261 : EntityPalette + { + private static readonly Dictionary mappings = new(); + + static EntityPalette261() + { + mappings[0] = EntityType.AcaciaBoat; + mappings[1] = EntityType.AcaciaChestBoat; + mappings[2] = EntityType.Allay; + mappings[3] = EntityType.AreaEffectCloud; + mappings[4] = EntityType.Armadillo; + mappings[5] = EntityType.ArmorStand; + mappings[6] = EntityType.Arrow; + mappings[7] = EntityType.Axolotl; + mappings[8] = EntityType.BambooChestRaft; + mappings[9] = EntityType.BambooRaft; + mappings[10] = EntityType.Bat; + mappings[11] = EntityType.Bee; + mappings[12] = EntityType.BirchBoat; + mappings[13] = EntityType.BirchChestBoat; + mappings[14] = EntityType.Blaze; + mappings[15] = EntityType.BlockDisplay; + mappings[16] = EntityType.Bogged; + mappings[17] = EntityType.Breeze; + mappings[18] = EntityType.BreezeWindCharge; + mappings[19] = EntityType.Camel; + mappings[20] = EntityType.CamelHusk; + mappings[21] = EntityType.Cat; + mappings[22] = EntityType.CaveSpider; + mappings[23] = EntityType.CherryBoat; + mappings[24] = EntityType.CherryChestBoat; + mappings[25] = EntityType.ChestMinecart; + mappings[26] = EntityType.Chicken; + mappings[27] = EntityType.Cod; + mappings[28] = EntityType.CopperGolem; + mappings[29] = EntityType.CommandBlockMinecart; + mappings[30] = EntityType.Cow; + mappings[31] = EntityType.Creaking; + mappings[32] = EntityType.Creeper; + mappings[33] = EntityType.DarkOakBoat; + mappings[34] = EntityType.DarkOakChestBoat; + mappings[35] = EntityType.Dolphin; + mappings[36] = EntityType.Donkey; + mappings[37] = EntityType.DragonFireball; + mappings[38] = EntityType.Drowned; + mappings[39] = EntityType.Egg; + mappings[40] = EntityType.ElderGuardian; + mappings[41] = EntityType.Enderman; + mappings[42] = EntityType.Endermite; + mappings[43] = EntityType.EnderDragon; + mappings[44] = EntityType.EnderPearl; + mappings[45] = EntityType.EndCrystal; + mappings[46] = EntityType.Evoker; + mappings[47] = EntityType.EvokerFangs; + mappings[48] = EntityType.ExperienceBottle; + mappings[49] = EntityType.ExperienceOrb; + mappings[50] = EntityType.EyeOfEnder; + mappings[51] = EntityType.FallingBlock; + mappings[52] = EntityType.Fireball; + mappings[53] = EntityType.FireworkRocket; + mappings[54] = EntityType.Fox; + mappings[55] = EntityType.Frog; + mappings[56] = EntityType.FurnaceMinecart; + mappings[57] = EntityType.Ghast; + mappings[58] = EntityType.HappyGhast; + mappings[59] = EntityType.Giant; + mappings[60] = EntityType.GlowItemFrame; + mappings[61] = EntityType.GlowSquid; + mappings[62] = EntityType.Goat; + mappings[63] = EntityType.Guardian; + mappings[64] = EntityType.Hoglin; + mappings[65] = EntityType.HopperMinecart; + mappings[66] = EntityType.Horse; + mappings[67] = EntityType.Husk; + mappings[68] = EntityType.Illusioner; + mappings[69] = EntityType.Interaction; + mappings[70] = EntityType.IronGolem; + mappings[71] = EntityType.Item; + mappings[72] = EntityType.ItemDisplay; + mappings[73] = EntityType.ItemFrame; + mappings[74] = EntityType.JungleBoat; + mappings[75] = EntityType.JungleChestBoat; + mappings[76] = EntityType.LeashKnot; + mappings[77] = EntityType.LightningBolt; + mappings[78] = EntityType.Llama; + mappings[79] = EntityType.LlamaSpit; + mappings[80] = EntityType.MagmaCube; + mappings[81] = EntityType.MangroveBoat; + mappings[82] = EntityType.MangroveChestBoat; + mappings[83] = EntityType.Mannequin; + mappings[84] = EntityType.Marker; + mappings[85] = EntityType.Minecart; + mappings[86] = EntityType.Mooshroom; + mappings[87] = EntityType.Mule; + mappings[88] = EntityType.Nautilus; + mappings[89] = EntityType.OakBoat; + mappings[90] = EntityType.OakChestBoat; + mappings[91] = EntityType.Ocelot; + mappings[92] = EntityType.OminousItemSpawner; + mappings[93] = EntityType.Painting; + mappings[94] = EntityType.PaleOakBoat; + mappings[95] = EntityType.PaleOakChestBoat; + mappings[96] = EntityType.Panda; + mappings[97] = EntityType.Parched; + mappings[98] = EntityType.Parrot; + mappings[99] = EntityType.Phantom; + mappings[100] = EntityType.Pig; + mappings[101] = EntityType.Piglin; + mappings[102] = EntityType.PiglinBrute; + mappings[103] = EntityType.Pillager; + mappings[104] = EntityType.PolarBear; + mappings[105] = EntityType.SplashPotion; + mappings[106] = EntityType.LingeringPotion; + mappings[107] = EntityType.Pufferfish; + mappings[108] = EntityType.Rabbit; + mappings[109] = EntityType.Ravager; + mappings[110] = EntityType.Salmon; + mappings[111] = EntityType.Sheep; + mappings[112] = EntityType.Shulker; + mappings[113] = EntityType.ShulkerBullet; + mappings[114] = EntityType.Silverfish; + mappings[115] = EntityType.Skeleton; + mappings[116] = EntityType.SkeletonHorse; + mappings[117] = EntityType.Slime; + mappings[118] = EntityType.SmallFireball; + mappings[119] = EntityType.Sniffer; + mappings[120] = EntityType.Snowball; + mappings[121] = EntityType.SnowGolem; + mappings[122] = EntityType.SpawnerMinecart; + mappings[123] = EntityType.SpectralArrow; + mappings[124] = EntityType.Spider; + mappings[125] = EntityType.SpruceBoat; + mappings[126] = EntityType.SpruceChestBoat; + mappings[127] = EntityType.Squid; + mappings[128] = EntityType.Stray; + mappings[129] = EntityType.Strider; + mappings[130] = EntityType.Tadpole; + mappings[131] = EntityType.TextDisplay; + mappings[132] = EntityType.Tnt; + mappings[133] = EntityType.TntMinecart; + mappings[134] = EntityType.TraderLlama; + mappings[135] = EntityType.Trident; + mappings[136] = EntityType.TropicalFish; + mappings[137] = EntityType.Turtle; + mappings[138] = EntityType.Vex; + mappings[139] = EntityType.Villager; + mappings[140] = EntityType.Vindicator; + mappings[141] = EntityType.WanderingTrader; + mappings[142] = EntityType.Warden; + mappings[143] = EntityType.WindCharge; + mappings[144] = EntityType.Witch; + mappings[145] = EntityType.Wither; + mappings[146] = EntityType.WitherSkeleton; + mappings[147] = EntityType.WitherSkull; + mappings[148] = EntityType.Wolf; + mappings[149] = EntityType.Zoglin; + mappings[150] = EntityType.Zombie; + mappings[151] = EntityType.ZombieHorse; + mappings[152] = EntityType.ZombieNautilus; + mappings[153] = EntityType.ZombieVillager; + mappings[154] = EntityType.ZombifiedPiglin; + mappings[155] = EntityType.Player; + mappings[156] = EntityType.FishingBobber; + } + + protected override Dictionary GetDict() + { + return mappings; + } + } +} diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 35454a6e..75fb26d0 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -431,6 +431,7 @@ namespace MinecraftClient.Mapping Glowstone, GoldBlock, GoldOre, + GoldenDandelion, Granite, GraniteSlab, GraniteStairs, @@ -799,6 +800,7 @@ namespace MinecraftClient.Mapping PottedDeadBush, PottedFern, PottedFloweringAzaleaBush, + PottedGoldenDandelion, PottedJungleSapling, PottedLilyOfTheValley, PottedMangrovePropagule, diff --git a/tools/gen_entity_metadata_palette.py b/tools/gen_entity_metadata_palette.py index 5c54e80c..2aac53dd 100644 --- a/tools/gen_entity_metadata_palette.py +++ b/tools/gen_entity_metadata_palette.py @@ -46,13 +46,17 @@ FIELD_TO_ENUM = { "VILLAGER_DATA": "VillagerData", "OPTIONAL_UNSIGNED_INT": "OptionalVarInt", "POSE": "Pose", + "CAT_SOUND_VARIANT": "CatSoundVariant", "CAT_VARIANT": "CatVariant", - "COW_VARIANT": "CowVariant", - "WOLF_VARIANT": "WolfVariant", - "WOLF_SOUND_VARIANT": "WolfSoundVariant", - "FROG_VARIANT": "FrogVariant", - "PIG_VARIANT": "PigVariant", + "CHICKEN_SOUND_VARIANT": "ChickenSoundVariant", "CHICKEN_VARIANT": "ChickenVariant", + "COW_SOUND_VARIANT": "CowSoundVariant", + "COW_VARIANT": "CowVariant", + "FROG_VARIANT": "FrogVariant", + "PIG_SOUND_VARIANT": "PigSoundVariant", + "PIG_VARIANT": "PigVariant", + "WOLF_SOUND_VARIANT": "WolfSoundVariant", + "WOLF_VARIANT": "WolfVariant", "OPTIONAL_GLOBAL_POS": "OptionalGlobalPosition", "PAINTING_VARIANT": "PaintingVariant", "SNIFFER_STATE": "SnifferState", From d4014f7c879c8172aebf34c1fa00c964ec9ba7ff Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 17:51:14 +0800 Subject: [PATCH 102/484] feat: add 26.1 packet palette, structured components registry, and version routing Add PacketPalette261 with new packet types (GameRuleValues, LowDiskSpaceWarning, Attack, SetGameRule). Create StructuredComponentsRegistry261 with 6 new components (additional_trade_cost, dye, pig/cow/chicken/cat sound_variant). Update version routing in PacketType18Handler, EntityMetadataPalette, StructuredComponentsHandler, and Program.cs to support protocol 775 (26.1). Made-with: Cursor --- .../Mapping/EntityMetadataPalette.cs | 1 + MinecraftClient/Program.cs | 2 +- .../PacketPalettes/PacketPalette261.cs | 266 ++++++++++++++++++ .../Protocol/Handlers/PacketType18Handler.cs | 3 +- .../Protocol/Handlers/PacketTypesIn.cs | 2 + .../Protocol/Handlers/PacketTypesOut.cs | 2 + .../StructuredComponentsRegistry261.cs | 129 +++++++++ .../StructuredComponentsHandler.cs | 1 + 8 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette261.cs create mode 100644 MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry261.cs diff --git a/MinecraftClient/Mapping/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index e4ec35e6..98875ffb 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -27,6 +27,7 @@ public abstract class EntityMetadataPalette <= Protocol18Handler.MC_1_21_7_Version => new EntityMetadataPalette1215(), // 1.21.5 - 1.21.8 <= Protocol18Handler.MC_1_21_9_Version => new EntityMetadataPalette1219(), // 1.21.9 - 1.21.10 <= Protocol18Handler.MC_1_21_11_Version => new EntityMetadataPalette12111(), // 1.21.11 + <= Protocol18Handler.MC_26_1_Version => new EntityMetadataPalette261(), // 26.1 _ => throw new NotImplementedException() }; } diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index d09a8e8a..cd6716eb 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.21.11"; + public const string MCHighestVersion = "26.1"; public static readonly string? BuildInfo = null; private static Tuple? offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette261.cs b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette261.cs new file mode 100644 index 00000000..ead41d2c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette261.cs @@ -0,0 +1,266 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.PacketPalettes; + +public class PacketPalette261 : PacketTypePalette + { + private readonly Dictionary typeIn = new() + { + { 0x00, PacketTypesIn.Bundle }, // Bundle delimiter + { 0x01, PacketTypesIn.SpawnEntity }, // Add Entity + { 0x02, PacketTypesIn.EntityAnimation }, // Animate + { 0x03, PacketTypesIn.Statistics }, // Award Stats + { 0x04, PacketTypesIn.BlockChangedAck }, // Block Changed Ack + { 0x05, PacketTypesIn.BlockBreakAnimation }, // Block Destruction + { 0x06, PacketTypesIn.BlockEntityData }, // Block Entity Data + { 0x07, PacketTypesIn.BlockAction }, // Block Event + { 0x08, PacketTypesIn.BlockChange }, // Block Update + { 0x09, PacketTypesIn.BossBar }, // Boss Event + { 0x0A, PacketTypesIn.ServerDifficulty }, // Change Difficulty + { 0x0B, PacketTypesIn.ChunkBatchFinished }, // Chunk Batch Finished + { 0x0C, PacketTypesIn.ChunkBatchStarted }, // Chunk Batch Start + { 0x0D, PacketTypesIn.ChunksBiomes }, // Chunks Biomes + { 0x0E, PacketTypesIn.ClearTiles }, // Clear Titles + { 0x0F, PacketTypesIn.TabComplete }, // Command Suggestions + { 0x10, PacketTypesIn.DeclareCommands }, // Commands + { 0x11, PacketTypesIn.CloseWindow }, // Container Close + { 0x12, PacketTypesIn.WindowItems }, // Container Set Content + { 0x13, PacketTypesIn.WindowProperty }, // Container Set Data + { 0x14, PacketTypesIn.SetSlot }, // Container Set Slot + { 0x15, PacketTypesIn.CookieRequest }, // Cookie Request + { 0x16, PacketTypesIn.SetCooldown }, // Cooldown + { 0x17, PacketTypesIn.ChatSuggestions }, // Custom Chat Completions + { 0x18, PacketTypesIn.PluginMessage }, // Custom Payload + { 0x19, PacketTypesIn.DamageEvent }, // Damage Event + { 0x1A, PacketTypesIn.DebugBlockValue }, // Debug Block Value + { 0x1B, PacketTypesIn.DebugChunkValue }, // Debug Chunk Value + { 0x1C, PacketTypesIn.DebugEntityValue }, // Debug Entity Value + { 0x1D, PacketTypesIn.DebugEvent }, // Debug Event + { 0x1E, PacketTypesIn.DebugSample }, // Debug Sample + { 0x1F, PacketTypesIn.HideMessage }, // Delete Chat + { 0x20, PacketTypesIn.Disconnect }, // Disconnect + { 0x21, PacketTypesIn.ProfilelessChatMessage }, // Disguised Chat + { 0x22, PacketTypesIn.EntityStatus }, // Entity Event + { 0x23, PacketTypesIn.EntityPositionSync }, // Entity Position Sync + { 0x24, PacketTypesIn.Explosion }, // Explode + { 0x25, PacketTypesIn.UnloadChunk }, // Forget Level Chunk + { 0x26, PacketTypesIn.ChangeGameState }, // Game Event + { 0x27, PacketTypesIn.GameRuleValues }, // Game Rule Values (new in 26.1) + { 0x28, PacketTypesIn.GameTestHighlightPos }, // Game Test Highlight Pos + { 0x29, PacketTypesIn.OpenHorseWindow }, // Mount Screen Open (renamed from Horse Screen Open) + { 0x2A, PacketTypesIn.HurtAnimation }, // Hurt Animation + { 0x2B, PacketTypesIn.InitializeWorldBorder }, // Initialize Border + { 0x2C, PacketTypesIn.KeepAlive }, // Keep Alive + { 0x2D, PacketTypesIn.ChunkData }, // Level Chunk With Light + { 0x2E, PacketTypesIn.Effect }, // Level Event + { 0x2F, PacketTypesIn.Particle }, // Level Particles + { 0x30, PacketTypesIn.UpdateLight }, // Light Update + { 0x31, PacketTypesIn.JoinGame }, // Login + { 0x32, PacketTypesIn.LowDiskSpaceWarning }, // Low Disk Space Warning (new in 26.1) + { 0x33, PacketTypesIn.MapData }, // Map Item Data + { 0x34, PacketTypesIn.TradeList }, // Merchant Offers + { 0x35, PacketTypesIn.EntityPosition }, // Move Entity Pos + { 0x36, PacketTypesIn.EntityPositionAndRotation }, // Move Entity Pos Rot + { 0x37, PacketTypesIn.MoveMinecartAlongTrack }, // Move Minecart Along Track + { 0x38, PacketTypesIn.EntityRotation }, // Move Entity Rot + { 0x39, PacketTypesIn.VehicleMove }, // Move Vehicle + { 0x3A, PacketTypesIn.OpenBook }, // Open Book + { 0x3B, PacketTypesIn.OpenWindow }, // Open Screen + { 0x3C, PacketTypesIn.OpenSignEditor }, // Open Sign Editor + { 0x3D, PacketTypesIn.Ping }, // Ping + { 0x3E, PacketTypesIn.PingResponse }, // Pong Response + { 0x3F, PacketTypesIn.CraftRecipeResponse }, // Place Ghost Recipe + { 0x40, PacketTypesIn.PlayerAbilities }, // Player Abilities + { 0x41, PacketTypesIn.ChatMessage }, // Player Chat + { 0x42, PacketTypesIn.EndCombatEvent }, // Player Combat End + { 0x43, PacketTypesIn.EnterCombatEvent }, // Player Combat Enter + { 0x44, PacketTypesIn.DeathCombatEvent }, // Player Combat Kill + { 0x45, PacketTypesIn.PlayerRemove }, // Player Info Remove + { 0x46, PacketTypesIn.PlayerInfo }, // Player Info Update + { 0x47, PacketTypesIn.FacePlayer }, // Player Look At + { 0x48, PacketTypesIn.PlayerPositionAndLook }, // Player Position + { 0x49, PacketTypesIn.PlayerRotation }, // Player Rotation + { 0x4A, PacketTypesIn.RecipeBookAdd }, // Recipe Book Add + { 0x4B, PacketTypesIn.RecipeBookRemove }, // Recipe Book Remove + { 0x4C, PacketTypesIn.RecipeBookSettings }, // Recipe Book Settings + { 0x4D, PacketTypesIn.DestroyEntities }, // Remove Entities + { 0x4E, PacketTypesIn.RemoveEntityEffect }, // Remove Mob Effect + { 0x4F, PacketTypesIn.ResetScore }, // Reset Score + { 0x50, PacketTypesIn.RemoveResourcePack }, // Resource Pack Pop + { 0x51, PacketTypesIn.ResourcePackSend }, // Resource Pack Push + { 0x52, PacketTypesIn.Respawn }, // Respawn + { 0x53, PacketTypesIn.EntityHeadLook }, // Rotate Head + { 0x54, PacketTypesIn.MultiBlockChange }, // Section Blocks Update + { 0x55, PacketTypesIn.SelectAdvancementTab }, // Select Advancements Tab + { 0x56, PacketTypesIn.ServerData }, // Server Data + { 0x57, PacketTypesIn.ActionBar }, // Set Action Bar Text + { 0x58, PacketTypesIn.WorldBorderCenter }, // Set Border Center + { 0x59, PacketTypesIn.WorldBorderLerpSize }, // Set Border Lerp Size + { 0x5A, PacketTypesIn.WorldBorderSize }, // Set Border Size + { 0x5B, PacketTypesIn.WorldBorderWarningDelay }, // Set Border Warning Delay + { 0x5C, PacketTypesIn.WorldBorderWarningReach }, // Set Border Warning Distance + { 0x5D, PacketTypesIn.Camera }, // Set Camera + { 0x5E, PacketTypesIn.UpdateViewPosition }, // Set Chunk Cache Center + { 0x5F, PacketTypesIn.UpdateViewDistance }, // Set Chunk Cache Radius + { 0x60, PacketTypesIn.SetCursorItem }, // Set Cursor Item + { 0x61, PacketTypesIn.SpawnPosition }, // Set Default Spawn Position + { 0x62, PacketTypesIn.DisplayScoreboard }, // Set Display Objective + { 0x63, PacketTypesIn.EntityMetadata }, // Set Entity Data + { 0x64, PacketTypesIn.AttachEntity }, // Set Entity Link + { 0x65, PacketTypesIn.EntityVelocity }, // Set Entity Motion + { 0x66, PacketTypesIn.EntityEquipment }, // Set Equipment + { 0x67, PacketTypesIn.SetExperience }, // Set Experience + { 0x68, PacketTypesIn.UpdateHealth }, // Set Health + { 0x69, PacketTypesIn.SetHeldSlot }, // Set Held Slot + { 0x6A, PacketTypesIn.ScoreboardObjective }, // Set Objective + { 0x6B, PacketTypesIn.SetPassengers }, // Set Passengers + { 0x6C, PacketTypesIn.SetPlayerInventory }, // Set Player Inventory + { 0x6D, PacketTypesIn.Teams }, // Set Player Team + { 0x6E, PacketTypesIn.UpdateScore }, // Set Score + { 0x6F, PacketTypesIn.UpdateSimulationDistance }, // Set Simulation Distance + { 0x70, PacketTypesIn.SetTitleSubTitle }, // Set Subtitle Text + { 0x71, PacketTypesIn.TimeUpdate }, // Set Time + { 0x72, PacketTypesIn.SetTitleText }, // Set Title Text + { 0x73, PacketTypesIn.SetTitleTime }, // Set Titles Animation + { 0x74, PacketTypesIn.EntitySoundEffect }, // Sound Entity + { 0x75, PacketTypesIn.SoundEffect }, // Sound + { 0x76, PacketTypesIn.StartConfiguration }, // Start Configuration + { 0x77, PacketTypesIn.StopSound }, // Stop Sound + { 0x78, PacketTypesIn.StoreCookie }, // Store Cookie + { 0x79, PacketTypesIn.SystemChat }, // System Chat + { 0x7A, PacketTypesIn.PlayerListHeaderAndFooter }, // Tab List + { 0x7B, PacketTypesIn.NBTQueryResponse }, // Tag Query + { 0x7C, PacketTypesIn.CollectItem }, // Take Item Entity + { 0x7D, PacketTypesIn.EntityTeleport }, // Teleport Entity + { 0x7E, PacketTypesIn.TestInstanceBlockStatus }, // Test Instance Block Status + { 0x7F, PacketTypesIn.SetTickingState }, // Ticking State + { 0x80, PacketTypesIn.StepTick }, // Ticking Step + { 0x81, PacketTypesIn.Transfer }, // Transfer + { 0x82, PacketTypesIn.Advancements }, // Update Advancements + { 0x83, PacketTypesIn.EntityProperties }, // Update Attributes + { 0x84, PacketTypesIn.EntityEffect }, // Update Mob Effect + { 0x85, PacketTypesIn.DeclareRecipes }, // Update Recipes + { 0x86, PacketTypesIn.Tags }, // Update Tags + { 0x87, PacketTypesIn.ProjectilePower }, // Projectile Power + { 0x88, PacketTypesIn.CustomReportDetails }, // Custom Report Details + { 0x89, PacketTypesIn.ServerLinks }, // Server Links + { 0x8A, PacketTypesIn.Waypoint }, // Waypoint + { 0x8B, PacketTypesIn.ClearDialog }, // Clear Dialog + { 0x8C, PacketTypesIn.ShowDialog } // Show Dialog + }; + + private readonly Dictionary typeOut = new() + { + { 0x00, PacketTypesOut.TeleportConfirm }, // Accept Teleportation + { 0x01, PacketTypesOut.Attack }, // Attack (new in 26.1) + { 0x02, PacketTypesOut.QueryBlockNBT }, // Block Entity Tag Query + { 0x03, PacketTypesOut.BundleItemSelected }, // Bundle Item Selected + { 0x04, PacketTypesOut.SetDifficulty }, // Change Difficulty + { 0x05, PacketTypesOut.ChangeGameMode }, // Change Game Mode + { 0x06, PacketTypesOut.MessageAcknowledgment }, // Chat Ack + { 0x07, PacketTypesOut.ChatCommand }, // Chat Command + { 0x08, PacketTypesOut.SignedChatCommand }, // Chat Command Signed + { 0x09, PacketTypesOut.ChatMessage }, // Chat + { 0x0A, PacketTypesOut.PlayerSession }, // Chat Session Update + { 0x0B, PacketTypesOut.ChunkBatchReceived }, // Chunk Batch Received + { 0x0C, PacketTypesOut.ClientStatus }, // Client Command + { 0x0D, PacketTypesOut.ClientTickEnd }, // Client Tick End + { 0x0E, PacketTypesOut.ClientSettings }, // Client Information + { 0x0F, PacketTypesOut.TabComplete }, // Command Suggestion + { 0x10, PacketTypesOut.AcknowledgeConfiguration }, // Configuration Acknowledged + { 0x11, PacketTypesOut.ClickWindowButton }, // Container Button Click + { 0x12, PacketTypesOut.ClickWindow }, // Container Click + { 0x13, PacketTypesOut.CloseWindow }, // Container Close + { 0x14, PacketTypesOut.ChangeContainerSlotState }, // Container Slot State Changed + { 0x15, PacketTypesOut.CookieResponse }, // Cookie Response + { 0x16, PacketTypesOut.PluginMessage }, // Custom Payload + { 0x17, PacketTypesOut.DebugSampleSubscription }, // Debug Subscription Request (renamed) + { 0x18, PacketTypesOut.EditBook }, // Edit Book + { 0x19, PacketTypesOut.EntityNBTRequest }, // Entity Tag Query + { 0x1A, PacketTypesOut.InteractEntity }, // Interact + { 0x1B, PacketTypesOut.GenerateStructure }, // Jigsaw Generate + { 0x1C, PacketTypesOut.KeepAlive }, // Keep Alive + { 0x1D, PacketTypesOut.LockDifficulty }, // Lock Difficulty + { 0x1E, PacketTypesOut.PlayerPosition }, // Move Player Pos + { 0x1F, PacketTypesOut.PlayerPositionAndRotation }, // Move Player Pos Rot + { 0x20, PacketTypesOut.PlayerRotation }, // Move Player Rot + { 0x21, PacketTypesOut.PlayerMovement }, // Move Player Status Only + { 0x22, PacketTypesOut.VehicleMove }, // Move Vehicle + { 0x23, PacketTypesOut.SteerBoat }, // Paddle Boat + { 0x24, PacketTypesOut.PickItem }, // Pick Item From Block + { 0x25, PacketTypesOut.PickItemFromEntity }, // Pick Item From Entity + { 0x26, PacketTypesOut.PingRequest }, // Ping Request + { 0x27, PacketTypesOut.CraftRecipeRequest }, // Place Recipe + { 0x28, PacketTypesOut.PlayerAbilities }, // Player Abilities + { 0x29, PacketTypesOut.PlayerDigging }, // Player Action + { 0x2A, PacketTypesOut.EntityAction }, // Player Command + { 0x2B, PacketTypesOut.SteerVehicle }, // Player Input + { 0x2C, PacketTypesOut.PlayerLoaded }, // Player Loaded + { 0x2D, PacketTypesOut.Pong }, // Pong + { 0x2E, PacketTypesOut.SetDisplayedRecipe }, // Recipe Book Change Settings + { 0x2F, PacketTypesOut.SetRecipeBookState }, // Recipe Book Seen Recipe + { 0x30, PacketTypesOut.NameItem }, // Rename Item + { 0x31, PacketTypesOut.ResourcePackStatus }, // Resource Pack + { 0x32, PacketTypesOut.AdvancementTab }, // Seen Advancements + { 0x33, PacketTypesOut.SelectTrade }, // Select Trade + { 0x34, PacketTypesOut.SetBeaconEffect }, // Set Beacon + { 0x35, PacketTypesOut.HeldItemChange }, // Set Carried Item + { 0x36, PacketTypesOut.UpdateCommandBlock }, // Set Command Block + { 0x37, PacketTypesOut.UpdateCommandBlockMinecart }, // Set Command Minecart + { 0x38, PacketTypesOut.CreativeInventoryAction }, // Set Creative Mode Slot + { 0x39, PacketTypesOut.SetGameRule }, // Set Game Rule (new in 26.1) + { 0x3A, PacketTypesOut.UpdateJigsawBlock }, // Set Jigsaw Block + { 0x3B, PacketTypesOut.UpdateStructureBlock }, // Set Structure Block + { 0x3C, PacketTypesOut.SetTestBlock }, // Set Test Block + { 0x3D, PacketTypesOut.UpdateSign }, // Sign Update + { 0x3F, PacketTypesOut.Animation }, // Swing + { 0x40, PacketTypesOut.Spectate }, // Teleport To Entity + { 0x41, PacketTypesOut.TestInstanceBlockAction }, // Test Instance Block Action + { 0x42, PacketTypesOut.PlayerBlockPlacement }, // Use Item On + { 0x43, PacketTypesOut.UseItem }, // Use Item + { 0x44, PacketTypesOut.CustomClickAction } // Custom Click Action + }; + + private readonly Dictionary configurationTypesIn = new() + { + { 0x00, ConfigurationPacketTypesIn.CookieRequest }, + { 0x01, ConfigurationPacketTypesIn.PluginMessage }, + { 0x02, ConfigurationPacketTypesIn.Disconnect }, + { 0x03, ConfigurationPacketTypesIn.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesIn.KeepAlive }, + { 0x05, ConfigurationPacketTypesIn.Ping }, + { 0x06, ConfigurationPacketTypesIn.ResetChat }, + { 0x07, ConfigurationPacketTypesIn.RegistryData }, + { 0x08, ConfigurationPacketTypesIn.RemoveResourcePack }, + { 0x09, ConfigurationPacketTypesIn.ResourcePack }, + { 0x0A, ConfigurationPacketTypesIn.StoreCookie }, + { 0x0B, ConfigurationPacketTypesIn.Transfer }, + { 0x0C, ConfigurationPacketTypesIn.FeatureFlags }, + { 0x0D, ConfigurationPacketTypesIn.UpdateTags }, + { 0x0E, ConfigurationPacketTypesIn.KnownDataPacks }, + { 0x0F, ConfigurationPacketTypesIn.CustomReportDetails }, + { 0x10, ConfigurationPacketTypesIn.ServerLinks }, + { 0x11, ConfigurationPacketTypesIn.ClearDialog }, + { 0x12, ConfigurationPacketTypesIn.ShowDialog }, + { 0x13, ConfigurationPacketTypesIn.CodeOfConduct } + }; + + private readonly Dictionary configurationTypesOut = new() + { + { 0x00, ConfigurationPacketTypesOut.ClientInformation }, + { 0x01, ConfigurationPacketTypesOut.CookieResponse }, + { 0x02, ConfigurationPacketTypesOut.PluginMessage }, + { 0x03, ConfigurationPacketTypesOut.FinishConfiguration }, + { 0x04, ConfigurationPacketTypesOut.KeepAlive }, + { 0x05, ConfigurationPacketTypesOut.Pong }, + { 0x06, ConfigurationPacketTypesOut.ResourcePackResponse }, + { 0x07, ConfigurationPacketTypesOut.KnownDataPacks }, + { 0x08, ConfigurationPacketTypesOut.CustomClickAction }, + { 0x09, ConfigurationPacketTypesOut.AcceptCodeOfConduct } + }; + + protected override Dictionary GetListIn() => typeIn; + protected override Dictionary GetListOut() => typeOut; + protected override Dictionary GetConfigurationListIn() => configurationTypesIn!; + protected override Dictionary GetConfigurationListOut() => configurationTypesOut!; + } diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index d8e56c86..21515782 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,8 +48,9 @@ namespace MinecraftClient.Protocol.Handlers { PacketTypePalette p = protocol switch { - > Protocol18Handler.MC_1_21_11_Version => throw new NotImplementedException(Translations + > Protocol18Handler.MC_26_1_Version => throw new NotImplementedException(Translations .exception_palette_packet), + >= Protocol18Handler.MC_26_1_Version => new PacketPalette261(), <= Protocol18Handler.MC_1_21_11_Version and > Protocol18Handler.MC_1_21_7_Version => new PacketPalette1219(), <= Protocol18Handler.MC_1_21_7_Version and > Protocol18Handler.MC_1_21_5_Version => new PacketPalette1216(), <= Protocol18Handler.MC_1_21_5_Version and > Protocol18Handler.MC_1_21_4_Version => new PacketPalette1215(), diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs index 5ff6ad2e..a36bc4ba 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -169,5 +169,7 @@ namespace MinecraftClient.Protocol.Handlers DebugEntityValue, // Added in 1.21.9 DebugEvent, // Added in 1.21.9 GameTestHighlightPos, // Added in 1.21.9 + GameRuleValues, // Added in 26.1 + LowDiskSpaceWarning, // Added in 26.1 } } diff --git a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs index 111f3653..99704ae8 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -78,5 +78,7 @@ namespace MinecraftClient.Protocol.Handlers WindowConfirmation, // ChangeGameMode, // Added in 1.21.6 CustomClickAction, // Added in 1.21.6 + Attack, // Added in 26.1 + SetGameRule, // Added in 26.1 } } diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry261.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry261.cs new file mode 100644 index 00000000..579ff9d6 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry261.cs @@ -0,0 +1,129 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_2; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_11; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +public class StructuredComponentsRegistry261 : StructuredComponentRegistry +{ + public StructuredComponentsRegistry261(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : base(dataTypes, itemPalette, subComponentRegistry) + { + RegisterComponent(0, "minecraft:custom_data"); + RegisterComponent(1, "minecraft:max_stack_size"); + RegisterComponent(2, "minecraft:max_damage"); + RegisterComponent(3, "minecraft:damage"); + RegisterComponent(4, "minecraft:unbreakable"); + RegisterComponent(5, "minecraft:use_effects"); + RegisterComponent(6, "minecraft:custom_name"); + RegisterComponent(7, "minecraft:minimum_attack_charge"); + RegisterComponent(8, "minecraft:damage_type"); + RegisterComponent(9, "minecraft:item_name"); + RegisterComponent(10, "minecraft:item_model"); + RegisterComponent(11, "minecraft:lore"); + RegisterComponent(12, "minecraft:rarity"); + RegisterComponent(13, "minecraft:enchantments"); + RegisterComponent(14, "minecraft:can_place_on"); + RegisterComponent(15, "minecraft:can_break"); + RegisterComponent(16, "minecraft:attribute_modifiers"); + RegisterComponent(17, "minecraft:custom_model_data"); + RegisterComponent(18, "minecraft:tooltip_display"); + RegisterComponent(19, "minecraft:repair_cost"); + RegisterComponent(20, "minecraft:creative_slot_lock"); + RegisterComponent(21, "minecraft:enchantment_glint_override"); + RegisterComponent(22, "minecraft:intangible_projectile"); + RegisterComponent(23, "minecraft:food"); + RegisterComponent(24, "minecraft:consumable"); + RegisterComponent(25, "minecraft:use_remainder"); + RegisterComponent(26, "minecraft:use_cooldown"); + RegisterComponent(27, "minecraft:damage_resistant"); + RegisterComponent(28, "minecraft:tool"); + RegisterComponent(29, "minecraft:weapon"); + RegisterComponent(30, "minecraft:attack_range"); + RegisterComponent(31, "minecraft:enchantable"); + RegisterComponent(32, "minecraft:equippable"); + RegisterComponent(33, "minecraft:repairable"); + RegisterComponent(34, "minecraft:glider"); + RegisterComponent(35, "minecraft:tooltip_style"); + RegisterComponent(36, "minecraft:death_protection"); + RegisterComponent(37, "minecraft:blocks_attacks"); + RegisterComponent(38, "minecraft:piercing_weapon"); + RegisterComponent(39, "minecraft:kinetic_weapon"); + RegisterComponent(40, "minecraft:swing_animation"); + RegisterComponent(41, "minecraft:additional_trade_cost"); // New in 26.1 + RegisterComponent(42, "minecraft:stored_enchantments"); + RegisterComponent(43, "minecraft:dye"); // New in 26.1 + RegisterComponent(44, "minecraft:dyed_color"); + RegisterComponent(45, "minecraft:map_color"); + RegisterComponent(46, "minecraft:map_id"); + RegisterComponent(47, "minecraft:map_decorations"); + RegisterComponent(48, "minecraft:map_post_processing"); + RegisterComponent(49, "minecraft:charged_projectiles"); + RegisterComponent(50, "minecraft:bundle_contents"); + RegisterComponent(51, "minecraft:potion_contents"); + RegisterComponent(52, "minecraft:potion_duration_scale"); + RegisterComponent(53, "minecraft:suspicious_stew_effects"); + RegisterComponent(54, "minecraft:writable_book_content"); + RegisterComponent(55, "minecraft:written_book_content"); + RegisterComponent(56, "minecraft:trim"); + RegisterComponent(57, "minecraft:debug_stick_state"); + RegisterComponent(58, "minecraft:entity_data"); + RegisterComponent(59, "minecraft:bucket_entity_data"); + RegisterComponent(60, "minecraft:block_entity_data"); + RegisterComponent(61, "minecraft:instrument"); + RegisterComponent(62, "minecraft:provides_trim_material"); + RegisterComponent(63, "minecraft:ominous_bottle_amplifier"); + RegisterComponent(64, "minecraft:jukebox_playable"); + RegisterComponent(65, "minecraft:provides_banner_patterns"); + RegisterComponent(66, "minecraft:recipes"); + RegisterComponent(67, "minecraft:lodestone_tracker"); + RegisterComponent(68, "minecraft:firework_explosion"); + RegisterComponent(69, "minecraft:fireworks"); + RegisterComponent(70, "minecraft:profile"); + RegisterComponent(71, "minecraft:note_block_sound"); + RegisterComponent(72, "minecraft:banner_patterns"); + RegisterComponent(73, "minecraft:base_color"); + RegisterComponent(74, "minecraft:pot_decorations"); + RegisterComponent(75, "minecraft:container"); + RegisterComponent(76, "minecraft:block_state"); + RegisterComponent(77, "minecraft:bees"); + RegisterComponent(78, "minecraft:lock"); + RegisterComponent(79, "minecraft:container_loot"); + + RegisterComponent(80, "minecraft:break_sound"); + RegisterComponent(81, "minecraft:villager/variant"); + RegisterComponent(82, "minecraft:wolf/variant"); + RegisterComponent(83, "minecraft:wolf/sound_variant"); + RegisterComponent(84, "minecraft:wolf/collar"); + RegisterComponent(85, "minecraft:fox/variant"); + RegisterComponent(86, "minecraft:salmon/size"); + RegisterComponent(87, "minecraft:parrot/variant"); + RegisterComponent(88, "minecraft:tropical_fish/pattern"); + RegisterComponent(89, "minecraft:tropical_fish/base_color"); + RegisterComponent(90, "minecraft:tropical_fish/pattern_color"); + RegisterComponent(91, "minecraft:mooshroom/variant"); + RegisterComponent(92, "minecraft:rabbit/variant"); + RegisterComponent(93, "minecraft:pig/variant"); + RegisterComponent(94, "minecraft:pig/sound_variant"); // New in 26.1 + RegisterComponent(95, "minecraft:cow/variant"); + RegisterComponent(96, "minecraft:cow/sound_variant"); // New in 26.1 + RegisterComponent(97, "minecraft:chicken/variant"); + RegisterComponent(98, "minecraft:chicken/sound_variant"); // New in 26.1 + RegisterComponent(99, "minecraft:zombie_nautilus/variant"); + RegisterComponent(100, "minecraft:frog/variant"); + RegisterComponent(101, "minecraft:horse/variant"); + RegisterComponent(102, "minecraft:painting/variant"); + RegisterComponent(103, "minecraft:llama/variant"); + RegisterComponent(104, "minecraft:axolotl/variant"); + RegisterComponent(105, "minecraft:cat/variant"); + RegisterComponent(106, "minecraft:cat/sound_variant"); // New in 26.1 + RegisterComponent(107, "minecraft:cat/collar"); + RegisterComponent(108, "minecraft:sheep/color"); + RegisterComponent(109, "minecraft:shulker/color"); + } +} diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs index c8b805c2..19644397 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -33,6 +33,7 @@ public class StructuredComponentsHandler { Protocol18Handler.MC_1_20_6_Version => typeof(StructuredComponentsRegistry1206), Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), + >= Protocol18Handler.MC_26_1_Version => typeof(StructuredComponentsRegistry261), >= Protocol18Handler.MC_1_21_11_Version => typeof(StructuredComponentsRegistry12111), >= Protocol18Handler.MC_1_21_5_Version => typeof(StructuredComponentsRegistry1215), >= Protocol18Handler.MC_1_21_2_Version => typeof(StructuredComponentsRegistry1212), From d1837d104bf4fc0c07bee0a6b44373bd7b7be43f Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 22 Mar 2026 17:51:29 +0800 Subject: [PATCH 103/484] feat: handle 26.1 protocol changes and snapshot version support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Protocol18: add MC_26_1_Version constant (775), version-gated palette routing for blocks/items/entities/metadata, and new TimeUpdate packet format (WorldClock map replaces dayTime+tickDayTime) - Protocol18Terrain: read new fluidCount short in chunk sections (26.1+) - DataTypes: add CatSoundVariant to entity metadata VarInt readers - ProtocolHandler: add NormalizeSnapshotProtocol() to map RC/snapshot protocol numbers (e.g. 0x4000012E → 775) to release versions, pass raw protocol version through for server handshake compatibility Made-with: Cursor --- .../Protocol/Handlers/DataTypes.cs | 4 ++ .../Protocol/Handlers/Protocol18.cs | 55 ++++++++++++++----- .../Protocol/Handlers/Protocol18Terrain.cs | 3 + MinecraftClient/Protocol/ProtocolHandler.cs | 31 +++++++++-- 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index bd2c84e4..3af09266 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -893,16 +893,20 @@ namespace MinecraftClient.Protocol.Handlers value = ReadNextVarInt(cache); break; case EntityMetaDataType.CatVariant: // Cat Variant + case EntityMetaDataType.CatSoundVariant: // Cat Sound Variant (26.1+) value = ReadNextVarInt(cache); break; case EntityMetaDataType.CowVariant: // Cow Variant (1.21.5+) + case EntityMetaDataType.CowSoundVariant: // Cow Sound Variant (26.1+) case EntityMetaDataType.WolfVariant: // Wolf Variant (1.20.6+) case EntityMetaDataType.WolfSoundVariant: // Wolf Sound Variant (1.21.5+) value = ReadNextVarInt(cache); break; case EntityMetaDataType.FrogVariant: // Frog Variant case EntityMetaDataType.PigVariant: // Pig Variant (1.21.5+) + case EntityMetaDataType.PigSoundVariant: // Pig Sound Variant (26.1+) case EntityMetaDataType.ChickenVariant: // Chicken Variant (1.21.5+) + case EntityMetaDataType.ChickenSoundVariant: // Chicken Sound Variant (26.1+) value = ReadNextVarInt(cache); break; case EntityMetaDataType.GlobalPosition: // GlobalPos diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ac69e14f..4f036fb7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -80,12 +80,14 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC_1_21_7_Version = 772; internal const int MC_1_21_9_Version = 773; internal const int MC_1_21_11_Version = 774; + internal const int MC_26_1_Version = 775; private int compression_treshold = -1; private int autocomplete_transaction_id = 0; private readonly Dictionary window_actions = new(); private CurrentState currentState = CurrentState.Login; private readonly int protocolVersion; + private readonly int rawProtocolVersion; private int currentDimension; private bool isOnlineMode = false; private readonly BlockingCollection>> packetQueue = new(); @@ -119,13 +121,14 @@ namespace MinecraftClient.Protocol.Handlers readonly RandomNumberGenerator randomGen; public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHandler handler, - ForgeInfo? forgeInfo) + ForgeInfo? forgeInfo, int rawProtocolVersion = 0) { ConsoleIO.SetAutoCompleteEngine(this); ChatParser.InitTranslations(); socketWrapper = new SocketWrapper(Client); dataTypes = new DataTypes(protocolVersion); this.protocolVersion = protocolVersion; + this.rawProtocolVersion = rawProtocolVersion != 0 ? rawProtocolVersion : protocolVersion; this.handler = handler; pForge = new Protocol18Forge(forgeInfo, protocolVersion, dataTypes, this, handler); pTerrain = new Protocol18Terrain(protocolVersion, dataTypes, handler); @@ -135,21 +138,21 @@ namespace MinecraftClient.Protocol.Handlers lastSeenMessagesCollector = protocolVersion >= MC_1_19_3_Version ? new(20) : new(5); chunkBatchStartTime = GetNanos(); - if (handler.GetTerrainEnabled() && protocolVersion > MC_1_21_11_Version) + if (handler.GetTerrainEnabled() && protocolVersion > MC_26_1_Version) { log.Error($"§c{Translations.extra_terrainandmovement_disabled}"); handler.SetTerrainEnabled(false); } if (handler.GetInventoryEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_11_Version) + protocolVersion is < MC_1_8_Version or > MC_26_1_Version) { log.Error($"§c{Translations.extra_inventory_disabled}"); handler.SetInventoryEnabled(false); } if (handler.GetEntityHandlingEnabled() && - protocolVersion is < MC_1_8_Version or > MC_1_21_11_Version) + protocolVersion is < MC_1_8_Version or > MC_26_1_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -158,8 +161,9 @@ namespace MinecraftClient.Protocol.Handlers Block.Palette = protocolVersion switch { // Block palette - > MC_1_21_11_Version when handler.GetTerrainEnabled() => + > MC_26_1_Version when handler.GetTerrainEnabled() => throw new NotImplementedException(Translations.exception_palette_block), + >= MC_26_1_Version => new Palette261(), >= MC_1_21_9_Version => new Palette1219(), >= MC_1_21_6_Version => new Palette1216(), // 1.21.7/1.21.8 blocks unchanged, reuse 1216 >= MC_1_21_5_Version => new Palette1215(), @@ -182,8 +186,9 @@ namespace MinecraftClient.Protocol.Handlers entityPalette = protocolVersion switch { // Entity palette - > MC_1_21_11_Version when handler.GetEntityHandlingEnabled() => + > MC_26_1_Version when handler.GetEntityHandlingEnabled() => throw new NotImplementedException(Translations.exception_palette_entity), + >= MC_26_1_Version => new EntityPalette261(), >= MC_1_21_11_Version => new EntityPalette12111(), >= MC_1_21_9_Version => new EntityPalette1219(), >= MC_1_21_6_Version => new EntityPalette1216(), // 1.21.7/1.21.8 entities unchanged, reuse 1216 @@ -211,8 +216,9 @@ namespace MinecraftClient.Protocol.Handlers itemPalette = protocolVersion switch { // Item palette - > MC_1_21_11_Version when handler.GetInventoryEnabled() => + > MC_26_1_Version when handler.GetInventoryEnabled() => throw new NotImplementedException(Translations.exception_palette_item), + >= MC_26_1_Version => new ItemPalette261(), >= MC_1_21_11_Version => new ItemPalette12111(), >= MC_1_21_9_Version => new ItemPalette1219(), >= MC_1_21_7_Version => new ItemPalette1217(), @@ -2681,7 +2687,7 @@ namespace MinecraftClient.Protocol.Handlers // Also make a palette for field? Will be a lot of work var healthField = protocolVersion switch { - > MC_1_21_11_Version => throw new NotImplementedException(Translations + > MC_26_1_Version => throw new NotImplementedException(Translations .exception_palette_healthfield), // 1.17 and above >= MC_1_17_Version => 9, @@ -2711,11 +2717,30 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.TimeUpdate: - var worldAge = dataTypes.ReadNextLong(packetData); - var timeOfDay = dataTypes.ReadNextLong(packetData); - if (protocolVersion >= MC_1_21_2_Version) - dataTypes.ReadNextBool(packetData); // Tick day time - handler.OnTimeUpdate(worldAge, timeOfDay); + if (protocolVersion >= MC_26_1_Version) + { + var worldAge = dataTypes.ReadNextLong(packetData); + long timeOfDay = 0; + var clockCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < clockCount; i++) + { + dataTypes.ReadNextVarInt(packetData); // clock holder id + var totalTicks = dataTypes.ReadNextVarLong(packetData); + dataTypes.ReadNextFloat(packetData); // partialTick + dataTypes.ReadNextFloat(packetData); // rate + if (i == 0) + timeOfDay = totalTicks; + } + handler.OnTimeUpdate(worldAge, timeOfDay); + } + else + { + var worldAge = dataTypes.ReadNextLong(packetData); + var timeOfDay = dataTypes.ReadNextLong(packetData); + if (protocolVersion >= MC_1_21_2_Version) + dataTypes.ReadNextBool(packetData); // Tick day time + handler.OnTimeUpdate(worldAge, timeOfDay); + } break; case PacketTypesIn.EntityTeleport: if (handler.GetEntityHandlingEnabled()) @@ -3164,8 +3189,8 @@ namespace MinecraftClient.Protocol.Handlers { // 1. Send the handshake packet SendPacket(0x00, dataTypes.ConcatBytes( - // Protocol Version - DataTypes.GetVarInt(protocolVersion), + // Protocol Version (use raw version for snapshot/RC servers) + DataTypes.GetVarInt(rawProtocolVersion), // Server Address dataTypes.GetString(pForge.GetServerAddress(handler.GetServerHost())), diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs index 09f99cf5..33ea43af 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs @@ -185,6 +185,9 @@ namespace MinecraftClient.Protocol.Handlers // Non-air block count inside chunk section, for lighting purposes int blockCnt = dataTypes.ReadNextShort(cache); + if (protocolversion >= Protocol18Handler.MC_26_1_Version) + dataTypes.ReadNextShort(cache); // Fluid count (26.1+) + // Read Block states (Type: Paletted Container) Chunk? chunk = ReadBlockStatesField(cache); diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index fa1700cc..ae1abd60 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -145,20 +145,22 @@ namespace MinecraftClient.Protocol public static IMinecraftCom GetProtocolHandler(TcpClient client, int protocolVersion, ForgeInfo? forgeInfo, IMinecraftComHandler handler) { + int normalizedVersion = NormalizeSnapshotProtocol(protocolVersion); + int[] suppoertedVersionsProtocol16 = { 51, 60, 61, 72, 73, 74, 78 }; - if (Array.IndexOf(suppoertedVersionsProtocol16, protocolVersion) > -1) - return new Protocol16Handler(client, protocolVersion, handler); + if (Array.IndexOf(suppoertedVersionsProtocol16, normalizedVersion) > -1) + return new Protocol16Handler(client, normalizedVersion, handler); int[] suppoertedVersionsProtocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, - 769, 770, 771, 772, 773, 774 + 769, 770, 771, 772, 773, 774, 775 }; - if (Array.IndexOf(suppoertedVersionsProtocol18, protocolVersion) > -1) - return new Protocol18Handler(client, protocolVersion, handler, forgeInfo); + if (Array.IndexOf(suppoertedVersionsProtocol18, normalizedVersion) > -1) + return new Protocol18Handler(client, normalizedVersion, handler, forgeInfo, protocolVersion); throw new NotSupportedException(string.Format(Translations.exception_version_unsupport, protocolVersion)); } @@ -370,6 +372,8 @@ namespace MinecraftClient.Protocol return 773; case "1.21.11": return 774; + case "26.1": + return 775; default: return 0; } @@ -458,10 +462,27 @@ namespace MinecraftClient.Protocol 772 => "1.21.7", 773 => "1.21.9", 774 => "1.21.11", + 775 => "26.1", _ => "0.0" }; } + /// + /// Normalize snapshot/pre-release protocol numbers (0x40000000 | data_version) to the + /// corresponding release protocol number. Unknown snapshot versions pass through unchanged. + /// + public static int NormalizeSnapshotProtocol(int protocol) + { + if ((protocol & 0x40000000) == 0) + return protocol; + + return protocol switch + { + 0x4000012E => 775, // 26.1-rc-2 → 26.1 + _ => protocol + }; + } + /// /// Check if we can force-enable Forge support for a Minecraft version without using server Ping /// From 9613e0df51f14c8726d4a989792e14a86fed739b Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 14:29:02 +0100 Subject: [PATCH 104/484] Added AI Assisted development documentation. Updated Vuepress to the latest version. Added SEO and Sitemap plugins to Vuepress. --- .gitignore | 2 + docs/.vuepress/client.ts | 66 + docs/.vuepress/config.ts | 78 +- docs/.vuepress/configs/l10n_configs/en.ts | 1 + docs/guide/README.md | 31 +- docs/guide/ai-assisted-development.md | 714 +++ docs/guide/contibuting.md | 2 + docs/package.json | 21 +- docs/yarn.lock | 6502 ++++++++++++++------- tools/mcc-env.sh | 2 +- tools/pull-translations.sh | 66 + 11 files changed, 5381 insertions(+), 2104 deletions(-) create mode 100644 docs/.vuepress/client.ts create mode 100644 docs/guide/ai-assisted-development.md create mode 100755 tools/pull-translations.sh diff --git a/.gitignore b/.gitignore index df83a1de..fe783fa4 100644 --- a/.gitignore +++ b/.gitignore @@ -409,6 +409,8 @@ FodyWeavers.xsd # docs !/docs/.vuepress +/docs/.vuepress/.cache +/docs/.vuepress/.temp /docs/.vuepress/dist # translations diff --git a/docs/.vuepress/client.ts b/docs/.vuepress/client.ts new file mode 100644 index 00000000..4cbef77c --- /dev/null +++ b/docs/.vuepress/client.ts @@ -0,0 +1,66 @@ +import { computed, defineComponent, h } from 'vue' +import { + defineClientConfig, + resolveRouteFullPath, + useRoute, + useRouter, +} from 'vuepress/client' + +const guardEvent = (event: MouseEvent): boolean => { + if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) return false + if (event.defaultPrevented) return false + if (event.button !== undefined && event.button !== 0) return false + + if (event.currentTarget instanceof Element) { + const target = event.currentTarget.getAttribute('target') + if (target?.match(/\b_blank\b/i)) return false + } + + event.preventDefault() + return true +} + +const SafeRouteLink = defineComponent({ + name: 'RouteLink', + props: { + to: { + type: String, + required: true, + }, + active: Boolean, + activeClass: { + type: String, + default: 'route-link-active', + }, + }, + setup(props, { slots }) { + const router = useRouter() + const route = useRoute() + const path = computed(() => + props.to.startsWith('#') || props.to.startsWith('?') + ? props.to + : `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).substring(1)}`, + ) + + return () => + h( + 'a', + { + class: ['route-link', { [props.activeClass]: props.active }], + href: path.value, + onClick: (event: MouseEvent) => { + if (guardEvent(event)) { + void router.push(props.to).catch(() => {}) + } + }, + }, + slots.default?.() ?? [], + ) + }, +}) + +export default defineClientConfig({ + enhance({ app }) { + app.component('RouteLink', SafeRouteLink) + }, +}) diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index 574c87d8..d9e3a930 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -1,17 +1,17 @@ import process from 'node:process' + import { viteBundler } from '@vuepress/bundler-vite' import { webpackBundler } from '@vuepress/bundler-webpack' -import { defineUserConfig } from '@vuepress/cli' +import { markdownChartPlugin } from '@vuepress/plugin-markdown-chart' +import { redirectPlugin } from '@vuepress/plugin-redirect' +import { searchPlugin } from '@vuepress/plugin-search' import { shikiPlugin } from '@vuepress/plugin-shiki' import { defaultTheme } from '@vuepress/theme-default' -import { getDirname, path } from '@vuepress/utils' -import { searchPlugin } from "@vuepress/plugin-search"; -import { redirectPlugin } from "vuepress-plugin-redirect"; +import { defineUserConfig } from 'vuepress' import { headConfig } from './configs/head.js' import { mainConfig, defaultThemeConfig } from './configs/locales_config.js' -const __dirname = getDirname(import.meta.url) const isProd = process.env.NODE_ENV === 'production' export default defineUserConfig({ @@ -29,8 +29,9 @@ export default defineUserConfig({ // configure default theme theme: defaultTheme({ - logo: "/images/MCC_logo.png", - repo: "MCCTeam/Minecraft-Console-Client", + hostname: 'https://mccteam.github.io', + logo: '/images/MCC_logo.png', + repo: 'MCCTeam/Minecraft-Console-Client', docsBranch: 'master', docsDir: 'docs', @@ -42,55 +43,58 @@ export default defineUserConfig({ git: isProd, // use shiki plugin in production mode instead prismjs: !isProd, + seo: isProd + ? { + canonical: 'https://mccteam.github.io/', + } + : false, + sitemap: isProd + ? { + changefreq: 'weekly', + } + : false, }, }), - // configure markdown - markdown: { - importCode: { - handleImportPath: (str) => - str.replace(/^@vuepress/, path.resolve(__dirname, '../../ecosystem')), - }, - }, - // use plugins plugins: [ redirectPlugin({ - hostname: "https://mccteam.github.io", + hostname: 'https://mccteam.github.io', config: { - "/r/entity.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/EntityType.cs", - "/r/entity/index.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/EntityType.cs", + '/r/entity.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/EntityType.cs', + '/r/entity/index.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/EntityType.cs', - "/r/item.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs", - "/r/item/index.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs", + '/r/item.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs', + '/r/item/index.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Inventory/ItemType.cs', - "/r/block.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/Material.cs", - "/r/block/index.html": "https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/Material.cs", + '/r/block.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/Material.cs', + '/r/block/index.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Mapping/Material.cs', - "/r/l-code.html": "https://github.com/MCCTeam/Minecraft-Console-Client/discussions/2239#discussion-4447461", - "/r/l-code/index.html": "https://github.com/MCCTeam/Minecraft-Console-Client/discussions/2239#discussion-4447461", + '/r/l-code.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/discussions/2239#discussion-4447461', + '/r/l-code/index.html': 'https://github.com/MCCTeam/Minecraft-Console-Client/discussions/2239#discussion-4447461', - "/r/dc-fmt.html": "https://www.writebots.com/discord-text-formatting/", - "/r/dc-fmt/index.html": "https://www.writebots.com/discord-text-formatting/", + '/r/dc-fmt.html': 'https://www.writebots.com/discord-text-formatting/', + '/r/dc-fmt/index.html': 'https://www.writebots.com/discord-text-formatting/', - "/r/tg-fmt.html": "https://sendpulse.com/blog/telegram-text-formatting", - "/r/tg-fmt/index.html": "https://sendpulse.com/blog/telegram-text-formatting", + '/r/tg-fmt.html': 'https://sendpulse.com/blog/telegram-text-formatting', + '/r/tg-fmt/index.html': 'https://sendpulse.com/blog/telegram-text-formatting', }, }), - // only enable shiki plugin in production mode - isProd ? shikiPlugin({ theme: 'dark-plus' }) : [], + ...(isProd ? [shikiPlugin({ theme: 'dark-plus' })] : []), searchPlugin({ - maxSuggestions: 15, - hotKeys: ["s", "/"], - locales: { - "/": { - placeholder: "Search", - }, + maxSuggestions: 15, + hotKeys: ['s', '/'], + locales: { + '/': { + placeholder: 'Search', }, + }, }), - 'vuepress-plugin-mermaidjs' + markdownChartPlugin({ + mermaid: true, + }), ], }) diff --git a/docs/.vuepress/configs/l10n_configs/en.ts b/docs/.vuepress/configs/l10n_configs/en.ts index fa0c6533..795a765b 100644 --- a/docs/.vuepress/configs/l10n_configs/en.ts +++ b/docs/.vuepress/configs/l10n_configs/en.ts @@ -62,6 +62,7 @@ export const defaultThemeConfig_en: DefaultThemeLocaleData = { "/guide/creating-text-script.md", "/guide/chat-bots.md", "/guide/creating-bots.md", + "/guide/ai-assisted-development.md", "/guide/contibuting.md" ], diff --git a/docs/guide/README.md b/docs/guide/README.md index 3c527887..0ed618bc 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -4,16 +4,23 @@ title: About & Features # Introduction -- [About](#about) -- [Quick Intro (YouTube Videos)](#quick-intro) -- [Features](#features) -- [Why Minecraft Console Client?](#why-minecraft-console-client) -- [Getting Help](#getting-help) -- [Submitting a bug report or an idea/feature-request](#bugs-ideas-feature-requests) -- [Important notes on some features](#notes-on-some-features) -- [Credits](#credits) -- [Disclaimer](#disclaimer) -- [License](#license) +- [Introduction](#introduction) + - [About](#about) + - [Features](#features) + - [Why Minecraft Console Client?](#why-minecraft-console-client) + - [Quick Intro](#quick-intro) + - [The list of the tutorials:](#the-list-of-the-tutorials) + - [Getting Help](#getting-help) + - [Before getting help](#before-getting-help) + - [Bugs, Ideas, Feature Requests](#bugs-ideas-feature-requests) + - [Before submitting](#before-submitting) + - [AI-Assisted Development](#ai-assisted-development) + - [Notes on some features](#notes-on-some-features) + - [Inventory, Terrain and Entity Handling](#inventory-terrain-and-entity-handling) + - [Path-Finding and Physics](#path-finding-and-physics) + - [Credits](#credits) + - [Disclaimer](#disclaimer) + - [License](#license) ## About @@ -107,6 +114,10 @@ If you're reporting a bug, please be descriptive as much as possible, try to exp - **Please use the search option here or in the `Issues` section and read the documentation so we avoid duplicate questions/ideas/reports. Thank you!** - **Please be kind, patient and respect others. Thank you!** +## AI-Assisted Development + +If you want the repeatable agent workflow used by maintainers, start with [AI-Assisted Development](ai-assisted-development.md). + ## Notes on some features ### Inventory, Terrain and Entity Handling diff --git a/docs/guide/ai-assisted-development.md b/docs/guide/ai-assisted-development.md new file mode 100644 index 00000000..b7785c19 --- /dev/null +++ b/docs/guide/ai-assisted-development.md @@ -0,0 +1,714 @@ +--- +title: AI-Assisted Development +--- + +# AI-Assisted Development + +This guide documents the MCC AI-assisted development workflow as a real working loop, not a patch generator running on guesses. The goal is to give the agent an environment it can drive on its own: build MCC, start a local server, send commands, inspect logs, and repeat. Once that loop is in place, iteration is faster and regressions are easier to catch. + +The practical goal is a closed loop: + +```mermaid +flowchart LR + edit[Edit] --> build[Build] + build --> run[Run] + run --> test[Test] + test --> inspect[Inspect] + inspect --> repeat[Repeat] + repeat --> edit +``` + +

Warning

+ +If you develop on Windows, use WSL2. This workflow is built around Unix-style shells, `tmux`, `python3`, and shell helper functions. Do not try to run the full AI workflow from plain PowerShell or CMD. + +
+ +## Index + +- [What This Workflow Covers](#what-this-workflow-covers) +- [Setup](#setup) +- [How The Harness Works](#how-the-harness-works) +- [Repository Tools](#repository-tools) +- [Skills](#skills) +- [Standard Development Loop](#standard-development-loop) +- [Testing And Validation](#testing-and-validation) +- [Version Adaptation Notes](#version-adaptation-notes) +- [Example Workflows](#example-workflows) + +## What This Workflow Covers + +This is the workflow for: + +- local MCC development +- local offline server testing +- AI-assisted debugging +- bot authoring +- protocol and version adaptation work +- documentation work that should still follow the same disciplined loop + +It is built around two layers: + +- repo tools in `tools/`, which do the actual work +- AI skills in `.skills/`, which tell the agent when and how to use those tools + +## Setup + +You only do most of this once. + +
+Windows: install WSL2 first + +Open PowerShell as Administrator and run: + +```powershell +wsl --install +``` + +If WSL is already enabled and you specifically want Ubuntu, use: + +```powershell +wsl --install -d Ubuntu +``` + +If the install stalls at `0.0%`, use: + +```powershell +wsl --install --web-download -d Ubuntu +``` + +Restart if Windows asks for it, then open the Ubuntu shell and finish the Linux user setup there. + +From this point on, do MCC development inside WSL. That includes cloning the repo, building, running servers, and using AI agent tooling. + +Reference: [Microsoft WSL installation guide](https://learn.microsoft.com/windows/wsl/install) + +
+ +
+Linux and macOS: use Bash or Zsh + +Bash and Zsh both work with MCC's helper scripts. + +Check your current shell: + +```bash +echo $SHELL +``` + +Notes: + +- Bash is the normal baseline on Linux. +- Zsh is the default interactive shell on modern macOS. +- The helper script `tools/mcc-env.sh` can be sourced from either `~/.bashrc` or `~/.zshrc`. + +
+ +
+Install Git + +Ubuntu, Debian, and derivatives: + +```bash +sudo apt update +sudo apt install git +``` + +Arch Linux: + +```bash +sudo pacman -S git +``` + +macOS with Homebrew: + +```bash +brew install git +``` + +Verify: + +```bash +git --version +``` + +Reference: [Git downloads](https://git-scm.com/downloads) + +
+ +
+Install .NET SDK 10 + +MCC currently builds on `.NET 10`. You need the SDK, not just the runtime. + +Supported Ubuntu releases and Ubuntu-based distros with the correct feed enabled: + +```bash +sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0 +``` + +Debian 12: + +```bash +wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +sudo dpkg -i packages-microsoft-prod.deb +rm packages-microsoft-prod.deb +sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0 +``` + +Debian 13: + +```bash +wget https://packages.microsoft.com/config/debian/13/packages-microsoft-prod.deb -O packages-microsoft-prod.deb +sudo dpkg -i packages-microsoft-prod.deb +rm packages-microsoft-prod.deb +sudo apt-get update && sudo apt-get install -y dotnet-sdk-10.0 +``` + +Arch Linux: + +```bash +sudo pacman -S dotnet-sdk +``` + +macOS with Homebrew: + +```bash +brew install --cask dotnet-sdk +``` + +Verify: + +```bash +dotnet --version +``` + +References: + +- [Install .NET on Ubuntu](https://learn.microsoft.com/dotnet/core/install/linux-ubuntu) +- [Install .NET on Debian](https://learn.microsoft.com/dotnet/core/install/linux-debian) +- [Homebrew `dotnet-sdk` cask](https://formulae.brew.sh/cask/dotnet-sdk) + +
+ +
+Install Java 21 + +The local server harness uses `java` directly, so Java 21 needs to be on your `PATH`. + +Ubuntu and Ubuntu-based distros: + +```bash +sudo apt update +sudo apt install openjdk-21-jdk +``` + +Debian: + +Package availability varies by Debian release. If `openjdk-21-jdk` is not available in your configured repositories, install a current JDK 21 build from your preferred vendor instead of forcing a stale package name. + +Arch Linux: + +```bash +sudo pacman -S jdk21-openjdk +``` + +macOS with Homebrew: + +```bash +brew install openjdk@21 +sudo ln -sfn "$(brew --prefix openjdk@21)/libexec/openjdk.jdk" /Library/Java/JavaVirtualMachines/openjdk-21.jdk +``` + +Homebrew marks `openjdk@21` as keg-only, which is why the symlink step matters. + +Verify: + +```bash +java -version +``` + +References: + +- [Ubuntu `openjdk-21-jdk` package](https://packages.ubuntu.com/noble/openjdk-21-jdk) +- [Arch `jdk21-openjdk` package](https://archlinux.org/packages/extra/x86_64/jdk21-openjdk/) +- [Homebrew `openjdk@21` formula](https://formulae.brew.sh/formula/openjdk@21) + +
+ +
+Install Python 3 + +Python 3 is required for the RCON helper and the version-adaptation tools. + +Ubuntu, Debian, and derivatives: + +```bash +sudo apt update +sudo apt install python3 +``` + +Arch Linux: + +```bash +sudo pacman -S python +``` + +macOS with Homebrew: + +```bash +brew install python@3.14 +``` + +Homebrew currently provides Python 3 through the `python@3.14` formula, and aliases it as `python` and `python3`. + +Verify: + +```bash +python3 --version +``` + +References: + +- [Ubuntu `python3` package](https://packages.ubuntu.com/noble/python/python3) +- [Arch `python` package](https://archlinux.org/packages/core/x86_64/python/) +- [Homebrew Python formula](https://formulae.brew.sh/formula/python@3.14) + +
+ +
+Install tmux + +The local Minecraft server runs in a `tmux` session so it can keep running while the agent builds and restarts MCC. + +Ubuntu, Debian, and derivatives: + +```bash +sudo apt update +sudo apt install tmux +``` + +Arch Linux: + +```bash +sudo pacman -S tmux +``` + +macOS with Homebrew: + +```bash +brew install tmux +``` + +Verify: + +```bash +tmux -V +``` + +
+ +
+Clone the repo and initialize submodules + +Clone with submodules in one step: + +```bash +git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive +``` + +If you already cloned it without submodules: + +```bash +git submodule update --init --recursive +``` + +
+ +
+Prepare a server version and decompiled source + +From the repo root, use the decompiler helper to download the official server jar and create the decompiled source tree: + +```bash +tools/decompile.sh --version 1.20.6 +``` + +That creates the paths used by the harness and the version-adaptation workflow: + +- `MinecraftOfficial/downloads/1.20.6/server.jar` +- `MinecraftOfficial/1.20.6-decompiled/` + +If you are doing protocol work, this step is not optional. + +
+ +
+Load the MCC shell helpers in Bash + +Add this line to `~/.bashrc`: + +```bash +source "$HOME/Minecraft/Minecraft-Console-Client/tools/mcc-env.sh" +``` + +Reload the shell: + +```bash +source ~/.bashrc +``` + +This gives you the helper functions used by the workflow: + +- `mc-start` +- `mc-stop` +- `mc-cmd` +- `mc-log` +- `mc-rcon` +- `mcc-build` +- `mcc-run` +- `mcc-cmd` +- `mcc-kill` +- `mcc-reload` + +
+ +
+Load the MCC shell helpers in Zsh + +Add this line to `~/.zshrc`: + +```bash +source "$HOME/Minecraft/Minecraft-Console-Client/tools/mcc-env.sh" +``` + +Reload the shell: + +```bash +source ~/.zshrc +``` + +If your clone lives somewhere else, update the path in the `source` line. + +
+ +
+Verify the environment + +Run these checks: + +```bash +git --version +dotnet --version +java -version +python3 --version +tmux -V +``` + +Then make sure the helper functions are loaded: + +```bash +type mc-start +type mcc-build +type mcc-run +``` + +
+ +## How The Harness Works + +AI agents do not get a rich interactive terminal in the same way a human does. That is why this workflow uses a harness instead of relying on live keyboard input. + +The moving parts are: + +- a local Minecraft server running in `tmux` +- `mc-rcon` for server-side commands such as `/op`, `/give`, `/summon`, or gamerule setup +- MCC started with `MCC_FILE_INPUT=1` +- `FileInputBot`, which watches `mcc_input.txt` and turns file lines into MCC commands or server chat +- logs from MCC and the local server, which the agent can inspect between runs + +The result is simple: the agent can change code, rebuild, start the app, inject commands, and read the result without waiting for a human to sit in the terminal. + +## Repository Tools + +These are the repo-level tools that make the workflow practical. + +| Path | Purpose | +| --- | --- | +| `tools/mcc-env.sh` | Loads the shell helper functions used for the normal loop. | +| `tools/start-server.sh` | Starts a local Minecraft server in a named `tmux` session with a FIFO for stdin. | +| `tools/mc-rcon.sh` | Sends RCON commands to the local server using `python3`. | +| `tools/decompile.sh` | Downloads `MinecraftDecompiler.jar` if needed, decompiles the requested Minecraft version, and fetches `server.jar` for server-side work. | +| `tools/diff_registries.py` | Compares registries between two Minecraft versions to show which palettes need updates. | +| `tools/gen_item_palette.py` | Generates item palette source from decompiled or reported registry data. | +| `tools/gen_block_palette.py` | Generates block palette source from authoritative block reports. | +| `tools/gen_entity_palette.py` | Generates entity palette source from registry reports. | +| `tools/gen_entity_metadata_palette.py` | Generates entity metadata palette source from serializer registration order. | +| `tools/gen_command_argument_registry.py` | Helps update modern declare-commands registry order. | +| `tools/gen_block_shapes.py` | Downloads and compacts collision shape data for physics support. | + +There is one more piece worth calling out: + +- `MinecraftClient/ChatBots/FileInputBot.cs` is what makes file-driven command injection possible. +- It is loaded when `MCC_FILE_INPUT=1` is set. +- `mcc-run` in `tools/mcc-env.sh` already sets that flag for you. + +## Skills + +The tools above do the work. The skills in `.skills/` tell the AI when to use them and what good output looks like. + +| Skill | What it is for | Notes | +| --- | --- | --- | +| `mcc-dev-workflow` | The default build, run, debug, and local server loop. | This is the skill to use for most day-to-day MCC debugging. It assumes WSL, `tmux`, Java, and the local harness. | +| `mcc-integration-testing` | Repeatable end-to-end testing against a local offline server. | This skill bundles its own scripts under `.skills/mcc-integration-testing/scripts/`. Those are skill resources, not top-level repo scripts. | +| `mcc-version-adaptation` | Protocol and palette updates for new Minecraft versions. | Use this when routing, registries, metadata, palettes, or structured components change. | +| `mcc-chatbot-authoring` | Authoring or repairing built-in bots and standalone `/script` bots. | This skill bundles references and templates under `.skills/mcc-chatbot-authoring/`. It defaults to standalone `/script` bots unless built-in wiring is requested. | +| `csharp-best-practices` | C# 12 / .NET 10 coding guidance for this repo. | Use it whenever the change touches MCC runtime code. | +| `humanizer` | Documentation and prose cleanup. | Use it for docs, guides, release notes, and anything that starts sounding machine-written. | +| `skill-creator` | Creating or evolving skills themselves. | This is for improving the AI workflow, not for normal MCC feature work. | + +The important distinction is this: + +- repo tools are executable scripts and source files +- skills are instructions, references, templates, and workflow constraints for the AI + +Some skills also carry their own bundled resources: + +- `mcc-integration-testing` bundles scripts and a command matrix reference +- `mcc-chatbot-authoring` bundles references and bot templates +- `skill-creator` bundles scripts, eval tooling, and reviewer assets + +## Standard Development Loop + +This is the core loop you should expect an agent to follow. + +### 1. Start the local server + +```bash +mc-start 1.20.6 +``` + +Check the recent server output: + +```bash +mc-log 1.20.6 +``` + +### 2. Build MCC + +```bash +mcc-build +``` + +### 3. Run MCC with file input enabled + +```bash +mcc-run +``` + +The raw form looks like this: + +```bash +MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release -- CursorBot - localhost:25565 +``` + +### 4. Set up server state through RCON + +Examples: + +```bash +mc-rcon "op CursorBot" +mc-rcon "gamerule sendCommandFeedback true" +mc-rcon "give CursorBot diamond_sword 1" +mc-rcon "summon minecraft:armor_stand ~ ~ ~" +``` + +### 5. Drive MCC through `mcc_input.txt` + +Examples: + +```bash +mcc-cmd "inventory player list" +mcc-cmd "entity" +mcc-cmd "/gamemode creative" +``` + +Behavior: + +- lines starting with `/` are sent as server commands or chat +- lines without `/` are treated as MCC internal commands first +- if a line is not an MCC internal command, it falls back to normal chat sending + +### 6. Inspect the result + +Read the MCC output and the server log, decide what changed, and either keep iterating or stop. + +### 7. Rebuild and restart fast + +```bash +mcc-reload +``` + +That is the usual tight loop for regression work. + +## Testing And Validation + +There are two main testing styles in this workflow. + +### Manual validation + +This is enough for smaller changes: + +- join the local server +- grant operator privileges with `mc-rcon` +- run internal MCC commands through `mcc-cmd` +- trigger gameplay or server state changes through `mc-rcon` +- inspect logs for parsing errors, disconnects, or wrong output + +Typical manual checks: + +- inventory listing and creative item injection +- entity tracking after `summon` +- terrain and chunk handling after join +- chat and command flow +- explosion, particle, and sound events + +### Scripted full-spectrum testing + +The `mcc-integration-testing` skill goes further. It bundles its own scripts under `.skills/mcc-integration-testing/scripts/` and expects the shell helpers from `~/.zshrc`. + +Treat those scripts as skill-owned resources. Read the skill before running them directly, and do not assume they behave like top-level repo tools. + +That skill is designed for repeatable offline validation of: + +- chat +- slash commands +- MCC internal commands +- inventory handling +- entity handling +- particles and sounds +- TNT and explosion handling + +Server settings that matter for AI-driven offline testing: + +- `eula=true` +- `online-mode=false` +- `enforce-secure-profile=false` +- `enable-rcon=true` +- `rcon.password=test123` + +If those are wrong, the loop gets noisy fast. + +## Version Adaptation Notes + +Version work needs a stricter process than normal bug fixing. + +The important rule is simple: + +- for newer versions, especially `1.21.9+`, use server data reports as the authority for items and blocks +- use decompiled source for implementation details, field order, codecs, and serializer logic +- do not stop at a palette diff; finish with a build and a live server test + +The usual order is: + +1. `tools/decompile.sh --version ` +2. generate server reports from `server.jar` +3. run `tools/diff_registries.py` +4. regenerate the palettes that actually changed +5. update version routing and packet handling +6. build MCC +7. test against the real target version + +That is exactly the sort of work `mcc-version-adaptation` is meant to guide. + +## Example Workflows + +These are four common patterns this guide is meant to support. + +### Example 1: Debug a runtime regression + +Use skills: + +- `mcc-dev-workflow` +- `csharp-best-practices` + +Typical loop: + +```bash +mc-start 1.20.6 +mcc-build +mcc-run +mc-rcon "op CursorBot" +mcc-cmd "inventory player list" +mcc-cmd "entity" +``` + +Then inspect the MCC output, patch the code, and use: + +```bash +mcc-reload +``` + +### Example 2: Build or repair a bot + +Use skills: + +- `mcc-chatbot-authoring` +- `csharp-best-practices` +- `mcc-dev-workflow` + +Typical flow: + +1. Decide whether this should be a standalone `/script` bot or a built-in bot. +2. Use the authoring skill's references and templates. +3. Build MCC. +4. Start a local server and join it. +5. Test the bot behavior through live commands, chat, or event-driven actions. +6. Make sure cleanup paths such as `OnUnload()` are correct. + +For standalone script work, the skill defaults to `/script` unless built-in repo wiring is explicitly needed. + +### Example 3: Adapt MCC to a new Minecraft version + +Use skills: + +- `mcc-version-adaptation` +- `mcc-dev-workflow` +- `mcc-integration-testing` + +Typical flow: + +```bash +tools/decompile.sh --version 1.21.11 +``` + +Generate server reports: + +```bash +cd /tmp +java -DbundlerMainClass=net.minecraft.data.Main \ + -jar "$MCC_SERVERS/1.21.11/server.jar" \ + --reports --output /tmp/mc_reports +``` + +Run the registry diff: + +```bash +python3 tools/diff_registries.py 1.21.10 1.21.11 --registry /tmp/mc_reports/reports/registries.json +``` + +Then regenerate the palettes that changed, update routing, build MCC, start a local server for the target version, and run live validation before calling the work done. + +### Example 4: Write or update documentation for the workflow itself + +Use skills: + +- `humanizer` +- `skill-creator`, if you are changing the skills rather than just the docs + +Typical flow: + +1. Re-read the relevant skill files and repo tools. +2. Update the guide so the written process matches the real process. +3. Keep the instructions concrete enough that another contributor can follow them without guessing. +4. If the workflow itself changed, update the relevant skill too instead of leaving the docs ahead of the automation. diff --git a/docs/guide/contibuting.md b/docs/guide/contibuting.md index 5d4c6711..c89c5b69 100644 --- a/docs/guide/contibuting.md +++ b/docs/guide/contibuting.md @@ -6,6 +6,8 @@ title: Contributing At this moment this page needs to be created. +If you are working with SWE AI agents, start with [AI-Assisted Development](ai-assisted-development.md). It covers the shell setup, local server loop, and the skills in `.skills/`. + For now you can use our article from the [Git Hub repository Wiki](https://github.com/MCCTeam/Minecraft-Console-Client/wiki/Update-console-client-to-new-version) written by [ReinforceZwei](https://github.com/ReinforceZwei). ## Translations diff --git a/docs/package.json b/docs/package.json index b032f2eb..f80de657 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,18 +7,23 @@ "license": "CDDL-1.0", "private": false, "scripts": { - "docs:build": "vuepress-cli build --clean-cache", + "docs:build": "vuepress build . --clean-cache", "docs:clean": "rimraf .vuepress/.temp .vuepress/.cache .vuepress/dist", - "docs:dev": "vuepress-cli dev --clean-cache", + "docs:dev": "vuepress dev . --clean-cache", "docs:serve": "anywhere -s -h localhost -d .vuepress/dist" }, "devDependencies": { - "@vuepress/bundler-webpack": "^2.0.0-beta.53", - "@vuepress/plugin-search": "^2.0.0-beta.53", - "@vuepress/plugin-shiki": "^2.0.0-beta.53", - "vuepress": "^2.0.0-beta.53", - "vuepress-plugin-mermaidjs": "2.0.0-beta.2", - "vuepress-plugin-redirect": "^2.0.0-beta.120" + "@vuepress/bundler-vite": "2.0.0-rc.26", + "@vuepress/bundler-webpack": "2.0.0-rc.26", + "@vuepress/plugin-markdown-chart": "2.0.0-rc.125", + "@vuepress/plugin-redirect": "2.0.0-rc.125", + "@vuepress/plugin-search": "2.0.0-rc.125", + "@vuepress/plugin-shiki": "2.0.0-rc.125", + "@vuepress/theme-default": "2.0.0-rc.125", + "mermaid": "11.13.0", + "sass-embedded": "1.98.0", + "sass-loader": "16.0.7", + "vuepress": "2.0.0-rc.26" }, "dependencies": { "anywhere": "^1.6.0" diff --git a/docs/yarn.lock b/docs/yarn.lock index 165da9a5..80376ff9 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2,6 +2,14 @@ # yarn lockfile v1 +"@antfu/install-pkg@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz#78fa036be1a6081b5a77a5cf59f50c7752b6ba26" + integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ== + dependencies: + package-manager-detector "^1.3.0" + tinyexec "^1.0.1" + "@babel/code-frame@^7.0.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" @@ -9,11 +17,21 @@ dependencies: "@babel/highlight" "^7.18.6" +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.18.6": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + "@babel/highlight@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" @@ -23,25 +41,364 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.4": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.1.tgz#3e045a92f7b4623cafc2425eddcb8cf2e54f9cc5" - integrity sha512-hp0AYxaZJhxULfM1zyp7Wgr+pSUKBcP3M+PHnSzWGdXOzg/kHWIgiUWARvubhUKGOEw3xqY4x+lyZ9ytBVcELw== +"@babel/parser@^7.29.0": + version "7.29.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1" + integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA== + dependencies: + "@babel/types" "^7.29.0" -"@braintree/sanitize-url@^3.1.0": +"@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + +"@braintree/sanitize-url@^7.1.1": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz#ca2035b0fefe956a8676ff0c69af73e605fcd81f" + integrity sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA== + +"@bufbuild/protobuf@^2.5.0": + version "2.11.0" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.11.0.tgz#3ec3985c9074b23aea337957225fe15a0e845f8e" + integrity sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ== + +"@chevrotain/cst-dts-gen@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz#501ea6177fa21cc57264c792ef5cc3d0bb9410fd" + integrity sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q== + dependencies: + "@chevrotain/gast" "11.1.2" + "@chevrotain/types" "11.1.2" + lodash-es "4.17.23" + +"@chevrotain/gast@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@chevrotain/gast/-/gast-11.1.2.tgz#213393f2b5842e8bf13369bdc042c7fd18201af2" + integrity sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g== + dependencies: + "@chevrotain/types" "11.1.2" + lodash-es "4.17.23" + +"@chevrotain/regexp-to-ast@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz#6aeb0b3fd5e3f220b063b3d856fbbaed582e4cfa" + integrity sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw== + +"@chevrotain/types@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@chevrotain/types/-/types-11.1.2.tgz#e83a1a2704f0c5e49e7592b214031a0f4a34d7e5" + integrity sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw== + +"@chevrotain/utils@11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@chevrotain/utils/-/utils-11.1.2.tgz#a0b13637acc0a2933d8a2edeba4bf1da789c565d" + integrity sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA== + +"@esbuild/aix-ppc64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz#80fcbe36130e58b7670511e888b8e88a259ed76c" + integrity sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA== + +"@esbuild/aix-ppc64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz#4c585002f7ad694d38fe0e8cbf5cfd939ccff327" + integrity sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q== + +"@esbuild/android-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz#8aa4965f8d0a7982dc21734bf6601323a66da752" + integrity sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg== + +"@esbuild/android-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz#7625d0952c3b402d3ede203a16c9f2b78f8a4827" + integrity sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw== + +"@esbuild/android-arm@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz#300712101f7f50f1d2627a162e6e09b109b6767a" + integrity sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg== + +"@esbuild/android-arm@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.4.tgz#9a0cf1d12997ec46dddfb32ce67e9bca842381ac" + integrity sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ== + +"@esbuild/android-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz#87dfb27161202bdc958ef48bb61b09c758faee16" + integrity sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg== + +"@esbuild/android-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.4.tgz#06e1fdc6283fccd6bc6aadd6754afce6cf96f42e" + integrity sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw== + +"@esbuild/darwin-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz#79197898ec1ff745d21c071e1c7cc3c802f0c1fd" + integrity sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg== + +"@esbuild/darwin-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz#6c550ee6c0273bcb0fac244478ff727c26755d80" + integrity sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ== + +"@esbuild/darwin-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz#146400a8562133f45c4d2eadcf37ddd09718079e" + integrity sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA== + +"@esbuild/darwin-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz#ed7a125e9f25ce0091b9aff783ee943f6ba6cb86" + integrity sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw== + +"@esbuild/freebsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz#1c5f9ba7206e158fd2b24c59fa2d2c8bb47ca0fe" + integrity sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg== + +"@esbuild/freebsd-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz#597dc8e7161dba71db4c1656131c1f1e9d7660c6" + integrity sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw== + +"@esbuild/freebsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz#ea631f4a36beaac4b9279fa0fcc6ca29eaeeb2b3" + integrity sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ== + +"@esbuild/freebsd-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz#ea171f9f4f00efaa8e9d3fe8baa1b75d757d1b36" + integrity sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ== + +"@esbuild/linux-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz#e1066bce58394f1b1141deec8557a5f0a22f5977" + integrity sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ== + +"@esbuild/linux-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz#e52d57f202369386e6dbcb3370a17a0491ab1464" + integrity sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA== + +"@esbuild/linux-arm@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz#452cd66b20932d08bdc53a8b61c0e30baf4348b9" + integrity sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw== + +"@esbuild/linux-arm@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz#5e0c0b634908adbce0a02cebeba8b3acac263fb6" + integrity sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg== + +"@esbuild/linux-ia32@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz#b24f8acc45bcf54192c7f2f3be1b53e6551eafe0" + integrity sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA== + +"@esbuild/linux-ia32@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz#5f90f01f131652473ec06b038a14c49683e14ec7" + integrity sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA== + +"@esbuild/linux-loong64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz#f9cfffa7fc8322571fbc4c8b3268caf15bd81ad0" + integrity sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng== + +"@esbuild/linux-loong64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz#63bacffdb99574c9318f9afbd0dd4fff76a837e3" + integrity sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA== + +"@esbuild/linux-mips64el@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz#575a14bd74644ffab891adc7d7e60d275296f2cd" + integrity sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw== + +"@esbuild/linux-mips64el@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz#c4b6952eca6a8efff67fee3671a3536c8e67b7eb" + integrity sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw== + +"@esbuild/linux-ppc64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz#75b99c70a95fbd5f7739d7692befe60601591869" + integrity sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA== + +"@esbuild/linux-ppc64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz#6dea67d3d98c6986f1b7769e4f1848e5ae47ad58" + integrity sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA== + +"@esbuild/linux-riscv64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz#2e3259440321a44e79ddf7535c325057da875cd6" + integrity sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w== + +"@esbuild/linux-riscv64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz#9ad2b4c3c0502c6bada9c81997bb56c597853489" + integrity sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw== + +"@esbuild/linux-s390x@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz#17676cabbfe5928da5b2a0d6df5d58cd08db2663" + integrity sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg== + +"@esbuild/linux-s390x@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz#c43d3cfd073042ca6f5c52bb9bc313ed2066ce28" + integrity sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA== + +"@esbuild/linux-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz#0583775685ca82066d04c3507f09524d3cd7a306" + integrity sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw== + +"@esbuild/linux-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz#45fa173e0591ac74d80d3cf76704713e14e2a4a6" + integrity sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA== + +"@esbuild/netbsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz#f04c4049cb2e252fe96b16fed90f70746b13f4a4" + integrity sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg== + +"@esbuild/netbsd-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz#366b0ef40cdb986fc751cbdad16e8c25fe1ba879" + integrity sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q== + +"@esbuild/netbsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz#77da0d0a0d826d7c921eea3d40292548b258a076" + integrity sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ== + +"@esbuild/netbsd-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz#e985d49a3668fd2044343071d52e1ae815112b3e" + integrity sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg== + +"@esbuild/openbsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz#6296f5867aedef28a81b22ab2009c786a952dccd" + integrity sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A== + +"@esbuild/openbsd-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz#6fb4ab7b73f7e5572ce5ec9cf91c13ff6dd44842" + integrity sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow== + +"@esbuild/openbsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz#f8d23303360e27b16cf065b23bbff43c14142679" + integrity sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw== + +"@esbuild/openbsd-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz#641f052040a0d79843d68898f5791638a026d983" + integrity sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ== + +"@esbuild/openharmony-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz#49e0b768744a3924be0d7fd97dd6ce9b2923d88d" + integrity sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg== + +"@esbuild/openharmony-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz#fc1d33eac9d81ae0a433b3ed1dd6171a20d4e317" + integrity sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg== + +"@esbuild/sunos-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz#a6ed7d6778d67e528c81fb165b23f4911b9b13d6" + integrity sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w== + +"@esbuild/sunos-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz#af2cd5ca842d6d057121f66a192d4f797de28f53" + integrity sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g== + +"@esbuild/win32-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz#9ac14c378e1b653af17d08e7d3ce34caef587323" + integrity sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg== + +"@esbuild/win32-arm64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz#78ec7e59bb06404583d4c9511e621db31c760de3" + integrity sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg== + +"@esbuild/win32-ia32@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz#918942dcbbb35cc14fca39afb91b5e6a3d127267" + integrity sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ== + +"@esbuild/win32-ia32@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz#0e616aa488b7ee5d2592ab070ff9ec06a9fddf11" + integrity sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw== + +"@esbuild/win32-x64@0.25.12": + version "0.25.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz#9bdad8176be7811ad148d1f8772359041f46c6c5" + integrity sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA== + +"@esbuild/win32-x64@0.27.4": + version "0.27.4" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz#1f7ba71a3d6155d44a6faa8dbe249c62ab3e408c" + integrity sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg== + +"@iconify/types@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@iconify/types/-/types-2.0.0.tgz#ab0e9ea681d6c8a1214f30cd741fe3a20cc57f57" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/utils@^3.0.2": version "3.1.0" - resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-3.1.0.tgz#8ff71d51053cd5ee4981e5a501d80a536244f7fd" - integrity sha512-GcIY79elgB+azP74j8vqkiXz8xLFfIzbQJdlwOPisgbKT00tviJQuEghOXSMVxJ00HoYJbGswr4kcllUc4xCcg== + resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-3.1.0.tgz#fb41882915f97fee6f91a2fbb8263e8772ca0438" + integrity sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw== + dependencies: + "@antfu/install-pkg" "^1.1.0" + "@iconify/types" "^2.0.0" + mlly "^1.8.0" -"@esbuild/android-arm@0.15.12": - version "0.15.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.12.tgz#e548b10a5e55b9e10537a049ebf0bc72c453b769" - integrity sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA== +"@jest/pattern@30.0.1": + version "30.0.1" + resolved "https://registry.yarnpkg.com/@jest/pattern/-/pattern-30.0.1.tgz#d5304147f49a052900b4b853dedb111d080e199f" + integrity sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA== + dependencies: + "@types/node" "*" + jest-regex-util "30.0.1" -"@esbuild/linux-loong64@0.15.12": - version "0.15.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.12.tgz#475b33a2631a3d8ca8aa95ee127f9a61d95bf9c1" - integrity sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw== +"@jest/schemas@30.0.5": + version "30.0.5" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-30.0.5.tgz#7bdf69fc5a368a5abdb49fd91036c55225846473" + integrity sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA== + dependencies: + "@sinclair/typebox" "^0.34.0" + +"@jest/types@30.3.0": + version "30.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-30.3.0.tgz#cada800d323cb74945c24ac74615fdb312a6c85f" + integrity sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw== + dependencies: + "@jest/pattern" "30.0.1" + "@jest/schemas" "30.0.5" + "@types/istanbul-lib-coverage" "^2.0.6" + "@types/istanbul-reports" "^3.0.4" + "@types/node" "*" + "@types/yargs" "^17.0.33" + chalk "^4.1.2" "@jridgewell/gen-mapping@^0.3.0": version "0.3.2" @@ -107,6 +464,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/sourcemap-codec@^1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" @@ -123,102 +485,722 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@jsonjoy.com/base64@17.67.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-17.67.0.tgz#7eeda3cb41138d77a90408fd2e42b2aba10576d7" + integrity sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw== + +"@jsonjoy.com/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578" + integrity sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA== + +"@jsonjoy.com/buffers@17.67.0", "@jsonjoy.com/buffers@^17.65.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz#5c58dbcdeea8824ce296bd1cfce006c2eb167b3d" + integrity sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw== + +"@jsonjoy.com/buffers@^1.0.0", "@jsonjoy.com/buffers@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz#8d99c7f67eaf724d3428dfd9826c6455266a5c83" + integrity sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA== + +"@jsonjoy.com/codegen@17.67.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz#3635fd8769d77e19b75dc5574bc9756019b2e591" + integrity sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q== + +"@jsonjoy.com/codegen@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz#5c23f796c47675f166d23b948cdb889184b93207" + integrity sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g== + +"@jsonjoy.com/fs-core@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz#03c0d7a7bf96030376f7194b9c5c815cb7bf71d7" + integrity sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA== + dependencies: + "@jsonjoy.com/fs-node-builtins" "4.57.1" + "@jsonjoy.com/fs-node-utils" "4.57.1" + thingies "^2.5.0" + +"@jsonjoy.com/fs-fsa@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz#87ffa6cd695b363b58b9ccddc87a66212a1b25fd" + integrity sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA== + dependencies: + "@jsonjoy.com/fs-core" "4.57.1" + "@jsonjoy.com/fs-node-builtins" "4.57.1" + "@jsonjoy.com/fs-node-utils" "4.57.1" + thingies "^2.5.0" + +"@jsonjoy.com/fs-node-builtins@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz#a6793654d6ffaead81f040e3becc063a265deb7c" + integrity sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og== + +"@jsonjoy.com/fs-node-to-fsa@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz#9011872df67ac302f0b0f7fd13502993a026c306" + integrity sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg== + dependencies: + "@jsonjoy.com/fs-fsa" "4.57.1" + "@jsonjoy.com/fs-node-builtins" "4.57.1" + "@jsonjoy.com/fs-node-utils" "4.57.1" + +"@jsonjoy.com/fs-node-utils@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz#e9d030b676f7f4074eb90a42927bac708dc4312c" + integrity sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw== + dependencies: + "@jsonjoy.com/fs-node-builtins" "4.57.1" + +"@jsonjoy.com/fs-node@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz#3dae969fe02d9450f5dfc7c12bfe3b859cb1038e" + integrity sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ== + dependencies: + "@jsonjoy.com/fs-core" "4.57.1" + "@jsonjoy.com/fs-node-builtins" "4.57.1" + "@jsonjoy.com/fs-node-utils" "4.57.1" + "@jsonjoy.com/fs-print" "4.57.1" + "@jsonjoy.com/fs-snapshot" "4.57.1" + glob-to-regex.js "^1.0.0" + thingies "^2.5.0" + +"@jsonjoy.com/fs-print@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz#59359be175145cd44e83f7cdfba06cb1fed23313" + integrity sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw== + dependencies: + "@jsonjoy.com/fs-node-utils" "4.57.1" + tree-dump "^1.1.0" + +"@jsonjoy.com/fs-snapshot@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz#54cd9073a97e290a1650070f2ee9529a0accdb93" + integrity sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg== + dependencies: + "@jsonjoy.com/buffers" "^17.65.0" + "@jsonjoy.com/fs-node-utils" "4.57.1" + "@jsonjoy.com/json-pack" "^17.65.0" + "@jsonjoy.com/util" "^17.65.0" + +"@jsonjoy.com/json-pack@^1.11.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz#93f8dd57fe3a3a92132b33d1eb182dcd9e7629fa" + integrity sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg== + dependencies: + "@jsonjoy.com/base64" "^1.1.2" + "@jsonjoy.com/buffers" "^1.2.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/json-pointer" "^1.0.2" + "@jsonjoy.com/util" "^1.9.0" + hyperdyperid "^1.2.0" + thingies "^2.5.0" + tree-dump "^1.1.0" + +"@jsonjoy.com/json-pack@^17.65.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz#8dd8ff65dd999c5d4d26df46c63915c7bdec093a" + integrity sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w== + dependencies: + "@jsonjoy.com/base64" "17.67.0" + "@jsonjoy.com/buffers" "17.67.0" + "@jsonjoy.com/codegen" "17.67.0" + "@jsonjoy.com/json-pointer" "17.67.0" + "@jsonjoy.com/util" "17.67.0" + hyperdyperid "^1.2.0" + thingies "^2.5.0" + tree-dump "^1.1.0" + +"@jsonjoy.com/json-pointer@17.67.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz#74439573dc046e0c9a3a552fb94b391bc75313b8" + integrity sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA== + dependencies: + "@jsonjoy.com/util" "17.67.0" + +"@jsonjoy.com/json-pointer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz#049cb530ac24e84cba08590c5e36b431c4843408" + integrity sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg== + dependencies: + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/util" "^1.9.0" + +"@jsonjoy.com/util@17.67.0", "@jsonjoy.com/util@^17.65.0": + version "17.67.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-17.67.0.tgz#7c4288fc3808233e55c7610101e7bb4590cddd3f" + integrity sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew== + dependencies: + "@jsonjoy.com/buffers" "17.67.0" + "@jsonjoy.com/codegen" "17.67.0" + +"@jsonjoy.com/util@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-1.9.0.tgz#7ee95586aed0a766b746cd8d8363e336c3c47c46" + integrity sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ== + dependencies: + "@jsonjoy.com/buffers" "^1.0.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@mdit-vue/plugin-component@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-component/-/plugin-component-0.11.1.tgz#0ffd542a6ef26655a6c48c8f255fe1ac4f3db6fc" - integrity sha512-fCqyYPwEXFa182/Vz6g8McDi3SCIwm3yHWkWddHx+QNn0gMGFqkhJVcz/wjCIA3oCoWUBWM80aZ09ZuoQiOmvQ== +"@mdit-vue/plugin-component@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-component/-/plugin-component-3.0.2.tgz#bf26d37a770811943a38a9758605e918e523ff4d" + integrity sha512-Fu53MajrZMOAjOIPGMTdTXgHLgGU9KwTqKtYc6WNYtFZNKw04euSfJ/zFg8eBY/2MlciVngkF7Gyc2IL7e8Bsw== dependencies: - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/plugin-frontmatter@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-frontmatter/-/plugin-frontmatter-0.11.1.tgz#4e4e013bf151fa54525f4e9c7c0a829912364ccb" - integrity sha512-AdZJInjD1pTJXlfhuoBS5ycuIQ3ewBfY0R/XHM3TRDEaDHQJHxouUCpCyijZmpdljTU45lFetIowaKtAi7GBog== +"@mdit-vue/plugin-frontmatter@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-frontmatter/-/plugin-frontmatter-3.0.2.tgz#2f0b73e8b103b6aa79253e143407ce9299f839ff" + integrity sha512-QKKgIva31YtqHgSAz7S7hRcL7cHXiqdog4wxTfxeQCHo+9IP4Oi5/r1Y5E93nTPccpadDWzAwr3A0F+kAEnsVQ== dependencies: - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" gray-matter "^4.0.3" - markdown-it "^13.0.1" + markdown-it "^14.1.0" -"@mdit-vue/plugin-headers@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-headers/-/plugin-headers-0.11.1.tgz#246c56102f3ab197afa2a8c87fe669afb87df735" - integrity sha512-eBUonsEkXP2Uf2MIXSWZGCcLCIMSA1XfThJwhzSAosoa7fO5aw52LKCweddmn7zLQvgQh7p7382sFAhCc2KXog== +"@mdit-vue/plugin-headers@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-headers/-/plugin-headers-3.0.2.tgz#17f41ce4f461ff3d3d52f72fc697ce5b00ab3a00" + integrity sha512-Z3PpDdwBTO5jlW2r617tQibkwtCc5unTnj/Ew1SCxTQaXjtKgwP9WngdSN+xxriISHoNOYzwpoUw/1CW8ntibA== dependencies: - "@mdit-vue/shared" "0.11.0" - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@mdit-vue/shared" "3.0.2" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/plugin-sfc@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-sfc/-/plugin-sfc-0.11.1.tgz#1e7102ea3f67f0761e482ac50c413f7e10e1ba41" - integrity sha512-3AjQXqExzT9FWGNOeTBqK1pbt1UA5anrZvjo7OO2PJ3lrfZd0rbjionFkmW/VW1912laHUraIP6n74mUNqPuWw== +"@mdit-vue/plugin-sfc@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-sfc/-/plugin-sfc-3.0.2.tgz#80084da4a19d387e75048ea54dc4c030609255e7" + integrity sha512-dhxIrCGu5Nd4Cgo9JJHLjdNy2lMEv+LpimetBHDSeEEJxJBC4TPN0Cljn+3/nV1uJdGyw33UZA86PGdgt1LsoA== dependencies: - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/plugin-title@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-title/-/plugin-title-0.11.1.tgz#98e116bc64d59b380a529f22d077dc105f6e862f" - integrity sha512-lvgR1pSgwX5D3tmLGyYBsfd3GbEoscqYsLTE8Vg+rCY8LfSrHdwrOD3Eg+SM2KyS5+gn+Zw4nS0S1yxOIVZBCQ== +"@mdit-vue/plugin-title@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-title/-/plugin-title-3.0.2.tgz#265f942794466105a680a327c69503e43e34630d" + integrity sha512-KTDP7s68eKTwy4iYp5UauQuVJf+tDMdJZMO6K4feWYS8TX95ItmcxyX7RprfBWLTUwNXBYOifsL6CkIGlWcNjA== dependencies: - "@mdit-vue/shared" "0.11.0" - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@mdit-vue/shared" "3.0.2" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/plugin-toc@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-toc/-/plugin-toc-0.11.1.tgz#81394518fd48e54a94e6c41d804270c2b37761bf" - integrity sha512-1tkGb1092ZgLhoSmE5hkC6U0IRGG5bWhUY4p14npV4cwqntciXEoXRqPA1jGEDh5hnofZC0bHbeS3uKxsmAEew== +"@mdit-vue/plugin-toc@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/plugin-toc/-/plugin-toc-3.0.2.tgz#a768b3b22e1045669463ea5b3f44b6421da3ae2a" + integrity sha512-Dz0dURjD5wR4nBxFMiqb0BTGRAOkCE60byIemqLqnkF6ORKKJ8h5aLF5J5ssbLO87hwu81IikHiaXvqoiEneoQ== dependencies: - "@mdit-vue/shared" "0.11.0" - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@mdit-vue/shared" "3.0.2" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/shared@0.11.0", "@mdit-vue/shared@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@mdit-vue/shared/-/shared-0.11.0.tgz#c4b2554795fd1924302fe7f7fee2b5fb412aa578" - integrity sha512-eiGe42y7UYpjO6/8Lg6OpAtzZrRU9k8dhpX1e/kJMTcL+tn+XkqRMJJ8I2pdrOQMSkgvIva5FNAriykqFzkdGg== +"@mdit-vue/shared@3.0.2", "@mdit-vue/shared@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/shared/-/shared-3.0.2.tgz#dbe3ab5bad165c0b9cdba62dbd3c3a8116e2997b" + integrity sha512-anFGls154h0iVzUt5O43EaqYvPwzfUxQ34QpNQsUQML7pbEJMhcgkRNvYw9hZBspab+/TP45agdPw5joh6/BBA== dependencies: - "@mdit-vue/types" "0.11.0" - "@types/markdown-it" "^12.2.3" - markdown-it "^13.0.1" + "@mdit-vue/types" "3.0.2" + "@types/markdown-it" "^14.1.2" + markdown-it "^14.1.0" -"@mdit-vue/types@0.11.0", "@mdit-vue/types@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@mdit-vue/types/-/types-0.11.0.tgz#ab9c6f4e69d9c9eaabf1a73e59dc699875b224ef" - integrity sha512-ygCGP7vFpqS02hpZwEe1uz8cfImWX06+zRs08J+tCZRKb6k+easIaIHFtY9ZSxt7j9L/gAPLDo/5RmOT6z0DPQ== +"@mdit-vue/types@3.0.2", "@mdit-vue/types@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@mdit-vue/types/-/types-3.0.2.tgz#bcc569c5435ecb38b750a58ce69e555cf0021120" + integrity sha512-00aAZ0F0NLik6I6Yba2emGbHLxv+QYrPH00qQ5dFKXlAo1Ll2RHDXwY7nN2WAfrx2pP+WrvSRFTGFCNGdzBDHw== -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== +"@mdit/helper@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@mdit/helper/-/helper-0.23.1.tgz#c7ee7ce42f26ff7e61febc978288099a4fb3bc15" + integrity sha512-ifWDG3VbUAx1ia7eBWEHm5vpv5QFUPY3kFLPPZzYBr15A7/d5w7D+8ZBg8xxqkvyC73Ys+zF14EQCq7eQAXYxg== dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" + "@types/markdown-it" "^14.1.2" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== +"@mdit/plugin-alert@^0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@mdit/plugin-alert/-/plugin-alert-0.23.1.tgz#c017f37619796b5428b275c78c318305f01086b3" + integrity sha512-vbWxewra32hfZKF+XeeWK/eoAzQbe0cSRfSattX9oxGOcaEbcVx2/g7nmI9//ItsOKO7XNRy7ZKLdnm+CaMPvg== dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" + "@types/markdown-it" "^14.1.2" + +"@mdit/plugin-container@^0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@mdit/plugin-container/-/plugin-container-0.23.1.tgz#d5b0a44f21c6aecabeb9fb2721b769f01dcdae35" + integrity sha512-mHTp4+zvuE6uqhG6honfR6F5wLgAIcLlGVCu8xHIoO6H8Oc23lrjl+8Ieyr+PKLH3Lz0QFQf0fWdwNi44EsYSg== + dependencies: + "@types/markdown-it" "^14.1.2" + +"@mdit/plugin-plantuml@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@mdit/plugin-plantuml/-/plugin-plantuml-0.24.1.tgz#80750e6098c61bc7ac8f1ae9611b8efbd8295ee3" + integrity sha512-tRPAnofSMjrrCypghiBDyqyF0cH/wBzS0zjSVjfc+RfMgURt3B4OKvXDc+PsXU6MvJPXVKuMW1ngM4nddPtUyg== + dependencies: + "@mdit/plugin-uml" "0.24.1" + "@types/markdown-it" "^14.1.2" + +"@mdit/plugin-tab@^0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@mdit/plugin-tab/-/plugin-tab-0.24.1.tgz#db23ce9a692627ac1a2b048a3e43a6b60d9bc2cb" + integrity sha512-DSRNyGEBnEgqd1Pw3gt1ropVJv0n5AMCJREY4iq2GNUtxdzNP8jGO7UdXqdnmUPXTWSUZkE7pPu7tvL+38dBHQ== + dependencies: + "@mdit/helper" "0.23.1" + "@types/markdown-it" "^14.1.2" + +"@mdit/plugin-uml@0.24.1": + version "0.24.1" + resolved "https://registry.yarnpkg.com/@mdit/plugin-uml/-/plugin-uml-0.24.1.tgz#15616891fb9f7a36281092255c9988c07aa6381e" + integrity sha512-e/aStB1zb9HwV0KtBIkh7z68ZRW9TnmLTZ+kCZt7HbNywGQvRlHv8myZ0BWVAe5Gbo5LH+aFRSVE72pJ9QP1Xg== + dependencies: + "@mdit/helper" "0.23.1" + "@types/markdown-it" "^14.1.2" + +"@mermaid-js/parser@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@mermaid-js/parser/-/parser-1.0.1.tgz#51c5f43c918a37c35904adef40c98e5862effbdf" + integrity sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ== + dependencies: + langium "^4.0.0" + +"@noble/hashes@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + +"@parcel/watcher-android-arm64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz#5f32e0dba356f4ac9a11068d2a5c134ca3ba6564" + integrity sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A== + +"@parcel/watcher-darwin-arm64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz#88d3e720b59b1eceffce98dac46d7c40e8be5e8e" + integrity sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA== + +"@parcel/watcher-darwin-x64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz#bf05d76a78bc15974f15ec3671848698b0838063" + integrity sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg== + +"@parcel/watcher-freebsd-x64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz#8bc26e9848e7303ac82922a5ae1b1ef1bdb48a53" + integrity sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng== + +"@parcel/watcher-linux-arm-glibc@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz#1328fee1deb0c2d7865079ef53a2ba4cc2f8b40a" + integrity sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ== + +"@parcel/watcher-linux-arm-musl@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz#bad0f45cb3e2157746db8b9d22db6a125711f152" + integrity sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg== + +"@parcel/watcher-linux-arm64-glibc@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz#b75913fbd501d9523c5f35d420957bf7d0204809" + integrity sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA== + +"@parcel/watcher-linux-arm64-musl@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz#da5621a6a576070c8c0de60dea8b46dc9c3827d4" + integrity sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA== + +"@parcel/watcher-linux-x64-glibc@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz#ce437accdc4b30f93a090b4a221fd95cd9b89639" + integrity sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ== + +"@parcel/watcher-linux-x64-musl@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz#02400c54b4a67efcc7e2327b249711920ac969e2" + integrity sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg== + +"@parcel/watcher-win32-arm64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz#caae3d3c7583ca0a7171e6bd142c34d20ea1691e" + integrity sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q== + +"@parcel/watcher-win32-ia32@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz#9ac922550896dfe47bfc5ae3be4f1bcaf8155d6d" + integrity sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g== + +"@parcel/watcher-win32-x64@2.5.6": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz#73fdafba2e21c448f0e456bbe13178d8fe11739d" + integrity sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw== + +"@parcel/watcher@^2.4.1": + version "2.5.6" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.5.6.tgz#3f932828c894f06d0ad9cfefade1756ecc6ef1f1" + integrity sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ== + dependencies: + detect-libc "^2.0.3" + is-glob "^4.0.3" + node-addon-api "^7.0.0" + picomatch "^4.0.3" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.5.6" + "@parcel/watcher-darwin-arm64" "2.5.6" + "@parcel/watcher-darwin-x64" "2.5.6" + "@parcel/watcher-freebsd-x64" "2.5.6" + "@parcel/watcher-linux-arm-glibc" "2.5.6" + "@parcel/watcher-linux-arm-musl" "2.5.6" + "@parcel/watcher-linux-arm64-glibc" "2.5.6" + "@parcel/watcher-linux-arm64-musl" "2.5.6" + "@parcel/watcher-linux-x64-glibc" "2.5.6" + "@parcel/watcher-linux-x64-musl" "2.5.6" + "@parcel/watcher-win32-arm64" "2.5.6" + "@parcel/watcher-win32-ia32" "2.5.6" + "@parcel/watcher-win32-x64" "2.5.6" + +"@peculiar/asn1-cms@^2.6.0", "@peculiar/asn1-cms@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz#cb5445c1bad9197d176073bf142a5c035b460640" + integrity sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + "@peculiar/asn1-x509-attr" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-csr@^2.6.0": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz#9629d403bc5a61254f28ed0b90e99cee61c0e8be" + integrity sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-ecc@^2.6.0": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz#d29c4af671508a9934edc78e7c9419fbf7bc9870" + integrity sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-pfx@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz#75cddd14d43ef875109e91ea150377d679c8fbc1" + integrity sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw== + dependencies: + "@peculiar/asn1-cms" "^2.6.1" + "@peculiar/asn1-pkcs8" "^2.6.1" + "@peculiar/asn1-rsa" "^2.6.1" + "@peculiar/asn1-schema" "^2.6.0" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-pkcs8@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz#bd56b4bb9e8a3702369049713a89134c87c6931a" + integrity sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-pkcs9@^2.6.0": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz#ddc5222952f25b59a0562a6f8cabdb72f586a496" + integrity sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw== + dependencies: + "@peculiar/asn1-cms" "^2.6.1" + "@peculiar/asn1-pfx" "^2.6.1" + "@peculiar/asn1-pkcs8" "^2.6.1" + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + "@peculiar/asn1-x509-attr" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-rsa@^2.6.0", "@peculiar/asn1-rsa@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz#2cdf9f9ea6d6fdbaae214b9fed6de0534b654437" + integrity sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-schema@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz#0dca1601d5b0fed2a72fed7a5f1d0d7dbe3a6f82" + integrity sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg== + dependencies: + asn1js "^3.0.6" + pvtsutils "^1.3.6" + tslib "^2.8.1" + +"@peculiar/asn1-x509-attr@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz#6425008b8099476010aace5b8ae9f9cbc41db0ab" + integrity sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.1" + asn1js "^3.0.6" + tslib "^2.8.1" + +"@peculiar/asn1-x509@^2.6.0", "@peculiar/asn1-x509@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz#4e8995659e16178e0e90fe90519aa269045af262" + integrity sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA== + dependencies: + "@peculiar/asn1-schema" "^2.6.0" + asn1js "^3.0.6" + pvtsutils "^1.3.6" + tslib "^2.8.1" + +"@peculiar/x509@^1.14.2": + version "1.14.3" + resolved "https://registry.yarnpkg.com/@peculiar/x509/-/x509-1.14.3.tgz#2c44c2b89474346afec38a0c2803ec4fb8ce959e" + integrity sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA== + dependencies: + "@peculiar/asn1-cms" "^2.6.0" + "@peculiar/asn1-csr" "^2.6.0" + "@peculiar/asn1-ecc" "^2.6.0" + "@peculiar/asn1-pkcs9" "^2.6.0" + "@peculiar/asn1-rsa" "^2.6.0" + "@peculiar/asn1-schema" "^2.6.0" + "@peculiar/asn1-x509" "^2.6.0" + pvtsutils "^1.3.6" + reflect-metadata "^0.2.2" + tslib "^2.8.1" + tsyringe "^4.10.0" + +"@pkgr/core@^0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" + integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== + +"@rolldown/pluginutils@1.0.0-rc.2": + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz#10324e74cb3396cb7b616042ea7e9e6aa7d8d458" + integrity sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw== + +"@rollup/rollup-android-arm-eabi@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.0.tgz#7e158ddfc16f78da99c0d5ccbae6cae403ef3284" + integrity sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A== + +"@rollup/rollup-android-arm64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.0.tgz#49f4ae0e22b6f9ffbcd3818b9a0758fa2d10b1cd" + integrity sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw== + +"@rollup/rollup-darwin-arm64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.0.tgz#bb200269069acf5c1c4d79ad142524f77e8b8236" + integrity sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA== + +"@rollup/rollup-darwin-x64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.0.tgz#1bf7a92b27ebdd5e0d1d48503c7811160773be1a" + integrity sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw== + +"@rollup/rollup-freebsd-arm64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.0.tgz#5ccf537b99c5175008444702193ad0b1c36f7f16" + integrity sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw== + +"@rollup/rollup-freebsd-x64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.0.tgz#1196ecd7bf4e128624ef83cd1f9d785114474a77" + integrity sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA== + +"@rollup/rollup-linux-arm-gnueabihf@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.0.tgz#cc147633a4af229fee83a737bf2334fbac3dc28e" + integrity sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g== + +"@rollup/rollup-linux-arm-musleabihf@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.0.tgz#3559f9f060153ea54594a42c3b87a297bedcc26e" + integrity sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ== + +"@rollup/rollup-linux-arm64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.0.tgz#e91f887b154123485cfc4b59befe2080fcd8f2df" + integrity sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A== + +"@rollup/rollup-linux-arm64-musl@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.0.tgz#660752f040df9ba44a24765df698928917c0bf21" + integrity sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ== + +"@rollup/rollup-linux-loong64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.0.tgz#cb0e939a5fa479ccef264f3f45b31971695f869c" + integrity sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw== + +"@rollup/rollup-linux-loong64-musl@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.0.tgz#42f86fbc82cd1a81be2d346476dd3231cf5ee442" + integrity sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog== + +"@rollup/rollup-linux-ppc64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.0.tgz#39776a647a789dc95ea049277c5ef8f098df77f9" + integrity sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ== + +"@rollup/rollup-linux-ppc64-musl@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.0.tgz#466f20029a8e8b3bb2954c7ddebc9586420cac2c" + integrity sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg== + +"@rollup/rollup-linux-riscv64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.0.tgz#cff9877c78f12e7aa6246f6902ad913e99edb2b7" + integrity sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA== + +"@rollup/rollup-linux-riscv64-musl@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.0.tgz#9a762fb99b5a82a921017f56491b7e892b9fb17d" + integrity sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ== + +"@rollup/rollup-linux-s390x-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.0.tgz#9d25ad8ac7dab681935baf78ac5ea92d14629cdf" + integrity sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ== + +"@rollup/rollup-linux-x64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.0.tgz#5e5139e11819fa38a052368da79422cb4afcf466" + integrity sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg== + +"@rollup/rollup-linux-x64-musl@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.0.tgz#b6211d46e11b1f945f5504cc794fce839331ed08" + integrity sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw== + +"@rollup/rollup-openbsd-x64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.0.tgz#e6e09eebaa7012bb9c7331b437a9e992bd94ca35" + integrity sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw== + +"@rollup/rollup-openharmony-arm64@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.0.tgz#f7d99ae857032498e57a5e7259fb7100fd24a87e" + integrity sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA== + +"@rollup/rollup-win32-arm64-msvc@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.0.tgz#41e392f5d9f3bf1253fdaf2f6d6f6b1bfc452856" + integrity sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ== + +"@rollup/rollup-win32-ia32-msvc@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.0.tgz#f41b0490be0e5d3cf459b4dc076a192b532adea9" + integrity sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w== + +"@rollup/rollup-win32-x64-gnu@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.0.tgz#0fcf9f1fcb750f0317b13aac3b3231687e6397a5" + integrity sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA== + +"@rollup/rollup-win32-x64-msvc@4.60.0": + version "4.60.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.0.tgz#3afdb30405f6d4248df5e72e1ca86c5eab55fab8" + integrity sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w== + +"@shikijs/core@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-4.0.2.tgz#386a00acc6965ced582e9066bfb237de7ee99174" + integrity sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw== + dependencies: + "@shikijs/primitive" "4.0.2" + "@shikijs/types" "4.0.2" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.5" + +"@shikijs/engine-javascript@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-4.0.2.tgz#d49b766c23fb6e71c19b9a797ff5357c8a61db5e" + integrity sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag== + dependencies: + "@shikijs/types" "4.0.2" + "@shikijs/vscode-textmate" "^10.0.2" + oniguruma-to-es "^4.3.4" + +"@shikijs/engine-oniguruma@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-4.0.2.tgz#41ed06adcc4a4e6f49e05643dfe0d772dbb19c2b" + integrity sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg== + dependencies: + "@shikijs/types" "4.0.2" + "@shikijs/vscode-textmate" "^10.0.2" + +"@shikijs/langs@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-4.0.2.tgz#1ac31a223d74729cf230441f9bb7d7975384101f" + integrity sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg== + dependencies: + "@shikijs/types" "4.0.2" + +"@shikijs/primitive@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/primitive/-/primitive-4.0.2.tgz#4efa1efab1b828c20563c2097d2effa5ac79bf04" + integrity sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw== + dependencies: + "@shikijs/types" "4.0.2" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + +"@shikijs/themes@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-4.0.2.tgz#24c5c059e89a8e7630fb40a240bc6b5a336bb080" + integrity sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA== + dependencies: + "@shikijs/types" "4.0.2" + +"@shikijs/transformers@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-4.0.2.tgz#aefcf084326b3c8a218fc9aa33950ab2e5aacd5a" + integrity sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg== + dependencies: + "@shikijs/core" "4.0.2" + "@shikijs/types" "4.0.2" + +"@shikijs/types@4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-4.0.2.tgz#75180a19acf124b37f48b53a9e6373de2e2e4f28" + integrity sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg== + dependencies: + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224" + integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== + +"@sinclair/typebox@^0.34.0": + version "0.34.48" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.48.tgz#75b0ead87e59e1adbd6dccdc42bad4fddee73b59" + integrity sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA== "@types/body-parser@*": version "1.19.2" @@ -228,17 +1210,17 @@ "@types/connect" "*" "@types/node" "*" -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== +"@types/bonjour@^3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== +"@types/connect-history-api-fallback@^1.5.4": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" @@ -250,10 +1232,220 @@ dependencies: "@types/node" "*" -"@types/debug@^4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== +"@types/d3-array@*": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.2.tgz#e02151464d02d4a1b44646d0fcdb93faf88fde8c" + integrity sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw== + +"@types/d3-axis@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795" + integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-brush@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c" + integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-chord@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d" + integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-contour@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231" + integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== + dependencies: + "@types/d3-array" "*" + "@types/geojson" "*" + +"@types/d3-delaunay@*": + version "6.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1" + integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== + +"@types/d3-dispatch@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz#ef004d8a128046cfce434d17182f834e44ef95b2" + integrity sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA== + +"@types/d3-drag@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-dsv@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== + +"@types/d3-ease@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-fetch@*": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== + dependencies: + "@types/d3-dsv" "*" + +"@types/d3-force@*": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a" + integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== + +"@types/d3-format@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90" + integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== + +"@types/d3-geo@*": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@*": + version "3.1.7" + resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b" + integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== + +"@types/d3-interpolate@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" + integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== + +"@types/d3-polygon@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c" + integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== + +"@types/d3-quadtree@*": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f" + integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== + +"@types/d3-random@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb" + integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== + +"@types/d3-scale-chromatic@*": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39" + integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== + +"@types/d3-scale@*": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" + integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== + dependencies: + "@types/d3-time" "*" + +"@types/d3-selection@*": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3" + integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== + +"@types/d3-shape@*": + version "3.1.8" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.8.tgz#d1516cc508753be06852cd06758e3bb54a22b0e3" + integrity sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time-format@*": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2" + integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== + +"@types/d3-time@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" + integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== + +"@types/d3-timer@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + +"@types/d3-transition@*": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706" + integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@*": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/d3@^7.4.3": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2" + integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== + dependencies: + "@types/d3-array" "*" + "@types/d3-axis" "*" + "@types/d3-brush" "*" + "@types/d3-chord" "*" + "@types/d3-color" "*" + "@types/d3-contour" "*" + "@types/d3-delaunay" "*" + "@types/d3-dispatch" "*" + "@types/d3-drag" "*" + "@types/d3-dsv" "*" + "@types/d3-ease" "*" + "@types/d3-fetch" "*" + "@types/d3-force" "*" + "@types/d3-format" "*" + "@types/d3-geo" "*" + "@types/d3-hierarchy" "*" + "@types/d3-interpolate" "*" + "@types/d3-path" "*" + "@types/d3-polygon" "*" + "@types/d3-quadtree" "*" + "@types/d3-random" "*" + "@types/d3-scale" "*" + "@types/d3-scale-chromatic" "*" + "@types/d3-selection" "*" + "@types/d3-shape" "*" + "@types/d3-time" "*" + "@types/d3-time-format" "*" + "@types/d3-timer" "*" + "@types/d3-transition" "*" + "@types/d3-zoom" "*" + +"@types/debug@^4.1.12": + version "4.1.13" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.13.tgz#22d1cc9d542d3593caea764f974306ab36286ee7" + integrity sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw== dependencies: "@types/ms" "*" @@ -273,7 +1465,7 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.8": +"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.8": version "1.0.8" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -287,7 +1479,17 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.14": +"@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": + version "4.19.8" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz#99b960322a4d576b239a640ab52ef191989b036f" + integrity sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": version "4.17.14" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== @@ -297,23 +1499,51 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/fs-extra@^9.0.13": - version "9.0.13" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" - integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== +"@types/express@^4.17.23", "@types/express@^4.17.25": + version "4.17.25" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" + integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "^1" + +"@types/fs-extra@^11.0.4": + version "11.0.4" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.4.tgz#e16a863bb8843fba8c5004362b5a73e17becca45" + integrity sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ== + dependencies: + "@types/jsonfile" "*" "@types/node" "*" -"@types/hash-sum@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/hash-sum/-/hash-sum-1.0.0.tgz#838f4e8627887d42b162d05f3d96ca636c2bc504" - integrity sha512-FdLBT93h3kcZ586Aee66HPCVJ6qvxVjBlDWNmxSGSbCZe9hTsjRKdSsl4y1T+3zfujxo9auykQMnFsfyHWD7wg== +"@types/geojson@*": + version "7946.0.16" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a" + integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== + +"@types/hash-sum@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/hash-sum/-/hash-sum-1.0.2.tgz#32e6e4343ee25914b2a3822f27e8e641ca534f63" + integrity sha512-UP28RddqY8xcU0SCEp9YKutQICXpaAq9N8U2klqF5hegGha7KzTOL8EdhIIV3bOSGBzjEpN9bU/d+nNZBdJYVw== + +"@types/hast@^3.0.0", "@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== +"@types/http-errors@*": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== + "@types/http-proxy@^1.17.8": version "1.17.9" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" @@ -321,6 +1551,25 @@ dependencies: "@types/node" "*" +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + "@types/json-schema@*", "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -331,36 +1580,55 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/linkify-it@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" - integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== - -"@types/markdown-it-emoji@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz#f12a97df2758f38b4b38f277b468780459faff14" - integrity sha512-2ln8Wjbcj/0oRi/6VnuMeWEHHuK8uapFttvcLmDIe1GKCsFBLOLBX+D+xhDa9oWOQV0IpvxwrSfKKssAqqroog== +"@types/jsonfile@*": + version "6.1.4" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.4.tgz#614afec1a1164e7d670b4a7ad64df3e7beb7b702" + integrity sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ== dependencies: - "@types/markdown-it" "*" + "@types/node" "*" -"@types/markdown-it@*", "@types/markdown-it@^12.2.3": - version "12.2.3" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" - integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== +"@types/linkify-it@^5": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" + integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== + +"@types/markdown-it-emoji@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/markdown-it-emoji/-/markdown-it-emoji-3.0.1.tgz#035d4d38110113ea0ce911f06bc2c2b03ca1ad42" + integrity sha512-cz1j8R35XivBqq9mwnsrP2fsz2yicLhB8+PDtuVkKOExwEdsVBNI+ROL3sbhtR5occRZ66vT0QnwFZCqdjf3pA== dependencies: - "@types/linkify-it" "*" - "@types/mdurl" "*" + "@types/markdown-it" "^14" -"@types/mdurl@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== +"@types/markdown-it@^14", "@types/markdown-it@^14.1.2": + version "14.1.2" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.2.tgz#57f2532a0800067d9b934f3521429a2e8bfb4c61" + integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog== + dependencies: + "@types/linkify-it" "^5" + "@types/mdurl" "^2" + +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + +"@types/mdurl@^2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" + integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + "@types/ms@*": version "0.7.31" resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" @@ -371,10 +1639,17 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/node@^24.9.2": + version "24.12.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.12.0.tgz#6222e028210e5322e4f4f6767f8d88e5ea3b33d2" + integrity sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ== + dependencies: + undici-types "~7.16.0" + +"@types/picomatch@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-4.0.2.tgz#85a232bafed4121527cbf70c0ef461b46b2cc10b" + integrity sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA== "@types/qs@*": version "6.9.7" @@ -386,19 +1661,41 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== +"@types/retry@0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" + integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== +"@types/sax@^1.2.1": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.7.tgz#ba5fe7df9aa9c89b6dff7688a19023dd2963091d" + integrity sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A== + dependencies: + "@types/node" "*" + +"@types/send@*": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" + integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== + dependencies: + "@types/node" "*" + +"@types/send@<1": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" + integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" -"@types/serve-static@*", "@types/serve-static@^1.13.10": +"@types/serve-static@*": version "1.15.0" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== @@ -406,435 +1703,560 @@ "@types/mime" "*" "@types/node" "*" -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== +"@types/serve-static@^1", "@types/serve-static@^1.15.5": + version "1.15.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" + integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "<1" + +"@types/sockjs@^0.3.36": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" -"@types/web-bluetooth@^0.0.16": - version "0.0.16" - resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8" - integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ== +"@types/trusted-types@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== -"@types/webpack-env@^1.18.0": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.0.tgz#ed6ecaa8e5ed5dfe8b2b3d00181702c9925f13fb" - integrity sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg== +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== +"@types/web-bluetooth@^0.0.21": + version "0.0.21" + resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz#525433c784aed9b457aaa0ee3d92aeb71f346b63" + integrity sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA== + +"@types/webpack-env@^1.18.8": + version "1.18.8" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.8.tgz#71f083718c094204d7b64443701d32f1db3989e3" + integrity sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A== + +"@types/ws@^8.5.10": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" -"@vitejs/plugin-vue@^3.1.2": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz#a1484089dd85d6528f435743f84cdd0d215bbb54" - integrity sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw== +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== -"@vue/compiler-core@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.41.tgz#fb5b25f23817400f44377d878a0cdead808453ef" - integrity sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw== +"@types/yargs@^17.0.33": + version "17.0.35" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== dependencies: - "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.41" + "@types/yargs-parser" "*" + +"@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + +"@upsetjs/venn.js@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@upsetjs/venn.js/-/venn.js-2.0.0.tgz#3be192038cdda927aa4f8b22ab51af82abf47f34" + integrity sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw== + optionalDependencies: + d3-selection "^3.0.0" + d3-transition "^3.0.1" + +"@vitejs/plugin-vue@^6.0.1": + version "6.0.5" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-6.0.5.tgz#20ebb46c4da069753d9cfb1309c4334213cc3f7b" + integrity sha512-bL3AxKuQySfk1iGcBsQnoRVexTPJq0Z/ixFVM8OhVJAP6ZXXXLtM7NFKWhLl30Kg7uTBqIaPXbh+nuQCuBDedg== + dependencies: + "@rolldown/pluginutils" "1.0.0-rc.2" + +"@vue/compiler-core@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.30.tgz#0f984da9207f24f9ddfb700052a43247a953fd9a" + integrity sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw== + dependencies: + "@babel/parser" "^7.29.0" + "@vue/shared" "3.5.30" + entities "^7.0.1" estree-walker "^2.0.2" - source-map "^0.6.1" + source-map-js "^1.2.1" -"@vue/compiler-dom@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz#dc63dcd3ce8ca8a8721f14009d498a7a54380299" - integrity sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw== +"@vue/compiler-dom@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz#a38dbdd520479244c8b673123b4bd06a82e733ee" + integrity sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g== dependencies: - "@vue/compiler-core" "3.2.41" - "@vue/shared" "3.2.41" + "@vue/compiler-core" "3.5.30" + "@vue/shared" "3.5.30" -"@vue/compiler-sfc@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz#238fb8c48318408c856748f4116aff8cc1dc2a73" - integrity sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w== +"@vue/compiler-sfc@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz#5c716d844f240154263e99b25fba6e1802c0c8c6" + integrity sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A== dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.41" - "@vue/compiler-dom" "3.2.41" - "@vue/compiler-ssr" "3.2.41" - "@vue/reactivity-transform" "3.2.41" - "@vue/shared" "3.2.41" + "@babel/parser" "^7.29.0" + "@vue/compiler-core" "3.5.30" + "@vue/compiler-dom" "3.5.30" + "@vue/compiler-ssr" "3.5.30" + "@vue/shared" "3.5.30" estree-walker "^2.0.2" - magic-string "^0.25.7" - postcss "^8.1.10" - source-map "^0.6.1" + magic-string "^0.30.21" + postcss "^8.5.8" + source-map-js "^1.2.1" -"@vue/compiler-ssr@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz#344f564d68584b33367731c04ffc949784611fcb" - integrity sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ== +"@vue/compiler-ssr@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz#e9b407d7e56be1e307a7621f2e8d2501267ff1d0" + integrity sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA== dependencies: - "@vue/compiler-dom" "3.2.41" - "@vue/shared" "3.2.41" + "@vue/compiler-dom" "3.5.30" + "@vue/shared" "3.5.30" -"@vue/devtools-api@^6.4.5": - version "6.4.5" - resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz#d54e844c1adbb1e677c81c665ecef1a2b4bb8380" - integrity sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ== +"@vue/devtools-api@^6.6.4": + version "6.6.4" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343" + integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== -"@vue/reactivity-transform@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz#9ff938877600c97f646e09ac1959b5150fb11a0c" - integrity sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A== +"@vue/devtools-api@^8.0.2", "@vue/devtools-api@^8.0.7": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-8.1.0.tgz#a5b623e7a2f1c1339c560b4242a9308e29b1c3ea" + integrity sha512-O44X57jjkLKbLEc4OgL/6fEPOOanRJU8kYpCE8qfKlV96RQZcdzrcLI5mxMuVRUeXhHKIHGhCpHacyCk0HyO4w== dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.41" - "@vue/shared" "3.2.41" - estree-walker "^2.0.2" - magic-string "^0.25.7" + "@vue/devtools-kit" "^8.1.0" -"@vue/reactivity@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.41.tgz#0ad3bdf76d76822da1502dc9f394dafd02642963" - integrity sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g== +"@vue/devtools-kit@^8.0.2", "@vue/devtools-kit@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-8.1.0.tgz#b29e9ddac45a222c2495e3fa36e110b6bd35b8a2" + integrity sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q== dependencies: - "@vue/shared" "3.2.41" + "@vue/devtools-shared" "^8.1.0" + birpc "^2.6.1" + hookable "^5.5.3" + perfect-debounce "^2.0.0" -"@vue/runtime-core@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.41.tgz#775bfc00b3fadbaddab77138f23322aee3517a76" - integrity sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ== +"@vue/devtools-shared@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-8.1.0.tgz#58bc97d235987b60ca81e6018718c46281163a0b" + integrity sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA== + +"@vue/reactivity@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.30.tgz#1ff13f7d570b16b4f009f007772c7b71be1dd09d" + integrity sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q== dependencies: - "@vue/reactivity" "3.2.41" - "@vue/shared" "3.2.41" + "@vue/shared" "3.5.30" -"@vue/runtime-dom@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz#cdf86be7410f7b15c29632a96ce879e5b4c9ab92" - integrity sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA== +"@vue/runtime-core@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.30.tgz#abe448b25e88f583b1847323a2f19f5e4a21837d" + integrity sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg== dependencies: - "@vue/runtime-core" "3.2.41" - "@vue/shared" "3.2.41" - csstype "^2.6.8" + "@vue/reactivity" "3.5.30" + "@vue/shared" "3.5.30" -"@vue/server-renderer@3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.41.tgz#ca64552c05878f94e8d191ac439141c06c0fb2ad" - integrity sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig== +"@vue/runtime-dom@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz#41d1b6424b754300f735c2ecb1a7457b4125dab3" + integrity sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw== dependencies: - "@vue/compiler-ssr" "3.2.41" - "@vue/shared" "3.2.41" + "@vue/reactivity" "3.5.30" + "@vue/runtime-core" "3.5.30" + "@vue/shared" "3.5.30" + csstype "^3.2.3" -"@vue/shared@3.2.41", "@vue/shared@^3.2.41": - version "3.2.41" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.41.tgz#fbc95422df654ea64e8428eced96ba6ad555d2bb" - integrity sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw== - -"@vuepress/bundler-vite@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/bundler-vite/-/bundler-vite-2.0.0-beta.53.tgz#6c425cccbe6f4d281a87dee320ded6f1e9eee329" - integrity sha512-zkqkV+EnoTi7cTRi6xjb0SRg0GzRYwceJu80/6q7Bd+h+VktqhapcHAZ8QaIsq8OxCXbg3sms/A9kg3UxBnRqg== +"@vue/server-renderer@3.5.30": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.30.tgz#116515063d609d3ceca1170f3b09122f24f187b5" + integrity sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ== dependencies: - "@vitejs/plugin-vue" "^3.1.2" - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - autoprefixer "^10.4.12" + "@vue/compiler-ssr" "3.5.30" + "@vue/shared" "3.5.30" + +"@vue/shared@3.5.30", "@vue/shared@^3.5.29": + version "3.5.30" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.30.tgz#5d7a0d3ca151647484303fd9f057e2e13ecb80ef" + integrity sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ== + +"@vuepress/bundler-vite@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/bundler-vite/-/bundler-vite-2.0.0-rc.26.tgz#99e0a3fe47dcc5d01036117307fd20d3c065187b" + integrity sha512-4+YfKs2iOxuVSMW+L2tFzu2+X2HiGAREpo1DbkkYVDa5GyyPR+YsSueXNZMroTdzWDk5kAUz2Z1Tz1lIu7TO2g== + dependencies: + "@vitejs/plugin-vue" "^6.0.1" + "@vuepress/bundlerutils" "2.0.0-rc.26" + "@vuepress/client" "2.0.0-rc.26" + "@vuepress/core" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + autoprefixer "^10.4.21" connect-history-api-fallback "^2.0.0" - postcss "^8.4.18" - postcss-load-config "^4.0.1" - rollup "^2.79.1" - vite "~3.1.8" - vue "^3.2.41" - vue-router "^4.1.6" + postcss "^8.5.6" + postcss-load-config "^6.0.1" + rollup "^4.52.4" + vite "~7.1.9" + vue "^3.5.22" + vue-router "^4.6.0" -"@vuepress/bundler-webpack@^2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/bundler-webpack/-/bundler-webpack-2.0.0-beta.53.tgz#9430f03aba4afb33ad296182073743ab8f0031c8" - integrity sha512-7J8GVabqiMMvRLMsWFlPf9LJ+xqvEUN8U7cnZ3Nm9Dbxd6hBk1kTE+tRa2JOEqJ6xjPHUxNLXTyP/IKgTAqQ7g== +"@vuepress/bundler-webpack@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/bundler-webpack/-/bundler-webpack-2.0.0-rc.26.tgz#66faf720a99e1c4297caadea785f869ed3ae8e03" + integrity sha512-6lkAnXB/ML7CIJHI8/9GDRHdu4p/Ap1eLRmj2+E4lHYHKpnwNzEDJoISaZWMwwNsr2satsb0iAUc/xvucUH5Kg== dependencies: - "@types/express" "^4.17.14" - "@types/webpack-env" "^1.18.0" - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - autoprefixer "^10.4.12" - chokidar "^3.5.3" - copy-webpack-plugin "^11.0.0" - css-loader "^6.7.1" - esbuild-loader "~2.20.0" - express "^4.18.2" - html-webpack-plugin "^5.5.0" - mini-css-extract-plugin "^2.6.1" - postcss "^8.4.18" - postcss-csso "^6.0.1" - postcss-loader "^7.0.1" - style-loader "^3.3.1" - vue "^3.2.41" - vue-loader "^17.0.0" - vue-router "^4.1.6" - webpack "^5.74.0" - webpack-chain "^6.5.1" - webpack-dev-server "^4.11.1" - webpack-merge "^5.8.0" + "@types/express" "^4.17.23" + "@types/webpack-env" "^1.18.8" + "@vuepress/bundlerutils" "2.0.0-rc.26" + "@vuepress/client" "2.0.0-rc.26" + "@vuepress/core" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + autoprefixer "^10.4.21" + copy-webpack-plugin "^13.0.1" + css-loader "^7.1.2" + css-minimizer-webpack-plugin "^7.0.2" + esbuild-loader "~4.4.0" + express "^4.21.2" + html-webpack-plugin "^5.6.4" + lightningcss "^1.30.2" + mini-css-extract-plugin "^2.9.4" + postcss "^8.5.6" + postcss-loader "^8.2.0" + style-loader "^4.0.0" + vue "^3.5.22" + vue-loader "^17.4.2" + vue-router "^4.6.0" + webpack "^5.102.1" + webpack-dev-server "^5.2.2" + webpack-merge "^6.0.1" + webpack-v5-chain "^1.0.0" -"@vuepress/cli@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/cli/-/cli-2.0.0-beta.53.tgz#5c8670abadb29797eb65071be93b0b6a76f444c0" - integrity sha512-MT2y6syOIP17hq/mWiZXTDEViDb3/k5eIVzlvpw4N8oiAr4hwwdCUzQ5vKVd7trn+83KvG5XYOLtjrj1hexlYg== +"@vuepress/bundlerutils@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/bundlerutils/-/bundlerutils-2.0.0-rc.26.tgz#abd85490414a6fb3001d66ee8878af1f9e4a1e56" + integrity sha512-OnhUvzuJFEzPBjivZX7j6EhPE6sAwAIfyi3pAFmOpQDHPP7/l0q2I4bNVVGK4t9EZDu4N7Dl40/oFHhIMy5New== dependencies: - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" + "@vuepress/client" "2.0.0-rc.26" + "@vuepress/core" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + vue "^3.5.22" + vue-router "^4.6.0" + +"@vuepress/cli@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/cli/-/cli-2.0.0-rc.26.tgz#aeffa6ddeda09d25351f690a0dfb6f99165cf9bd" + integrity sha512-63/4nIHrl9pbutUWs6SirWxmyykjvR9BWvu7bvczO1hAkWOyDQPcU18JXWy8q38CyMzPxCeedUfP3BQsZs3UgA== + dependencies: + "@vuepress/core" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" cac "^6.7.14" - chokidar "^3.5.3" - envinfo "^7.8.1" - esbuild "^0.15.12" + chokidar "^4.0.3" + envinfo "^7.18.0" + esbuild "^0.25.10" -"@vuepress/client@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/client/-/client-2.0.0-beta.53.tgz#c60fd217d01510ea62f57b8077940a51342f45f8" - integrity sha512-TDKxlrUvwfWu3QAY4SHeu9mVqBkEoKvuoy0WsKy7x9omEy8+HJG1O9y664bP9SotD52skcKL1iW38nQJR2+AkQ== +"@vuepress/client@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/client/-/client-2.0.0-rc.26.tgz#3fb1e38550b5deb2f39c05a996aa9e52ab77f397" + integrity sha512-+irF1HOTD6sAHdcTjp3yRcfuGlJYAW+YvDhq+7n3TPXeMH/wJbmGmAs2oRIDkx6Nlt3XkMMpFo7e9pOU22ut1w== dependencies: - "@vue/devtools-api" "^6.4.5" - "@vuepress/shared" "2.0.0-beta.53" - vue "^3.2.41" - vue-router "^4.1.6" + "@vue/devtools-api" "^8.0.2" + "@vue/devtools-kit" "^8.0.2" + "@vuepress/shared" "2.0.0-rc.26" + vue "^3.5.22" + vue-router "^4.6.0" -"@vuepress/core@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/core/-/core-2.0.0-beta.53.tgz#600da932f6ece8699580ecaf9937bc6bf6e7a71d" - integrity sha512-s642hM+PpiNphLm/KZvva45OYKX6hWRh2Y+C92TDGzCMxiONI8ZxGLqXRCw5bKw5NGh91s+P4sf3iaY+JxL1Ig== +"@vuepress/core@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/core/-/core-2.0.0-rc.26.tgz#3ca0d556fd4ea9571318a1786eed0068f96de192" + integrity sha512-Wyiv9oRvdT0lAPGU0Pj1HetjKicbX8/gqbBVYv2MmL7Y4a3r0tyQ92IdZ8LHiAgPvzctntQr/JXIELedvU1t/w== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/markdown" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - vue "^3.2.41" + "@vuepress/client" "2.0.0-rc.26" + "@vuepress/markdown" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + vue "^3.5.22" -"@vuepress/markdown@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/markdown/-/markdown-2.0.0-beta.53.tgz#8f9cc4a91e7bfb34d2606ffcde1d13526dc69308" - integrity sha512-ohIujGc0tVSsFTBD5kyB0asxLsDtctzrOOgHvaS2fDWqm0MQisjxnQKNFdbWk9bfddAyty0aKN+m/4l0f5lCDw== +"@vuepress/helper@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/helper/-/helper-2.0.0-rc.125.tgz#bca8d067fad528cb10c23b919d1a4e7eb24e2388" + integrity sha512-2NzP2HZCUYRfjcKI8c+Ml3hFdViBXZv88gaW1kNskuPM3P5/sSgjdM7997ZZPyuokANh8jwKwckA2PQ8UIRyiQ== dependencies: - "@mdit-vue/plugin-component" "^0.11.1" - "@mdit-vue/plugin-frontmatter" "^0.11.1" - "@mdit-vue/plugin-headers" "^0.11.1" - "@mdit-vue/plugin-sfc" "^0.11.1" - "@mdit-vue/plugin-title" "^0.11.1" - "@mdit-vue/plugin-toc" "^0.11.1" - "@mdit-vue/shared" "^0.11.0" - "@mdit-vue/types" "^0.11.0" - "@types/markdown-it" "^12.2.3" - "@types/markdown-it-emoji" "^2.0.2" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - markdown-it "^13.0.1" - markdown-it-anchor "^8.6.5" - markdown-it-emoji "^2.0.2" - mdurl "^1.0.1" + "@vue/shared" "^3.5.29" + "@vueuse/core" "^14.2.1" + cheerio "^1.2.0" + fflate "^0.8.2" + gray-matter "^4.0.3" + vue "^3.5.29" -"@vuepress/plugin-active-header-links@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-beta.53.tgz#08b4a196a659b06fe386d04e824ffaa31ddd0e58" - integrity sha512-rlDQ4CpF/awzHN6l6c5C4/bbiAZisZ2Z9cP2GJJBbxIb6QA6GOrIoHMt6L+9321Q+/jmntjoRJT4yHP/jg8OMA== - dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - ts-debounce "^4.0.0" - vue "^3.2.41" - vue-router "^4.1.6" +"@vuepress/highlighter-helper@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/highlighter-helper/-/highlighter-helper-2.0.0-rc.125.tgz#23224751933f7ebe3d4720f310954d8414ef7e74" + integrity sha512-v7dCssUGyaq1Ip8su0lWTb9QyXzhMQL6YjSds9BLqEpJIihmWrtZpAYDSvENineWGKzV+cr/2bPgHN5jBWaogw== -"@vuepress/plugin-back-to-top@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-beta.53.tgz#ef19c8a8b48643b9eaf9a0c3acffcb60958024a6" - integrity sha512-M7+WIA1e57yHbpUKksVDQdcHceslqeGn0/MldjmZHZ/xosxjM/ZIsw7AiSdmCcISEZBr60IXxDoLqJMNhMNQLQ== +"@vuepress/markdown@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/markdown/-/markdown-2.0.0-rc.26.tgz#1b191051763091d6bf6b1a8633ad0b5487b17694" + integrity sha512-ZAXkRxqPDjxqcG4j4vN2ZL5gmuRmgGH7n0s/7pcWIGFH3BJodp/PXMYCklnne1VwARIim9rqE3FKPB/ifJX0yA== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - ts-debounce "^4.0.0" - vue "^3.2.41" + "@mdit-vue/plugin-component" "^3.0.2" + "@mdit-vue/plugin-frontmatter" "^3.0.2" + "@mdit-vue/plugin-headers" "^3.0.2" + "@mdit-vue/plugin-sfc" "^3.0.2" + "@mdit-vue/plugin-title" "^3.0.2" + "@mdit-vue/plugin-toc" "^3.0.2" + "@mdit-vue/shared" "^3.0.2" + "@mdit-vue/types" "^3.0.2" + "@types/markdown-it" "^14.1.2" + "@types/markdown-it-emoji" "^3.0.1" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + markdown-it "^14.1.0" + markdown-it-anchor "^9.2.0" + markdown-it-emoji "^3.0.0" + mdurl "^2.0.0" -"@vuepress/plugin-container@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-container/-/plugin-container-2.0.0-beta.53.tgz#b112de6559af7fb82c42327bbe2be6969d810d70" - integrity sha512-kkEee5iGRHfGVFNBsF2b5vCfjC7dcmU2zqICJq8/UZbhWuyAavpmDovQYLCVh/yTfNE1FlRUOAFFI+jf3bvF9g== +"@vuepress/plugin-active-header-links@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-rc.125.tgz#fd5e3b761c857ffb73458d3254aad5afdd37eaba" + integrity sha512-sUuwJUi0pQxdQ1S63Srk2gP0pzN/rv4QAYOiz/mMmZW/iGoe6CY6RBvwLOQ0CNNUjJ5vGbgJWvZfZ8Fy7IjENA== dependencies: - "@types/markdown-it" "^12.2.3" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/markdown" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - markdown-it "^13.0.1" - markdown-it-container "^3.0.0" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" -"@vuepress/plugin-external-link-icon@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-external-link-icon/-/plugin-external-link-icon-2.0.0-beta.53.tgz#8ad4fe660192bc991ccf7051dd5fdc9476e6a0f9" - integrity sha512-S+IY1PK96Vbuf90IdZBe36kRpMCXrGr9TPaPm1aAQ9GA0Y5QQkTV876SXsb0n1B6Ae2AsSieulB2o4lyoL1LBQ== +"@vuepress/plugin-back-to-top@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-rc.125.tgz#20d8b214ef8aaf988d19d41d3030afefc207bba5" + integrity sha512-tFXN7BtHr+jMVyJl6O6trpw2gFdE04sODDf/I1QMquOXl/Wezr4gdtl+OeBcBL/9zuduNYAb03hoAmWAQRtgLQ== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/markdown" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - vue "^3.2.41" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" -"@vuepress/plugin-git@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-git/-/plugin-git-2.0.0-beta.53.tgz#6fffbf178ec4ee41e0134198474b96af6d31d3bc" - integrity sha512-hefVEUhxTgvDcrsIutVBBfJvixR/L6iTQZ9eDAj2z71fOgnVNdN8PNZ9XRDm3nhZrye9X44AmJI82Wk9SlwgVw== +"@vuepress/plugin-copy-code@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-copy-code/-/plugin-copy-code-2.0.0-rc.125.tgz#5539bc1e25af881eb11f700c6d08f265d742daa0" + integrity sha512-wm2EVnUmwEcu8boAbjYG+xdymr02kORdV18DsXwd/NpwlmbzcXUe8Qw/48qZBsa2bhxLTlnu3qjcARn1oFRQyQ== dependencies: - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - execa "^6.1.0" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" -"@vuepress/plugin-medium-zoom@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-medium-zoom/-/plugin-medium-zoom-2.0.0-beta.53.tgz#03a7b49bdcac4bdc8e813019f74d849e348d3540" - integrity sha512-hvmO40is/JrHDcSFp73qwX90nXUAaBBZHokZ0I3D61u6acFtI4HU/vpJpu+3oiqjXHQaUNqZO5eDr4EpypGjUg== +"@vuepress/plugin-git@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-git/-/plugin-git-2.0.0-rc.125.tgz#fd01d931ad174a2bcdc893294ed7903509554808" + integrity sha512-iki07M125tSSFpdADMfY0pAd+LtimuETqEv8OuHut4o1ZeY+TleyBVpsprgAu4UfpkisKQuM8pYjGagLXsj3rQ== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - medium-zoom "^1.0.6" - vue "^3.2.41" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + rehype-parse "^9.0.1" + rehype-sanitize "^6.0.0" + rehype-stringify "^10.0.1" + unified "^11.0.5" + vue "^3.5.29" -"@vuepress/plugin-nprogress@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-beta.53.tgz#7e83e959180b74e6026f3c15e4e92479ba1f72c3" - integrity sha512-xO8Dqw1yCttY6N+jDpuwE3RG+jQVPE0EieRafTWRO+fGCFobGa/6Zldc4x3+alB2xyXwFAy2495NYgPudNIWeQ== +"@vuepress/plugin-links-check@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-links-check/-/plugin-links-check-2.0.0-rc.125.tgz#c11ea03dc32359a43007a015df3f1840c1ba2384" + integrity sha512-z44Ut/uDZMwexmyh/rpsqQg+AvqffvT6JPpVQs6gkj0jBTEvmGAMOdrImBGH7xLrtFz/gZ4eeZcIC3aCdCSOtw== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - vue "^3.2.41" - vue-router "^4.1.6" + "@vuepress/helper" "2.0.0-rc.125" -"@vuepress/plugin-palette@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-palette/-/plugin-palette-2.0.0-beta.53.tgz#ae9d40ce7e6f24a41d9758de277076cbcd376473" - integrity sha512-iYCb397nu/WacvXEaTmeex7lxkjHqRPXLAqBccrD4JWPshP2iu1ajM316jI8sUXSPTZZl4GOQ7+fqbr+UGHdEg== +"@vuepress/plugin-markdown-chart@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-markdown-chart/-/plugin-markdown-chart-2.0.0-rc.125.tgz#e0b4e5235c550387540c9eb6748bc4eb04f759f8" + integrity sha512-WG9PmFs7QO2ivbEeDKdPFL7Kap5zJC0PaWhf4wjLyOh2KaGqlz/YJufqdcQDVOLnvmszRk0t2WX7kgROaGv53A== dependencies: - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - chokidar "^3.5.3" + "@mdit/plugin-container" "^0.23.1" + "@mdit/plugin-plantuml" "^0.24.1" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" -"@vuepress/plugin-prismjs@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-prismjs/-/plugin-prismjs-2.0.0-beta.53.tgz#b6a0cec28306c6fa049ddc2624f606b27b49f493" - integrity sha512-8zAMHqSPJK8Nw9hP2V12BrAfT88Mmw37Lhi6cbc0S9Ub+wapzZkD9I1SuR1OEssqqMrHL2h1dWx25RqYstn7eA== +"@vuepress/plugin-markdown-hint@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-markdown-hint/-/plugin-markdown-hint-2.0.0-rc.125.tgz#b2f493f05197370391e66729a1a35e15c43e3079" + integrity sha512-0uZTI4GucVjoUUCUbV1jU6HaQfQCL41Zvm6UO2yhBqmlIVBxv+PGhr3p1U33165LN2bJve6Zj1JFiCsy6pjsyw== dependencies: - "@vuepress/core" "2.0.0-beta.53" - prismjs "^1.29.0" + "@mdit/plugin-alert" "^0.23.1" + "@mdit/plugin-container" "^0.23.1" + "@types/markdown-it" "^14.1.2" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" -"@vuepress/plugin-search@^2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-search/-/plugin-search-2.0.0-beta.53.tgz#6904650490dc4d1d5385cf288baf896f9fa40e73" - integrity sha512-x9FScY9aLTzlp6D5wO1d0kDkAO9TkzLwGueNx5F13Nkq589weq8uTTiNRA2oDM0l+H9BF6vDJ+XJlzE5W3u9gQ== +"@vuepress/plugin-markdown-tab@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.125.tgz#aa294657d10fac4d19c9e14a3365e20e0220a925" + integrity sha512-GSEj7OKsry8dmG608XRYBo9NeDYmE5Z1b44e9/xxC1VQlgV+Egf7yzakb+YHIYAiLlzCbQrhm7XLTQnAu8EbKg== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - chokidar "^3.5.3" - vue "^3.2.41" - vue-router "^4.1.6" + "@mdit/plugin-tab" "^0.24.1" + "@types/markdown-it" "^14.1.2" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" -"@vuepress/plugin-shiki@^2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-beta.53.tgz#38f2ce16fd5af61bc41bc0ea2611e94f68cb2405" - integrity sha512-Bpcv7GZyvj1mk1PoYVJAB42B+4JuKZBho4iqfHGtPhqLg5jcVLgd/p4OscC7fTL2S94ubES4q8G1WXu8JGtJuQ== +"@vuepress/plugin-medium-zoom@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-medium-zoom/-/plugin-medium-zoom-2.0.0-rc.125.tgz#eaccfc050a1ce5b4b4942b00da0f6612c054fb67" + integrity sha512-lyiMEFvGGG88866EC2nOf8nJ9eQxVSstf/vGAqma13GrhTWLCQHdugdQDC6AmooWPranKd2X3O1LSL9Yd2BbOQ== dependencies: - "@vuepress/core" "2.0.0-beta.53" - shiki "^0.11.1" + "@vuepress/helper" "2.0.0-rc.125" + medium-zoom "^1.1.0" + vue "^3.5.29" -"@vuepress/plugin-theme-data@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-beta.53.tgz#b838a2afae815301c8b9d1ec3cfe865a72d4f302" - integrity sha512-fTOWrsO+ql2ZcN1UtF7Xc6+J/XfOAL+4+0Tq6fSky4Gv1HdC2Euey+r+RYgYkTdogdbL2VaUp3s+jhcow5WWAg== +"@vuepress/plugin-nprogress@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-rc.125.tgz#c81fc6456d68c3d127c5900b3b025228d73bd55e" + integrity sha512-RfD/MOYCeYYOZEC+rG+sHZjaw+OGt8dAwKOeviWcJiEONxdiD8uMPmAqdtek3q37zNrKb5yVfIDIIS3/qjsQwA== dependencies: - "@vue/devtools-api" "^6.4.5" - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - vue "^3.2.41" + "@vuepress/helper" "2.0.0-rc.125" + vue "^3.5.29" -"@vuepress/shared@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/shared/-/shared-2.0.0-beta.53.tgz#acf19da2dd23c09afd29cffb993644e29b91d229" - integrity sha512-B0qWorGxC3ruSHdZcJW24XtEDEU3L3uPr0xzTeKVfHjOM4b9hN83YzBtW4n/WPnmk1RXVE9266Ulh9ZL5okGOw== +"@vuepress/plugin-palette@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-palette/-/plugin-palette-2.0.0-rc.125.tgz#327491d14f10f9fb1051beb4fa330cb03ceb639f" + integrity sha512-prcq3bLD+pjtg9iXRl6nJov/k0cqAs83JlHvJEgo0anLr0a8zJyhxMtgUQFRxY2t01DL6fNYoVeMHQIGhyWceQ== dependencies: - "@mdit-vue/types" "^0.11.0" - "@vue/shared" "^3.2.41" + "@vuepress/helper" "2.0.0-rc.125" + chokidar "^5.0.0" -"@vuepress/theme-default@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/theme-default/-/theme-default-2.0.0-beta.53.tgz#0891d380360a4f4cd07b54953582cafb4ad174d0" - integrity sha512-FNzEgD2D+ZZRpgF4PfUMCVfKkpzHjmapMlho6Q74d1iqf5cbDeiTyUSWXM2SWHwyZDbdbemjcnfiztb1c215ow== +"@vuepress/plugin-prismjs@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-prismjs/-/plugin-prismjs-2.0.0-rc.125.tgz#5dd03dbe040175e449cdb1c61b99cdbedc5ff379" + integrity sha512-z5AvS88NIxChFELUftN5rdL2jF4zI1h1QweV60ou4l1eP3reru7hx3etNH+lqG4Yll31KYzFFjA6EOGgn7pN/g== dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/plugin-active-header-links" "2.0.0-beta.53" - "@vuepress/plugin-back-to-top" "2.0.0-beta.53" - "@vuepress/plugin-container" "2.0.0-beta.53" - "@vuepress/plugin-external-link-icon" "2.0.0-beta.53" - "@vuepress/plugin-git" "2.0.0-beta.53" - "@vuepress/plugin-medium-zoom" "2.0.0-beta.53" - "@vuepress/plugin-nprogress" "2.0.0-beta.53" - "@vuepress/plugin-palette" "2.0.0-beta.53" - "@vuepress/plugin-prismjs" "2.0.0-beta.53" - "@vuepress/plugin-theme-data" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - "@vueuse/core" "^9.3.1" - sass "^1.55.0" - vue "^3.2.41" - vue-router "^4.1.6" + "@vuepress/helper" "2.0.0-rc.125" + "@vuepress/highlighter-helper" "2.0.0-rc.125" + prismjs "^1.30.0" -"@vuepress/utils@2.0.0-beta.53": - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/@vuepress/utils/-/utils-2.0.0-beta.53.tgz#ac61235436a4c45e03e7e856ea59a55de0f890cc" - integrity sha512-cYqAspUJoY1J84kbDbPbrIcfaoID5Wb+BUrcWV7x8EFPXTn/KBLgc4/KBxWkdxk8O9V96/bXBDSLlalqLJCmJw== +"@vuepress/plugin-redirect@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-redirect/-/plugin-redirect-2.0.0-rc.125.tgz#30e05e3f973f835af5482baa506b2847919ca0c9" + integrity sha512-DYIr4Ay1PpbvIYNQFuhXtrCrjqtGfsMSxFThfyNeZ12Xw8VntowE0CSiONL7XaqCJ2RzsqH/MfYlk6rUJY6cjg== dependencies: - "@types/debug" "^4.1.7" - "@types/fs-extra" "^9.0.13" - "@types/hash-sum" "^1.0.0" - "@vuepress/shared" "2.0.0-beta.53" - chalk "^5.1.2" - debug "^4.3.4" - fs-extra "^10.1.0" - globby "^13.1.2" + "@vuepress/helper" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + commander "^14.0.3" + vue "^3.5.29" + +"@vuepress/plugin-search@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-search/-/plugin-search-2.0.0-rc.125.tgz#ad2fb6db5418b626987b229ffaa039fbda7755ff" + integrity sha512-yORJ3GoRVURw+E0+F84IIS2Z2oqZVVPS5sd1ldq61Sy52cdkCws5wGKa7ossVn6nBQpaEV4bLDccPccL5XciNQ== + dependencies: + "@vuepress/helper" "2.0.0-rc.125" + chokidar "^5.0.0" + vue "^3.5.29" + +"@vuepress/plugin-seo@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-seo/-/plugin-seo-2.0.0-rc.125.tgz#f573cd08bfb089adf71ae5dc42d7f440356ceddc" + integrity sha512-m8NPIMCIi84DVg5h99PvmAy6raxBVbV8Ne4GPCIjhpU2gGG4IHyuAk3NBKWig2n6daGPph1uFZYx8FOeqyJObQ== + dependencies: + "@vuepress/helper" "2.0.0-rc.125" + +"@vuepress/plugin-shiki@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-rc.125.tgz#63c52e3418d8cabf2be619b887f03219d09b72d8" + integrity sha512-VaSfhMkJAs9i7qFgCay42CkS9eQjYHpu5bzAa4Ioxdt/WWX2tonc98ydUpVbpmFl177ZRdP2IRCYf8TulJ9xqA== + dependencies: + "@shikijs/transformers" "^4.0.1" + "@vuepress/helper" "2.0.0-rc.125" + "@vuepress/highlighter-helper" "2.0.0-rc.125" + nanoid "^5.1.6" + shiki "^4.0.1" + synckit "^0.11.12" + +"@vuepress/plugin-sitemap@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.125.tgz#eab6496dd50f8fd809e8083c3b52be0a44d57c92" + integrity sha512-Q1mJbDGVBZ560wsIEqVYQciHwZtNufTCQPejiF6+WfMfqJMpiFZJkF2dsGBmR7w586/vYfkHwEeRqwvJPoYxdg== + dependencies: + "@vuepress/helper" "2.0.0-rc.125" + sitemap "^9.0.1" + +"@vuepress/plugin-theme-data@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-rc.125.tgz#ad3807db957da35fa3bf071dec4c5656e7e0d29c" + integrity sha512-f+QX2MBDmrPWA66fPIbXb/mPKpBqmpsF9Z6VNiigreZy3DWfQImw3blOTl4e8fbA61u8O1KTI78UenMxdxAu7A== + dependencies: + "@vue/devtools-api" "^8.0.7" + vue "^3.5.29" + +"@vuepress/shared@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/shared/-/shared-2.0.0-rc.26.tgz#557ad6c7177529ae99a4c7e618de7b460f1607bd" + integrity sha512-Zl9XNG/fYenZqzuYYGOfHzjmp1HCOj68gcJnJABOX1db0H35dkPSPsxuMjbTljClUqMlfj70CLeip/h04upGVw== + dependencies: + "@mdit-vue/types" "^3.0.2" + +"@vuepress/theme-default@2.0.0-rc.125": + version "2.0.0-rc.125" + resolved "https://registry.yarnpkg.com/@vuepress/theme-default/-/theme-default-2.0.0-rc.125.tgz#5d219bd12c0a9b113e61fbd222a1d5138c105ba5" + integrity sha512-sYUtniwfjU6Jwfq7GxQXLHDviah1rYUjtbWYiir1SIuz8m56SzPJxWza27ef/DL5OnrlLmG4Z4bgXUmgkZZocA== + dependencies: + "@vuepress/helper" "2.0.0-rc.125" + "@vuepress/plugin-active-header-links" "2.0.0-rc.125" + "@vuepress/plugin-back-to-top" "2.0.0-rc.125" + "@vuepress/plugin-copy-code" "2.0.0-rc.125" + "@vuepress/plugin-git" "2.0.0-rc.125" + "@vuepress/plugin-links-check" "2.0.0-rc.125" + "@vuepress/plugin-markdown-hint" "2.0.0-rc.125" + "@vuepress/plugin-markdown-tab" "2.0.0-rc.125" + "@vuepress/plugin-medium-zoom" "2.0.0-rc.125" + "@vuepress/plugin-nprogress" "2.0.0-rc.125" + "@vuepress/plugin-palette" "2.0.0-rc.125" + "@vuepress/plugin-prismjs" "2.0.0-rc.125" + "@vuepress/plugin-seo" "2.0.0-rc.125" + "@vuepress/plugin-sitemap" "2.0.0-rc.125" + "@vuepress/plugin-theme-data" "2.0.0-rc.125" + "@vueuse/core" "^14.2.1" + vue "^3.5.29" + +"@vuepress/utils@2.0.0-rc.26": + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/@vuepress/utils/-/utils-2.0.0-rc.26.tgz#e708f6d006929f36fbb95313ca4e6b1d5f91002a" + integrity sha512-RWzZrGQ0WLSWdELuxg7c6q1D9I22T5PfK/qNFkOsv9eD3gpUsU4jq4zAoumS8o+NRIWHovCJ9WnAhHD0Ns5zAw== + dependencies: + "@types/debug" "^4.1.12" + "@types/fs-extra" "^11.0.4" + "@types/hash-sum" "^1.0.2" + "@types/picomatch" "^4.0.2" + "@vuepress/shared" "2.0.0-rc.26" + debug "^4.4.3" + fs-extra "^11.3.2" hash-sum "^2.0.0" - ora "^6.1.2" + ora "^9.0.0" + picocolors "^1.1.1" + picomatch "^4.0.3" + tinyglobby "^0.2.15" upath "^2.0.1" -"@vueuse/core@^9.3.1": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-9.4.0.tgz#afb30f9494b0954e51a489526566b14f1e2c5fb3" - integrity sha512-JzgenGj1ZF2BHOen5rsFiAyyI9sXAv7aKhNLlm9b7SwYQeKTcxTWdhudonURCSP3Egl9NQaRBzes2lv/1JUt/Q== +"@vueuse/core@^14.2.1": + version "14.2.1" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-14.2.1.tgz#b5cf36a07b4ea973381e18523ad0ed6ddc98a5be" + integrity sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ== dependencies: - "@types/web-bluetooth" "^0.0.16" - "@vueuse/metadata" "9.4.0" - "@vueuse/shared" "9.4.0" - vue-demi "*" + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "14.2.1" + "@vueuse/shared" "14.2.1" -"@vueuse/metadata@9.4.0": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-9.4.0.tgz#5c8eb105a8ad9eb7b47f78a226ff993560d0bd7f" - integrity sha512-7GKMdGAsJyQJl35MYOz/RDpP0FxuiZBRDSN79QIPbdqYx4Sd0sVTnIC68KJ6Oln0t0SouvSUMvRHuno216Ud2Q== +"@vueuse/metadata@14.2.1": + version "14.2.1" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-14.2.1.tgz#bd3338a565c2f651b9d18ac0f8825aa6077ee461" + integrity sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw== -"@vueuse/shared@9.4.0": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-9.4.0.tgz#634022fe42b3d5ece1d81d749724966f5071c8c3" - integrity sha512-fTuem51KwMCnqUKkI8B57qAIMcFovtGgsCtAeqxIzH3i6nE9VYge+gVfneNHAAy7lj8twbkNfqQSygOPJTm4tQ== - dependencies: - vue-demi "*" +"@vueuse/shared@14.2.1": + version "14.2.1" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-14.2.1.tgz#829a271147937f6b105bb1422d3171e6142f47ba" + integrity sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw== "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" @@ -967,7 +2389,7 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: +accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -985,6 +2407,11 @@ acorn@^8.15.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== +acorn@^8.16.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" + integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== + acorn@^8.5.0: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" @@ -1034,10 +2461,10 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== +ansi-regex@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== ansi-styles@^3.2.1: version "3.2.1" @@ -1074,6 +2501,11 @@ anywhere@^1.6.0: serve-index "^1.9.1" serve-static "^1.13.2" +arg@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1106,16 +2538,20 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== +asn1js@^3.0.6: + version "3.0.7" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.7.tgz#15f1f2f59e60f80d5b43ef14047a294a969f824f" + integrity sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ== + dependencies: + pvtsutils "^1.3.6" + pvutils "^1.1.3" + tslib "^2.8.1" + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -1126,27 +2562,21 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^10.4.12: - version "10.4.13" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" - integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== +autoprefixer@^10.4.21: + version "10.4.27" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.27.tgz#51ea301a5c3c5f8642f8e564759c4f573be486f2" + integrity sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA== dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001426" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" + browserslist "^4.28.1" + caniuse-lite "^1.0.30001774" + fraction.js "^5.3.4" + picocolors "^1.1.1" postcss-value-parser "^4.2.0" -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== base@^0.11.1: version "0.11.2" @@ -1181,40 +2611,34 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-5.1.0.tgz#183715f678c7188ecef9fe475d90209400624273" - integrity sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ== - dependencies: - buffer "^6.0.3" - inherits "^2.0.4" - readable-stream "^3.4.0" +birpc@^2.6.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/birpc/-/birpc-2.9.0.tgz#b59550897e4cd96a223e2a6c1475b572236ed145" + integrity sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw== -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== +body-parser@~1.20.3: + version "1.20.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" + integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== dependencies: - bytes "3.1.2" + bytes "~3.1.2" content-type "~1.0.5" debug "2.6.9" depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.14.0" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" -bonjour-service@^1.0.11: - version "1.0.14" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== +bonjour-service@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" + integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" @@ -1223,14 +2647,6 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - braces@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -1254,17 +2670,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - -browserslist@^4.28.1: +browserslist@^4.0.0, browserslist@^4.28.1: version "4.28.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== @@ -1280,24 +2686,23 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== +bundle-name@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" + integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" + run-applescript "^7.0.0" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - -bytes@3.1.2: +bytes@3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +bytestreamjs@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bytestreamjs/-/bytestreamjs-2.0.1.tgz#a32947c7ce389a6fa11a09a9a563d0a45889535e" + integrity sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ== + cac@^6.7.14: version "6.7.14" resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" @@ -1318,13 +2723,21 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-bind@^1.0.0: +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" callsites@^3.0.0: version "3.1.0" @@ -1339,16 +2752,31 @@ camel-case@^4.1.2: pascal-case "^3.1.2" tslib "^2.0.3" -caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: - version "1.0.30001429" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz#70cdae959096756a85713b36dd9cb82e62325639" - integrity sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg== +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001774: + version "1.0.30001780" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz#0e413de292808868a62ed9118822683fa120a110" + integrity sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ== caniuse-lite@^1.0.30001759: version "1.0.30001769" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1358,7 +2786,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1366,15 +2794,73 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.0.0, chalk@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.1.2.tgz#d957f370038b75ac572471e83be4c5ca9f8e8c45" - integrity sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ== +chalk@^5.6.2: + version "5.6.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.2.0.tgz#f23b777c49021ead7475dcf3390d3535a7f896d6" + integrity sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.2.2" + encoding-sniffer "^0.2.1" + htmlparser2 "^10.1.0" + parse5 "^7.3.0" + parse5-htmlparser2-tree-adapter "^7.1.0" + parse5-parser-stream "^7.1.2" + undici "^7.19.0" + whatwg-mimetype "^4.0.0" + +chevrotain-allstar@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz#b7412755f5d83cc139ab65810cdb00d8db40e6ca" + integrity sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw== + dependencies: + lodash-es "^4.17.21" + +chevrotain@~11.1.1: + version "11.1.2" + resolved "https://registry.yarnpkg.com/chevrotain/-/chevrotain-11.1.2.tgz#1db446bdeb63fe42d366508a34280c2e3c0c4f62" + integrity sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg== + dependencies: + "@chevrotain/cst-dts-gen" "11.1.2" + "@chevrotain/gast" "11.1.2" + "@chevrotain/regexp-to-ast" "11.1.2" + "@chevrotain/types" "11.1.2" + "@chevrotain/utils" "11.1.2" + lodash-es "4.17.23" + +chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -1386,11 +2872,30 @@ chalk@^5.0.0, chalk@^5.1.2: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.0, chokidar@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== + dependencies: + readdirp "^4.0.1" + +chokidar@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-5.0.0.tgz#949c126a9238a80792be9a0265934f098af369a5" + integrity sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw== + dependencies: + readdirp "^5.0.0" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== +ci-info@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.4.0.tgz#7d54eff9f54b45b62401c26032696eb59c8bd18c" + integrity sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1408,17 +2913,17 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" -cli-cursor@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" - integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== +cli-cursor@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" + integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== dependencies: - restore-cursor "^4.0.0" + restore-cursor "^5.0.0" -cli-spinners@^2.6.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== +cli-spinners@^3.2.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-3.4.0.tgz#1f11f6d48c4e5bc6849fcb4efa0dc98f9e7299ea" + integrity sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw== clone-deep@^4.0.1: version "4.0.1" @@ -1429,11 +2934,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1466,21 +2966,46 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colord@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + colorette@^2.0.10: version "2.0.19" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -commander@2, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +colorjs.io@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef" + integrity sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== commander@7: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + +commander@^14.0.3: + version "14.0.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.3.tgz#425d79b48f9af82fcd9e4fc1ea8af6c5ec07bbc2" + integrity sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -1491,30 +3016,30 @@ component-emitter@^1.2.1: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compressible@~2.0.16: +compressible@~2.0.18: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: mime-db ">= 1.43.0 < 2" -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== +compression@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" + integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" + bytes "3.1.2" + compressible "~2.0.18" debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" + negotiator "~0.6.4" + on-headers "~1.1.0" + safe-buffer "5.2.1" vary "~1.1.2" -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== connect-history-api-fallback@^1.2.0: version "1.6.0" @@ -1536,7 +3061,7 @@ connect@^3.6.6: parseurl "~1.3.3" utils-merge "1.0.1" -content-disposition@0.5.4: +content-disposition@~0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -1553,71 +3078,91 @@ content-type@~1.0.5: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie-signature@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" + integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@~0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -copy-webpack-plugin@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" - integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== +copy-webpack-plugin@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz#fba18c22bcab3633524e1b652580ff4489eddc0d" + integrity sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw== dependencies: - fast-glob "^3.2.11" glob-parent "^6.0.1" - globby "^13.1.1" normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" + schema-utils "^4.2.0" + serialize-javascript "^6.0.2" + tinyglobby "^0.2.12" core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-1.0.3.tgz#650334b41b869578a543358b80cda7e0abe0a60a" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" + layout-base "^1.0.0" -cross-spawn@^7.0.3: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== +cose-base@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-2.2.0.tgz#1c395c35b6e10bb83f9769ca8b817d614add5c01" + integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" + layout-base "^2.0.0" -css-loader@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== +cosmiconfig@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.1.tgz#df110631a8547b5d1a98915271986f06e3011379" + integrity sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ== + dependencies: + env-paths "^2.2.1" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + +css-declaration-sorter@^7.2.0: + version "7.3.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.3.1.tgz#acd204976d7ca5240b5579bfe6e73d4d088fd568" + integrity sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA== + +css-loader@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.4.tgz#8f6bf9f8fc8cbef7d2ef6e80acc6545eaefa90b1" + integrity sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw== dependencies: icss-utils "^5.1.0" - postcss "^8.4.7" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" + postcss "^8.4.40" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.5" + semver "^7.6.3" + +css-minimizer-webpack-plugin@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.4.tgz#92d2643e3658e3f484a70382a5dba18e51997f2e" + integrity sha512-2iACis+P8qdLj1tHcShtztkGhCNIRUajJj7iX0IM9a5FA0wXGwjV8Nf6+HsBjBfb4LO8TTAVoetBbM54V6f3+Q== + dependencies: + "@jridgewell/trace-mapping" "^0.3.25" + cssnano "^7.0.4" + jest-worker "^30.0.5" + postcss "^8.4.40" + schema-utils "^4.2.0" + serialize-javascript "^6.0.2" css-select@^4.1.3: version "4.3.0" @@ -1630,6 +3175,25 @@ css-select@^4.1.3: domutils "^2.8.0" nth-check "^2.0.1" +css-select@^5.1.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.2.2.tgz#01b6e8d163637bb2dd6c982ca4ed65863682786e" + integrity sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-tree@^3.0.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.2.1.tgz#86cac7011561272b30e6b1e042ba6ce047aa7518" + integrity sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA== + dependencies: + mdn-data "2.27.1" + source-map-js "^1.2.1" + css-tree@~2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" @@ -1643,11 +3207,65 @@ css-what@^6.0.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== +css-what@^6.1.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.2.2.tgz#cdcc8f9b6977719fdfbd1de7aec24abf756b9dea" + integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +cssnano-preset-default@^7.0.11: + version "7.0.11" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-7.0.11.tgz#ea81661d0e8fe59b752560cca4a9f2fac763e92c" + integrity sha512-waWlAMuCakP7//UCY+JPrQS1z0OSLeOXk2sKWJximKWGupVxre50bzPlvpbUwZIDylhf/ptf0Pk+Yf7C+hoa3g== + dependencies: + browserslist "^4.28.1" + css-declaration-sorter "^7.2.0" + cssnano-utils "^5.0.1" + postcss-calc "^10.1.1" + postcss-colormin "^7.0.6" + postcss-convert-values "^7.0.9" + postcss-discard-comments "^7.0.6" + postcss-discard-duplicates "^7.0.2" + postcss-discard-empty "^7.0.1" + postcss-discard-overridden "^7.0.1" + postcss-merge-longhand "^7.0.5" + postcss-merge-rules "^7.0.8" + postcss-minify-font-values "^7.0.1" + postcss-minify-gradients "^7.0.1" + postcss-minify-params "^7.0.6" + postcss-minify-selectors "^7.0.6" + postcss-normalize-charset "^7.0.1" + postcss-normalize-display-values "^7.0.1" + postcss-normalize-positions "^7.0.1" + postcss-normalize-repeat-style "^7.0.1" + postcss-normalize-string "^7.0.1" + postcss-normalize-timing-functions "^7.0.1" + postcss-normalize-unicode "^7.0.6" + postcss-normalize-url "^7.0.1" + postcss-normalize-whitespace "^7.0.1" + postcss-ordered-values "^7.0.2" + postcss-reduce-initial "^7.0.6" + postcss-reduce-transforms "^7.0.1" + postcss-svgo "^7.1.1" + postcss-unique-selectors "^7.0.5" + +cssnano-utils@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-5.0.1.tgz#f529e9aa0d7930512ca45b9e2ddb8d6b9092eb30" + integrity sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg== + +cssnano@^7.0.4: + version "7.1.3" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-7.1.3.tgz#2a542bb8d62b6bee9e23e455ba2e507fd102f611" + integrity sha512-mLFHQAzyapMVFLiJIn7Ef4C2UCEvtlTlbyILR6B5ZsUAV3D/Pa761R5uC1YPhyBkRd3eqaDm2ncaNrD7R4mTRg== + dependencies: + cssnano-preset-default "^7.0.11" + lilconfig "^3.1.3" + csso@^5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" @@ -1655,15 +3273,36 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -csstype@^2.6.8: - version "2.6.21" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" - integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w== +csstype@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== -d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" - integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz#762fa121df9930ffeb51a495d87917c570ac209b" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz#e4d6f6490df4fab58ae9cea9e5c3ab8d7472f471" + integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== + dependencies: + cose-base "^2.2.0" + +cytoscape@^3.33.1: + version "3.33.1" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.33.1.tgz#449e05d104b760af2912ab76482d24c01cdd4c97" + integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ== + +"d3-array@1 - 2": + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: version "3.2.4" @@ -1672,27 +3311,11 @@ d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: dependencies: internmap "1 - 2" -d3-axis@1: - version "1.0.12" - resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9" - integrity sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ== - d3-axis@3: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-3.0.0.tgz#c42a4a13e8131d637b745fc2973824cfeaf93322" integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== -d3-brush@1: - version "1.1.6" - resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.1.6.tgz#b0a22c7372cabec128bdddf9bddc058592f89e9b" - integrity sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - d3-brush@3: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-3.0.0.tgz#6f767c4ed8dcb79de7ede3e1c0f89e63ef64d31c" @@ -1704,14 +3327,6 @@ d3-brush@3: d3-selection "3" d3-transition "3" -d3-chord@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.6.tgz#309157e3f2db2c752f0280fedd35f2067ccbb15f" - integrity sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA== - dependencies: - d3-array "1" - d3-path "1" - d3-chord@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-3.0.1.tgz#d156d61f485fce8327e6abf339cb41d8cbba6966" @@ -1719,28 +3334,11 @@ d3-chord@3: dependencies: d3-path "1 - 3" -d3-collection@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" - integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== - -d3-color@1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" - integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== - "d3-color@1 - 3", d3-color@3: version "3.1.0" resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== -d3-contour@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" - integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== - dependencies: - d3-array "^1.1.1" - d3-contour@4: version "4.0.2" resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-4.0.2.tgz#bb92063bc8c5663acb2422f99c73cbb6c6ae3bcc" @@ -1755,24 +3353,11 @@ d3-delaunay@6: dependencies: delaunator "5" -d3-dispatch@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" - integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== - "d3-dispatch@1 - 3", d3-dispatch@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e" integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== -d3-drag@1: - version "1.2.5" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.2.5.tgz#2537f451acd39d31406677b7dc77c82f7d988f70" - integrity sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w== - dependencies: - d3-dispatch "1" - d3-selection "1" - "d3-drag@2 - 3", d3-drag@3: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba" @@ -1781,15 +3366,6 @@ d3-drag@1: d3-dispatch "1 - 3" d3-selection "3" -d3-dsv@1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.2.0.tgz#9d5f75c3a5f8abd611f74d3f5847b0d4338b885c" - integrity sha512-9yVlqvZcSOMhCYzniHE7EVUws7Fa1zgw+/EAV2BxJoG3ME19V6BQFBwI855XQDsxyOuG7NibqRMTtiF/Qup46g== - dependencies: - commander "2" - iconv-lite "0.4" - rw "1" - "d3-dsv@1 - 3", d3-dsv@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73" @@ -1799,23 +3375,11 @@ d3-dsv@1: iconv-lite "0.6" rw "1" -d3-ease@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.7.tgz#9a834890ef8b8ae8c558b2fe55bd57f5993b85e2" - integrity sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ== - "d3-ease@1 - 3", d3-ease@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== -d3-fetch@1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-1.2.0.tgz#15ce2ecfc41b092b1db50abd2c552c2316cf7fc7" - integrity sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA== - dependencies: - d3-dsv "1" - d3-fetch@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-fetch/-/d3-fetch-3.0.1.tgz#83141bff9856a0edb5e38de89cdcfe63d0a60a22" @@ -1823,16 +3387,6 @@ d3-fetch@3: dependencies: d3-dsv "1 - 3" -d3-force@1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" - integrity sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg== - dependencies: - d3-collection "1" - d3-dispatch "1" - d3-quadtree "1" - d3-timer "1" - d3-force@3: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-3.0.0.tgz#3e2ba1a61e70888fe3d9194e30d6d14eece155c4" @@ -1842,23 +3396,11 @@ d3-force@3: d3-quadtree "1 - 3" d3-timer "1 - 3" -d3-format@1: - version "1.4.5" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" - integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== - "d3-format@1 - 3", d3-format@3: version "3.1.0" resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== -d3-geo@1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.12.1.tgz#7fc2ab7414b72e59fbcbd603e80d9adc029b035f" - integrity sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg== - dependencies: - d3-array "1" - d3-geo@3: version "3.1.0" resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.0.tgz#74fd54e1f4cebd5185ac2039217a98d39b0a4c0e" @@ -1866,23 +3408,11 @@ d3-geo@3: dependencies: d3-array "2.5.0 - 3" -d3-hierarchy@1: - version "1.1.9" - resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" - integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== - d3-hierarchy@3: version "3.1.2" resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz#b01cd42c1eed3d46db77a5966cf726f8c09160c6" integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== -d3-interpolate@1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" - integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== - dependencies: - d3-color "1" - "d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" @@ -1900,43 +3430,28 @@ d3-path@1: resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== -d3-polygon@1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.6.tgz#0bf8cb8180a6dc107f518ddf7975e12abbfbd38e" - integrity sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ== - d3-polygon@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-3.0.1.tgz#0b45d3dd1c48a29c8e057e6135693ec80bf16398" integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== -d3-quadtree@1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" - integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== - "d3-quadtree@1 - 3", d3-quadtree@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-3.0.1.tgz#6dca3e8be2b393c9a9d514dabbd80a92deef1a4f" integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== -d3-random@1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.1.2.tgz#2833be7c124360bf9e2d3fd4f33847cfe6cab291" - integrity sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ== - d3-random@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-3.0.1.tgz#d4926378d333d9c0bfd1e6fa0194d30aebaa20f4" integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== -d3-scale-chromatic@1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz#54e333fc78212f439b14641fb55801dd81135a98" - integrity sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg== +d3-sankey@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.12.3.tgz#b3c268627bd72e5d80336e8de6acbfec9d15d01d" + integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== dependencies: - d3-color "1" - d3-interpolate "1" + d3-array "1 - 2" + d3-shape "^1.2.0" d3-scale-chromatic@3: version "3.0.0" @@ -1946,18 +3461,6 @@ d3-scale-chromatic@3: d3-color "1 - 3" d3-interpolate "1 - 3" -d3-scale@2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" - integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== - dependencies: - d3-array "^1.2.0" - d3-collection "1" - d3-format "1" - d3-interpolate "1" - d3-time "1" - d3-time-format "2" - d3-scale@4: version "4.0.2" resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" @@ -1969,23 +3472,11 @@ d3-scale@4: d3-time "2.1.1 - 3" d3-time-format "2 - 4" -d3-selection@1, d3-selection@^1.1.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.4.2.tgz#dcaa49522c0dbf32d6c1858afc26b6094555bc5c" - integrity sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg== - -"d3-selection@2 - 3", d3-selection@3: +"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== -d3-shape@1: - version "1.3.7" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - d3-shape@3: version "3.2.0" resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" @@ -1993,12 +3484,12 @@ d3-shape@3: dependencies: d3-path "^3.1.0" -d3-time-format@2: - version "2.3.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.3.0.tgz#107bdc028667788a8924ba040faf1fbccd5a7850" - integrity sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ== +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== dependencies: - d3-time "1" + d3-path "1" "d3-time-format@2 - 4", d3-time-format@4: version "4.1.0" @@ -2007,11 +3498,6 @@ d3-time-format@2: dependencies: d3-time "1 - 3" -d3-time@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" - integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== - "d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: version "3.1.0" resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" @@ -2019,29 +3505,12 @@ d3-time@1: dependencies: d3-array "2 - 3" -d3-timer@1: - version "1.0.10" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" - integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== - "d3-timer@1 - 3", d3-timer@3: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== -d3-transition@1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.3.2.tgz#a98ef2151be8d8600543434c1ca80140ae23b398" - integrity sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA== - dependencies: - d3-color "1" - d3-dispatch "1" - d3-ease "1" - d3-interpolate "1" - d3-selection "^1.1.0" - d3-timer "1" - -"d3-transition@2 - 3", d3-transition@3: +"d3-transition@2 - 3", d3-transition@3, d3-transition@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f" integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== @@ -2052,22 +3521,6 @@ d3-transition@1: d3-interpolate "1 - 3" d3-timer "1 - 3" -d3-voronoi@1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" - integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== - -d3-zoom@1: - version "1.8.3" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.8.3.tgz#b6a3dbe738c7763121cd05b8a7795ffe17f4fc0a" - integrity sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ== - dependencies: - d3-dispatch "1" - d3-drag "1" - d3-interpolate "1" - d3-selection "1" - d3-transition "1" - d3-zoom@3: version "3.0.0" resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3" @@ -2079,47 +3532,10 @@ d3-zoom@3: d3-selection "2 - 3" d3-transition "2 - 3" -d3@^5.14: - version "5.16.0" - resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877" - integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw== - dependencies: - d3-array "1" - d3-axis "1" - d3-brush "1" - d3-chord "1" - d3-collection "1" - d3-color "1" - d3-contour "1" - d3-dispatch "1" - d3-drag "1" - d3-dsv "1" - d3-ease "1" - d3-fetch "1" - d3-force "1" - d3-format "1" - d3-geo "1" - d3-hierarchy "1" - d3-interpolate "1" - d3-path "1" - d3-polygon "1" - d3-quadtree "1" - d3-random "1" - d3-scale "2" - d3-scale-chromatic "1" - d3-selection "1" - d3-shape "1" - d3-time "1" - d3-time-format "2" - d3-timer "1" - d3-transition "1" - d3-voronoi "1" - d3-zoom "1" - -d3@^7.0.0: - version "7.8.5" - resolved "https://registry.yarnpkg.com/d3/-/d3-7.8.5.tgz#fde4b760d4486cdb6f0cc8e2cbff318af844635c" - integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== +d3@^7.9.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-7.9.0.tgz#579e7acb3d749caf8860bd1741ae8d371070cd5d" + integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA== dependencies: d3-array "3" d3-axis "3" @@ -2152,28 +3568,18 @@ d3@^7.0.0: d3-transition "3" d3-zoom "3" -dagre-d3@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/dagre-d3/-/dagre-d3-0.6.4.tgz#0728d5ce7f177ca2337df141ceb60fbe6eeb7b29" - integrity sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ== +dagre-d3-es@7.0.14: + version "7.0.14" + resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz#1272276e26457cf3b97dac569f8f0531ec33c377" + integrity sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg== dependencies: - d3 "^5.14" - dagre "^0.8.5" - graphlib "^2.1.8" - lodash "^4.17.15" + d3 "^7.9.0" + lodash-es "^4.17.21" -dagre@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" - integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== - dependencies: - graphlib "^2.1.8" - lodash "^4.17.15" - -dayjs@^1.11.6: - version "1.11.6" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.6.tgz#2e79a226314ec3ec904e3ee1dd5a4f5e5b1c7afb" - integrity sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ== +dayjs@^1.11.19: + version "1.11.20" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.20.tgz#88d919fd639dc991415da5f4cb6f1b6650811938" + integrity sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -2182,41 +3588,47 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.3.4: +debug@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decode-uri-component@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== -deepmerge@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.2.tgz#10499d868844cdad4fee0842df8c7f6f0c95a753" - integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ== +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== +default-browser-id@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.1.tgz#f7a7ccb8f5104bf8e0f71ba3b1ccfa5eafdb21e8" + integrity sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q== + +default-browser@^5.2.1: + version "5.5.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.5.0.tgz#2792e886f2422894545947cc80e1a444496c5976" + integrity sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw== dependencies: - execa "^5.0.0" + bundle-name "^4.1.0" + default-browser-id "^5.0.0" -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== define-property@^0.2.5: version "0.2.5" @@ -2247,7 +3659,7 @@ delaunator@5: dependencies: robust-predicates "^3.0.0" -depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -2257,27 +3669,32 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -destroy@1.2.0: +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-libc@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== + detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== +devlop@^1.0.0, devlop@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + dequal "^2.0.0" dns-packet@^5.2.2: version "5.4.0" @@ -2302,7 +3719,16 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" -domelementtype@^2.0.1, domelementtype@^2.2.0: +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== @@ -2314,10 +3740,19 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: dependencies: domelementtype "^2.2.0" -dompurify@2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.5.tgz#c83ed5a3ae5ce23e52efe654ea052ffb358dd7e3" - integrity sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ== +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +dompurify@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.3.3.tgz#680cae8af3e61320ddf3666a3bc843f7b291b2b6" + integrity sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA== + optionalDependencies: + "@types/trusted-types" "^2.0.7" domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" @@ -2328,6 +3763,15 @@ domutils@^2.5.2, domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1, domutils@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78" + integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -2336,16 +3780,20 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== - electron-to-chromium@^1.5.263: version "1.5.286" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" @@ -2361,10 +3809,23 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.19.0: - version "5.19.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" - integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + +encoding-sniffer@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz#396ec97ac22ce5a037ba44af1992ac9d46a7b819" + integrity sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw== + dependencies: + iconv-lite "^0.6.3" + whatwg-encoding "^3.1.1" + +enhanced-resolve@^5.20.0: + version "5.20.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz#eeeb3966bea62c348c40a0cc9e7912e2557d0be0" + integrity sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA== dependencies: graceful-fs "^4.2.4" tapable "^2.3.0" @@ -2374,15 +3835,30 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -envinfo@^7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== +entities@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== + +entities@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-7.0.1.tgz#26e8a88889db63417dcb9a1e79a3f1bc92b5976b" + integrity sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA== + +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +envinfo@^7.18.0: + version "7.21.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.21.0.tgz#04a251be79f92548541f37d13c8b6f22940c3bae" + integrity sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow== error-ex@^1.3.1: version "1.3.2" @@ -2391,155 +3867,101 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + es-module-lexer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== -esbuild-android-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.12.tgz#5e8151d5f0a748c71a7fbea8cee844ccf008e6fc" - integrity sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q== - -esbuild-android-arm64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.12.tgz#5ee72a6baa444bc96ffcb472a3ba4aba2cc80666" - integrity sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA== - -esbuild-darwin-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.12.tgz#70047007e093fa1b3ba7ef86f9b3fa63db51fe25" - integrity sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q== - -esbuild-darwin-arm64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.12.tgz#41c951f23d9a70539bcca552bae6e5196696ae04" - integrity sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw== - -esbuild-freebsd-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.12.tgz#a761b5afd12bbedb7d56c612e9cfa4d2711f33f0" - integrity sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw== - -esbuild-freebsd-arm64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.12.tgz#6b0839d4d58deabc6cbd96276eb8cbf94f7f335e" - integrity sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g== - -esbuild-linux-32@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.12.tgz#bd50bfe22514d434d97d5150977496e2631345b4" - integrity sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA== - -esbuild-linux-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.12.tgz#074bb2b194bf658245f8490f29c01ffcdfa8c931" - integrity sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA== - -esbuild-linux-arm64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.12.tgz#3bf789c4396dc032875a122988efd6f3733f28f5" - integrity sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ== - -esbuild-linux-arm@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.12.tgz#b91b5a8d470053f6c2c9c8a5e67ec10a71fe4a67" - integrity sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A== - -esbuild-linux-mips64le@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.12.tgz#2fb54099ada3c950a7536dfcba46172c61e580e2" - integrity sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A== - -esbuild-linux-ppc64le@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.12.tgz#9e3b8c09825fb27886249dfb3142a750df29a1b7" - integrity sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg== - -esbuild-linux-riscv64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.12.tgz#923d0f5b6e12ee0d1fe116b08e4ae4478fe40693" - integrity sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA== - -esbuild-linux-s390x@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.12.tgz#3b1620220482b96266a0c6d9d471d451a1eab86f" - integrity sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww== - -esbuild-loader@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-2.20.0.tgz#28fcff0142fa7bd227512d69f31e9a6e202bb88f" - integrity sha512-dr+j8O4w5RvqZ7I4PPB4EIyVTd679EBQnMm+JBB7av+vu05Zpje2IpK5N3ld1VWa+WxrInIbNFAg093+E1aRsA== +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== dependencies: - esbuild "^0.15.6" - joycon "^3.0.1" - json5 "^2.2.0" - loader-utils "^2.0.0" - tapable "^2.2.0" - webpack-sources "^2.2.0" + es-errors "^1.3.0" -esbuild-netbsd-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.12.tgz#276730f80da646859b1af5a740e7802d8cd73e42" - integrity sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w== +esbuild-loader@~4.4.0: + version "4.4.2" + resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-4.4.2.tgz#9a799c590840d3eafd66dbf86f4f7bfa45dd2495" + integrity sha512-8LdoT9sC7fzfvhxhsIAiWhzLJr9yT3ggmckXxsgvM07wgrRxhuT98XhLn3E7VczU5W5AFsPKv9DdWcZIubbWkQ== + dependencies: + esbuild "^0.27.1" + get-tsconfig "^4.10.1" + loader-utils "^2.0.4" + webpack-sources "^1.4.3" -esbuild-openbsd-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.12.tgz#bd0eea1dd2ca0722ed489d88c26714034429f8ae" - integrity sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw== - -esbuild-sunos-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.12.tgz#5e56bf9eef3b2d92360d6d29dcde7722acbecc9e" - integrity sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg== - -esbuild-windows-32@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.12.tgz#a4f1a301c1a2fa7701fcd4b91ef9d2620cf293d0" - integrity sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw== - -esbuild-windows-64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.12.tgz#bc2b467541744d653be4fe64eaa9b0dbbf8e07f6" - integrity sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA== - -esbuild-windows-arm64@0.15.12: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.12.tgz#9a7266404334a86be800957eaee9aef94c3df328" - integrity sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA== - -esbuild@^0.15.12, esbuild@^0.15.6, esbuild@^0.15.9: - version "0.15.12" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.12.tgz#6c8e22d6d3b7430d165c33848298d3fc9a1f251c" - integrity sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng== +esbuild@^0.25.0, esbuild@^0.25.10: + version "0.25.12" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.12.tgz#97a1d041f4ab00c2fce2f838d2b9969a2d2a97a5" + integrity sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg== optionalDependencies: - "@esbuild/android-arm" "0.15.12" - "@esbuild/linux-loong64" "0.15.12" - esbuild-android-64 "0.15.12" - esbuild-android-arm64 "0.15.12" - esbuild-darwin-64 "0.15.12" - esbuild-darwin-arm64 "0.15.12" - esbuild-freebsd-64 "0.15.12" - esbuild-freebsd-arm64 "0.15.12" - esbuild-linux-32 "0.15.12" - esbuild-linux-64 "0.15.12" - esbuild-linux-arm "0.15.12" - esbuild-linux-arm64 "0.15.12" - esbuild-linux-mips64le "0.15.12" - esbuild-linux-ppc64le "0.15.12" - esbuild-linux-riscv64 "0.15.12" - esbuild-linux-s390x "0.15.12" - esbuild-netbsd-64 "0.15.12" - esbuild-openbsd-64 "0.15.12" - esbuild-sunos-64 "0.15.12" - esbuild-windows-32 "0.15.12" - esbuild-windows-64 "0.15.12" - esbuild-windows-arm64 "0.15.12" + "@esbuild/aix-ppc64" "0.25.12" + "@esbuild/android-arm" "0.25.12" + "@esbuild/android-arm64" "0.25.12" + "@esbuild/android-x64" "0.25.12" + "@esbuild/darwin-arm64" "0.25.12" + "@esbuild/darwin-x64" "0.25.12" + "@esbuild/freebsd-arm64" "0.25.12" + "@esbuild/freebsd-x64" "0.25.12" + "@esbuild/linux-arm" "0.25.12" + "@esbuild/linux-arm64" "0.25.12" + "@esbuild/linux-ia32" "0.25.12" + "@esbuild/linux-loong64" "0.25.12" + "@esbuild/linux-mips64el" "0.25.12" + "@esbuild/linux-ppc64" "0.25.12" + "@esbuild/linux-riscv64" "0.25.12" + "@esbuild/linux-s390x" "0.25.12" + "@esbuild/linux-x64" "0.25.12" + "@esbuild/netbsd-arm64" "0.25.12" + "@esbuild/netbsd-x64" "0.25.12" + "@esbuild/openbsd-arm64" "0.25.12" + "@esbuild/openbsd-x64" "0.25.12" + "@esbuild/openharmony-arm64" "0.25.12" + "@esbuild/sunos-x64" "0.25.12" + "@esbuild/win32-arm64" "0.25.12" + "@esbuild/win32-ia32" "0.25.12" + "@esbuild/win32-x64" "0.25.12" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +esbuild@^0.27.1: + version "0.27.4" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.4.tgz#b9591dd7e0ab803a11c9c3b602850403bef22f00" + integrity sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.27.4" + "@esbuild/android-arm" "0.27.4" + "@esbuild/android-arm64" "0.27.4" + "@esbuild/android-x64" "0.27.4" + "@esbuild/darwin-arm64" "0.27.4" + "@esbuild/darwin-x64" "0.27.4" + "@esbuild/freebsd-arm64" "0.27.4" + "@esbuild/freebsd-x64" "0.27.4" + "@esbuild/linux-arm" "0.27.4" + "@esbuild/linux-arm64" "0.27.4" + "@esbuild/linux-ia32" "0.27.4" + "@esbuild/linux-loong64" "0.27.4" + "@esbuild/linux-mips64el" "0.27.4" + "@esbuild/linux-ppc64" "0.27.4" + "@esbuild/linux-riscv64" "0.27.4" + "@esbuild/linux-s390x" "0.27.4" + "@esbuild/linux-x64" "0.27.4" + "@esbuild/netbsd-arm64" "0.27.4" + "@esbuild/netbsd-x64" "0.27.4" + "@esbuild/openbsd-arm64" "0.27.4" + "@esbuild/openbsd-x64" "0.27.4" + "@esbuild/openharmony-arm64" "0.27.4" + "@esbuild/sunos-x64" "0.27.4" + "@esbuild/win32-arm64" "0.27.4" + "@esbuild/win32-ia32" "0.27.4" + "@esbuild/win32-x64" "0.27.4" escalade@^3.2.0: version "3.2.0" @@ -2606,36 +4028,6 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" - integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^3.0.1" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2649,39 +4041,39 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -express@^4.17.3, express@^4.18.2: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== +express@^4.21.2, express@^4.22.1: + version "4.22.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" + integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" - content-disposition "0.5.4" + body-parser "~1.20.3" + content-disposition "~0.5.4" content-type "~1.0.4" - cookie "0.6.0" - cookie-signature "1.0.6" + cookie "~0.7.1" + cookie-signature "~1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" + finalhandler "~1.3.1" + fresh "~0.5.2" + http-errors "~2.0.0" + merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "~0.1.12" proxy-addr "~2.0.7" - qs "6.11.0" + qs "~6.14.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "~0.19.0" + serve-static "~1.16.2" setprototypeof "1.2.0" - statuses "2.0.1" + statuses "~2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -2701,6 +4093,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -2720,29 +4117,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - fast-uri@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -2750,10 +4129,15 @@ faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" -fflate@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.4.tgz#61587e5d958fdabb5a9368a302c25363f4f69f50" - integrity sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw== +fdir@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + +fflate@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" + integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== fill-range@^4.0.0: version "4.0.0" @@ -2785,19 +4169,24 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" + integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - statuses "2.0.1" + statuses "~2.0.2" unpipe "~1.0.0" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + follow-redirects@^1.0.0: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" @@ -2813,10 +4202,10 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +fraction.js@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" + integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== fragment-cache@^0.2.1: version "0.2.1" @@ -2825,66 +4214,76 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fresh@0.5.2: +fresh@0.5.2, fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== +fs-extra@^11.3.2: + version "11.3.4" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.4.tgz#ab6934eca8bcf6f7f6b82742e33591f86301d6fc" + integrity sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -get-intrinsic@^1.0.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-east-asian-width@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz#ce7008fe345edcf5497a6f557cfa54bc318a9ce7" + integrity sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA== + +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + +get-tsconfig@^4.10.1: + version "4.13.6" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.6.tgz#2fbfda558a98a691a798f123afd95915badce876" + integrity sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw== + dependencies: + resolve-pkg-maps "^1.0.0" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - glob-parent@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" @@ -2892,33 +4291,27 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regex.js@^1.0.0, glob-to-regex.js@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz#2b323728271d133830850e32311f40766c5f6413" + integrity sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ== + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^13.1.1, globby@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.2.tgz#29047105582427ab6eca4f905200667b056da515" - integrity sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^4.0.0" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.10" @@ -2930,13 +4323,6 @@ graceful-fs@^4.2.11: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -graphlib@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" - integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== - dependencies: - lodash "^4.17.15" - gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -2947,6 +4333,11 @@ gray-matter@^4.0.3: section-matter "^1.0.0" strip-bom-string "^1.0.0" +hachure-fill@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/hachure-fill/-/hachure-fill-0.5.2.tgz#d19bc4cc8750a5962b47fb1300557a85fcf934cc" + integrity sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg== + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -2962,10 +4353,10 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== has-value@^0.3.1: version "0.3.1" @@ -2998,23 +4389,105 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash-sum@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hast-util-from-html@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz#485c74785358beb80c4ba6346299311ac4c49c82" + integrity sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw== + dependencies: + "@types/hast" "^3.0.0" + devlop "^1.1.0" + hast-util-from-parse5 "^8.0.0" + parse5 "^7.0.0" + vfile "^6.0.0" + vfile-message "^4.0.0" + +hast-util-from-parse5@^8.0.0: + version "8.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz#830a35022fff28c3fea3697a98c2f4cc6b835a2e" + integrity sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^9.0.0" + property-information "^7.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-sanitize@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz#edb260d94e5bba2030eb9375790a8753e5bf391f" + integrity sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg== + dependencies: + "@types/hast" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + unist-util-position "^5.0.0" + +hast-util-to-html@^9.0.0, hast-util-to-html@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz#ccc673a55bb8e85775b08ac28380f72d47167005" + integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + +hastscript@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-9.0.1.tgz#dbc84bef6051d40084342c229c451cd9dc567dff" + integrity sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hookable@^5.5.3: + version "5.5.3" + resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d" + integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ== + hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -3025,11 +4498,6 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" -html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== - html-minifier-terser@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" @@ -3043,10 +4511,15 @@ html-minifier-terser@^6.0.2: relateurl "^0.2.7" terser "^5.10.0" -html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +html-webpack-plugin@^5.6.4: + version "5.6.6" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.6.tgz#5321b9579f4a1949318550ced99c2a4a4e60cbaf" + integrity sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -3054,6 +4527,16 @@ html-webpack-plugin@^5.5.0: pretty-error "^4.0.0" tapable "^2.0.0" +htmlparser2@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-10.1.0.tgz#fe3f2e12c73b6e462d4e10395db9c1119e4d6ae4" + integrity sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.2.2" + entities "^7.0.1" + htmlparser2@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" @@ -3090,6 +4573,17 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@~2.0.0, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" @@ -3105,10 +4599,10 @@ http-proxy-middleware@^0.19.1: lodash "^4.17.11" micromatch "^3.1.10" -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== +http-proxy-middleware@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" + integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -3125,90 +4619,72 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +hyperdyperid@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b" + integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== -human-signals@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" - integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== - -iconv-lite@0.4, iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@0.6: +iconv-lite@0.6, iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@~0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +immutable@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.5.tgz#93ee4db5c2a9ab42a4a783069f3c5d8847d40165" + integrity sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A== -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -immutable@^4.0.0: - version "4.3.8" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.8.tgz#02d183c7727fb2bb1d5d0380da0d779dce9296a7" - integrity sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw== - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== +import-fresh@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + "internmap@1 - 2": version "2.0.3" resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== +ipaddr.js@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz#71dce70e1398122208996d1c22f2ba46a24b1abc" + integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -3241,13 +4717,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -3280,10 +4749,10 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" @@ -3309,11 +4778,23 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-interactive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== +is-network-error@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.3.1.tgz#a2a86b80ffd6b05b774755c73c8aaab16597e58d" + integrity sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw== + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3331,6 +4812,11 @@ is-plain-obj@^3.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3338,43 +4824,28 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-unicode-supported@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" - integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== +is-unicode-supported@^2.0.0, is-unicode-supported@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" + integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== +is-wsl@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.1.tgz#327897b26832a3eb117da6c27492d04ca132594f" + integrity sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw== dependencies: - is-docker "^2.0.0" + is-inside-container "^1.0.0" isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -3387,11 +4858,28 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -javascript-stringify@^2.0.1: +javascript-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== +jest-regex-util@30.0.1: + version "30.0.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-30.0.1.tgz#f17c1de3958b67dfe485354f5a10093298f2a49b" + integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA== + +jest-util@30.3.0: + version "30.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.3.0.tgz#95a4fbacf2dac20e768e2f1744b70519f2ba7980" + integrity sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg== + dependencies: + "@jest/types" "30.3.0" + "@types/node" "*" + chalk "^4.1.2" + ci-info "^4.2.0" + graceful-fs "^4.2.11" + picomatch "^4.0.3" + jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -3401,10 +4889,21 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -joycon@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" - integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== +jest-worker@^30.0.5: + version "30.3.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-30.3.0.tgz#ae4dc1f1d93d0cba1415624fcedaec40ea764f14" + integrity sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ== + dependencies: + "@types/node" "*" + "@ungap/structured-clone" "^1.3.0" + jest-util "30.3.0" + merge-stream "^2.0.0" + supports-color "^8.1.1" + +jiti@^2.5.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.6.1.tgz#178ef2fc9a1a594248c20627cd820187a4d78d92" + integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== js-tokens@^4.0.0: version "4.0.0" @@ -3419,6 +4918,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -3429,16 +4935,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json5@^2.1.2, json5@^2.2.0: +json5@^2.1.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -3448,10 +4949,17 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -khroma@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.4.1.tgz#ad6a5b6a972befc5112ce5129887a1a83af2c003" - integrity sha512-+GmxKvmiRuCcUYDgR7g5Ngo0JEDeOsGdNONdU2zsiBQaK4z19Y2NvXqfEDE0ZiIrg45GTZyAnPLVsLZZACYm3Q== +katex@^0.16.25: + version "0.16.40" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.40.tgz#87c94e4149f8fa7c22ff95bae1dc687355a38d63" + integrity sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q== + dependencies: + commander "^8.3.0" + +khroma@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/khroma/-/khroma-2.1.0.tgz#45f2ce94ce231a437cf5b63c2e886e6eb42bbbb1" + integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" @@ -3477,34 +4985,132 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klona@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== +langium@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/langium/-/langium-4.2.1.tgz#23e9e12d79778578efa912e3ca8fe313aa61ac17" + integrity sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ== + dependencies: + chevrotain "~11.1.1" + chevrotain-allstar "~0.3.1" + vscode-languageserver "~9.0.1" + vscode-languageserver-textdocument "~1.0.11" + vscode-uri "~3.1.0" -lilconfig@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +launch-editor@^2.6.1: + version "2.13.2" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.13.2.tgz#41d51baaf8afb393224b89bd2bcb4e02f2306405" + integrity sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg== + dependencies: + picocolors "^1.1.1" + shell-quote "^1.8.3" + +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + +lightningcss-android-arm64@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz#f033885116dfefd9c6f54787523e3514b61e1968" + integrity sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg== + +lightningcss-darwin-arm64@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz#50b71871b01c8199584b649e292547faea7af9b5" + integrity sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ== + +lightningcss-darwin-x64@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz#35f3e97332d130b9ca181e11b568ded6aebc6d5e" + integrity sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w== + +lightningcss-freebsd-x64@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz#9777a76472b64ed6ff94342ad64c7bafd794a575" + integrity sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig== + +lightningcss-linux-arm-gnueabihf@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz#13ae652e1ab73b9135d7b7da172f666c410ad53d" + integrity sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw== + +lightningcss-linux-arm64-gnu@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz#417858795a94592f680123a1b1f9da8a0e1ef335" + integrity sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ== + +lightningcss-linux-arm64-musl@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz#6be36692e810b718040802fd809623cffe732133" + integrity sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg== + +lightningcss-linux-x64-gnu@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz#0b7803af4eb21cfd38dd39fe2abbb53c7dd091f6" + integrity sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA== + +lightningcss-linux-x64-musl@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz#88dc8ba865ddddb1ac5ef04b0f161804418c163b" + integrity sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg== + +lightningcss-win32-arm64-msvc@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz#4f30ba3fa5e925f5b79f945e8cc0d176c3b1ab38" + integrity sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw== + +lightningcss-win32-x64-msvc@1.32.0: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz#141aa5605645064928902bb4af045fa7d9f4220a" + integrity sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q== + +lightningcss@^1.30.2: + version "1.32.0" + resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9" + integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ== + dependencies: + detect-libc "^2.0.3" + optionalDependencies: + lightningcss-android-arm64 "1.32.0" + lightningcss-darwin-arm64 "1.32.0" + lightningcss-darwin-x64 "1.32.0" + lightningcss-freebsd-x64 "1.32.0" + lightningcss-linux-arm-gnueabihf "1.32.0" + lightningcss-linux-arm64-gnu "1.32.0" + lightningcss-linux-arm64-musl "1.32.0" + lightningcss-linux-x64-gnu "1.32.0" + lightningcss-linux-x64-musl "1.32.0" + lightningcss-win32-arm64-msvc "1.32.0" + lightningcss-win32-x64-msvc "1.32.0" + +lilconfig@^3.1.1, lilconfig@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkify-it@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" - integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== +linkify-it@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" + integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== dependencies: - uc.micro "^1.0.1" + uc.micro "^2.0.0" loader-runner@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== -loader-utils@^2.0.0: +loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== @@ -3513,18 +5119,33 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: +lodash-es@4.17.23, lodash-es@^4.17.21, lodash-es@^4.17.23: + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.23.tgz#58c4360fd1b5d33afc6c0bbd3d1149349b1138e0" + integrity sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@^4.17.11, lodash@^4.17.20, lodash@^4.17.21: version "4.17.23" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== -log-symbols@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-5.1.0.tgz#a20e3b9a5f53fac6aeb8e2bb22c07cf2c8f16d93" - integrity sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA== +log-symbols@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-7.0.1.tgz#f52e68037d96f589fc572ff2193dc424d48c195b" + integrity sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg== dependencies: - chalk "^5.0.0" - is-unicode-supported "^1.1.0" + is-unicode-supported "^2.0.0" + yoctocolors "^2.1.1" lower-case@^2.0.2: version "2.0.2" @@ -3533,19 +5154,12 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +magic-string@^0.30.21: + version "0.30.21" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91" + integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== dependencies: - yallist "^4.0.0" - -magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== - dependencies: - sourcemap-codec "^1.4.8" + "@jridgewell/sourcemap-codec" "^1.5.5" map-cache@^0.2.2: version "0.2.2" @@ -3559,94 +5173,172 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-it-anchor@^8.6.5: - version "8.6.5" - resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz#30c4bc5bbff327f15ce3c429010ec7ba75e7b5f8" - integrity sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ== +markdown-it-anchor@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz#89375d9a2a79336403ab7c4fd36b1965cc45e5c8" + integrity sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg== -markdown-it-container@^3.0.0: +markdown-it-emoji@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b" - integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw== + resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-3.0.0.tgz#8475a04d671d7c93f931b76fb90c582768b7f0b5" + integrity sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg== -markdown-it-emoji@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/markdown-it-emoji/-/markdown-it-emoji-2.0.2.tgz#cd42421c2fda1537d9cc12b9923f5c8aeb9029c8" - integrity sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ== - -markdown-it@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" - integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== +markdown-it@^14.1.0: + version "14.1.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.1.tgz#856f90b66fc39ae70affd25c1b18b581d7deee1f" + integrity sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA== dependencies: argparse "^2.0.1" - entities "~3.0.1" - linkify-it "^4.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" + entities "^4.4.0" + linkify-it "^5.0.0" + mdurl "^2.0.0" + punycode.js "^2.3.1" + uc.micro "^2.1.0" + +marked@^16.3.0: + version "16.4.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3" + integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA== + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +mdast-util-to-hast@^13.0.0: + version "13.2.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz#d7ff84ca499a57e2c060ae67548ad950e689a053" + integrity sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" mdn-data@2.0.28: version "2.0.28" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== +mdn-data@2.27.1: + version "2.27.1" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.27.1.tgz#e37b9c50880b75366c4d40ac63d9bbcacdb61f0e" + integrity sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ== + +mdurl@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0" + integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w== media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -medium-zoom@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/medium-zoom/-/medium-zoom-1.0.6.tgz#9247f21ca9313d8bbe9420aca153a410df08d027" - integrity sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg== +medium-zoom@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/medium-zoom/-/medium-zoom-1.1.0.tgz#6efb6bbda861a02064ee71a2617a8dc4381ecc71" + integrity sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ== -memfs@^3.4.3: - version "3.4.9" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.9.tgz#403bb953776d72fef4e39e1197a25ffa156d143a" - integrity sha512-3rm8kbrzpUGRyPKSGuk387NZOwQ90O4rI9tsWQkzNW7BLSnKGp23RsEsKK8N8QVCrtJoAMqy3spxHC4os4G6PQ== +memfs@^4.43.1: + version "4.57.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.57.1.tgz#5ccee42e2aab1cf086c45baf9c4ef1ff4fffb123" + integrity sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ== dependencies: - fs-monkey "^1.0.3" + "@jsonjoy.com/fs-core" "4.57.1" + "@jsonjoy.com/fs-fsa" "4.57.1" + "@jsonjoy.com/fs-node" "4.57.1" + "@jsonjoy.com/fs-node-builtins" "4.57.1" + "@jsonjoy.com/fs-node-to-fsa" "4.57.1" + "@jsonjoy.com/fs-node-utils" "4.57.1" + "@jsonjoy.com/fs-print" "4.57.1" + "@jsonjoy.com/fs-snapshot" "4.57.1" + "@jsonjoy.com/json-pack" "^1.11.0" + "@jsonjoy.com/util" "^1.9.0" + glob-to-regex.js "^1.0.1" + thingies "^2.5.0" + tree-dump "^1.0.3" + tslib "^2.0.0" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -mermaid@^8.14.0: - version "8.14.0" - resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.14.0.tgz#ef589b0537f56d6340069070edb51719a4faba00" - integrity sha512-ITSHjwVaby1Li738sxhF48sLTxcNyUAoWfoqyztL1f7J6JOLpHOuQPNLBb6lxGPUA0u7xP9IRULgvod0dKu35A== +mermaid@11.13.0: + version "11.13.0" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-11.13.0.tgz#da1a05337073a3141aa8c7d2608048f5db9ed587" + integrity sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw== dependencies: - "@braintree/sanitize-url" "^3.1.0" - d3 "^7.0.0" - dagre "^0.8.5" - dagre-d3 "^0.6.4" - dompurify "2.3.5" - graphlib "^2.1.8" - khroma "^1.4.1" - moment-mini "^2.24.0" - stylis "^4.0.10" + "@braintree/sanitize-url" "^7.1.1" + "@iconify/utils" "^3.0.2" + "@mermaid-js/parser" "^1.0.1" + "@types/d3" "^7.4.3" + "@upsetjs/venn.js" "^2.0.0" + cytoscape "^3.33.1" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.2.0" + d3 "^7.9.0" + d3-sankey "^0.12.3" + dagre-d3-es "7.0.14" + dayjs "^1.11.19" + dompurify "^3.3.1" + katex "^0.16.25" + khroma "^2.1.0" + lodash-es "^4.17.23" + marked "^16.3.0" + roughjs "^4.6.6" + stylis "^4.3.6" + ts-dedent "^2.2.0" + uuid "^11.1.0" methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromark-util-character@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" + integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" + integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" + integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-symbol@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" + integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== + +micromark-util-types@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" + integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== + micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -3666,7 +5358,7 @@ micromatch@^3.1.10: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.2: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -3679,47 +5371,48 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + +mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime-types@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-function@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" + integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -mini-css-extract-plugin@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" - integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== +mini-css-extract-plugin@^2.9.4: + version "2.10.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.1.tgz#a7f0bb890f4e1ce6dfc124bd1e6d6fcd3b359844" + integrity sha512-k7G3Y5QOegl380tXmZ68foBRRjE9Ljavx835ObdvmZjQ639izvZD8CS7BkWw1qKPPzHsGL/JDhl0uyU1zc2rJw== dependencies: schema-utils "^4.0.0" + tapable "^2.2.1" minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.1.1: - version "3.1.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" - integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== - dependencies: - brace-expansion "^1.1.7" - minimist@^1.2.0: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" @@ -3733,10 +5426,15 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -moment-mini@^2.24.0: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.29.4.tgz#cbbcdc58ce1b267506f28ea6668dbe060a32758f" - integrity sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg== +mlly@^1.7.4, mlly@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.8.2.tgz#e7f7919a82d13b174405613117249a3f449d78bb" + integrity sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA== + dependencies: + acorn "^8.16.0" + pathe "^2.0.3" + pkg-types "^1.3.1" + ufo "^1.6.3" ms@2.0.0: version "2.0.0" @@ -3748,7 +5446,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3761,10 +5459,15 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.6: - version "3.3.8" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" - integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + +nanoid@^5.1.6: + version "5.1.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.1.7.tgz#a9f09a4ce73ba0b88830af36ee49666bad7827b6" + integrity sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ== nanomatch@^1.2.9: version "1.2.13" @@ -3788,6 +5491,11 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -3801,45 +5509,21 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-forge@^1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" - integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw== +node-addon-api@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" + integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== node-releases@^2.0.27: version "2.0.27" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -3856,10 +5540,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-visit@^1.0.0: version "1.0.1" @@ -3880,7 +5564,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@2.4.1: +on-finished@2.4.1, on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -3894,64 +5578,70 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== +on-headers@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" + integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== +onetime@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-7.0.0.tgz#9f16c92d8c9ef5120e3acd9dd9957cceecc1ab60" + integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== dependencies: - wrappy "1" + mimic-function "^5.0.0" -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" +oniguruma-parser@^0.12.1: + version "0.12.1" + resolved "https://registry.yarnpkg.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz#82ba2208d7a2b69ee344b7efe0ae930c627dcc4a" + integrity sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w== -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== +oniguruma-to-es@^4.3.4: + version "4.3.5" + resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-4.3.5.tgz#f2571bb8c8ea52c0bec5595c48cb2d5ebb2b809c" + integrity sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ== dependencies: - mimic-fn "^4.0.0" + oniguruma-parser "^0.12.1" + regex "^6.1.0" + regex-recursion "^6.0.2" -open@^8.0.9: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== +open@^10.0.3: + version "10.2.0" + resolved "https://registry.yarnpkg.com/open/-/open-10.2.0.tgz#b9d855be007620e80b6fb05fac98141fe62db73c" + integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" + default-browser "^5.2.1" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + wsl-utils "^0.1.0" -ora@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/ora/-/ora-6.1.2.tgz#7b3c1356b42fd90fb1dad043d5dbe649388a0bf5" - integrity sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw== +ora@^9.0.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-9.3.0.tgz#187c87cc1062350f549f481de32bf91424c2b0e3" + integrity sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw== dependencies: - bl "^5.0.0" - chalk "^5.0.0" - cli-cursor "^4.0.0" - cli-spinners "^2.6.1" + chalk "^5.6.2" + cli-cursor "^5.0.0" + cli-spinners "^3.2.0" is-interactive "^2.0.0" - is-unicode-supported "^1.1.0" - log-symbols "^5.1.0" - strip-ansi "^7.0.1" - wcwidth "^1.0.1" + is-unicode-supported "^2.1.0" + log-symbols "^7.0.1" + stdin-discarder "^0.3.1" + string-width "^8.1.0" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== +p-retry@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.1.tgz#81828f8dc61c6ef5a800585491572cc9892703af" + integrity sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ== dependencies: - "@types/retry" "0.12.0" + "@types/retry" "0.12.2" + is-network-error "^1.0.0" retry "^0.13.1" +package-manager-detector@^1.3.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/package-manager-detector/-/package-manager-detector-1.6.0.tgz#70d0cf0aa02c877eeaf66c4d984ede0be9130734" + integrity sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -3967,7 +5657,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^5.0.0: +parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -3977,6 +5667,28 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse5-htmlparser2-tree-adapter@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz#b5a806548ed893a43e24ccb42fbb78069311e81b" + integrity sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g== + dependencies: + domhandler "^5.0.3" + parse5 "^7.0.0" + +parse5-parser-stream@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz#d7c20eadc37968d272e2c02660fff92dd27e60e1" + integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow== + dependencies: + parse5 "^7.0.0" + +parse5@^7.0.0, parse5@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== + dependencies: + entities "^6.0.0" + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -3995,40 +5707,25 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-data-parser@0.1.0, path-data-parser@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/path-data-parser/-/path-data-parser-0.1.0.tgz#8f5ba5cc70fc7becb3dcefaea08e2659aba60b8c" + integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-to-regexp@~0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== +pathe@^2.0.1, pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +perfect-debounce@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-2.1.0.tgz#e7078e38f231cb191855c3136a4423aef725d261" + integrity sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g== picocolors@^1.1.1: version "1.1.1" @@ -4040,55 +5737,185 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + +pkg-types@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== + dependencies: + confbox "^0.1.8" + mlly "^1.7.4" + pathe "^2.0.1" + +pkijs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.4.0.tgz#d9164def30ff6d97be2d88966d5e36192499ca9c" + integrity sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw== + dependencies: + "@noble/hashes" "1.4.0" + asn1js "^3.0.6" + bytestreamjs "^2.0.1" + pvtsutils "^1.3.6" + pvutils "^1.1.3" + tslib "^2.8.1" + +points-on-curve@0.2.0, points-on-curve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/points-on-curve/-/points-on-curve-0.2.0.tgz#7dbb98c43791859434284761330fa893cb81b4d1" + integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== + +points-on-path@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/points-on-path/-/points-on-path-0.2.1.tgz#553202b5424c53bed37135b318858eacff85dd52" + integrity sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g== + dependencies: + path-data-parser "0.1.0" + points-on-curve "0.2.0" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== -postcss-csso@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-csso/-/postcss-csso-6.0.1.tgz#6a3e812e236fde6d710a525f2b63e6d9da5a5008" - integrity sha512-ZV4yEziMrx6CEiqabGLrDva0pMD7Fbw7yP+LzJvaynM4OJgTssGN6dHiMsJMJdpmNaLJltXVLsrb/5sxbFa8sA== +postcss-calc@^10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-10.1.1.tgz#52b385f2e628239686eb6e3a16207a43f36064ca" + integrity sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw== dependencies: - csso "^5.0.5" + postcss-selector-parser "^7.0.0" + postcss-value-parser "^4.2.0" -postcss-load-config@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" - integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== +postcss-colormin@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-7.0.6.tgz#8f1bcfaa6f4959a872824f3b5bd4e1278bf35e45" + integrity sha512-oXM2mdx6IBTRm39797QguYzVEWzbdlFiMNfq88fCCN1Wepw3CYmJ/1/Ifa/KjWo+j5ZURDl2NTldLJIw51IeNQ== dependencies: - lilconfig "^2.0.5" - yaml "^2.1.1" + browserslist "^4.28.1" + caniuse-api "^3.0.0" + colord "^2.9.3" + postcss-value-parser "^4.2.0" -postcss-loader@^7.0.1: +postcss-convert-values@^7.0.9: + version "7.0.9" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-7.0.9.tgz#6ada5c2c480f1ddbd4c886339025a916ecc8ff01" + integrity sha512-l6uATQATZaCa0bckHV+r6dLXfWtUBKXxO3jK+AtxxJJtgMPD+VhhPCCx51I4/5w8U5uHV67g3w7PXj+V3wlMlg== + dependencies: + browserslist "^4.28.1" + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-7.0.6.tgz#4e9c696a83391d90b3ffa4485ac144e555db443c" + integrity sha512-Sq+Fzj1Eg5/CPf1ERb0wS1Im5cvE2gDXCE+si4HCn1sf+jpQZxDI4DXEp8t77B/ImzDceWE2ebJQFXdqZ6GRJw== + dependencies: + postcss-selector-parser "^7.1.1" + +postcss-discard-duplicates@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.2.tgz#9cf3e659d4f94b046eef6f93679490c0250a8e4e" + integrity sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w== + +postcss-discard-empty@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.0.1.tgz#4c883cc0a1b2bfe2074377b7a74c1cd805684395" - integrity sha512-VRviFEyYlLjctSM93gAZtcJJ/iSkPZ79zWbN/1fSH+NisBByEiVLqpdVDrPLVSi8DX0oJo12kL/GppTBdKVXiQ== + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-7.0.1.tgz#b6c57e8b5c69023169abea30dceb93f98a2ffd9f" + integrity sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg== + +postcss-discard-overridden@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-7.0.1.tgz#bd9c9bc5e4548d3b6e67e7f8d64f2c9d745ae2a0" + integrity sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg== + +postcss-load-config@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz#6fd7dcd8ae89badcf1b2d644489cbabf83aa8096" + integrity sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g== dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.5" - semver "^7.3.7" + lilconfig "^3.1.1" -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-loader@^8.2.0: + version "8.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.2.1.tgz#c3d9b35498af906fe6c25eb62583c06f619f92fc" + integrity sha512-k98jtRzthjj3f76MYTs9JTpRqV1RaaMhEU0Lpw9OTmQZQdppg4B30VZ74BojuBHt3F4KyubHJoXCMUeM8Bqeow== + dependencies: + cosmiconfig "^9.0.0" + jiti "^2.5.1" + semver "^7.6.2" -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== +postcss-merge-longhand@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-7.0.5.tgz#e1b126e92f583815482e8b1e82c47d2435a20421" + integrity sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^7.0.5" + +postcss-merge-rules@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-7.0.8.tgz#d63ce875b9f7880ca4aa89d9ae3eaa3657215f82" + integrity sha512-BOR1iAM8jnr7zoQSlpeBmCsWV5Uudi/+5j7k05D0O/WP3+OFMPD86c1j/20xiuRtyt45bhxw/7hnhZNhW2mNFA== + dependencies: + browserslist "^4.28.1" + caniuse-api "^3.0.0" + cssnano-utils "^5.0.1" + postcss-selector-parser "^7.1.1" + +postcss-minify-font-values@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-7.0.1.tgz#6fb4770131b31fd5a2014bd84e32f386a3406664" + integrity sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-7.0.1.tgz#933cb642dd00df397237c17194f37dcbe4cad739" + integrity sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A== + dependencies: + colord "^2.9.3" + cssnano-utils "^5.0.1" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-7.0.6.tgz#ca0df1bd4eaa70ee7a4ee17f393d275988f44657" + integrity sha512-YOn02gC68JijlaXVuKvFSCvQOhTpblkcfDre2hb/Aaa58r2BIaK4AtE/cyZf2wV7YKAG+UlP9DT+By0ry1E4VQ== + dependencies: + browserslist "^4.28.1" + cssnano-utils "^5.0.1" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-7.0.6.tgz#1e0240e1fa3372d81d3f0586591f1e8d2ae21e16" + integrity sha512-lIbC0jy3AAwDxEgciZlBullDiMBeBCT+fz5G8RcA9MWqh/hfUkpOI3vNDUNEZHgokaoiv0juB9Y8fGcON7rU/A== + dependencies: + cssesc "^3.0.0" + postcss-selector-parser "^7.1.1" + +postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== + +postcss-modules-local-by-default@^4.0.5: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz#d150f43837831dae25e4085596e84f6f5d6ec368" + integrity sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw== dependencies: icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" + postcss-selector-parser "^7.0.0" postcss-value-parser "^4.1.0" -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== +postcss-modules-scope@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c" + integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA== dependencies: - postcss-selector-parser "^6.0.4" + postcss-selector-parser "^7.0.0" postcss-modules-values@^4.0.0: version "4.0.0" @@ -4097,27 +5924,127 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== +postcss-normalize-charset@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-7.0.1.tgz#bccc3f7c5f4440883608eea8b444c8f41ce55ff6" + integrity sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ== + +postcss-normalize-display-values@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.1.tgz#feb40277d89a7f677b67a84cac999f0306e38235" + integrity sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-7.0.1.tgz#c771c0d33034455205f060b999d8557c2308d22c" + integrity sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.1.tgz#05fe4d838eedbd996436c5cab78feef9bb1ae57b" + integrity sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-7.0.1.tgz#0f111e7b5dfb6de6ab19f09d9e1c16fabeee232f" + integrity sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.1.tgz#7b645a36f113fec49d95d56386c9980316c71216" + integrity sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.6.tgz#6935d6baf7f7374a34c216a7fe13229acd1073f2" + integrity sha512-z6bwTV84YW6ZvvNoaNLuzRW4/uWxDKYI1iIDrzk6D2YTL7hICApy+Q1LP6vBEsljX8FM7YSuV9qI79XESd4ddQ== + dependencies: + browserslist "^4.28.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-7.0.1.tgz#d6471a22b6747ce93d7038c16eb9f1ba8b307e25" + integrity sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.1.tgz#ab8e9ff1f3213f3f3851c0a7d0e4ce4716777cea" + integrity sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-7.0.2.tgz#0e803fbb9601e254270481772252de9a8c905f48" + integrity sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw== + dependencies: + cssnano-utils "^5.0.1" + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-7.0.6.tgz#fa3af45e60cd04d9a3d29315eb97c82b7b447ead" + integrity sha512-G6ZyK68AmrPdMB6wyeA37ejnnRG2S8xinJrZJnOv+IaRKf6koPAVbQsiC7MfkmXaGmF1UO+QCijb27wfpxuRNg== + dependencies: + browserslist "^4.28.1" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.1.tgz#f87111264b0dfa07e1f708d7e6401578707be5d6" + integrity sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-selector-parser@^7.0.0, postcss-selector-parser@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz#e75d2e0d843f620e5df69076166f4e16f891cb9f" + integrity sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" +postcss-svgo@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-7.1.1.tgz#14b90fd2a1b1f27bcb2d0ef0444f954237e7883c" + integrity sha512-zU9H9oEDrUFKa0JB7w+IYL7Qs9ey1mZyjhbf0KLxwJDdDRtoPvCmaEfknzqfHj44QS9VD6c5sJnBAVYTLRg/Sg== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^4.0.1" + +postcss-unique-selectors@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-7.0.5.tgz#a7dd5652c95f459176e5f135c021473e4ee58874" + integrity sha512-3QoYmEt4qg/rUWDn6Tc8+ZVPmbp4G1hXDtCNWDx0st8SjtCbRcxRXDDM1QrEiXGG3A45zscSJFb4QH90LViyxg== + dependencies: + postcss-selector-parser "^7.1.1" + postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.1.10, postcss@^8.4.16, postcss@^8.4.18, postcss@^8.4.7: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== +postcss@^8.4.40, postcss@^8.5.6, postcss@^8.5.8: + version "8.5.8" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.8.tgz#6230ecc8fb02e7a0f6982e53990937857e13f399" + integrity sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg== dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" pretty-error@^4.0.0: version "4.0.0" @@ -4127,7 +6054,7 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -prismjs@^1.29.0: +prismjs@^1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9" integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== @@ -4137,6 +6064,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +property-information@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" + integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -4145,22 +6077,34 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +punycode.js@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" + integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== +pvtsutils@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.6.tgz#ec46e34db7422b9e4fdc5490578c1883657d6001" + integrity sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg== dependencies: - side-channel "^1.0.4" + tslib "^2.8.1" -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +pvutils@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.5.tgz#84b0dea4a5d670249aa9800511804ee0b7c2809c" + integrity sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA== + +qs@~6.14.0: + version "6.14.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c" + integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q== + dependencies: + side-channel "^1.1.0" randombytes@^2.1.0: version "2.1.0" @@ -4174,15 +6118,15 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" readable-stream@^2.0.1: version "2.3.7" @@ -4197,7 +6141,7 @@ readable-stream@^2.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.4.0: +readable-stream@^3.0.6: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -4206,6 +6150,16 @@ readable-stream@^3.0.6, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readdirp@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" + integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== + +readdirp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-5.0.0.tgz#fbf1f71a727891d685bb1786f9ba74084f6e2f91" + integrity sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ== + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -4213,6 +6167,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +reflect-metadata@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" + integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -4221,6 +6180,51 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regex-recursion@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/regex-recursion/-/regex-recursion-6.0.2.tgz#a0b1977a74c87f073377b938dbedfab2ea582b33" + integrity sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg== + dependencies: + regex-utilities "^2.3.0" + +regex-utilities@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-utilities/-/regex-utilities-2.3.0.tgz#87163512a15dce2908cf079c8960d5158ff43280" + integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng== + +regex@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/regex/-/regex-6.1.0.tgz#d7ce98f8ee32da7497c13f6601fca2bc4a6a7803" + integrity sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg== + dependencies: + regex-utilities "^2.3.0" + +rehype-parse@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-9.0.1.tgz#9993bda129acc64c417a9d3654a7be38b2a94c20" + integrity sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag== + dependencies: + "@types/hast" "^3.0.0" + hast-util-from-html "^2.0.0" + unified "^11.0.0" + +rehype-sanitize@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz#16e95f4a67a69cbf0f79e113c8e0df48203db73c" + integrity sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg== + dependencies: + "@types/hast" "^3.0.0" + hast-util-sanitize "^5.0.0" + +rehype-stringify@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-10.0.1.tgz#2ec1ebc56c6aba07905d3b4470bdf0f684f30b75" + integrity sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA== + dependencies: + "@types/hast" "^3.0.0" + hast-util-to-html "^9.0.0" + unified "^11.0.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -4262,27 +6266,23 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +restore-cursor@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" + integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" - integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" + onetime "^7.0.0" + signal-exit "^4.1.0" ret@~0.1.10: version "0.1.15" @@ -4294,59 +6294,82 @@ retry@^0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - robust-predicates@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== -rollup@^2.79.1: - version "2.79.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" - integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== - optionalDependencies: - fsevents "~2.3.2" - -rollup@~2.78.0: - version "2.78.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.1.tgz#52fe3934d9c83cb4f7c4cb5fb75d88591be8648f" - integrity sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg== - optionalDependencies: - fsevents "~2.3.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== +rollup@^4.43.0, rollup@^4.52.4: + version "4.60.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.60.0.tgz#d7d68c8cda873e96e08b2443505609b7e7be9eb8" + integrity sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ== dependencies: - queue-microtask "^1.2.2" + "@types/estree" "1.0.8" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.60.0" + "@rollup/rollup-android-arm64" "4.60.0" + "@rollup/rollup-darwin-arm64" "4.60.0" + "@rollup/rollup-darwin-x64" "4.60.0" + "@rollup/rollup-freebsd-arm64" "4.60.0" + "@rollup/rollup-freebsd-x64" "4.60.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.60.0" + "@rollup/rollup-linux-arm-musleabihf" "4.60.0" + "@rollup/rollup-linux-arm64-gnu" "4.60.0" + "@rollup/rollup-linux-arm64-musl" "4.60.0" + "@rollup/rollup-linux-loong64-gnu" "4.60.0" + "@rollup/rollup-linux-loong64-musl" "4.60.0" + "@rollup/rollup-linux-ppc64-gnu" "4.60.0" + "@rollup/rollup-linux-ppc64-musl" "4.60.0" + "@rollup/rollup-linux-riscv64-gnu" "4.60.0" + "@rollup/rollup-linux-riscv64-musl" "4.60.0" + "@rollup/rollup-linux-s390x-gnu" "4.60.0" + "@rollup/rollup-linux-x64-gnu" "4.60.0" + "@rollup/rollup-linux-x64-musl" "4.60.0" + "@rollup/rollup-openbsd-x64" "4.60.0" + "@rollup/rollup-openharmony-arm64" "4.60.0" + "@rollup/rollup-win32-arm64-msvc" "4.60.0" + "@rollup/rollup-win32-ia32-msvc" "4.60.0" + "@rollup/rollup-win32-x64-gnu" "4.60.0" + "@rollup/rollup-win32-x64-msvc" "4.60.0" + fsevents "~2.3.2" + +roughjs@^4.6.6: + version "4.6.6" + resolved "https://registry.yarnpkg.com/roughjs/-/roughjs-4.6.6.tgz#1059f49a5e0c80dee541a005b20cc322b222158b" + integrity sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ== + dependencies: + hachure-fill "^0.5.2" + path-data-parser "^0.1.0" + points-on-curve "^0.2.0" + points-on-path "^0.2.1" + +run-applescript@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.1.0.tgz#2e9e54c4664ec3106c5b5630e249d3d6595c4911" + integrity sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== rw@1: version "1.3.3" resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +rxjs@^7.4.0: + version "7.8.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + dependencies: + tslib "^2.1.0" safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -4359,14 +6382,154 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@^1.55.0: - version "1.55.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c" - integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A== +sass-embedded-all-unknown@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.98.0.tgz#0c91965a1ba012f0aadb6b3d55a6d5c0b18bac04" + integrity sha512-6n4RyK7/1mhdfYvpP3CClS3fGoYqDvRmLClCESS6I7+SAzqjxvGG6u5Fo+cb1nrPNbbilgbM4QKdgcgWHO9NCA== dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" + sass "1.98.0" + +sass-embedded-android-arm64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.98.0.tgz#58e21f445c301b59728003c503a80b5fbb1182a7" + integrity sha512-M9Ra98A6vYJHpwhoC/5EuH1eOshQ9ZyNwC8XifUDSbRl/cGeQceT1NReR9wFj3L7s1pIbmes1vMmaY2np0uAKQ== + +sass-embedded-android-arm@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-android-arm/-/sass-embedded-android-arm-1.98.0.tgz#40e4b7ce6f474416226a76776ce1e4dc9fde466c" + integrity sha512-LjGiMhHgu7VL1n7EJxTCre1x14bUsWd9d3dnkS2rku003IWOI/fxc7OXgaKagoVzok1kv09rzO3vFXJR5ZeONQ== + +sass-embedded-android-riscv64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.98.0.tgz#9de379d27ed167444cdc1bfc80d102a8a9d0e111" + integrity sha512-WPe+0NbaJIZE1fq/RfCZANMeIgmy83x4f+SvFOG7LhUthHpZWcOcrPTsCKKmN3xMT3iw+4DXvqTYOCYGRL3hcQ== + +sass-embedded-android-x64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-android-x64/-/sass-embedded-android-x64-1.98.0.tgz#a4f688057d737b711f96f840231b3dce4f43c850" + integrity sha512-zrD25dT7OHPEgLWuPEByybnIfx4rnCtfge4clBgjZdZ3lF6E7qNLRBtSBmoFflh6Vg0RlEjJo5VlpnTMBM5MQQ== + +sass-embedded-darwin-arm64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.98.0.tgz#a71da5fe877884e0b5aee3e59fb425abda94bb02" + integrity sha512-cgr1z9rBnCdMf8K+JabIaYd9Rag2OJi5mjq08XJfbJGMZV/TA6hFJCLGkr5/+ZOn4/geTM5/3aSfQ8z5EIJAOg== + +sass-embedded-darwin-x64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.98.0.tgz#0dedd7f956bf25252c13af0ca983af23e9b87dff" + integrity sha512-OLBOCs/NPeiMqTdOrMFbVHBQFj19GS3bSVSxIhcCq16ZyhouUkYJEZjxQgzv9SWA2q6Ki8GCqp4k6jMeUY9dcA== + +sass-embedded-linux-arm64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.98.0.tgz#a17f72336a25664ae536bd5df19b42b84a08625d" + integrity sha512-axOE3t2MTBwCtkUCbrdM++Gj0gC0fdHJPrgzQ+q1WUmY9NoNMGqflBtk5mBZaWUeha2qYO3FawxCB8lctFwCtw== + +sass-embedded-linux-arm@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.98.0.tgz#af86953007a36e0b3dd21dcb8244ecc420447c6d" + integrity sha512-03baQZCxVyEp8v1NWBRlzGYrmVT/LK7ZrHlF1piscGiGxwfdxoLXVuxsylx3qn/dD/4i/rh7Bzk7reK1br9jvQ== + +sass-embedded-linux-musl-arm64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.98.0.tgz#e8b34278e0313b20de0285d3aefe0c6f19742bb4" + integrity sha512-LeqNxQA8y4opjhe68CcFvMzCSrBuJqYVFbwElEj9bagHXQHTp9xVPJRn6VcrC+0VLEDq13HVXMv7RslIuU0zmA== + +sass-embedded-linux-musl-arm@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.98.0.tgz#8c007f05d54bc9a86457733517dae64fa9f1f99d" + integrity sha512-OBkjTDPYR4hSaueOGIM6FDpl9nt/VZwbSRpbNu9/eEJcxE8G/vynRugW8KRZmCFjPy8j/jkGBvvS+k9iOqKV3g== + +sass-embedded-linux-musl-riscv64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.98.0.tgz#846fe9bf7b31baf7d86f3b349768a56d55034748" + integrity sha512-7w6hSuOHKt8FZsmjRb3iGSxEzM87fO9+M8nt5JIQYMhHTj5C+JY/vcske0v715HCVj5e1xyTnbGXf8FcASeAIw== + +sass-embedded-linux-musl-x64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.98.0.tgz#c29018ed2909c4a2e37980053e52f71b35d0f76a" + integrity sha512-QikNyDEJOVqPmxyCFkci8ZdCwEssdItfjQFJB+D+Uy5HFqcS5Lv3d3GxWNX/h1dSb23RPyQdQc267ok5SbEyJw== + +sass-embedded-linux-riscv64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.98.0.tgz#91b262e32e14fd4c0cd72b1e2c320cdcdd8d9d94" + integrity sha512-E7fNytc/v4xFBQKzgzBddV/jretA4ULAPO6XmtBiQu4zZBdBozuSxsQLe2+XXeb0X4S2GIl72V7IPABdqke/vA== + +sass-embedded-linux-x64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.98.0.tgz#f89609c115914d09f7ae6d9c4b9cae42c903ffec" + integrity sha512-VsvP0t/uw00mMNPv3vwyYKUrFbqzxQHnRMO+bHdAMjvLw4NFf6mscpym9Bzf+NXwi1ZNKnB6DtXjmcpcvqFqYg== + +sass-embedded-unknown-all@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.98.0.tgz#1256f1c0ccd5ac8d1004a8764d91735e4fafac57" + integrity sha512-C4MMzcAo3oEDQnW7L8SBgB9F2Fq5qHPnaYTZRMOH3Mp/7kM4OooBInXpCiiFjLnjY95hzP4KyctVx0uYR6MYlQ== + dependencies: + sass "1.98.0" + +sass-embedded-win32-arm64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.98.0.tgz#d7c28b1504b0cfc253eaa2e2e675d48b2dd54311" + integrity sha512-nP/10xbAiPbhQkMr3zQfXE4TuOxPzWRQe1Hgbi90jv2R4TbzbqQTuZVOaJf7KOAN4L2Bo6XCTRjK5XkVnwZuwQ== + +sass-embedded-win32-x64@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.98.0.tgz#861ca78a70b6d6b0da8e0bc001f8b2f595e62c37" + integrity sha512-/lbrVsfbcbdZQ5SJCWcV0NVPd6YRs+FtAnfedp4WbCkO/ZO7Zt/58MvI4X2BVpRY/Nt5ZBo1/7v2gYcQ+J4svQ== + +sass-embedded@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.98.0.tgz#c8a314cd522361f814d838d1518be4406e9db716" + integrity sha512-Do7u6iRb6K+lrllcTkB1BXcHwOxcKe3rEfOF/GcCLE2w3WpddakRAosJOHFUR37DpsvimQXEt5abs3NzUjEIqg== + dependencies: + "@bufbuild/protobuf" "^2.5.0" + colorjs.io "^0.5.0" + immutable "^5.1.5" + rxjs "^7.4.0" + supports-color "^8.1.1" + sync-child-process "^1.0.2" + varint "^6.0.0" + optionalDependencies: + sass-embedded-all-unknown "1.98.0" + sass-embedded-android-arm "1.98.0" + sass-embedded-android-arm64 "1.98.0" + sass-embedded-android-riscv64 "1.98.0" + sass-embedded-android-x64 "1.98.0" + sass-embedded-darwin-arm64 "1.98.0" + sass-embedded-darwin-x64 "1.98.0" + sass-embedded-linux-arm "1.98.0" + sass-embedded-linux-arm64 "1.98.0" + sass-embedded-linux-musl-arm "1.98.0" + sass-embedded-linux-musl-arm64 "1.98.0" + sass-embedded-linux-musl-riscv64 "1.98.0" + sass-embedded-linux-musl-x64 "1.98.0" + sass-embedded-linux-riscv64 "1.98.0" + sass-embedded-linux-x64 "1.98.0" + sass-embedded-unknown-all "1.98.0" + sass-embedded-win32-arm64 "1.98.0" + sass-embedded-win32-x64 "1.98.0" + +sass-loader@16.0.7: + version "16.0.7" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.7.tgz#d1f8723b795805831d41b5825e3d9cd72cb939e7" + integrity sha512-w6q+fRHourZ+e+xA1kcsF27iGM6jdB8teexYCfdUw0sYgcDNeZESnDNT9sUmmPm3ooziwUJXGwZJSTF3kOdBfA== + dependencies: + neo-async "^2.6.2" + +sass@1.98.0: + version "1.98.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.98.0.tgz#924ce85a3745ccaccd976262fdc1bc0c13aa8e57" + integrity sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A== + dependencies: + chokidar "^4.0.0" + immutable "^5.1.5" source-map-js ">=0.6.2 <2.0.0" + optionalDependencies: + "@parcel/watcher" "^2.4.1" + +sax@^1.4.1, sax@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.0.tgz#da59637629307b97e7c4cb28e080a7bc38560d5b" + integrity sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA== schema-utils@^4.0.0: version "4.0.0" @@ -4378,7 +6541,7 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" -schema-utils@^4.3.0, schema-utils@^4.3.3: +schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== @@ -4401,19 +6564,18 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== +selfsigned@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-5.5.0.tgz#4c9ab7c7c9f35f18fb6a9882c253eb0e6bd6557b" + integrity sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew== dependencies: - node-forge "^1" + "@peculiar/x509" "^1.14.2" + pkijs "^3.3.3" -semver@^7.3.5, semver@^7.3.7: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" +semver@^7.6.2, semver@^7.6.3: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== send@0.18.0: version "0.18.0" @@ -4434,7 +6596,26 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.2: +send@~0.19.0, send@~0.19.1: + version "0.19.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" + integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~2.0.0" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "~0.5.2" + http-errors "~2.0.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.4.1" + range-parser "~1.2.1" + statuses "~2.0.2" + +serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== @@ -4454,7 +6635,7 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0, serve-static@^1.13.2: +serve-static@^1.13.2: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== @@ -4464,6 +6645,16 @@ serve-static@1.15.0, serve-static@^1.13.2: parseurl "~1.3.3" send "0.18.0" +serve-static@~1.16.2: + version "1.16.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" + integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== + dependencies: + encodeurl "~2.0.0" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "~0.19.1" + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -4479,7 +6670,7 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -4491,45 +6682,79 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== +shell-quote@^1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== + +shiki@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-4.0.2.tgz#d81495df11e1cb8a05907310a6d051e054435586" + integrity sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ== dependencies: - shebang-regex "^3.0.0" + "@shikijs/core" "4.0.2" + "@shikijs/engine-javascript" "4.0.2" + "@shikijs/engine-oniguruma" "4.0.2" + "@shikijs/langs" "4.0.2" + "@shikijs/themes" "4.0.2" + "@shikijs/types" "4.0.2" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shiki@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.11.1.tgz#df0f719e7ab592c484d8b73ec10e215a503ab8cc" - integrity sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: - jsonc-parser "^3.0.0" - vscode-oniguruma "^1.6.1" - vscode-textmate "^6.0.0" + es-errors "^1.3.0" + object-inspect "^1.13.3" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sitemap@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-9.0.1.tgz#33e9b09e2177eb896e05b16da4219f53919842f6" + integrity sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ== + dependencies: + "@types/node" "^24.9.2" + "@types/sax" "^1.2.1" + arg "^5.0.0" + sax "^1.4.1" snapdragon-node@^2.0.1: version "2.1.1" @@ -4570,16 +6795,21 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -source-list-map@^2.0.1: +source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -4609,15 +6839,15 @@ source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: +source-map@^0.6.0, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== spdy-transport@^3.0.0: version "3.0.0" @@ -4672,6 +6902,24 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +statuses@~2.0.1, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + +stdin-discarder@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stdin-discarder/-/stdin-discarder-0.3.1.tgz#92a1e741e709248865d0562bb7babe84d350ae6a" + integrity sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA== + +string-width@^8.1.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-8.2.0.tgz#bdb6a9bd6d7800db635adae96cdb0443fec56c42" + integrity sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw== + dependencies: + get-east-asian-width "^1.5.0" + strip-ansi "^7.1.2" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -4686,6 +6934,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -4693,37 +6949,35 @@ strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== +strip-ansi@^7.1.2: + version "7.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.2.0.tgz#d22a269522836a627af8d04b5c3fd2c7fa3e32e3" + integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w== dependencies: - ansi-regex "^6.0.1" + ansi-regex "^6.2.2" strip-bom-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +style-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-4.0.0.tgz#0ea96e468f43c69600011e0589cb05c44f3b17a5" + integrity sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA== -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== +stylehacks@^7.0.5: + version "7.0.8" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-7.0.8.tgz#cb5d00bb1779a30c4d408a7d576c016c88b36491" + integrity sha512-I3f053GBLIiS5Fg6OMFhq/c+yW+5Hc2+1fgq7gElDMMSqwlRb3tBf2ef6ucLStYRpId4q//bQO1FjcyNyy4yDQ== + dependencies: + browserslist "^4.28.1" + postcss-selector-parser "^7.1.1" -style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== - -stylis@^4.0.10: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" - integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylis@^4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.6.tgz#7c7b97191cb4f195f03ecab7d52f7902ed378320" + integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== supports-color@^5.3.0: version "5.5.0" @@ -4739,37 +6993,63 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: +supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svgo@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-4.0.1.tgz#c82dacd04ee9f1d55cd4e0b7f9a214c86670e3ee" + integrity sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w== + dependencies: + commander "^11.1.0" + css-select "^5.1.0" + css-tree "^3.0.1" + css-what "^6.1.0" + csso "^5.0.5" + picocolors "^1.1.1" + sax "^1.5.0" -tapable@^2.0.0, tapable@^2.2.0: +sync-child-process@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/sync-child-process/-/sync-child-process-1.0.2.tgz#45e7c72e756d1243e80b547ea2e17957ab9e367f" + integrity sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA== + dependencies: + sync-message-port "^1.0.0" + +sync-message-port@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/sync-message-port/-/sync-message-port-1.2.0.tgz#4b0d622085f21496061037125dec61755d96e330" + integrity sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg== + +synckit@^0.11.12: + version "0.11.12" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.12.tgz#abe74124264fbc00a48011b0d98bdc1cffb64a7b" + integrity sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ== + dependencies: + "@pkgr/core" "^0.2.9" + +tapable@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tapable@^2.3.0: +tapable@^2.2.1, tapable@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -terser-webpack-plugin@^5.3.16: - version "5.3.16" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" - integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== +terser-webpack-plugin@^5.3.17: + version "5.4.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz#95fc4cf4437e587be11ecf37d08636089174d76b" + integrity sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g== dependencies: "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" schema-utils "^4.3.0" - serialize-javascript "^6.0.2" terser "^5.31.1" terser@^5.10.0: @@ -4792,11 +7072,29 @@ terser@^5.31.1: commander "^2.20.0" source-map-support "~0.5.20" +thingies@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/thingies/-/thingies-2.6.0.tgz#e09b98b9e6f6caf8a759eca8481fea1de974d2b1" + integrity sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +tinyexec@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.4.tgz#6c60864fe1d01331b2f17c6890f535d7e5385408" + integrity sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw== + +tinyglobby@^0.2.12, tinyglobby@^0.2.15: + version "0.2.15" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" + integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== + dependencies: + fdir "^6.5.0" + picomatch "^4.0.3" + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -4829,21 +7127,53 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -toidentifier@1.0.1: +toidentifier@1.0.1, toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -ts-debounce@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ts-debounce/-/ts-debounce-4.0.0.tgz#33440ef64fab53793c3d546a8ca6ae539ec15841" - integrity sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg== +tree-dump@^1.0.3, tree-dump@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.1.0.tgz#ab29129169dc46004414f5a9d4a3c6e89f13e8a4" + integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA== + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +trough@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" + integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== + +ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tslib@^2.0.3: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== +tsyringe@^4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/tsyringe/-/tsyringe-4.10.0.tgz#d0c95815d584464214060285eaaadd94aa03299c" + integrity sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw== + dependencies: + tslib "^1.9.3" + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -4852,10 +7182,38 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== +uc.micro@^2.0.0, uc.micro@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" + integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== + +ufo@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.3.tgz#799666e4e88c122a9659805e30b9dc071c3aed4f" + integrity sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q== + +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== + +undici@^7.19.0: + version "7.24.5" + resolved "https://registry.yarnpkg.com/undici/-/undici-7.24.5.tgz#7debcf5623df2d1cb469b6face01645d9c852ae2" + integrity sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q== + +unified@^11.0.0, unified@^11.0.5: + version "11.0.5" + resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" + integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== + dependencies: + "@types/unist" "^3.0.0" + bail "^2.0.0" + devlop "^1.0.0" + extend "^3.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^6.0.0" union-value@^1.0.0: version "1.0.1" @@ -4867,12 +7225,50 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +unist-util-is@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.1.tgz#d0a3f86f2dd0db7acd7d8c2478080b5c67f9c6a9" + integrity sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz#777df7fb98652ce16b4b7cd999d0a1a40efa3a02" + integrity sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.1.0.tgz#9a2a28b0aa76a15e0da70a08a5863a2f060e2468" + integrity sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -4890,14 +7286,6 @@ upath@^2.0.1: resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-browserslist-db@^1.2.0: version "1.2.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" @@ -4938,123 +7326,140 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -vite@~3.1.8: - version "3.1.8" - resolved "https://registry.yarnpkg.com/vite/-/vite-3.1.8.tgz#fa29144167d19b773baffd65b3972ea4c12359c9" - integrity sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg== +vfile-location@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" + integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== dependencies: - esbuild "^0.15.9" - postcss "^8.4.16" - resolve "^1.22.1" - rollup "~2.78.0" + "@types/unist" "^3.0.0" + vfile "^6.0.0" + +vfile-message@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" + integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== + dependencies: + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" + +vite@~7.1.9: + version "7.1.12" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.12.tgz#8b29a3f61eba23bcb93fc9ec9af4a3a1e83eecdb" + integrity sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug== + dependencies: + esbuild "^0.25.0" + fdir "^6.5.0" + picomatch "^4.0.3" + postcss "^8.5.6" + rollup "^4.43.0" + tinyglobby "^0.2.15" optionalDependencies: - fsevents "~2.3.2" + fsevents "~2.3.3" -vscode-oniguruma@^1.6.1: - version "1.6.2" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607" - integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA== +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== -vscode-textmate@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-6.0.0.tgz#a3777197235036814ac9a92451492f2748589210" - integrity sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ== +vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== + dependencies: + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" -vue-demi@*: - version "0.13.11" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99" - integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A== +vscode-languageserver-textdocument@~1.0.11: + version "1.0.12" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631" + integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== -vue-loader@^17.0.0: - version "17.0.1" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.0.1.tgz#c0ee8875e0610a0c2d13ba9b4d50a9c8442e7a3a" - integrity sha512-/OOyugJnImKCkAKrAvdsWMuwoCqGxWT5USLsjohzWbMgOwpA5wQmzQiLMzZd7DjhIfunzAGIApTOgIylz/kwcg== +vscode-languageserver-types@3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== + +vscode-languageserver@~9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz#500aef82097eb94df90d008678b0b6b5f474015b" + integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== + dependencies: + vscode-languageserver-protocol "3.17.5" + +vscode-uri@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.1.0.tgz#dd09ec5a66a38b5c3fffc774015713496d14e09c" + integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ== + +vue-loader@^17.4.2: + version "17.4.2" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-17.4.2.tgz#f87f0d8adfcbbe8623de9eba1979d41ba223c6da" + integrity sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w== dependencies: chalk "^4.1.0" hash-sum "^2.0.0" - loader-utils "^2.0.0" + watchpack "^2.4.0" -vue-router@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.1.6.tgz#b70303737e12b4814578d21d68d21618469375a1" - integrity sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ== +vue-router@^4.6.0: + version "4.6.4" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.6.4.tgz#a0a9cb9ef811a106d249e4bb9313d286718020d8" + integrity sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg== dependencies: - "@vue/devtools-api" "^6.4.5" + "@vue/devtools-api" "^6.6.4" -vue@^3.2.41: - version "3.2.41" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.41.tgz#ed452b8a0f7f2b962f055c8955139c28b1c06806" - integrity sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ== +vue@^3.5.22, vue@^3.5.29: + version "3.5.30" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.30.tgz#66df25e9795af3e5522b36f24f3d290fde83f8a0" + integrity sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg== dependencies: - "@vue/compiler-dom" "3.2.41" - "@vue/compiler-sfc" "3.2.41" - "@vue/runtime-dom" "3.2.41" - "@vue/server-renderer" "3.2.41" - "@vue/shared" "3.2.41" + "@vue/compiler-dom" "3.5.30" + "@vue/compiler-sfc" "3.5.30" + "@vue/runtime-dom" "3.5.30" + "@vue/server-renderer" "3.5.30" + "@vue/shared" "3.5.30" -vuepress-plugin-mermaidjs@2.0.0-beta.2: - version "2.0.0-beta.2" - resolved "https://registry.yarnpkg.com/vuepress-plugin-mermaidjs/-/vuepress-plugin-mermaidjs-2.0.0-beta.2.tgz#cd6e030efff6981cd318534fa52c64533079a666" - integrity sha512-0pDJjLFsnMuvy3wc2iEhz0OQy+tQva04ynVdhMKdH6KtetuezxtNbwazEJcRQGzDzyo2r/5rGRLYvA4MhGnj5w== +vuepress@2.0.0-rc.26: + version "2.0.0-rc.26" + resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-2.0.0-rc.26.tgz#c1eb7c2cf58f2c1c6d932fc0006c2d52c116c281" + integrity sha512-ztTS3m6Q2MAb6D26vM2UyU5nOuxIhIk37SSD3jTcKI00x4ha0FcwY3Cm0MAt6w58REBmkwNLPxN5iiulatHtbw== dependencies: - mermaid "^8.14.0" + "@vuepress/cli" "2.0.0-rc.26" + "@vuepress/client" "2.0.0-rc.26" + "@vuepress/core" "2.0.0-rc.26" + "@vuepress/markdown" "2.0.0-rc.26" + "@vuepress/shared" "2.0.0-rc.26" + "@vuepress/utils" "2.0.0-rc.26" + vue "^3.5.22" -vuepress-plugin-redirect@^2.0.0-beta.120: - version "2.0.0-beta.120" - resolved "https://registry.yarnpkg.com/vuepress-plugin-redirect/-/vuepress-plugin-redirect-2.0.0-beta.120.tgz#b1a40c227e3170a903f86ad43dfa1b7a71364677" - integrity sha512-LFOlTZMSqnxwMxF0yb0jvZsTRTCxFH1Dj6jTLcIWERYGe4+EfdLUWtfMAixVLttdu9h3Nie3flJ65wMLdsPbDw== - dependencies: - "@vuepress/cli" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - cac "^6.7.14" - vuepress-shared "2.0.0-beta.120" - -vuepress-shared@2.0.0-beta.120: - version "2.0.0-beta.120" - resolved "https://registry.yarnpkg.com/vuepress-shared/-/vuepress-shared-2.0.0-beta.120.tgz#3f9b3e0533a93c096c5ba1c2eb99f92fdf784392" - integrity sha512-DSxkmHJEnA9oqgFnqtREqO2Q5S/mLRTl2/sQT6qdS8bWAmYEJZEAKBJpt0C2VCELyRMkehfhnTUJtf1MvSF/AA== - dependencies: - "@vuepress/client" "2.0.0-beta.53" - "@vuepress/plugin-git" "2.0.0-beta.53" - "@vuepress/shared" "2.0.0-beta.53" - "@vuepress/utils" "2.0.0-beta.53" - dayjs "^1.11.6" - execa "^6.1.0" - fflate "^0.7.4" - ora "^6.1.2" - vue "^3.2.41" - vue-router "^4.1.6" - -vuepress-vite@2.0.0-beta.53: - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/vuepress-vite/-/vuepress-vite-2.0.0-beta.53.tgz#6724d5edd99df2d494a8145206192e4cc88e9b9a" - integrity sha512-kITVMM+LcV5mDQXQXAKgK0adAGMm7oyPls6HPTLM9gUvpSs2A19zfwf8zFoxIF9X+ANay4Tg87egtnJOcp8Wcg== - dependencies: - "@vuepress/bundler-vite" "2.0.0-beta.53" - "@vuepress/cli" "2.0.0-beta.53" - "@vuepress/core" "2.0.0-beta.53" - "@vuepress/theme-default" "2.0.0-beta.53" - -vuepress@^2.0.0-beta.53: - version "2.0.0-beta.53" - resolved "https://registry.yarnpkg.com/vuepress/-/vuepress-2.0.0-beta.53.tgz#3530f36e6ef99827c8182c13db34aca4d4680231" - integrity sha512-swnH25oCHAE0ZIXBAp4gaalIsrxLLn+mguekOybwLcTNQUgbcqf8EXwVxOgN663JzPuHcxRAJg3nN/swKsFifQ== - dependencies: - vuepress-vite "2.0.0-beta.53" - -watchpack@^2.5.1: +watchpack@^2.4.0, watchpack@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== @@ -5069,92 +7474,91 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== -webpack-chain@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206" - integrity sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA== - dependencies: - deepmerge "^1.5.2" - javascript-stringify "^2.0.1" - -webpack-dev-middleware@^5.3.1: - version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== +webpack-dev-middleware@^7.4.2: + version "7.4.5" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz#d4e8720aa29cb03bc158084a94edb4594e3b7ac0" + integrity sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA== dependencies: colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" + memfs "^4.43.1" + mime-types "^3.0.1" + on-finished "^2.4.1" range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.11.1: - version "4.11.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" - integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== +webpack-dev-server@^5.2.2: + version "5.2.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz#7f36a78be7ac88833fd87757edee31469a9e47d3" + integrity sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ== dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" + "@types/bonjour" "^3.5.13" + "@types/connect-history-api-fallback" "^1.5.4" + "@types/express" "^4.17.25" + "@types/express-serve-static-core" "^4.17.21" + "@types/serve-index" "^1.9.4" + "@types/serve-static" "^1.15.5" + "@types/sockjs" "^0.3.36" + "@types/ws" "^8.5.10" ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" + bonjour-service "^1.2.1" + chokidar "^3.6.0" colorette "^2.0.10" - compression "^1.7.4" + compression "^1.8.1" connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" + express "^4.22.1" graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" + http-proxy-middleware "^2.0.9" + ipaddr.js "^2.1.0" + launch-editor "^2.6.1" + open "^10.0.3" + p-retry "^6.2.0" + schema-utils "^4.2.0" + selfsigned "^5.5.0" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" + webpack-dev-middleware "^7.4.2" + ws "^8.18.0" -webpack-merge@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== +webpack-merge@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" + integrity sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg== dependencies: clone-deep "^4.0.1" - wildcard "^2.0.0" + flat "^5.0.2" + wildcard "^2.0.1" -webpack-sources@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" - integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: - source-list-map "^2.0.1" - source-map "^0.6.1" + source-list-map "^2.0.0" + source-map "~0.6.1" -webpack-sources@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" - integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== +webpack-sources@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.4.tgz#a338b95eb484ecc75fbb196cbe8a2890618b4891" + integrity sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q== -webpack@^5.74.0: - version "5.105.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.0.tgz#38b5e6c5db8cbe81debbd16e089335ada05ea23a" - integrity sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw== +webpack-v5-chain@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-v5-chain/-/webpack-v5-chain-1.1.0.tgz#b2c1a407f2c1adf3eb964a18551efafa3a28bab4" + integrity sha512-GX6NmPpCPoKgjHxAzAhPOzDSMfdX3JzGRcppeYPSmwLmPjiqUDxGZ3rt8h4qsNsZ299rMUMIrHTk5QrIGjwW2g== + dependencies: + deepmerge "^4.3.1" + javascript-stringify "^2.1.0" + +webpack@^5.102.1: + version "5.105.4" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.4.tgz#1b77fcd55a985ac7ca9de80a746caffa38220169" + integrity sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.8" @@ -5162,11 +7566,11 @@ webpack@^5.74.0: "@webassemblyjs/ast" "^1.14.1" "@webassemblyjs/wasm-edit" "^1.14.1" "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.15.0" + acorn "^8.16.0" acorn-import-phases "^1.0.3" browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.19.0" + enhanced-resolve "^5.20.0" es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" @@ -5178,9 +7582,9 @@ webpack@^5.74.0: neo-async "^2.6.2" schema-utils "^4.3.3" tapable "^2.3.0" - terser-webpack-plugin "^5.3.16" + terser-webpack-plugin "^5.3.17" watchpack "^2.5.1" - webpack-sources "^3.3.3" + webpack-sources "^3.3.4" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -5196,39 +7600,41 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== +whatwg-encoding@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" + integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== dependencies: - isexe "^2.0.0" + iconv-lite "0.6.3" -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^8.4.2: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" - integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== - -yallist@^4.0.0: +whatwg-mimetype@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" + integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +wildcard@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== -yaml@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207" - integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg== +ws@^8.18.0: + version "8.20.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8" + integrity sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA== + +wsl-utils@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/wsl-utils/-/wsl-utils-0.1.0.tgz#8783d4df671d4d50365be2ee4c71917a0557baab" + integrity sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw== + dependencies: + is-wsl "^3.1.0" + +yoctocolors@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors/-/yoctocolors-2.1.2.tgz#d795f54d173494e7d8db93150cec0ed7f678c83a" + integrity sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug== + +zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== diff --git a/tools/mcc-env.sh b/tools/mcc-env.sh index eb481e68..95f8a994 100644 --- a/tools/mcc-env.sh +++ b/tools/mcc-env.sh @@ -1,7 +1,7 @@ #!/bin/bash # MCC (Minecraft Console Client) Development Utilities # Source this file to get helper functions: source $MCC_REPO/tools/mcc-env.sh -# Or add to ~/.bashrc: source "$HOME/Minecraft/Minecraft-Console-Client-milutinke/tools/mcc-env.sh" +# Or add to ~/.bashrc: source "$HOME/Minecraft/Minecraft-Console-Client/tools/mcc-env.sh" TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" export MCC_REPO="$(cd "$TOOLS_DIR/.." && pwd)" diff --git a/tools/pull-translations.sh b/tools/pull-translations.sh new file mode 100755 index 00000000..98cfaba7 --- /dev/null +++ b/tools/pull-translations.sh @@ -0,0 +1,66 @@ +#!/bin/bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +CONFIG_FILE="$REPO_ROOT/crowdin.yml" +TMP_CONFIG="" + +if [[ -z "${CROWDIN_PERSONAL_TOKEN:-}" && -n "${CROWDIN_TOKEN:-}" ]]; then + export CROWDIN_PERSONAL_TOKEN="$CROWDIN_TOKEN" +fi + +if [[ ! -f "$CONFIG_FILE" ]]; then + echo "Error: crowdin.yml not found at $CONFIG_FILE" >&2 + exit 1 +fi + +if [[ -z "${CROWDIN_PROJECT_ID:-}" ]]; then + echo "Error: CROWDIN_PROJECT_ID is not set" >&2 + exit 1 +fi + +if [[ -z "${CROWDIN_PERSONAL_TOKEN:-}" ]]; then + echo "Error: CROWDIN_PERSONAL_TOKEN is not set" >&2 + echo "Tip: the CI workflow stores this as CROWDIN_TOKEN and maps it to CROWDIN_PERSONAL_TOKEN." >&2 + exit 1 +fi + +run_crowdin() { + "$@" download translations --all --config "$CONFIG_FILE" +} + +cleanup() { + if [[ -n "$TMP_CONFIG" && -f "$TMP_CONFIG" ]]; then + rm -f "$TMP_CONFIG" + fi +} +trap cleanup EXIT + +make_temp_config() { + local base_path="$1" + TMP_CONFIG="$(mktemp "$REPO_ROOT/.crowdin.local.XXXXXX.yml")" + sed "s#\"base_path\": \"/\"#\"base_path\": \"$base_path\"#" "$CONFIG_FILE" > "$TMP_CONFIG" +} + +cd "$REPO_ROOT" + +if command -v crowdin >/dev/null 2>&1; then + echo "Using local Crowdin CLI" + make_temp_config "$REPO_ROOT" + crowdin download translations --all --config "$TMP_CONFIG" +elif command -v docker >/dev/null 2>&1; then + echo "Using Crowdin CLI via Docker" + make_temp_config "/work" + docker run --rm \ + --entrypoint crowdin \ + -e CROWDIN_PROJECT_ID \ + -e CROWDIN_PERSONAL_TOKEN \ + -v "$REPO_ROOT":/work \ + -w /work \ + crowdin/cli:latest \ + download translations --all --config /work/"$(basename "$TMP_CONFIG")" +else + echo "Error: neither 'crowdin' nor 'docker' is available" >&2 + echo "Install Crowdin CLI or Docker and try again." >&2 + exit 1 +fi From e4aeb51f71b4925a8fd19f3c76162a2ac2094c34 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 15:40:05 +0100 Subject: [PATCH 105/484] Updated documentation to the latest state --- docs/README.md | 2 +- docs/guide/README.md | 32 +- docs/guide/chat-bots.md | 120 +-- docs/guide/configuration.md | 31 +- docs/guide/contibuting.md | 10 +- docs/guide/creating-bots.md | 32 +- docs/guide/creating-text-script.md | 8 +- docs/guide/installation.md | 78 +- docs/guide/usage.md | 22 +- docs/guide/websocket/Commands.md | 1414 +------------------------- docs/guide/websocket/Events.md | 1525 +--------------------------- docs/guide/websocket/README.md | 143 +-- 12 files changed, 149 insertions(+), 3268 deletions(-) diff --git a/docs/README.md b/docs/README.md index ce8fc3b4..97a233ed 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,6 +18,6 @@ features: - title: Automation details: Create bots to do automated tasks - title: Supported Versions - details: 1.4 - 1.20.4 + details: 1.4.6 - 1.21.11 footer: Made by MCC Team with ❤️ --- diff --git a/docs/guide/README.md b/docs/guide/README.md index 0ed618bc..1c3cac0b 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -24,9 +24,9 @@ title: About & Features ## About -**Minecraft Console Client (MCC)** is a lightweight cross-platform open-source **Minecraft** TUI client for **Java edition** that allows you to connect to any Minecraft Java server, send commands and receive text messages in a fast and easy way without having to open the main Minecraft game. +**Minecraft Console Client (MCC)** is a lightweight, cross-platform, open-source **Minecraft** TUI client for **Java Edition**. It lets you connect to Minecraft Java servers, send commands, and receive text messages without launching the main game. -It also provides various automations that you can enable for administration and other purposes, as well as extensible C# API for creating Bots. +It also includes built-in automation for administration and utility work, plus an extensible C# API for creating bots and runtime scripts. It was originally made by [ORelio](https://github.com/ORelio) in 2012 on the [Minecraft Forum](http://www.minecraftforum.net/topic/1314800-/), now it's maintained by him and many other contributors from the community. @@ -57,7 +57,7 @@ It was originally made by [ORelio](https://github.com/ORelio) in 2012 on the [Mi - [Terrain Traversing](usage.md#move) - Entity Handling -_NOTE: Some of mentioned features are disabled by default and you will have to turn them on in the configuration file and some may require additional configuration on your part for your specific usage._ +_Note: Some of these features are disabled by default. You need to enable them in the configuration file, and some also require additional setup._ ## Why Minecraft Console Client? @@ -74,7 +74,7 @@ _NOTE: Some of mentioned features are disabled by default and you will have to t ## Quick Intro -Don't have time to read through the documentation, we got you, our community has made some simple introduction videos about the **Minecraft Console Client**. +If you do not want to read through the documentation right away, the community has made a few short introduction videos for **Minecraft Console Client**. ### The list of the tutorials: @@ -90,7 +90,7 @@ Using Commands, Scripts and other features: ## Getting Help -MCC has a community that is willing to help, we have a Discussions section in out Git Hub repository. +MCC has an active community, and the GitHub Discussions section is the best place to ask for help. Click [here](https://github.com/MCCTeam/Minecraft-Console-Client/discussions) to access it. @@ -101,13 +101,13 @@ Click [here](https://github.com/MCCTeam/Minecraft-Console-Client/discussions) to ## Bugs, Ideas, Feature Requests -Bug reporting, idea submitting or feature requesting are done in the [Issues](https://github.com/MCCTeam/Minecraft-Console-Client/issues) section of our [Github repository]([here](https://github.com/MCCTeam/Minecraft-Console-Client)). +Bug reports, ideas, and feature requests all go through the [Issues](https://github.com/MCCTeam/Minecraft-Console-Client/issues) section of our [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client). -Navigate to the Issues section, search for a bug, idea or a feature using the search option here in the documentation and in the `Issues` section on Git Hub before making your own. +Before opening a new issue, search both the documentation and the `Issues` section to avoid duplicates. -If you haven't found anything similar, go ahead and click on the `New issue` button, then choose what you want to do. +If you do not find anything similar, click `New issue` and choose the appropriate template. -If you're reporting a bug, please be descriptive as much as possible, try to explain how to re-create the bug, attack screenshots and logs, make sure that you have [`debugmessages`](configuration.me#debugmessages) set to `true` before sending a bug report or taking a screenshot. +If you are reporting a bug, be as specific as possible. Explain how to reproduce it, attach screenshots and logs, and make sure debug logging is enabled before collecting them. ### Before submitting @@ -122,20 +122,22 @@ If you want the repeatable agent workflow used by maintainers, start with [AI-As ### Inventory, Terrain and Entity Handling -Inventory handling is currently not supported in versions: `1.4.6 - 1.9` (*The inventory handling code is in the place, but we're missing Item Palettes, on which we're working.*) +MCC currently supports Minecraft versions `1.4.6` through `1.21.11`. -Terrain handling is currently not supported in versions: `1.4.6 - 1.6` +Feature support still depends on protocol version: -Entity handling is currently not supported in versions: `1.4.6 - 1.7` +- Inventory handling is supported on `1.8+`. +- Terrain handling is supported on `1.7.2+`. +- Entity handling is supported on `1.8+`. -There features might not always be implemented in the latest version of the game, since they're often subjected to major changes by Mojang, and we need some time to figure out what has changed and to implement the required changes. +These features may lag behind brand-new Minecraft releases when Mojang changes the protocol or registries in a major way. If there was a major game update, and the MCC hasn't been updated to support these features, if you're a programmer, feel free to contribute to the project. ### Path-Finding and Physics Currently the path-finding and physics have some limitations, those are: -- Path finding under slabs is not supported (currently being worked on, partialy complete but not avaliable in the main branch) +- Path finding under slabs is not supported - Swimming is not supported yet - Jumping is not supported yet - Knockback is not supported yet @@ -197,7 +199,7 @@ We remind you that **you may get banned** by your server for using this program. Minecraft Console Client is a totally free of charge, open source project. -The source code is available at [Github Repository](https://github.com/MCCTeam/Minecraft-Console-Client) +The source code is available at the [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client) Unless specifically stated, source code is from the MCC Team or Contributors, and available under CDDL-1.0. diff --git a/docs/guide/chat-bots.md b/docs/guide/chat-bots.md index 90fbee06..0dcf7965 100644 --- a/docs/guide/chat-bots.md +++ b/docs/guide/chat-bots.md @@ -17,7 +17,6 @@ redirectFrom:

Warning

-**Recently we have changed the configuration format from INI to TOML, this part of the documentation has only been partially updated, it's work in progress, for the time being please refer to the `MinecraftClient.ini` for setting names, the descriptions and options should be up to date in most cases, but not guaranteed.**
@@ -29,30 +28,32 @@ redirectFrom: ## List of built-in Chat Bots -- [Alerts](#alerts) -- [Anti AFK](#anti-afk) -- [Auto Attack](#auto-attack) -- [Auto Craft](#auto-craft) -- [Auto Dig](#auto-dig) -- [Auto Drop](#auto-drop) -- [Auto Eat](#auto-eat) -- [Auto Fishing](#auto-fishing) -- [Auto Relog](#auto-relog) -- [Auto Respond](#auto-respond) -- [Chat Log](#chat-log) -- [Discord Bridge](#discord-bridge) -- [Farmer](#farmer) -- [Follow Player](#follow-player) -- [Hangman](#hangman) -- [Mailer](#mailer) -- [Map](#map) -- [PlayerList Logger](#playerlist-logger) -- [Remote Control](#remote-control) -- [Replay Mod](#replay-mod) -- [Script Scheduler](#script-scheduler) -- [Telegram Bridge](#telegram-bridge) -- [Items Collector](#items-collector) -- [WebSocket](#websocket-chat-bot) +- [Chat Bots](#chat-bots) + - [About](#about) + - [List of built-in Chat Bots](#list-of-built-in-chat-bots) + - [Alerts](#alerts) + - [Anti AFK](#anti-afk) + - [Auto Attack](#auto-attack) + - [Auto Craft](#auto-craft) + - [Auto Dig](#auto-dig) + - [Auto Drop](#auto-drop) + - [Auto Eat](#auto-eat) + - [Auto Fishing](#auto-fishing) + - [Auto Relog](#auto-relog) + - [Auto Respond](#auto-respond) + - [Chat Log](#chat-log) + - [Discord Bridge](#discord-bridge) + - [Farmer](#farmer) + - [Follow player](#follow-player) + - [Hangman](#hangman) + - [Mailer](#mailer) + - [Map](#map) + - [PlayerList Logger](#playerlist-logger) + - [Remote Control](#remote-control) + - [Replay Capture](#replay-capture) + - [Script Scheduler](#script-scheduler) + - [Telegram Bridge](#telegram-bridge) + - [Items Collector](#items-collector) ## Alerts @@ -347,7 +348,7 @@ redirectFrom: To enable it, set `Custom` (boolean) to `true` and change `value` (double) to your preferred value (eg. `1.5`). - By the default, this is disabled and the MCC calculates it based on the server TPS. + By default, this is disabled and MCC calculates it based on the server TPS. - **Format:** `Cooldown_Time = { Custom = , value = }` @@ -2576,70 +2577,3 @@ redirectFrom: - **Default:** `true` -## WebSocket Chat Bot - -- **Description:** - - This chat bot allows you to remotely execute commands on the MCC and make Chat Bots in other programming languages over Web Socket. - - You can make your own library to do this, or use the reference implementation one which has been writen in TypeScript/JavaScript: [MCC.js](https://github.com/milutinke/MCC.js) - - If you want to write your own library, you can follow this guide on the protocol specification and avaliable events and commands: [WebSocket Chat Bot Guide](websocket/README.md) - -- **Settings:** - - **Section:** **`ChatBot.WebSocketBot`** - - #### `Enabled` - - - **Description:** - - This setting specifies if the Web Socket chat bot is enabled. - - - **Available values:** `true` and `false`. - - - **Type:** `boolean` - - - **Default:** `false` - - #### `Ip` - - - **Description:** - - The IP address that Websocket server will be bound to. - - - **Type:** `string` - - - **Default:** `127.0.0.1` (localhost) - - #### `Port` - - - **Description:** - - The Port that Websocket server will be bound to. - - - **Type:** `number` - - - **Default:** `8043` - - #### `Password` - - - **Description:** - - A password that will be used to authenticate on thw Websocket server - - **It is recommended to change the default password and to set a strong one** - - - **Type:** `string` - - - **Default:** `wspass12345` - - #### `DebugMode` - - - **Description:** - - This setting is for developers who are developing a library that uses this chat bot to remotely execute procedures/commands/functions. - - - **Type:** `boolean` - - - **Default:** `false` \ No newline at end of file diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index b3a67299..c8ce7f92 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -7,34 +7,33 @@ redirectFrom: # Configuration -**Minecraft Console Client** can be both configured by the [command line parameters](usage.md#command-line-parameters) and the configuration file. +**Minecraft Console Client** can be configured through both [command-line parameters](usage.md#command-line-parameters) and the configuration file. -By the default all of the configurations are stored in the configuration file named `MinecraftClient.ini` which is created the first time you run the program, but you also can specify your own configuration file by providing a path to it as a first parameter when starting the MCC, check out [Usage](usage.md#quick-usage-of-mcc-with-examples) for examples. +By default, MCC stores its settings in `MinecraftClient.ini`, which is created the first time you run the program. You can also pass a custom configuration file path as the first argument when starting MCC. See [Usage](usage.md#quick-usage-of-mcc-with-examples) for examples.

Warning

-**Recently we have changed the configuration format from INI to TOML, the documentation had to be updated. If you spot a mistake, please report it on our Discord or in the repository as an issue.**
## Notes -- Some settings will be omitted from the documentation due to them being not used often, we do not want documentation to be cluttered, we advise you to manually read through the configuration file, where every setting has a description next to it. -- Some plugin/bot related settings will be covered in the plugins section, not here +- Some less common settings are not repeated here. The generated config file contains inline descriptions for every setting. +- Bot-specific settings are documented in [Chat Bots](chat-bots.md). ## Configuration File ### Format -The configuration file uses the [TOML format](https://toml.io/en/), all of the options are key-value pairs separated into sections. +The configuration file uses the [TOML format](https://toml.io/en/). Options are key-value pairs grouped into sections. -Sections are defined in-between the square brackets (Example: `[This is a section]`), each occurrence of this marks a beginning of a new section. +Sections are defined between square brackets, for example `[This is a section]`. -The settings/options are defined as key-value pairs, where the name of the setting and the value are separated by the equals sign `=` (Example: `some-setting=some value`). +Settings are written as key-value pairs, with the key and value separated by `=`, for example `some-setting = "some value"`. Lines starting with `#` are comments, they do not have an effect on the configuration of the program, their purpose is purely a descriptive one. -**To get familiar with all the data types and styles of settings please read the [official TOML documenation](https://toml.io/en/v1.0.0).** +**For the full syntax and data types, see the [official TOML documentation](https://toml.io/en/v1.0.0).** Full Example: @@ -52,7 +51,7 @@ Section_Enabled = true colors = [ "red", "yellow", "green" ] [ThirdSection.Subsection] -Coordinate = { x = 145, y = 64, y = 2045 } +Coordinate = { x = 145, y = 64, z = 2045 } ``` ## Main Section @@ -107,11 +106,11 @@ Coordinate = { x = 145, y = 64, y = 2045 } - **Description:** - This setting is where you define the type of your account: `mojang` or `microsoft` + This setting defines the account type: `mojang`, `microsoft`, or `yggdrasil`.

Tip

- **Mojang accounts are going to stop working soon for everyone, they already are not working for some people.** + **Use `microsoft` for normal Microsoft accounts. `yggdrasil` is for custom authlib/Yggdrasil servers.**
@@ -159,12 +158,12 @@ Coordinate = { x = 145, y = 64, y = 2045 } - **Type:** `string` -- **Default:** `en_gb` +- **Default:** `en_us` - **Example:** ``` - Language = "en_gb" + Language = "en_us" ``` #### `ConsoleTitle` @@ -268,7 +267,7 @@ Coordinate = { x = 145, y = 64, y = 2045 }

Tip

- **MCC supports only 1.4.6 - 1.19.2** + **Current code support is `1.4.6` through `1.21.11`.**
@@ -286,7 +285,7 @@ Coordinate = { x = 145, y = 64, y = 2045 } - `no` - `force` -- **Default:** `auto` +- **Default:** `no`

Tip

diff --git a/docs/guide/contibuting.md b/docs/guide/contibuting.md index c89c5b69..a59279a7 100644 --- a/docs/guide/contibuting.md +++ b/docs/guide/contibuting.md @@ -4,11 +4,11 @@ title: Contributing # Contributing -At this moment this page needs to be created. +This page is still being filled in. For now, use the links below for the current contributor workflow. If you are working with SWE AI agents, start with [AI-Assisted Development](ai-assisted-development.md). It covers the shell setup, local server loop, and the skills in `.skills/`. -For now you can use our article from the [Git Hub repository Wiki](https://github.com/MCCTeam/Minecraft-Console-Client/wiki/Update-console-client-to-new-version) written by [ReinforceZwei](https://github.com/ReinforceZwei). +You can also use the guide in the [GitHub repository wiki](https://github.com/MCCTeam/Minecraft-Console-Client/wiki/Update-console-client-to-new-version) written by [ReinforceZwei](https://github.com/ReinforceZwei). ## Translations @@ -16,12 +16,12 @@ To improve translations for MCC, please visit: [Crowdin - Minecraft Console Clie **It is recommended to translate `MCC in-app text` first.** -If you can't find the language you want to translate into, please contact us at Github or Discord to add it. +If you cannot find the language you want to translate into, contact us on GitHub or Discord and we can add it. -Github: https://github.com/MCCTeam/Minecraft-Console-Client +GitHub: https://github.com/MCCTeam/Minecraft-Console-Client Discord: https://discord.gg/9HPr2EE4C4 ## Contributors -[Check out our contributors on Github](https://github.com/MCCTeam/Minecraft-Console-Client/graphs/contributors). +[Check out our contributors on GitHub](https://github.com/MCCTeam/Minecraft-Console-Client/graphs/contributors). diff --git a/docs/guide/creating-bots.md b/docs/guide/creating-bots.md index b5012a3b..6d0f6342 100644 --- a/docs/guide/creating-bots.md +++ b/docs/guide/creating-bots.md @@ -14,7 +14,7 @@ title: Creating Chat Bots

Tip

-**For now this page contains only the bare basics of the Chat Bot API, enough of details to teach you how to make basic Chat Bots. For more details you need to take a look at the [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs) and [Examples](#examples). This page will be improved in the future.** +**This page covers the basics of the Chat Bot API. For the full surface area, read [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs) and the example scripts linked below.**
@@ -42,7 +42,7 @@ This introduction assumes that you have the basic knowledge of C#.

Tip

-**Here we will use terms Chat Bot and Script interchangeably** +**In this page, "Chat Bot" and "Script" are used interchangeably.**
@@ -59,8 +59,8 @@ MCC.LoadBot(new ExampleChatBot()); // The code and comments above are defining a "Script Metadata" section -// Every single chat bot (script) must be a class which extends the ChatBot class. -// Your class must be instantiates in the "Script Metadata" section and passed to MCC.LoadBot function. +// Every chat bot script must define a class that extends ChatBot. +// Instantiate that class in the script metadata section and pass it to MCC.LoadBot. class ExampleChatBot : ChatBot { // This method will be called when the script has been initialized for the first time, it's called only once @@ -92,7 +92,7 @@ class ExampleChatBot : ChatBot Start MCC, connect to a server and run the following internal command: `/script ExampleChatBot.cs`. -If you did everything right you should see: `[Example Chat Bot] An example Chat Bot has been initialised!` message appear in your console log. +If everything worked, you should see `[Example Chat Bot] An example Chat Bot has been initialized!` in the console. ### Structure of Chat Bots @@ -111,9 +111,9 @@ Every single Chat Bot (Script) must have this section at the beginning in order `//MCCScript 1.0` marks the beginning of the **Script Metadata** section, this must always be on the first line or the Chat Bot (Script) will not load and will throw an error. -`//MCCScript Extensions` marks the end of the **Script Metadata** section, this must be defined before a Chat Bot (Script) class. +`//MCCScript Extensions` marks the end of the **Script Metadata** section. It must appear before the Chat Bot class. -In order for your Chat Bot (Script) to properly load in-between the `//MCCScript 1.0` and the `//MCCScript Extensions` lines you must instantiate your Chat Bot (Script) class and pass it to the `MCC.LoadBot` function. +To load a Chat Bot script, instantiate the bot class between `//MCCScript 1.0` and `//MCCScript Extensions`, then pass it to `MCC.LoadBot`. Example code: @@ -121,7 +121,7 @@ Example code: MCC.LoadBot(new YourChatBotClassNameHere()); ``` -**Script Metadata** section allows for including C# packages and libraries with: `//using ` and `/dll `. +The **Script Metadata** section also lets you include namespaces and DLL references with `//using ` and `//dll `.

Tip

@@ -129,7 +129,7 @@ MCC.LoadBot(new YourChatBotClassNameHere());
-By the default the following packages are loaded: +By default, the following namespaces are loaded: ```csharp using System; @@ -167,28 +167,28 @@ MCC.LoadBot(new ExampleChatBot()); ### Chat Bot Class -After the end of the **Script Metadata** section, you basically can define any number of classes you like, the only limitation is that the main class of your Chat Bot (Script) must extend `ChatBot` class. +After the **Script Metadata** section, you can define any number of helper classes. The main bot class must extend `ChatBot`. There are no required methods, everything is optional. -When the Chat Bot (Script) has been initialized for the first time the `Initialize` method will be called. +When the Chat Bot is initialized for the first time, the `Initialize` method is called. -In it you can initialize variables, eg. Dictionaries, etc.. +Use it to initialize state such as dictionaries or cached values.

Tip

**For allocating resources like a database connection, we recommend allocating them in `AfterGameJoined` and freeing them in `OnDisconnect`** -
. +
## Examples -You can find a lot of examples in our Git Hub Repository at [ChatBots](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/ChatBots) and [config](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config). +You can find more examples in the [ChatBots](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/ChatBots) and [config](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config) folders in the GitHub repository. ## C# API -As of the time of writing, the C# API has been changed in forks that are yet to be merged, so for now you can use the [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs) for reference. +The authoritative reference for the C# API is [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs). Each method is well documented with standard C# documentation comments. -In the future we will make a script to auto-generate this section based on the documentation in the code. +This page intentionally stays focused on the basics. For newer hooks and overloads, check the source file directly. diff --git a/docs/guide/creating-text-script.md b/docs/guide/creating-text-script.md index 0c4aa0a9..7b5178be 100644 --- a/docs/guide/creating-text-script.md +++ b/docs/guide/creating-text-script.md @@ -4,9 +4,9 @@ title: Creating Simple Script # Creating Simple Script -A simple script is a text file with one command per line. See [Internal Commands](https://mccteam.github.io/guide/usage.html#internal-commands) section or type `/help` in the console to see available commands. Any line beginning with `#` is ignored and treated as a comment. +A simple script is a text file with one command per line. See the [Internal Commands](usage.md#internal-commands) section, or type `/help` in the console to see the available commands. Any line beginning with `#` is ignored and treated as a comment. -Application variables defined using the set command or [AppVars] INI section can be used. The following read-only variables can also be used: `%username%, %login%, %serverip%, %serverport%, %datetime%` +Application variables defined with the `set` command or in the `[AppVars]` config section can be used. The following read-only variables are also available: `%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`. ## Example @@ -21,6 +21,6 @@ send Now quitting. Bye :) exit ``` -Go to [example scripts](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config) to see more example. +See the [example scripts](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config) folder for more examples. -If you want need advanced functions, please see [Creating Chat Bots](creating-bots.md) \ No newline at end of file +If you need more advanced behavior, see [Creating Chat Bots](creating-bots.md). diff --git a/docs/guide/installation.md b/docs/guide/installation.md index cf1db6f0..f9e66687 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -20,7 +20,7 @@ If you're not the kind of person that likes textual tutorials, our community has ## Download a compiled binary -You can download a compiled binary file of the latest build from our Releases section on Git Hub: [Download](https://github.com/MCCTeam/Minecraft-Console-Client/releases) +You can download a compiled binary of the latest build from the [GitHub Releases](https://github.com/MCCTeam/Minecraft-Console-Client/releases) page. ## Building from the source code @@ -33,7 +33,7 @@ However, if you want to build the program from source code, please follow the gu Requirements: - [Git](https://www.git-scm.com/) -- [.NET 7.0 or new-er](https://dotnet.microsoft.com/en-us/download) or [Visual Studio](https://visualstudio.microsoft.com/) configured for C# app development +- [.NET 10 SDK](https://dotnet.microsoft.com/en-us/download) or [Visual Studio](https://visualstudio.microsoft.com/) configured for C# app development

Tip

@@ -48,12 +48,18 @@ Install [Git](https://www.git-scm.com/) 1. Make a new folder where you want to keep the source code 2. Then open it up, hold `SHIFT` and do a `right-click` on the empty white space in the folder 3. Click on `Git Bash Here` in the context menu -4. Clone the [Git Hub Repository](https://github.com/MCCTeam/Minecraft-Console-Client) by typing end executing the following command: +4. Clone the [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client) by running: ```bash git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive ``` +If you cloned the repository without `--recursive`, run: + +```bash +git submodule update --init --recursive +``` + 5. Once the repository has been cloned, you can close the `Git Bash` terminal emulator 6. Open up the new cloned folder @@ -83,7 +89,7 @@ git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive 6. Right click on `MinecraftClient` solution in the `Solution Explorer` 7. Click `Build` -If the build has succeeded, the compiled binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net7.0/win-x64/publish` folder. +If the build succeeds, the published binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net10.0/win-x64/publish/`. #### Building using .NET manually without Visual Studio @@ -92,10 +98,10 @@ If the build has succeeded, the compiled binary `MinecraftClient.exe` will be in 3. Run the following command to build the project: ```bash -dotnet publish MinecraftClient -f net7.0 -r win-x64 --no-self-contained -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None +dotnet publish MinecraftClient.sln -f net10.0 -r win-x64 --self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded ``` -If the build has succeeded, the compiled binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net7.0/win-x64/publish` folder. +If the build succeeds, the published binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net10.0/win-x64/publish/`. ### Linux, macOS @@ -113,7 +119,7 @@ Requirements: - [Install Git on macOS](https://git-scm.com/download/mac) -- .NET SDK 7.0 or new-er +- .NET 10 SDK - [Install .NET on Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux) - [Install .NET on macOS](https://docs.microsoft.com/en-us/dotnet/core/install/macos) @@ -121,7 +127,7 @@ Requirements: #### Cloning using Git 1. Open up a terminal emulator and navigate to the folder where you will store the MCC -2. Recursively clone the [Git Hub Repository](https://github.com/MCCTeam/Minecraft-Console-Client) by typing end executing the following command: +2. Recursively clone the [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client) by running: ```bash git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive @@ -134,31 +140,31 @@ git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive - On Linux: ```bash - dotnet publish MinecraftClient -f net7.0 -r linux-x64 --no-self-contained -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None + dotnet publish MinecraftClient.sln -f net10.0 -r linux-x64 --self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded ```

Tip

- **If you're using Linux that is either ARM, 32-bit, Rhel based, Using Musl, or Tirzen, [find an appropriate RID](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#linux-rids) for your platform and replace the `-r linux-64` with an appropriate `-r RID_NAME` (Example for arm: `-r linux-arm64`)** + **If you are using Linux on ARM, 32-bit, RHEL-based distributions, or Musl, [pick the appropriate RID](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#linux-rids) for your platform and replace `-r linux-x64` with it, for example `-r linux-arm64`.**
- On macOS: ```bash - dotnet publish MinecraftClient -f net7.0 -r osx-x64 --no-self-contained -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=None + dotnet publish MinecraftClient.sln -f net10.0 -r osx-x64 --self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded ```

Tip

- **If you're not using MAC with Intel, find an appropriate RID for your ARM processor, [find an appropriate RID](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids) and replace the `-r osx-64` with an appropriate `-r RID_NAME` (Example for arm: `-r osx.12-arm64`)** + **If you are not using an Intel Mac, [pick the appropriate RID](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids) for your processor and replace `-r osx-x64` with it, for example `-r osx-arm64`.**
If the build has succeeded, the compiled binary `MinecraftClient` will be in: -- Linux: `MinecraftClient/bin/Release/net7.0/linux-x64/publish/` -- macOS: `MinecraftClient/bin/Release/net7.0/osx-x64/publish/` +- Linux: `MinecraftClient/bin/Release/net10.0/linux-x64/publish/` +- macOS: `MinecraftClient/bin/Release/net10.0/osx-x64/publish/` ## Using Docker @@ -175,11 +181,11 @@ Requirements:

Warning

-**Pay attention at warnings, Docker currently works, but you must start the containers in the interactive mode or MCC will crash, we're working on solving this.** +**Docker works, but you need to start the container in interactive mode. Starting it in headless mode can still crash MCC.**
-1. Clone the [Git Hub Repository](https://github.com/MCCTeam/Minecraft-Console-Client) by typing end executing the following command: +1. Clone the [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client) by running: ```bash git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive @@ -196,12 +202,12 @@ docker build -t minecraft-console-client:latest .

Danger

-**There is a bug with the ConsoleInteractive which causes a crash when a container is started in a headless mode, so you need to use the interactive mode. Do not restart containers in a classic way, stop then and start them with interactive mode (this command), after that simply detach with `CTRL + P` and then `CTRL + Q`.** +**Because of a ConsoleInteractive issue, starting the container in headless mode can crash MCC. Start it with the interactive command below, then detach with `CTRL + P` followed by `CTRL + Q` if you want to leave it running in the background.**
```bash -# You could also ignore the -v parameter if you dont want to mount the volume that is up to you. If you don't it's harder to edit the .ini file if thats something you want to do +# You can omit -v if you do not want a mounted volume. Keeping the volume makes it much easier to edit the TOML config stored in MinecraftClient.ini from the host. docker run -it -v :/opt/data minecraft-console-client:latest ``` @@ -234,11 +240,11 @@ Remember to remove the container after usage: docker-compose down ``` -If you use the INI file and entered your data (username, password, server) there, you can start your container using +If you use `MinecraftClient.ini` and entered your data there, you can start your container using ```bash docker-compose up -docker-compose up -d #for deamonized running in the background +docker-compose up -d # for daemonized background running ``` Note that you won't be able to interact with the client using `docker-compose up`. If you want that functionality, please use the first method: `docker-compose run MCC`. @@ -251,11 +257,11 @@ docker-compose down ## Run on Android -It is possible to run the Minecraft Console Client on Android through Termux and Ubuntu 22.04 in it, however it requires a manual setup with a lot of commands, be careful no to skip any steps. Note that this might take anywhere from 10 to 20 minutes or more to do depending on your technical knowledge level, Internet speed and CPU speed. +It is possible to run Minecraft Console Client on Android through Termux and Ubuntu 22.04, but it requires a manual setup with a lot of commands, so be careful not to skip any steps. Depending on your technical background, internet speed, and device speed, this can take anywhere from 10 to 20 minutes or more.

Tip

-**This section is going to get a bit technical, I'll try my best to make everything as simple as possible. If you are having trouble following along or if you encounter any issues, feel free to open up a discussion on our Github repository page.** +**This section gets a bit technical. If you run into issues, open a discussion on our GitHub repository page.**
@@ -277,11 +283,11 @@ It is possible to run the Minecraft Console Client on Android through Termux and

Warning

-**The Play Store version of Termux is outdated and not supported, do not use it, use the the [Github one](https://github.com/termux/termux-app/releases/latest/).** +**The Play Store version of Termux is outdated and not supported. Use the [GitHub release](https://github.com/termux/termux-app/releases/latest/) instead.**
-Go to [the Termux Github latest release](https://github.com/termux/termux-app/releases/latest/), download the `debug_universal.apk`, unzip it and run it. +Go to [the latest Termux GitHub release](https://github.com/termux/termux-app/releases/latest/), download the `debug_universal.apk`, unzip it, and run it.

Tip

@@ -350,7 +356,7 @@ Once the installation is complete, you can start Ubuntu with: #### Installing .NET on ARM -Since there are issues installing .NET 7.0 via the APT package manager at the time of writing, we will have to install it manually. +If the package-manager route does not provide a current enough SDK for your setup, install .NET manually instead. First we need to update the APT package manager repositories and install dependencies. @@ -366,7 +372,7 @@ After you did it, we need to install dependencies for .NET, with the following c apt install wget nano unzip libc6 libgcc1 libgssapi-krb5-2 libstdc++6 zlib1g libicu70 libssl3 -y ``` -After you have installed dependencies, it's time to install .NET, you either can follow this tutorial or the [Microsoft one](https://docs.microsoft.com/en-us/dotnet/core/install/linux-scripted-manual#manual-install). +After you have installed the dependencies, install .NET either by following this guide or by using Microsoft's [manual install instructions](https://learn.microsoft.com/en-us/dotnet/core/install/linux-scripted-manual#manual-install). Navigate to your `/root` home directory with the following command: @@ -374,27 +380,27 @@ Navigate to your `/root` home directory with the following command: cd /root ``` -First you need to download .NET 7.0, you can do it with the following command: +Download a current .NET SDK tarball for your platform from Microsoft. For example: ```bash -wget https://download.visualstudio.microsoft.com/download/pr/6cd2eaa7-4c06-4168-b90b-ee2d6bb40b10/4a8387eb07e17d262bfb9965f6d34462/dotnet-sdk-7.0.203-linux-arm64.tar.gz +wget ```

Tip

-**This tutorial assumes that you have 64 bit version of ARM processor, if you happen to have a 32-bit version replace the link in the command above with [this one](https://download.visualstudio.microsoft.com/download/pr/55972ef4-146e-47e6-b014-0163cbaca6a3/fa9713f73f44088898843016d68c5929/dotnet-sdk-7.0.203-linux-arm.tar.gz)** +**This example assumes a 64-bit ARM processor. If you are using a different architecture, download the matching SDK archive for that platform instead.**

Tip

-**This tutorial assumes that you're following along and using Ubuntu 22.04, if you're using a different distro, like Alpine, go to [here](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) and copy an appropriate link for your distro.** +**This tutorial assumes Ubuntu 22.04. If you are using a different distro, get the current SDK archive for your platform from the [.NET download page](https://dotnet.microsoft.com/en-us/download).**
Once the file has been downloaded, you need to run the following commands in order: -1. `DOTNET_FILE=dotnet-sdk-7.0.203-linux-arm64.tar.gz` +1. `DOTNET_FILE=`

Warning

@@ -537,7 +543,7 @@ Also, here are some linux tutorials for people who are new to it:

Tip

-**This is a new section, if you find a mistake, please report it by opening an Issue in our [Github repository](https://github.com/MCCTeam/Minecraft-Console-Client). Thank you!** +**This is a newer section. If you spot a mistake, please report it by opening an issue in our [GitHub repository](https://github.com/MCCTeam/Minecraft-Console-Client).**
@@ -1057,10 +1063,10 @@ Remove the file, we do not need it anymore: rm packages-microsoft-prod.deb ``` -Finally, install .NET Core 7: +Finally, install the current .NET SDK: ```bash -sudo apt-get update -y && sudo apt-get install -y dotnet-sdk-7.0 +sudo apt-get update -y && sudo apt-get install -y dotnet-sdk-10.0 ``` Run the following command to check if everything was installed correctly: @@ -1087,11 +1093,11 @@ path-to-application: If you do not get this output and the installation was not successful, [try other methods](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#2204). -If it was successful, you can now install the MCC. +If it was successful, you can now install MCC. ### Installing MCC on a VPS -Now that you have .NET Core 7.0 and a user account, you should install the `screen` utility, you will need this in order to keep the MCC running once you close down the SSH session (if you do not have it, the MCC will just stop working once you disconnect). You can look at the `screen` like a window, except it's in a terminal, it lets you have multiple "windows" open at the same time. +Now that you have the .NET SDK and a user account, install the `screen` utility. You will need it if you want MCC to keep running after you close the SSH session.

Tip

diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 633ed93c..93d5d150 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -47,7 +47,7 @@ screen -S mcc # Detach from the screen by pressing CTRL + A + D -# Re-attach if you want to have accces again +# Re-attach if you want access again screen -r mcc ``` @@ -59,7 +59,7 @@ See [Run using Docker](./installation.md#using-docker) ## Command-line usage -**Minecraft Console Client** has a plethora of useful command line parameters, here you can learn about them. +**Minecraft Console Client** has a number of useful command-line parameters. This section covers the most important ones. ### For people not familiar with the command line @@ -97,6 +97,8 @@ Here is an example for using a `--help` command line parameter for MCC that will MinecraftClient.exe --help ``` +MCC also supports a few maintenance and debugging switches such as `--upgrade`, `--force-upgrade`, `--generate`, `--keyboard-debug`, `BasicIO`, and `BasicIO-NoColor`. + ### Quick usage of MCC with examples

Tip

@@ -119,16 +121,16 @@ Examples: # Logging in as a user: notch, with a password: password123 onto a server with the ip: mc.someserver.com:25565 MinecraftClient.exe notch password123 mc.someserver.com:25565 -# Overriding a setting from MinecraftClient.ini using a command line parameter +# Overriding a setting from MinecraftClient.ini using a command-line parameter MinecraftClient.exe --debugmessages=false -# Providing a custom settings ini file and overriding a language to Chinese +# Providing a custom settings file and overriding the language to Chinese MinecraftClient.exe CustomSettingsFile.ini --language=zh ``` ### Rules of using the command line parameters -You can mix and match arguments by following theses rules: +You can mix and match arguments by following these rules: - First positional argument may be either the login or a settings file - Other positional arguments are read in order: login, password, server, command @@ -150,7 +152,7 @@ MinecraftClient.exe "/mycommand" ``` - This will automatically send `/mycommand` to the server and close. -- To send several commands and/or stay connected, use the 1ScriptScheduler1 bot instead. +- To send several commands or stay connected, use the `ScriptScheduler` bot instead. ```bash MinecraftClient.exe @@ -247,7 +249,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q Reports the block type at the given position. - If you use the `-s` option it will report the types of blocks around the targeted blokcs. + If you use the `-s` option, it also reports the surrounding block types. - **Usage:** @@ -558,11 +560,11 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q - **Description:** - Reloads settings from MinecraftClient.ini and Chat Bots. + Reloads the active configuration file and chat bots.

Tip

- **Some settings won't be reloaded since they are used before the client initialization. Also, settings provided by the command line paramteres will be overriden. This also does not reload the ReplayBot due to technical limitations.** + **Some settings are not reloaded because they are used before client initialization. Settings passed on the command line also override file values. ReplayCapture is not reloaded due to technical limitations.**
@@ -800,7 +802,7 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q

Tip

- **This command is avaliable only with [Follow Player](chat-bots.md#follow-player) Chat Bot enabled.** + **This command is available only when the [Follow Player](chat-bots.md#follow-player) chat bot is enabled.**
diff --git a/docs/guide/websocket/Commands.md b/docs/guide/websocket/Commands.md index d6754445..25f196e7 100644 --- a/docs/guide/websocket/Commands.md +++ b/docs/guide/websocket/Commands.md @@ -1,1413 +1,5 @@ -# Web Socket Commands +# WebSocket Commands -## Important +This page is archived. -**I'll try to include a full list of commands here with full examples, but you will have to take a look at the source code from time to time to see the types you can send in more details.** - -**The source code of the WebSocket Chat Bot:** [Click here](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/ChatBots/WebSocketBot.cs#L484) - -## Protocol Commands - -Protocol commands are commands to manipulate the protocol. - -### `Authenticate` - - This command is used to authenticate if there is a password set in the Web Socket chat bot settings. - - **Parameters:** - - It takes a single parameters of a string type that contains a password. - - **Example:** - - ```json - { - "command": "Authenticate", - "requestId": "a08rt980u15j890", - "parameters": ["wspass12345"] - } - ``` - -### `ChangeSessionId` - - This command is used to change the name/alias/id of a session. - - **Parameters:** - - It takes a single parameters of a string type that contains a name. - - **Example:** - - ```json - { - "command": "ChangeSessionId", - "requestId": "9845eybjb8936j0i3", - "parameters": ["My Custom Session Name"] - } - ``` - -## Procedures - -Procedures are the methods/functions you can execute on the MCC itself to interact with the minecraft server. - -### - `LogToConsole` - -**Description:** - -Log stuff in to the MCC console. - -**Parameters:** - -- `message` - - **Type:** `string` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "LogToConsole", - "requestId": "9qaeuitgng", - "parameters": ["Some text to log..."] -} -``` - -### - `LogDebugToConsole` - -**Description:** - -Log stuff in to the MCC debug console channel. - -**Parameters:** - -- `message` - - **Type:** `string` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "LogDebugToConsole", - "requestId": "yt30j83g-uq", - "parameters": ["Some text to log..."] -} -``` - -### - `LogToConsoleTranslated` - -**Description:** - -Log a translated string in to the MCC console. - -**Parameters:** - -- `message` - - **Type:** `string` - -**Return type:** `boolean` - -```json -{ - "command": "LogToConsoleTranslated", - "requestId": "qt089t1jh1t1t", - "parameters": ["ChatBot.WebSocketBot.DebugMode"] -} -``` - -### - `LogDebugToConsoleTranslated` - -**Description:** - -Log a translated string in to the MCC debug console channel. - -**Parameters:** - -- `message` - - **Type:** `string` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "LogDebugToConsoleTranslated", - "requestId": "gpiqahjgpag", - "parameters": ["ChatBot.WebSocketBot.DebugMode"] -} -``` - -### - `ReconnectToTheServer` - -**Description:** - -Reconnect to the server the MCC is connected to. - -**Parameters:** - -- `extraAttempts` - - **Type:** `integer` - - **Note:** Use -1 for unlimited attempts number. - -- `delaySeconds` - - **Type:** `integer` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "ReconnectToTheServer", - "requestId": "098uqh3r2w0qt9", - "parameters": [60, 360] -} -``` - -### - `DisconnectAndExit` - -**Description:** - -Disconnect MCC from the server and close the program. - -**Parameters:** - -- No parameters - -**Example:** - -```json -{ - "command": "DisconnectAndExit", - "requestId": "89seut02349wjk", - "parameters": [] -} -``` - -### - `RunScript` - -**Description:** - -Run a MCC C# script. - -**Parameters:** - -- `scriptName` - - **Type:** `string` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "RunScript", - "requestId": "q3r098qhtqj-0", - "parameters": ["testScript.cs"] -} -``` - -### - `GetTerrainEnabled` - -**Description:** - -Check if the Terrain Handling is enabled. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "GetTerrainEnabled", - "requestId": "089wqejru", - "parameters": [] -} -``` - -### - `SetTerrainEnabled` - -**Description:** - -Try enabling the Terrain Handling. - -**Parameters:** - -- `enabled` - - **Type:** `boolean` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "SetTerrainEnabled", - "requestId": "9uW4HT9A", - "parameters": [true] -} -``` - -### - `GetEntityHandlingEnabled` - -**Description:** - -Check if the Entity Handling is enabled. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "GetEntityHandlingEnabled", - "requestId": "ua5yht9-a8u", - "parameters": [] -} -``` - -### - `Sneak` - -**Description:** - -Toggle sneak. - -**Parameters:** - -- `toggle` - - **Type:** `boolean` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "Sneak", - "requestId": "iurwt8h97", - "parameters": [true] -} -``` - -### - `SendEntityAction` - -**Description:** - -Send an entity action. - -**Parameters:** - -- `actionType` - - **Type:** [`EntityActionType` as a an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Protocol/EntityActionType.cs#L3) - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "SendEntityAction", - "requestId": "0j5t3yb89j-q5b9j8", - "parameters": [1] -} -``` - -### - `DigBlock` - -**Description:** - -Dig a block in the world. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -- `swingArms` (optional, default `true`) - - **Type:** `boolean` - -- `lookAtBlock` (optional, default `true`) - - **Type:** `boolean` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "DigBlock", - "requestId": "89q58u9qb", - "parameters": [12.5, 72, 12.5, true, true] -} -``` - -### - `SetSlot` - -**Description:** - -Set the current active hot bar slot. - -**Parameters:** - -- `slotId` - - **Type:** `integer` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "SetSlot", - "requestId": "9hu43tv9hu4tv", - "parameters": [1] -} -``` - -### - `GetWorld` - -**Description:** - -Get world info. - -**Parameters:** - -- No parameters - -**Return type:** [`json encoded object with world info`](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/World.cs) - -**Example:** - -```json -{ - "command": "GetWorld", - "requestId": "89753q6bh756b", - "parameters": [] -} -``` - -### - `GetEntities` - -**Description:** - -Get a list of entities around the player. - -**Parameters:** - -- No parameters - -**Return type:** [`json encoded array of Entity`](https://github.com/milutinke/MCC.js/blob/dc5ccfecb65284f021c94c8381c3d7fb4f36a2c3/src/MccTypes/Entity.ts#L130) - -**Example:** - -```json -{ - "command": "GetEntities", - "requestId": "9ujrte9ujp", - "parameters": [] -} -``` - -### - `GetPlayersLatency` - -**Description:** - -Get a list of players and their latencies. - -**Parameters:** - -- No parameters - -**Return type:** `json encoded array of player object with { "": }` - -**Example:** - -```json -{ - "command": "GetPlayersLatency", - "requestId": "9uj53ybwj8945sby6", - "parameters": [] -} -``` - -### - `GetCurrentLocation` - -**Description:** - -Get the current bot location in the world. - -**Parameters:** - -- No parameters - -**Return type:** [`json encoded Location object`](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/Location.cs) - -**Example:** - -```json -{ - "command": "GetCurrentLocation", - "requestId": "8953ybu896b539j8056b3", - "parameters": [] -} -``` - -### - `MoveToLocation` - -**Description:** - -Move to a location in the world. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -- `allowUnsafe` (optional, default: `true`) - - **Type:** `boolean` - - **Description:** Allow the bot to go through unsafe areas, warning: it might get hurt. - -- `allowDirectTeleport` (optional, default: `false`) - - **Type:** `boolean` - - **Description:** Allow bot to send a teleport packet. - -- `maxOffset` (optional, default: `0`) - - **Type:** `integer` - - **Description:** Maximum number of blocks from the location where the bot can stop. - -- `minOfset` (optional, default: `0`) - - **Type:** `integer` - - **Description:** Minimum number of blocks from the location where the bot can stop. - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "MoveToLocation", - "requestId": "853yb8u,6b589uj", - "parameters": [12.5, 71, 142.5] -} -``` - -### - `ClientIsMoving` - -**Description:** - -Check if the bot is currently moving. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "ClientIsMoving", - "requestId": "539ayg88a9u63", - "parameters": [] -} -``` - -### - `LookAtLocation` - -**Description:** - -Make the bot look at a specific location. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "LookAtLocation", - "requestId": "a45g90unhu9a5t", - "parameters": [12, 71, 134] -} -``` - -### - `GetTimestamp` - -**Description:** - -Get current time in `yyyy-MM-dd HH:mm:ss` format. - -**Parameters:** - -- No parameters - -**Return type:** `string` - -**Example:** - -```json -{ - "command": "GetTimestamp", - "requestId": "87htgqq76y8g", - "parameters": [] -} -``` - -### - `GetServerPort` - -**Description:** - -Get the current server port. - -**Parameters:** - -- No parameters - -**Return type:** `int` - -**Example:** - -```json -{ - "command": "GetServerPort", - "requestId": "89u53ybq89uqb", - "parameters": [] -} -``` - -### - `GetServerHost` - -**Description:** - -Get the current server IPv4 address. - -**Parameters:** - -- No parameters - -**Return type:** `string` - -**Example:** - -```json -{ - "command": "GetServerHost", - "requestId": "hu3ay5u9h35", - "parameters": [] -} -``` - -### - `GetUsername` - -**Description:** - -Get current logged in account username. - -**Parameters:** - -- No parameters - -**Return type:** `string` - -**Example:** - -```json -{ - "command": "GetUsername", - "requestId": "8t7fhq87q6yw", - "parameters": [] -} -``` - -### - `GetGamemode` - -**Description:** - -Get the current game mode in which the bot is. - -**Parameters:** - -- No parameters - -**Return type:** `string` - -**Example:** - -```json -{ - "command": "GetGamemode", - "requestId": "5ta309h7835ty89j70", - "parameters": [] -} -``` - -### - `GetYaw` - -**Description:** - -Get current bot yaw. - -**Parameters:** - -- No parameters - -**Return type:** `double` - -**Example:** - -```json -{ - "command": "GetYaw", - "requestId": "B9Q5G380UJQ", - "parameters": [] -} -``` - -### - `GetPitch` - -**Description:** - -Get the current bot pitch. - -**Parameters:** - -- No parameters - -- **Return type:** `double` - -**Example:** - -```json -{ - "command": "GetPitch", - "requestId": "7hm4rtv2q5Y74", - "parameters": [] -} -``` - -### - `GetUserUUID` - -**Description:** - -Get the UUID of the current account. - -**Parameters:** - -- No parameters - -**Return type:** `string` - -**Example:** - -```json -{ - "command": "GetUserUUID", - "requestId": "34tva89hq986h", - "parameters": [] -} -``` - -### - `GetOnlinePlayers` - -**Description:** - -Get a list of online players on the server. - -**Parameters:** - -- No parameters - -**Return type:** `json encoded array of string` - -**Example:** - -```json -{ - "command": "GetOnlinePlayers", - "requestId": "894tvu2u8qv6", - "parameters": [] -} -``` - -### - `GetOnlinePlayersWithUUID` - -**Description:** - -Get a list of online players on the server with their nicknames and UUIDs. - -**Parameters:** - -- No parameters - -**Return type:** `json encoded array of object in the following format: { "": "" }` - -**Example:** - -```json -{ - "command": "GetOnlinePlayersWithUUID", - "requestId": "903fy5tv8qwu89", - "parameters": [] -} -``` - -### - `GetServerTPS` - -**Description:** - -Get the current server TPS. - -**Parameters:** - -- No parameters - -**Return type:** `integer` - -**Example:** - -```json -{ - "command": "GetServerTPS", - "requestId": "70atv4fy7890", - "parameters": [] -} -``` - -### - `InteractEntity` - -**Description:** - -Interact with an entity. - -**Parameters:** - -- `entityId` - - **Type:** `integer` - -- `interactionType` - - **Type:** [`InteractType` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/InteractType.cs) - -- `hand` (optional) - - **Type:** [`Hand` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/Hand.cs) - - **Default value:** `0` (Main Hand) - - You can omit this parameter if you want to interact with the main hand. - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "InteractEntity", - "requestId": "a34890u hgtv90h", - "parameters": [1452, 1] -} -``` - -### - `CreativeGive` - -**Description:** - -Give an item from the Creative Inventory. - -**Parameters:** - -- `slot` - - **Type:** `integer` - - **Description:** The slot id in which the items will be added to. - -- `itemType` - - **Type:** [`ItemType` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/ItemType.cs) - -- `count` - - **Type:** `integer` - - **Description** The number of items you want to give. - -- `nbt` (optional) - - **Type:** `string with json of nbt object` - - **Description** The item NBT data - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "CreativeGive", - "requestId": "sedoiuneag87", - "parameters": [12, 1, 64] -} -``` - -### - `CreativeDelete` - -**Description:** - -Clear an inventory slot of items in the Creative Mode. - -**Parameters:** - -- `slot` - - **Type:** `integer` - - **Description:** The slot id from which the items will be deleted from. - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "CreativeDelete", - "requestId": "09hfgq9qui0gq", - "parameters": [12] -} -``` - -### - `SendAnimation` - -**Description:** - -Send an animation, for example a hand swing. - -**Parameters:** - -- `hand` - - **Type:** [`Hand` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/Hand.cs) - - **Default value:** `0` (Main Hand) - - You can omit this parameter if you want to interact with the main hand. - -**Return type:** `boolean` - - -**Example:** - -```json -{ - "command": "SendAnimation", - "requestId": "0ig09ug0iwq", - "parameters": [] -} -``` - -### - `SendPlaceBlock` - -**Description:** - -Place a block somewhere in the world. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -- `direction` - - **Type:** [`Direction` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/Direction.cs) - -- `hand` (optional) - - **Type:** [`Hand` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/Hand.cs) - - **Default value:** `0` (Main Hand) - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "SendPlaceBlock", - "requestId": "zibgweybuini9o", - "parameters": [12, 72, 134, 4] -} -``` - -### - `UseItemInHand` - -**Description:** - -Use an item in the hand. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "UseItemInHand", - "requestId": "qat0qtg90gqtn", - "parameters": [] -} -``` - -### - `GetInventoryEnabled` - -**Description:** - -Check if the inventory is enabled. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "GetInventoryEnabled", - "requestId": "2t4q0j9qwg8h", - "parameters": [] -} -``` - -### - `GetPlayerInventory` - -**Description:** - -Get the items in the player inventory. - -**Parameters:** - -- No parameters - -**Return type:** [`json encoded inventory/container object`](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/Container.cs) - -**Example:** - -```json -{ - "command": "GetPlayerInventory", - "requestId": "gbugabuiga", - "parameters": [] -} -``` - -### - `GetInventories` - -**Description:** - -Get opened inventories list and items in them. - -**Parameters:** - -- No parameters - -**Return type:** [`json encoded array of inventory/container objects`](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/Container.cs) - -**Example:** - -```json -{ - "command": "GetPlayerInventory", - "requestId": "awgpawighago0ia", - "parameters": [] -} -``` - -### - `WindowAction` - -**Description:** - -Send an inventory action, for example a click. - -**Parameters:** - -- `windowId` - - **Type:** `integer` - - **Description:** An id of an inventory - -- `slotId` - - **Type:** `integer` - - **Description** An id of an inventory slot - -- `windowActionType` - - **Type:** [`WindowActionType` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Inventory/WindowActionType.cs) - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "WindowAction", - "requestId": "agpoigjawg0iawg", - "parameters": [2, 14, 1] -} -``` - -### - `ChangeSlot` - -**Description:** - -Change the currently selected hot bar slot. - -**Parameters:** - `slotId` - -**Type:** `integer` - -**Description** An id of an inventory slot. - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "ChangeSlot", - "requestId": "awdadiajh0fgi", - "parameters": [2] -} -``` - -### - `GetCurrentSlot` - -**Description:** - -Get the currently selected hot bar slot. - -**Parameters:** - -- No Parameters - -**Return type:** `integer` - -**Example:** - -```json -{ - "command": "GetCurrentSlot", - "requestId": "sadg0as8h", - "parameters": [] -} -``` - -### - `ClearInventories` - -**Description:** - -Clear the list of opened inventories. - -**Parameters:** - -- No Parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "ClearInventories", - "requestId": "2ouniuowaseghbnew", - "parameters": [] -} -``` - -### - `UpdateSign` - -**Description:** - -Update the text in signs. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -- `line1` - - **Type:** `string` - -- `line2` - - **Type:** `string` - -- `line3` - - **Type:** `string` - -- `line4` - - **Type:** `string` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "UpdateSign", - "requestId": "gsisgsuig0gs", - "parameters": [145, 67, 1234, "This is line 1", "This is line 2", "This is line 3", "This is line 4"] -} -``` - -### - `SelectTrade` - -**Description:** -Select a villager trade. - -**Parameters:** - -- `selectedSlot` - - **Type:** `integer` - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "SelectTrade", - "requestId": "awdpa[9doujwapdi]", - "parameters": [2] -} -``` - -### - `UpdateCommandBlock` - -**Description:** - -Update the command block. - -**Parameters:** - -- `X` - - **Type:** `double` - -- `Y` - - **Type:** `double` - -- `Z` - - **Type:** `double` - -- `command` - - **Type:** `string` - -- `mode` - - **Type:** [`CommandBlockMode` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/CommandBlockMode.cs) - -- `flags` - - **Type:** [`CommandBlockFlags` as an integer](https://github.com/MCCTeam/Minecraft-Console-Client/blob/5de84d7e5927062d867585d7fe0a0bba937ec039/MinecraftClient/Mapping/CommandBlockFlags.cs) - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "UpdateCommandBlock", - "requestId": "aw[apkda=-pd]", - "parameters": [56, 122, 34, "say This is a command", 4, 2] -} -``` - -### - `CloseInventory` - -**Description:** - -Close an inventory id. - -**Parameters:** - -- `windowId` - - **Type:** `integer` - - **Description:** Inventory Id - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "CloseInventory", - "requestId": "awpkfa0phiawd", - "parameters": [5] -} -``` - -### - `GetMaxChatMessageLength` - -**Description:** - -Get the max chat message length. - -**Parameters:** - -- No parameters - -**Return type:** `integer` - -**Example:** - -```json -{ - "command": "GetMaxChatMessageLength", - "requestId": "foajfja0fajf0i", - "parameters": [] -} -``` - -### - `Respawn` - -**Description:** - -Respawn the bot when it's dead. - -**Parameters:** - -- No parameters - -**Return type:** `boolean` - -**Example:** - -```json -{ - "command": "Respawn", - "requestId": "qawepifaihopafhio", - "parameters": [] -} -``` - -### - `GetProtocolVersion` - -**Description:** - -Get the current protocol version - -**Parameters:** - -No parameters - -**Return type:** `integer` - -**Example:** - -```json -{ - "command": "GetProtocolVersion", - "requestId": "219u2wqt-q9j-t9ujq", - "parameters": [] -} -``` +The command list that used to live here documented an older WebSocket bot that is no longer present in the current MCC codebase. There is no current in-tree implementation backing those commands, so keeping the old catalog here as if it were active would be misleading. diff --git a/docs/guide/websocket/Events.md b/docs/guide/websocket/Events.md index 3a6b6cec..5b17eaec 100644 --- a/docs/guide/websocket/Events.md +++ b/docs/guide/websocket/Events.md @@ -1,1524 +1,5 @@ -# Web Socket Events (Web Socket Chat Bot protocol events) +# WebSocket Events -## `OnWsCommandResponse` +This page is archived. - **Description:** - - Sent by the WebSocket Chat Bot when a command was executed. - - **Response body:** - - - `success` - - **Type:** `boolean` - - **Description:** Flags the command execution as either successful if `true` or not successful if `false`. - - - `requestId` - - **Type:** `string` - - **Description:** The request Id that was sent when the command was sent to the WebSocket Chat Bot, used to track commands. (Randomly generated on each command sending) - - - `command` - - **Type:** `string` - - **Description:** The command that was sent. - - - `result` - - **Type:** `object` - - **Description:** The value that the command has returned. - - **Example:** - - ```json - { - "event": "OnWsCommandResponse", - "data": { - "success": true, - "requestId": "ZLxcOhfMyf4SzNCqwMTx", - "command": "LogToConsole", - "result": true - } - } - ``` - -# MCC Events - -## `OnBlockBreakAnimation` - - **Description:** - - Sent when a block is broken in the world. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - - `Location` - - **Type:** `Location json encoded object` - - - `stage` - - **Type:** `integer` - - **Example:** - - ```json - { - "event": "OnBlockBreakAnimation", - "data": {} - } - ``` - -## `OnEntityAnimation` - - **Description:** - - Sent when an entity does an animation. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - - `animation` - - **Type:** `integer` - - **Example:** - - ```json - { - "event": "OnEntityAnimation", - "data": { - "entity": { - "ID":8, - "UUID":"8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "Name":"someplayer", - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":77, - "Location":{ - "X":-46.08784180879593, - "Y":68, - "Z":147.68046873807907, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":9, - "ChunkBlockX":1, - "ChunkBlockY":4, - "ChunkBlockZ":3 - }, - "Yaw":178.59375, - "Pitch":28.125, - "ObjectData":-1, - "Health":20, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":{ - "6":0 - }, - "Equipment": {} - }, - "animation":0 - } - } - ``` - -## `OnChatPrivate` - - **Description:** - - Sent when the MCC receives a private chat message. - - **Parameters:** - - - `sender` - - **Type:** `string` - - - `message` - - **Type:** `string` - - - `rawText` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnChatPublic", - "data": { - "sender":"milutinke", - "message":"hey there", - "rawText":"milutinke whispers to you: hey there" - } - } - ``` - -## `OnChatPublic` - - **Description:** - - Sent when a public message was sent in the chat. - - **Parameters:** - - - `username` - - **Type:** `string` - - - `message` - - **Type:** `string` - - - `rawText` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnChatPublic", - "data": { - "username":"milutinke", - "message":"hello world", - "rawText":" hello world" - } - } - ``` - -## `OnTeleportRequest` - - **Description:** - - Sent when the bot gets a teleport request - - **Parameters:** - - - `sender` - - **Type:** `string` - - - `rawText` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnTeleportRequest", - "data": { - "sender": "milutinke", - "rawText": "Milutinke want's to teleport to you. Type /tpaccept to accept the teleport request." - } - } - ``` - -## `OnChatRaw` - - **Description:** - - Sent when any kind of chat message was received by the MCC. Can contain JSON. - - **Parameters:** - - - `text` - - **Type:** `string` - - - `json` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnChatRaw", - "data": { - "text":"someplayer has made the advancement §a[§aCover Me with Diamonds]", - "json":"{\"translate\":\"chat.type.advancement.task\",\"with\":[{\"insertion\":\"someplayer\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/tell someplayer \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":{\"type\":\"minecraft:player\",\"id\":\"8c0e3dc3-9bcc-3e03-a138-53348330d4ee\",\"name\":{\"text\":\"someplayer\"}}},\"text\":\"someplayer\"},{\"color\":\"green\",\"translate\":\"chat.square_brackets\",\"with\":[{\"hoverEvent\":{\"action\":\"show_text\",\"contents\":{\"color\":\"green\",\"extra\":[{\"text\":\"\\n\"},{\"translate\":\"advancements.story.shiny_gear.description\"}],\"translate\":\"advancements.story.shiny_gear.title\"}},\"translate\":\"advancements.story.shiny_gear.title\"}]}]}" - } - } - ``` - -## `OnDisconnect` - - **Description:** - - Sent when the bot has disconnected from a server. At this point you can't send commands to the MCC. - - **Parameters:** - - - `reason` - - **Type:** `string` - - - `message` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnDisconnect", - "data": { - "reason": "", - "message": "" - } - } - ``` - -## `OnPlayerProperty` - - **Description:** - - Sent when the server need to update a player property - - **Parameters:** - - - `prop` - - **Type:** `json encoded object of { string key: double/number value }` - - **Example:** - - ```json - { - "event": "OnPlayerProperty", - "data": { - "minecraft:generic.movement_speed": 0.10000000149011612 - } - } - ``` - -## `OnServerTpsUpdate` - - **Description:** - - Sent when the server TPS changes/updates. - - **Parameters:** - - - `tps` - - **Type:** `double` - - **Example:** - - ```json - { - "event": "OnServerTpsUpdate", - "data": { - "tps": 20.0 - } - } - ``` - -## `OnTimeUpdate` - - **Description:** - - Sent when the world time changes. - - **NOTE: Sent quite frequently.** - - **Parameters:** - - - `worldAge` - - **Type:** `long` - - - `timeOfDay` - - **Type:** `long` - - **Example:** - - ```json - { - "event": "OnTimeUpdate", - "data": { - "worldAge": 1719192, - "timeOfDay": -1132 - } - } - ``` - -## `OnEntityMove` - - **Description:** - - Sent when an entity moves. - - **NOTE: Sent quite frequently.** - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - **Example:** - - ```json - { - "event": "OnEntityMove", - "data": { - "ID":16, - "UUID":"00000000-0000-0000-0000-000000000000", - "Name":null, - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":14, - "Location":{ - "X":5.5, - "Y":-47.9375, - "Z":204.5, - "Status":0, - "ChunkX":0, - "ChunkY":1, - "ChunkZ":12, - "ChunkBlockX":5, - "ChunkBlockY":0, - "ChunkBlockZ":12 - }, - "Yaw":0, - "Pitch":0, - "ObjectData":0, - "Health":1, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":null, - "Equipment": {} - } - } - ``` - -## `OnInternalCommand` - - **Description:** - - Sent when an internal MCC command has been executed. - - **Parameters:** - - - `command` - - **Type:** `string` - - - `parameters` - - **Type:** `string` - - - `result` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnInternalCommand", - "data": { - "command": "dig -115 74 -19", - "parameters": "-115 74 -19", - "result": "Attempting to dig block at -114,5 74 -18,5 (Grass Block)" - } - } - ``` - -## `OnEntitySpawn` - - **Description:** - - Sent when an entity is spawned or enters the player radius. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - **Example:** - - ```json - { - "event": "OnEntitySpawn", - "data": { - "ID":78, - "UUID":"00000000-0000-0000-0000-000000000000", - "Name":null, - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":15, - "Location":{ - "X":-47.5, - "Y":68, - "Z":146.5, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":9, - "ChunkBlockX":0, - "ChunkBlockY":4, - "ChunkBlockZ":2 - }, - "Yaw":30.9375, - "Pitch":0, - "ObjectData":0, - "Health":1, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":null, - "Equipment":{ } - } - } - ``` - -## `OnEntityDespawn` - - **Description:** - - Sent when an entity is de-spawned or leaves the player radius. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - **Example:** - - ```json - { - "event": "OnEntityDespawn", - "data": { - "ID":15, - "UUID":"00000000-0000-0000-0000-000000000000", - "Name":null, - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":56, - "Location":{ - "X":-38.818737210380526, - "Y":68, - "Z":194.05856433486986, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":12, - "ChunkBlockX":9, - "ChunkBlockY":4, - "ChunkBlockZ":2 - }, - "Yaw":0, - "Pitch":0, - "ObjectData":0, - "Health":1, - "Item":{ - "Type":396, - "Count":1, - "NBT":{ }, - "IsEmpty":false, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":{ - "8":{ - "Type":396, - "Count":1, - "NBT":{ - - }, - "IsEmpty":false, - "DisplayName":null, - "Lores":null, - "Damage":0 - } - }, - "Equipment":{ } - } - } - ``` - -### - `OnHeldItemChange` - - **Description:** - - Sent when a held item is changed. - - **Parameters:** - - - `itemSlot` - - **Type:** `integer` - - **Example:** - - ```json - { - "event": "OnHeldItemChange", - "data": { - "itemSlot": 1 - } - } - ``` - -### - `OnHealthUpdate` - - **Description:** - - Sent when player's health is updated. - - **Parameters:** - - - `health` - - **Type:** `float` - - - `food` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnHealthUpdate", - "data": { - "health": 18, - "food": 7 - } - } - ``` - -### - `OnExplosion` - - **Description:** - - Sent when there is an explosion. - - **Parameters:** - - - `Location` - - **Type:** `Location json encoded object` - - - `strength` - - **Type:** `float` - - - `recordCount` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnExplosion", - "data": { - "location": { - "X": -117.49000000953674, - "Y": 66.0612500011921, - "Z": -26.490000009536743, - "Status": 0, - "ChunkX": -8, - "ChunkY": 8, - "ChunkZ": -2, - "ChunkBlockX": 10, - "ChunkBlockY": 2, - "ChunkBlockZ": 5 - }, - "strength": 4, - "recordCount": 139 - } - } - ``` - -### - `OnSetExperience` - - **Description:** - - Sent when the player's experience is updated. - - **Parameters:** - - - `experienceBar` - - **Type:** `float` - - - `level` - - **Type:** `int` - -- `totalExperience` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnSetExperience", - "data": { - "experienceBar": 0.60504204, - "level": 7, - "totalExperience": 120 - } - } - ``` - -### - `OnGamemodeUpdate` - - **Description:** - - Sent when the player's game mode has changed. - - **Parameters:** - - - `playerName` - - **Type:** `string` - - - `uuid` - - **Type:** `string with UUID` - - - `gameMode` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnGamemodeUpdate", - "data": { - "playerName": "milutinke", - "uuid": "8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "gameMode": "creative" - } - } - ``` - -### - `OnLatencyUpdate` - - **Description:** - - Sent when the player's ping has changed. - - **Parameters:** - -- `playerName` - - **Type:** `string` - -- `uuid` - - **Type:** `string with UUID` - -- `latency` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnLatencyUpdate", - "data": { - "playerName": "someplayer", - "uuid":"baa6eda2-cbc5-5119-870d-1960ce60574d", - "latency": 14 - } - } - ``` - -### - `OnMapData` - - **Description:** - - Sent when map data is received. - - **Parameters:** - - - `mapId` - - **Type:** `int` - - - `scale` - - **Type:** `integer` - - - `trackingPosition` - - **Type:** `bool` - - - `locked` - - **Type:** `bool` - - - `icons` - - **Type:** `array of map icon object` - - - `columnsUpdated` - - **Type:** `integer` - - - `rowsUpdated` - - **Type:** `integer` - - - `mapColumnX` - - **Type:** `integer` - - - `mapRowZ` - - **Type:** `integer` - - - `colors` - - **Type:** `base 64 encoded string of colors` - - **Example:** - - ```json - { - "event": "OnMapData", - "data": { - "mapId": 1, - "scale": 0, - "trackingPosition": true, - "locked": false, - "icons": [], - "columnsUpdated": 128, - "rowsUpdated": 128, - "mapColumnX": 0, - "mapRowZ": 0, - "colors": null // ommited in this example, too long - } - } - ``` - -### - `OnTradeList` - - **Description:** - - Sent when villager's trade list has been received/updated. - - **Parameters:** - - - `windowId` - - **Type:** `int` - - - `trades` - - **Type:** `List` - - - `villagerInfo` - - **Type:** `VillagerInfo` - - -### - `OnTitle` - - **Description:** - - Sent when a title action has been received. - - **Parameters:** - - `action` - - **Type:** `int` - - - `titleText` - - **Type:** `string` - - - `subtitleText` - - **Type:** `string` - - - `actionBarText` - - **Type:** `string` - - - `fadeIn` - - **Type:** `int` - - - `stay` - - **Type:** `int` - - - `fadeout` - - **Type:** `int` - - - `json_` - - **Type:** `string` - -### - `OnEntityEquipment` - - **Description:** - - Sent when entity has changed or equipped equipment. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` (nullable) - - - `slot` - - **Type:** `int` - - - `item` - - **Type:** `Item?` - - **Example:** - - ```json - { - "event": "OnEntityEquipment", - "data": { - "entity":{ - "ID":8, - "UUID":"8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "Name":"someplayer", - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":77, - "Location":{ - "X":-46.88311344939438, - "Y":68, - "Z":146.96050249975414, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":9, - "ChunkBlockX":1, - "ChunkBlockY":4, - "ChunkBlockZ":2 - }, - "Yaw":178.59375, - "Pitch":28.125, - "ObjectData":-1, - "Health":20, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":{ - "6":0 - }, - "Equipment":{ - "0":{ - "Type":368, - "Count":1, - "NBT":{ - "Damage":0 - }, - "IsEmpty":false, - "DisplayName":null, - "Lores":null, - "Damage":0 - } - } - }, - "slot":0, - "item":{ - "Type":368, - "Count":1, - "NBT":{ - "Damage":0 - }, - "IsEmpty":false, - "DisplayName":null, - "Lores":null, - "Damage":0 - } - } - } - ``` - -### - `OnEntityEffect` - **Description:** - Sent when there are effects applied to an entity. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - - `effect` - - **Type:** `Effects` - - - `amplifier` - - **Type:** `int` - - - `duration` - - **Type:** `int` - - - `flags` - - **Type:** `integer` - - **Example:** - - ```json - { - "event": "OnEntityEffect", - "data": { - "entity": { - "ID": 50, - "UUID": "8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "Name": "milutinke", - "CustomNameJson": null, - "IsCustomNameVisible": false, - "CustomName": null, - "Latency": 0, - "Type": 77, - "Location": { - "X": -116.15188604696566, - "Y": 74.79847191937456, - "Z": -22.679173221632723, - "Status": 0, - "ChunkX": -8, - "ChunkY": 8, - "ChunkZ": -2, - "ChunkBlockX": 11, - "ChunkBlockY": 10, - "ChunkBlockZ": 9 - }, - "Yaw": 330.46875, - "Pitch": 9.84375, - "ObjectData": -1, - "Health": 20, - "Item": { - "Type": 18, - "Count": 0, - "NBT": null, - "IsEmpty": true, - "DisplayName": null, - "Lores": null, - "Damage": 0 - }, - "Pose": 0, - "Metadata": { - "9": 20, - "11": true, - "16": 122, - "17": 127 - }, - "Equipment": {} - }, - "effect": 33, - "amplifier": 0, - "duration": 77, - "flags": 0 - } - } - ``` - -### - `OnScoreboardObjective` - - **Description:** - - Sent when scoreboard objective has been added. - - **Parameters:** - - - `objectiveName` - - **Type:** `string` - - - `mode` - - **Type:** `integer` - - - `objectiveValue` - - **Type:** `string` - - - `type` - - **Type:** `int` - - - `json_` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnScoreboardObjective", - "data": { - "objectiveName": "testObj", - "mode": 0, - "objectiveValue": "Test Objective", - "type": 0, - "rawJson": "{\"text\":\"Testobj\"}" - } - } - ``` - -### - `OnUpdateScore` - - **Description:** - - Sent when scoreboard objective has been update/changed for an entity. - - **Parameters:** - - - `entityName` - - **Type:** `string` - - - `action` - - **Type:** `int` - - - `objectiveName` - - **Type:** `string` - - - `type` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnUpdateScore", - "data": { - "entityName": "test entity", - "action": 1, - "objectiveName": "test_objective", - "type": 1 - } - } - ``` - -### - `OnInventoryUpdate` - - **Description:** - - Sent when the an inventory has been updated. - - **Parameters:** - - - `inventoryId` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnInventoryUpdate", - "data": { - "inventoryId": 4 - } - } - ``` - -### - `OnInventoryOpen` - - **Description:** - - Sent when a player opens an inventory. - - **Parameters:** - - - `inventoryId` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnInventoryOpen", - "data": { - "inventoryId": 5 - } - } - ``` - -### - `OnInventoryClose` - - **Description:** - - Sent when a player/server closes an inventory. - - **Parameters:** - - - `inventoryId` - - **Type:** `int` - - **Example:** - - ```json - { - "event": "OnInventoryClose", - "data": { - "inventoryId": 4 - } - } - ``` - -### - `OnPlayerJoin` - - **Description:** - - Sent when a player joins the server. (Not the bot) - - **Parameters:** - - - `uuid` - - **Type:** `string with UUID` - - - `name` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnPlayerJoin", - "data": { - "uuid": "8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "name": "milutinke" - } - } - ``` - -### - `OnPlayerLeave` - - **Description:** - - Sent when a player leaves the server. (Not the bot) - - **Parameters:** - - - `uuid` - - **Type:** `string with UUID` - - - `name` - - **Type:** `string` - - **Example:** - - ```json - { - "event": "OnPlayerLeave", - "data": { - "uuid":"8c0e3dc3-9bcc-3e03-a138-53348330d4ee", - "name":"milutinke" - } - } - ``` - -### - `OnDeath` - - **Description:** - - Sent when the bot dies. - - **Parameters:** None - - **Example:** - - ```json - { - "event": "OnDeath", - "data": null - } - ``` - -### - `OnRespawn` - - **Description:** - - Sent when the bot respawns. - - **Parameters:** None - - **Example:** - - ```json - { - "event": "OnRespawn", - "data": null - } - ``` - -### - `OnEntityHealth` - - **Description:** - - Sent when an entity health changes/updates. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` (nullable) - - - `health` - - **Type:** `float` - - **Example:** - - ```json - { - "event": "OnEntityHealth", - "data": { - "entity":{ - "ID":78, - "UUID":"00000000-0000-0000-0000-000000000000", - "Name":null, - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":15, - "Location":{ - "X":-47.5, - "Y":68, - "Z":146.5, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":9, - "ChunkBlockX":0, - "ChunkBlockY":4, - "ChunkBlockZ":2 - }, - "Yaw":30.9375, - "Pitch":0, - "ObjectData":0, - "Health":3, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":{ - "9":4 - }, - "Equipment":{ - - } - }, - "health":3 - } - } - ``` - -### - `OnEntityMetadata` - - **Description:** - - Sent when entity's metadata has been received/updated/changed. - - **Parameters:** - - - `Entity` - - **Type:** `Entity json encoded object` - - - `metadata` - - **Type:** `Object of number as a key and object as value` (nullable) - - **Example:** - - ```json - { - "event": "OnEntityMetadata", - "data": { - "entity":{ - "ID":78, - "UUID":"00000000-0000-0000-0000-000000000000", - "Name":null, - "CustomNameJson":null, - "IsCustomNameVisible":false, - "CustomName":null, - "Latency":0, - "Type":15, - "Location":{ - "X":-47.5, - "Y":68, - "Z":146.5, - "Status":0, - "ChunkX":-3, - "ChunkY":8, - "ChunkZ":9, - "ChunkBlockX":0, - "ChunkBlockY":4, - "ChunkBlockZ":2 - }, - "Yaw":30.9375, - "Pitch":0, - "ObjectData":0, - "Health":3, - "Item":{ - "Type":18, - "Count":0, - "NBT":null, - "IsEmpty":true, - "DisplayName":null, - "Lores":null, - "Damage":0 - }, - "Pose":0, - "Metadata":{ - "9":3 - }, - "Equipment":{ - - } - }, - "metadata":{ - "9":3 - } - } - } - ``` - -### - `OnPlayerStatus` - - **Description:** - - Sent when player's status has been updated/changed. - - **Parameters:** - - - `statusId` - - **Type:** `integer` - - **Example:** - - ```json - { - "event": "OnPlayerStatus", - "data": { - "statusId": 5 - } - } - ``` - -### - `OnNetworkPacket` - - **Description:** - - Sent when player's status has been updated/changed. - - **Parameters:** - - - `packetId` - - **Type:** `integer` - - - `isLogin` - - **Type:** `boolean` - - **Description:** Is the packet sent during the `login` phase. (Always `false`) - - - `isInbound` - - **Type:** `integer` - - **Description:** Is the packet sent from the server or by the MCC. - - - `packetData` - - **Type:** `array of bytes` - - **Description:** A raw byte array. \ No newline at end of file +The event list that used to live here documented an older WebSocket bot protocol that is not implemented in the current MCC tree. The old event names and payloads no longer match the codebase, so this page should not be treated as current API documentation. diff --git a/docs/guide/websocket/README.md b/docs/guide/websocket/README.md index b5eff123..deb6d0f5 100644 --- a/docs/guide/websocket/README.md +++ b/docs/guide/websocket/README.md @@ -1,142 +1,7 @@ -# Web Socket Chat Bot documentation +# WebSocket Chat Bot -This is a documentation page on the Web Socket chat bot and on how to make a library that uses web socket to execute commands in the MCC and processes events sent by the MCC. +The in-tree WebSocket chat bot is not part of the current MCC codebase. -Please read the [Important things](#important-things) before everything. +These pages are kept only as historical placeholders because older documentation linked to them. Current mainline builds do not ship a `WebSocketBot`, and there is no supported WebSocket protocol to configure or rely on in the current project state. -# Page index - -- [Important things](#important-things) - - [Prerequisites](#prerequisites) - - [Limitations](#limitations) - - [Precision of information](#precisionvalidity-of-the-information-in-this-guide) -- [How does it work?](#how-does-it-work) -- [Sending commands](#sending-commands-to-mcc) -- [Websocket Commands](Commands.md) -- [Websocket Events](Events.md) -- [Reference Implementation](#reference-implementation) - -## Reference implementation - -I have made a reference implementation in TypeScript/JavaScript, it is avaliable here: - -[https://github.com/milutinke/MCC.js](https://github.com/milutinke/MCC.js) - -It is great for better understanding how this works. - -## Important things - -### Prerequisites - -This guide/documentation assumes that you have enough of programming knowledge to know: - - - What Web Socket is - - Basics of networking and concurency - - What JSON is - - What are the various data types such as boolean, integer, long, float, double, object, dictionary/hash map - -Without knowing those, I highly recommend learning about those concepts before trying to implement your own library. - -### Limitations - -The Web Socket chat bot should be considered experimental and prone to change, it has not been fully tested and might change, keep an eye on updates on our official Discord server. - -### Precision/Validity of the information in this guide - -This guide has been mostly generated from the code itself, so the types are C# types, except in few cases where I have manually changed them. - -For some thing you will have to dig in to the MCC C# code of the Chat Bot and various helper classes. - -**Some information sent by the MCC, for example entity metadata, block ids, item ids, or various other data is different for each Minecraft Version, thus you need to map it for each minecraft version.** - -Some events might not be that useful, eg. `OnNetworkPacket` - -## How does it work? - -So, basically, this Web Socket Chat Bot is a chat bot that has a Web Socket server running while you're connected to a minecraft server. - -It sends events, and listens for commands and responds to commands. - -It has build in authentication, which requires you to send a command to authenticate if the the password is set, if it is not set, it should automatically authenticate you on the first command. - -You also can name every connection (session) with an alias. - -The flow of the protocol is the following: - -``` -Connect to the chat bot via web socket - - | - | - \ / - ` - -Optionally set a session alias/name with "ChangeSessionId" command -(this can be done multiple times at any point) - - | - | - \ / - ` - -Send an "Authenticate" command if there is a password set - - | - | - \ / - ` - -Send commands and listen for events -``` - -In order to implement a library that communicates witht this chat bot, you need to make a way to send commands, remember the sent commands via the `requestId` value, and listen for `OnWsCommandResponse` event in which you need to detect if your command has been executed by looking for the `requestId` that matches the one you've sent. I also recommend you put a 5-10 seconds command execution timeout, where you discard the command if it has not been executed in the given timeout range. - -## Sending commands to MCC - -You can send text in the chat, execute client commands or execute remote procedures (WebSocket Chat Bot commands). - -Each thing that is sent to the chat bot results in a response through the [`OnWsCommandResponse`](#onwscommandresponse) event. - -### Sending chat messages - -To send a chat message just send a plain text with your message to via the web socket. - -### Executing client commands - -To execute a client command, just send plain text with your command. - -Example: `/move suth` - -### Execution remote procedures (WebSocket Chat Bot commands) - -In order to execute a remote procedure, you need to send a json encoded string in the following format: - -```json -{ - "command": "", - "requestId": "", - "parameters": [ 1, "some string", true, "etc.." ] -} -``` - -#### `command` - - Refers to the name of the command - -#### `requestId` - - Is a unique indentifier you generate on each command, it will be returned in the response of the command execution ([`OnWsCommandResponse`](#onwscommandresponse)), use it to track if a command has been successfully executed or not, and to get the return value if it has been successfully executed. (*It's recommended to generate at least 7 characters to avoid collision, best to use an UUID format*). - -#### `parameters` - - Are parameters (attibutes) of the procedure you're executing, they're sent as an array of data of various types, the Web Socket chat bot does parsing and conversion and returns an error if you have sent a wrong type for the given parameters, of if you haven't send enough of them. - - **Example:** - - ```json - { - "command": "Authenticate", - "requestId": "8w9u60-q39ik", - "parameters": ["wspass12345"] - } - ``` \ No newline at end of file +If this feature returns in a future release, this section should be rewritten from the implementation instead of from the old archived docs. From aa59c4d75a41be866a6c10f5e8fd80b44e5c44d7 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 15:57:44 +0100 Subject: [PATCH 106/484] Updated the installation methods, updated creating bots. Removed Web Socket Bot pages. --- docs/guide/ai-assisted-development.md | 2 + docs/guide/contibuting.md | 10 +- docs/guide/creating-bots.md | 43 +++++++- docs/guide/installation.md | 140 ++++++++++++++------------ docs/guide/websocket/Commands.md | 5 - docs/guide/websocket/Events.md | 5 - docs/guide/websocket/README.md | 7 -- 7 files changed, 127 insertions(+), 85 deletions(-) delete mode 100644 docs/guide/websocket/Commands.md delete mode 100644 docs/guide/websocket/Events.md delete mode 100644 docs/guide/websocket/README.md diff --git a/docs/guide/ai-assisted-development.md b/docs/guide/ai-assisted-development.md index b7785c19..3d9a764e 100644 --- a/docs/guide/ai-assisted-development.md +++ b/docs/guide/ai-assisted-development.md @@ -6,6 +6,8 @@ title: AI-Assisted Development This guide documents the MCC AI-assisted development workflow as a real working loop, not a patch generator running on guesses. The goal is to give the agent an environment it can drive on its own: build MCC, start a local server, send commands, inspect logs, and repeat. Once that loop is in place, iteration is faster and regressions are easier to catch. +If you are looking for the broader contributor entry point first, start with [Contributing](contibuting.md) and then come back here for the agent workflow. + The practical goal is a closed loop: ```mermaid diff --git a/docs/guide/contibuting.md b/docs/guide/contibuting.md index a59279a7..f1c8b597 100644 --- a/docs/guide/contibuting.md +++ b/docs/guide/contibuting.md @@ -4,12 +4,18 @@ title: Contributing # Contributing -This page is still being filled in. For now, use the links below for the current contributor workflow. +This page is still being filled in. For now, use the sections below as the current contributor entry points for code, docs, and translation work. -If you are working with SWE AI agents, start with [AI-Assisted Development](ai-assisted-development.md). It covers the shell setup, local server loop, and the skills in `.skills/`. +If you are doing maintainer-style work with coding agents, start with [AI-Assisted Development](ai-assisted-development.md). It covers the shell setup, local server loop, and the skills in `.skills/`. You can also use the guide in the [GitHub repository wiki](https://github.com/MCCTeam/Minecraft-Console-Client/wiki/Update-console-client-to-new-version) written by [ReinforceZwei](https://github.com/ReinforceZwei). +For now, the project has three main contribution paths: + +- code and bot work in the main MCC client +- documentation updates in `docs/` +- translations through Crowdin + ## Translations To improve translations for MCC, please visit: [Crowdin - Minecraft Console Client](https://crwd.in/minecraft-console-client). diff --git a/docs/guide/creating-bots.md b/docs/guide/creating-bots.md index 6d0f6342..0dacd8fa 100644 --- a/docs/guide/creating-bots.md +++ b/docs/guide/creating-bots.md @@ -8,6 +8,7 @@ title: Creating Chat Bots - [Requirements](#requirements) - [Quick Introduction](#quick-introduction) - [Examples](#examples) +- [AI-Assisted Bot Authoring](#ai-assisted-bot-authoring) - [C# API](#c#-api) ## Notes @@ -33,8 +34,8 @@ Crash courses: More in-depth: -- [Learn C# Youtube Playlist by Microsoft](https://www.youtube.com/playlist?list=PLdo4fOcmZ0oVxKLQCHpiUWun7vlJJvUiN) -- [Getting started with C# (An index of tutorials and the documentation) by Microsoft](https://docs.microsoft.com/en-us/dotnet/csharp/) +- [Learn C# YouTube Playlist by Microsoft](https://www.youtube.com/playlist?list=PLdo4fOcmZ0oVxKLQCHpiUWun7vlJJvUiN) +- [Getting started with C# (an index of tutorials and documentation) by Microsoft](https://learn.microsoft.com/en-us/dotnet/csharp/) ## Quick Introduction @@ -185,6 +186,44 @@ Use it to initialize state such as dictionaries or cached values. You can find more examples in the [ChatBots](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/ChatBots) and [config](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config) folders in the GitHub repository. +## AI-Assisted Bot Authoring + +If you are using an AI coding agent on this repository, use the `mcc-chatbot-authoring` skill for bot work. + +This skill is meant for: + +- standalone `/script` bots +- built-in MCC chat bots +- bot repairs and ports +- event handlers, movement logic, inventory logic, and plugin-channel work + +Its default behavior is important: if you ask for "a bot" without saying otherwise, it should prefer a standalone `//MCCScript` bot loaded with `/script`. It should only choose a built-in bot when you explicitly ask for repo wiring, automatic config loading, or a compiled MCC bot. + +The skill also follows MCC-specific rules, for example: + +- do not send chat from `Initialize()` +- use `AfterGameJoined()` for chat or commands after login +- normalize chat with `GetVerbatim(text)` before `IsChatMessage(...)` or `IsPrivateMessage(...)` +- fully clean up commands, timers, plugin channels, and movement locks + +### Example prompts + +```text +Create a standalone MCC /script bot that watches public chat for the word "auction" and logs matching messages to the console. Use the mcc-chatbot-authoring skill. +``` + +```text +Fix this existing MCC script bot so it stops sending chat from Initialize() and moves the startup command to AfterGameJoined(). Use the mcc-chatbot-authoring skill. +``` + +```text +Make a built-in MCC chat bot named AutoTorch and wire it fully into the repo config and bot registration. Use the mcc-chatbot-authoring skill. +``` + +```text +Create a standalone MCC /script bot that follows private messages, uses GetVerbatim(text), and replies only to bot owners. Use the mcc-chatbot-authoring skill. +``` + ## C# API The authoritative reference for the C# API is [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs). diff --git a/docs/guide/installation.md b/docs/guide/installation.md index f9e66687..91b13369 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -95,13 +95,31 @@ If the build succeeds, the published binary `MinecraftClient.exe` will be in `Mi 1. Open the `Minecraft-Console-Client` folder you've cloned or downloaded 2. Open the PowerShell (`Right-Click` on the whitespace and click `Open PowerShell`, or in Windows Explorer: `File -> Open PowerShell`) -3. Run the following command to build the project: +3. Install the .NET 10 SDK if you do not already have it. The easiest current option on Windows is: + +```powershell +winget install Microsoft.DotNet.SDK.10 +``` + +4. Run the following command for a normal local build: + +```bash +dotnet build MinecraftClient.sln -c Release +``` + +5. If you want a release-like published binary that matches the repo's CI workflow, run: ```bash dotnet publish MinecraftClient.sln -f net10.0 -r win-x64 --self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded ``` -If the build succeeds, the published binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net10.0/win-x64/publish/`. +6. Verify the SDK installation if needed: + +```bash +dotnet --info +``` + +If the publish step succeeds, the published binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net10.0/win-x64/publish/`. ### Linux, macOS @@ -121,8 +139,9 @@ Requirements: - .NET 10 SDK - - [Install .NET on Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux) - - [Install .NET on macOS](https://docs.microsoft.com/en-us/dotnet/core/install/macos) + - [Install .NET on Linux](https://learn.microsoft.com/en-us/dotnet/core/install/linux) + - [Install .NET on Ubuntu](https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-install) + - [Install .NET on macOS](https://learn.microsoft.com/en-us/dotnet/core/install/macos) #### Cloning using Git @@ -134,8 +153,25 @@ git clone https://github.com/MCCTeam/Minecraft-Console-Client.git --recursive ``` 3. Go to the folder you've cloned (should be `Minecraft-Console-Client`) -4. If you want to download translation resources, please check out [Download translation resources](#download-translation-resources-optional) -5. Run the following command to build the project: +4. Install the .NET 10 SDK. + + - On Ubuntu 24.04 LTS, use the built-in Ubuntu package feeds: + + ```bash + sudo apt-get update && \ + sudo apt-get install -y dotnet-sdk-10.0 + ``` + + - On macOS, the normal path is to use the official installer from the [.NET download page](https://dotnet.microsoft.com/en-us/download). Pick `Arm64` for Apple Silicon and `x64` for Intel Macs. + +5. If you want to download translation resources, please check out [Download translation resources](#download-translation-resources-optional) +6. Run the following command for a normal local build: + + ```bash + dotnet build MinecraftClient.sln -c Release + ``` + +7. Run the following command if you want a release-like published binary that matches the repo's CI workflow: - On Linux: @@ -166,6 +202,12 @@ If the build has succeeded, the compiled binary `MinecraftClient` will be in: - Linux: `MinecraftClient/bin/Release/net10.0/linux-x64/publish/` - macOS: `MinecraftClient/bin/Release/net10.0/osx-x64/publish/` +You can verify the SDK installation with: + +```bash +dotnet --info +``` + ## Using Docker Requirements: @@ -257,7 +299,7 @@ docker-compose down ## Run on Android -It is possible to run Minecraft Console Client on Android through Termux and Ubuntu 22.04, but it requires a manual setup with a lot of commands, so be careful not to skip any steps. Depending on your technical background, internet speed, and device speed, this can take anywhere from 10 to 20 minutes or more. +It is possible to run Minecraft Console Client on Android through Termux and Ubuntu 24.04, but it requires a manual setup with a lot of commands, so be careful not to skip any steps. Depending on your technical background, internet speed, and device speed, this can take anywhere from 10 to 20 minutes or more.

Tip

@@ -301,20 +343,20 @@ Go to [the latest Termux GitHub release](https://github.com/termux/termux-app/re
-#### Installing Ubuntu 22.04 +#### Installing Ubuntu 24.04 At this stage, you have 2 options: 1. Following this textual tutorial -2. Watching a [Youtube tutorial for installing Ubuntu](https://www.youtube.com/watch?v=5yit2t7smpM) +2. Watching a [YouTube tutorial for installing Ubuntu](https://www.youtube.com/watch?v=5yit2t7smpM)

Tip

-**If you decide to watch the Youtube tutorial, watch only up to `1:58`, the steps after are not needed and might just confuse you.** +**If you decide to watch the YouTube tutorial, watch only up to `1:58`. The steps after that are not needed here and might just confuse you.**
-In order to install Ubuntu 22.04 in Termux you require `wget` and `proot`, we're going to install them in the next step. +In order to install Ubuntu 24.04 in Termux you require `wget` and `proot`, and we are going to install them in the next step. Once you have Termux installed open it up and run the following command one after other (in order): @@ -380,7 +422,7 @@ Navigate to your `/root` home directory with the following command: cd /root ``` -Download a current .NET SDK tarball for your platform from Microsoft. For example: +Download a current .NET SDK tarball for your platform from Microsoft. Replace the placeholder below with the actual current download URL from the [.NET download page](https://dotnet.microsoft.com/en-us/download): ```bash wget @@ -394,7 +436,7 @@ wget

Tip

-**This tutorial assumes Ubuntu 22.04. If you are using a different distro, get the current SDK archive for your platform from the [.NET download page](https://dotnet.microsoft.com/en-us/download).** +**This tutorial assumes Ubuntu 24.04. If you are using a different distro, get the current SDK archive for your platform from the [.NET download page](https://dotnet.microsoft.com/en-us/download).**
@@ -404,7 +446,7 @@ Once the file has been downloaded, you need to run the following commands in ord

Warning

- **If you're using a different download link, update the file name in this command to match your version.** + **Replace the placeholder with the exact filename you downloaded. If you are using a different archive, update this value to match it exactly.**
@@ -423,7 +465,7 @@ Now we need to tell our shell to know where the `dotnet` command is, for future

Warning

-**You will need a basic knowledge of Nano text editor, if you do not know how to use it, watch this [Youtube video tutorial](https://www.youtube.com/watch?v=DLeATFgGM-A)** +**You will need a basic knowledge of the Nano text editor. If you do not know how to use it, watch this [YouTube tutorial](https://www.youtube.com/watch?v=DLeATFgGM-A).**
@@ -564,13 +606,13 @@ VPS stands for a **V**irtual **P**rivate **S**erver, it's basically a remote vir You can use a VPS for hosting a website, or a an app, or a game server, or your own VPN, or the Minecraft Console Client. -Here is a [Youtube video](https://youtu.be/42fwh_1KP_o) that explains it in more detail if you're interested. +Here is a [YouTube video](https://youtu.be/42fwh_1KP_o) that explains it in more detail if you are interested. ### Prerequisites -1. Gitbash (if you're on Windows) +1. Git Bash (if you are on Windows) - Download and install [Gitbash](https://git-scm.com/downloads). + Download and install [Git Bash](https://git-scm.com/downloads).

Tip

@@ -578,7 +620,7 @@ Here is a [Youtube video](https://youtu.be/42fwh_1KP_o) that explains it in more
-2. `ssh` and `ssh-keygen` commands (On Windows they're available with Gitbash, on macOs and Linux they should be available by default, it not, search on how to install them) +2. `ssh` and `ssh-keygen` commands (on Windows they are available with Git Bash; on macOS and Linux they should be available by default. If not, install them first.) 3. Basic knowledge of Linux shell commands, terminal emulator usage, SSH and Nano editor. @@ -613,7 +655,7 @@ The MCC is not expensive to run, so it can run on basically any hardware, you do

Danger

-**In this tutorial we will be using `Ubuntu 22.04`, make sure to select it as the OS when buying a VPS.** +**In this tutorial we will be using `Ubuntu 24.04 LTS`, so pick that family when choosing your VPS image.**
@@ -625,7 +667,7 @@ Some of the reliable and cheap hosting providers (sorted for price/performance):

Tip

- **Does not have Ubuntu 22.04 in the dropdown menu when ordering, you will have to re-install later or ask support to do it.** + **If Ubuntu 24.04 LTS is not in the dropdown when ordering, you may need to reinstall later or ask support to do it.**
@@ -701,7 +743,7 @@ Fill out the `Name` field with a name of your preference. ![VPS Name](/images/guide/VPS_Name.png) -For the **Application and OS images** select `Ubuntu Server 22.04 LTS (HVM), SSD Volume Type`. +For the **Application and OS images** select the current `Ubuntu Server 24.04 LTS` image. The exact AWS label may vary slightly by point release.

Danger

@@ -787,7 +829,7 @@ When you order the VPS, most likely you will be asked to provide the root accoun Other option is that you will get your login info in the email once the setup is done. -Once you have the root login account info, you need [Gitbash](https://git-scm.com/downloads) on Windows and `ssh` if you're on macOS or Linux (if you do not have it by some chance, search on how to install it, it is simple). +Once you have the root login account info, you need [Git Bash](https://git-scm.com/downloads) on Windows and `ssh` on macOS or Linux. If you're on Windows open `Git Bash`, on mac OS and Linux open a `Terminal` and type the following command: @@ -1009,9 +1051,9 @@ If did everything correctly you should see a Linux prompt and a welcome message You can do `whoami` to see your username. -Now you can install .NET Core 7 and MCC. +Now you can install the .NET 10 SDK and MCC. -### Installing .NET Core 7 +### Installing .NET 10 SDK

Tip

@@ -1019,12 +1061,6 @@ Now you can install .NET Core 7 and MCC.
-

Warning

- -**With newer versions of .NET Core 7 on Ubuntu 22.04 you might get the following error: `A fatal error occurred, the folder [/usr/share/dotnet/host/fxr] does not contain any version-numbered child folders`, if you get it, use [this solution](https://github.com/dotnet/sdk/issues/27082#issuecomment-1211143446)** - -
- Log in as the user you've created. Update the system packages and package manager repositories: @@ -1033,42 +1069,18 @@ Update the system packages and package manager repositories: sudo apt update -y && sudo apt upgrade -y ``` -Install `wget`: - -```bash -sudo apt install wget -y -``` - -Go to your home directory with: - -```bash -cd ~ -``` - -Download the Microsoft repository file: - -```bash -wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb -``` - -Add Microsoft repositories to the package manager: - -```bash -sudo dpkg -i packages-microsoft-prod.deb -``` - -Remove the file, we do not need it anymore: - -```bash -rm packages-microsoft-prod.deb -``` - -Finally, install the current .NET SDK: +On Ubuntu 24.04 LTS, the official Microsoft docs say .NET is available directly from the Ubuntu package feeds, so you do not need to add the old Microsoft package repository for .NET 10. Install the SDK with: ```bash sudo apt-get update -y && sudo apt-get install -y dotnet-sdk-10.0 ``` +You can verify the installation with: + +```bash +dotnet --info +``` + Run the following command to check if everything was installed correctly: ```bash @@ -1091,7 +1103,7 @@ path-to-application: The path to an application .dll file to execute. ``` -If you do not get this output and the installation was not successful, [try other methods](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#2204). +If you do not get this output and the installation was not successful, [try other methods](https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu-install). If it was successful, you can now install MCC. @@ -1105,7 +1117,7 @@ Now that you have the .NET SDK and a user account, install the `screen` utility.
-You also can learn about the screen command from [this Youtube tutorial](https://youtu.be/_ZJiEX4rmN4). +You can also learn about the `screen` command from [this YouTube tutorial](https://youtu.be/_ZJiEX4rmN4). To install the `screen` execute the following command: diff --git a/docs/guide/websocket/Commands.md b/docs/guide/websocket/Commands.md deleted file mode 100644 index 25f196e7..00000000 --- a/docs/guide/websocket/Commands.md +++ /dev/null @@ -1,5 +0,0 @@ -# WebSocket Commands - -This page is archived. - -The command list that used to live here documented an older WebSocket bot that is no longer present in the current MCC codebase. There is no current in-tree implementation backing those commands, so keeping the old catalog here as if it were active would be misleading. diff --git a/docs/guide/websocket/Events.md b/docs/guide/websocket/Events.md deleted file mode 100644 index 5b17eaec..00000000 --- a/docs/guide/websocket/Events.md +++ /dev/null @@ -1,5 +0,0 @@ -# WebSocket Events - -This page is archived. - -The event list that used to live here documented an older WebSocket bot protocol that is not implemented in the current MCC tree. The old event names and payloads no longer match the codebase, so this page should not be treated as current API documentation. diff --git a/docs/guide/websocket/README.md b/docs/guide/websocket/README.md deleted file mode 100644 index deb6d0f5..00000000 --- a/docs/guide/websocket/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# WebSocket Chat Bot - -The in-tree WebSocket chat bot is not part of the current MCC codebase. - -These pages are kept only as historical placeholders because older documentation linked to them. Current mainline builds do not ship a `WebSocketBot`, and there is no supported WebSocket protocol to configure or rely on in the current project state. - -If this feature returns in a future release, this section should be rewritten from the implementation instead of from the old archived docs. From d95b6bb9eb449052add50ae1d54d2572b11c113e Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 16:04:45 +0100 Subject: [PATCH 107/484] Added links for skills --- docs/guide/creating-bots.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/guide/creating-bots.md b/docs/guide/creating-bots.md index 0dacd8fa..a44416e7 100644 --- a/docs/guide/creating-bots.md +++ b/docs/guide/creating-bots.md @@ -190,6 +190,11 @@ You can find more examples in the [ChatBots](https://github.com/MCCTeam/Minecraf If you are using an AI coding agent on this repository, use the `mcc-chatbot-authoring` skill for bot work. +Skill links: + +- [Browse the skill on GitHub](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/.skills/mcc-chatbot-authoring) +- [Download the skill directory](https://download-directory.github.io/?url=https%3A%2F%2Fgithub.com%2FMCCTeam%2FMinecraft-Console-Client%2Ftree%2Fmaster%2F.skills%2Fmcc-chatbot-authoring) + This skill is meant for: - standalone `/script` bots From 5c2c176ba1896d747df6f14be35b4d09c186a5c0 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 16:29:14 +0100 Subject: [PATCH 108/484] Updated the latest version to: 26.1. Fixed Warning, Tip and info blocks not-rendering properly. Updated Physics section to be up to date. Fixed a formatting error on the Installation page. --- docs/.vuepress/styles/index.scss | 84 +++++++++++++++++++++++++++ docs/README.md | 2 +- docs/guide/README.md | 24 +++++--- docs/guide/ai-assisted-development.md | 6 +- docs/guide/configuration.md | 2 +- docs/guide/installation.md | 8 +-- tools/README.md | 2 +- 7 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 docs/.vuepress/styles/index.scss diff --git a/docs/.vuepress/styles/index.scss b/docs/.vuepress/styles/index.scss new file mode 100644 index 00000000..dbe9cbc8 --- /dev/null +++ b/docs/.vuepress/styles/index.scss @@ -0,0 +1,84 @@ +.custom-container { + --custom-container-accent: var(--vp-c-accent-bg); + --custom-container-title: var(--vp-c-accent-text); + --custom-container-soft: var(--vp-c-accent-soft); + + margin: 0.75rem 0; + padding: 0.85rem 1rem; + border-inline-start: 0.35rem solid var(--custom-container-accent); + border-radius: 0.75rem; + background: var(--custom-container-soft); + color: inherit; + font-size: var(--hint-font-size, 0.92rem); + transition: + background var(--vp-t-color), + color var(--vp-t-color), + border-color var(--vp-t-color); +} + +.custom-container > .custom-container-title { + margin: 0 0 0.45rem; + color: var(--custom-container-title); + font-weight: 700; + line-height: 1.25; +} + +.custom-container > :last-child { + margin-bottom: 0; +} + +.custom-container > :not(.custom-container-title):first-child { + margin-top: 0; +} + +.custom-container a { + color: var(--vp-c-accent); +} + +.custom-container :not(pre) > code { + background: var(--vp-c-control); +} + +.custom-container.tip { + --custom-container-accent: var(--tip-c-accent, var(--vp-c-green-bg)); + --custom-container-title: var(--tip-c-text, var(--vp-c-green-text)); + --custom-container-soft: var(--tip-c-soft, var(--vp-c-green-soft)); +} + +.custom-container.info { + --custom-container-accent: var(--info-c-accent, var(--vp-c-blue-bg)); + --custom-container-title: var(--info-c-text, var(--vp-c-blue-text)); + --custom-container-soft: var(--info-c-soft, var(--vp-c-blue-soft)); +} + +.custom-container.note { + --custom-container-accent: var(--note-c-accent, var(--vp-c-grey-bg)); + --custom-container-title: var(--note-c-text, var(--vp-c-grey-text)); + --custom-container-soft: var(--note-c-soft, var(--vp-c-grey-soft)); +} + +.custom-container.important { + --custom-container-accent: var(--important-c-accent, var(--vp-c-purple-bg)); + --custom-container-title: var(--important-c-text, var(--vp-c-purple-text)); + --custom-container-soft: var(--important-c-soft, var(--vp-c-purple-soft)); +} + +.custom-container.warning { + --custom-container-accent: var(--warning-c-accent, var(--vp-c-yellow-bg)); + --custom-container-title: var(--warning-c-text, var(--vp-c-yellow-text)); + --custom-container-soft: var(--warning-c-soft, var(--vp-c-yellow-soft)); +} + +.custom-container.danger, +.custom-container.caution { + --custom-container-accent: var(--caution-c-accent, var(--vp-c-red-bg)); + --custom-container-title: var(--caution-c-text, var(--vp-c-red-text)); + --custom-container-soft: var(--caution-c-soft, var(--vp-c-red-soft)); +} + +@media (max-width: 719px) { + .custom-container { + margin-inline: -0.75rem; + border-radius: 0.5rem; + } +} diff --git a/docs/README.md b/docs/README.md index 97a233ed..36bc8c0e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,6 +18,6 @@ features: - title: Automation details: Create bots to do automated tasks - title: Supported Versions - details: 1.4.6 - 1.21.11 + details: 1.4.6 - 26.1 footer: Made by MCC Team with ❤️ --- diff --git a/docs/guide/README.md b/docs/guide/README.md index 1c3cac0b..c1909fcf 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -122,7 +122,7 @@ If you want the repeatable agent workflow used by maintainers, start with [AI-As ### Inventory, Terrain and Entity Handling -MCC currently supports Minecraft versions `1.4.6` through `1.21.11`. +MCC currently supports Minecraft versions `1.4.6` through `26.1`. Feature support still depends on protocol version: @@ -136,16 +136,22 @@ If there was a major game update, and the MCC hasn't been updated to support the ### Path-Finding and Physics -Currently the path-finding and physics have some limitations, those are: -- Path finding under slabs is not supported -- Swimming is not supported yet -- Jumping is not supported yet -- Knockback is not supported yet +MCC now uses A* path-finding together with a physics-based movement system for movement and collision handling. What is supported and works: -- Terrain navigation (path-finding with A* algorithm and walking) -- Climbing up and down the ladders and all types of vines -- Gravity +- Terrain navigation with A* path-finding and physics-driven movement +- Collision-aware movement using real block shapes +- Automatic jumping when the path requires moving up +- Step-up movement for slabs and similar low obstacles +- Sneaking and sprinting +- Movement physics in water and lava +- Climbing up and down ladders and all types of vines +- Gravity, friction, and block speed modifiers such as ice, soul sand, soul soil, and honey blocks + +Current limitations: +- Path-finding is still block-based, so very complex terrain can still fail +- Automatic route planning still avoids underwater routes by default, so this is not a full swimming path-finder yet +- Knockback and other external velocity effects are not simulated yet ## Credits diff --git a/docs/guide/ai-assisted-development.md b/docs/guide/ai-assisted-development.md index 3d9a764e..9f1c59fe 100644 --- a/docs/guide/ai-assisted-development.md +++ b/docs/guide/ai-assisted-development.md @@ -681,7 +681,7 @@ Use skills: Typical flow: ```bash -tools/decompile.sh --version 1.21.11 +tools/decompile.sh --version 26.1 ``` Generate server reports: @@ -689,14 +689,14 @@ Generate server reports: ```bash cd /tmp java -DbundlerMainClass=net.minecraft.data.Main \ - -jar "$MCC_SERVERS/1.21.11/server.jar" \ + -jar "$MCC_SERVERS/26.1/server.jar" \ --reports --output /tmp/mc_reports ``` Run the registry diff: ```bash -python3 tools/diff_registries.py 1.21.10 1.21.11 --registry /tmp/mc_reports/reports/registries.json +python3 tools/diff_registries.py 1.21.10 26.1 --registry /tmp/mc_reports/reports/registries.json ``` Then regenerate the palettes that changed, update routing, build MCC, start a local server for the target version, and run live validation before calling the work done. diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index c8ce7f92..935c74bd 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -267,7 +267,7 @@ Coordinate = { x = 145, y = 64, z = 2045 }

Tip

- **Current code support is `1.4.6` through `1.21.11`.** + **Current code support is `1.4.6` through `26.1`.**
diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 91b13369..77082f1a 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -35,11 +35,9 @@ Requirements: - [Git](https://www.git-scm.com/) - [.NET 10 SDK](https://dotnet.microsoft.com/en-us/download) or [Visual Studio](https://visualstudio.microsoft.com/) configured for C# app development -

Tip

- - **If you want to modify the code, and you are new to C# or in programming in general, you might want to watch some C# tutorials, we recommend the ones listed in [Creating Bots](creating-bots.md#requirements) section.** - -
+::: tip +If you want to modify the code and you are new to C# or programming in general, the tutorials listed in [Creating Bots](creating-bots.md#requirements) are a good starting point. +::: #### Cloning using Git diff --git a/tools/README.md b/tools/README.md index 01e2ced6..4e8153a8 100644 --- a/tools/README.md +++ b/tools/README.md @@ -120,7 +120,7 @@ Downloads block collision shapes from PrismarineJS `minecraft-data` and compacts ```bash # Auto-download for a specific MC version -python3 tools/gen_block_shapes.py 1.21.11 +python3 tools/gen_block_shapes.py 26.1 # → MinecraftClient/Physics/BlockShapeData.json # From a local file (if network is slow) From 7162691b57447ff7eab2072100e2e0555cede64d Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 16:39:37 +0100 Subject: [PATCH 109/484] Added humanizer skill for Docs --- .skills/humanizer/README.md | 142 +++++++++++ .skills/humanizer/SKILL.md | 468 ++++++++++++++++++++++++++++++++++++ 2 files changed, 610 insertions(+) create mode 100644 .skills/humanizer/README.md create mode 100644 .skills/humanizer/SKILL.md diff --git a/.skills/humanizer/README.md b/.skills/humanizer/README.md new file mode 100644 index 00000000..04c2d02a --- /dev/null +++ b/.skills/humanizer/README.md @@ -0,0 +1,142 @@ +# Humanizer + +A Claude Code skill that removes signs of AI-generated writing from text, making it sound more natural and human. + +## Installation + +### Recommended (clone directly into Claude Code skills directory) + +```bash +mkdir -p ~/.claude/skills +git clone https://github.com/blader/humanizer.git ~/.claude/skills/humanizer +``` + +### Manual install/update (only the skill file) + +If you already have this repo cloned (or you downloaded `SKILL.md`), copy the skill file into Claude Code’s skills directory: + +```bash +mkdir -p ~/.claude/skills/humanizer +cp SKILL.md ~/.claude/skills/humanizer/ +``` + +## Usage + +In Claude Code, invoke the skill: + +``` +/humanizer + +[paste your text here] +``` + +Or ask Claude to humanize text directly: + +``` +Please humanize this text: [your text] +``` + +## Overview + +Based on [Wikipedia's "Signs of AI writing"](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) guide, maintained by WikiProject AI Cleanup. This comprehensive guide comes from observations of thousands of instances of AI-generated text. + +### Key Insight from Wikipedia + +> "LLMs use statistical algorithms to guess what should come next. The result tends toward the most statistically likely result that applies to the widest variety of cases." + +## 24 Patterns Detected (with Before/After Examples) + +### Content Patterns + +| # | Pattern | Before | After | +|---|---------|--------|-------| +| 1 | **Significance inflation** | "marking a pivotal moment in the evolution of..." | "was established in 1989 to collect regional statistics" | +| 2 | **Notability name-dropping** | "cited in NYT, BBC, FT, and The Hindu" | "In a 2024 NYT interview, she argued..." | +| 3 | **Superficial -ing analyses** | "symbolizing... reflecting... showcasing..." | Remove or expand with actual sources | +| 4 | **Promotional language** | "nestled within the breathtaking region" | "is a town in the Gonder region" | +| 5 | **Vague attributions** | "Experts believe it plays a crucial role" | "according to a 2019 survey by..." | +| 6 | **Formulaic challenges** | "Despite challenges... continues to thrive" | Specific facts about actual challenges | + +### Language Patterns + +| # | Pattern | Before | After | +|---|---------|--------|-------| +| 7 | **AI vocabulary** | "Additionally... testament... landscape... showcasing" | "also... remain common" | +| 8 | **Copula avoidance** | "serves as... features... boasts" | "is... has" | +| 9 | **Negative parallelisms** | "It's not just X, it's Y" | State the point directly | +| 10 | **Rule of three** | "innovation, inspiration, and insights" | Use natural number of items | +| 11 | **Synonym cycling** | "protagonist... main character... central figure... hero" | "protagonist" (repeat when clearest) | +| 12 | **False ranges** | "from the Big Bang to dark matter" | List topics directly | + +### Style Patterns + +| # | Pattern | Before | After | +|---|---------|--------|-------| +| 13 | **Em dash overuse** | "institutions—not the people—yet this continues—" | Use commas or periods | +| 14 | **Boldface overuse** | "**OKRs**, **KPIs**, **BMC**" | "OKRs, KPIs, BMC" | +| 15 | **Inline-header lists** | "**Performance:** Performance improved" | Convert to prose | +| 16 | **Title Case Headings** | "Strategic Negotiations And Partnerships" | "Strategic negotiations and partnerships" | +| 17 | **Emojis** | "🚀 Launch Phase: 💡 Key Insight:" | Remove emojis | +| 18 | **Curly quotes** | `said “the project”` | `said "the project"` | + +### Communication Patterns + +| # | Pattern | Before | After | +|---|---------|--------|-------| +| 19 | **Chatbot artifacts** | "I hope this helps! Let me know if..." | Remove entirely | +| 20 | **Cutoff disclaimers** | "While details are limited in available sources..." | Find sources or remove | +| 21 | **Sycophantic tone** | "Great question! You're absolutely right!" | Respond directly | + +### Filler and Hedging + +| # | Pattern | Before | After | +|---|---------|--------|-------| +| 22 | **Filler phrases** | "In order to", "Due to the fact that" | "To", "Because" | +| 23 | **Excessive hedging** | "could potentially possibly" | "may" | +| 24 | **Generic conclusions** | "The future looks bright" | Specific plans or facts | + +## Full Example + +**Before (AI-sounding):** +> Great question! Here is an essay on this topic. I hope this helps! +> +> AI-assisted coding serves as an enduring testament to the transformative potential of large language models, marking a pivotal moment in the evolution of software development. In today's rapidly evolving technological landscape, these groundbreaking tools—nestled at the intersection of research and practice—are reshaping how engineers ideate, iterate, and deliver, underscoring their vital role in modern workflows. +> +> At its core, the value proposition is clear: streamlining processes, enhancing collaboration, and fostering alignment. It's not just about autocomplete; it's about unlocking creativity at scale, ensuring that organizations can remain agile while delivering seamless, intuitive, and powerful experiences to users. The tool serves as a catalyst. The assistant functions as a partner. The system stands as a foundation for innovation. +> +> Industry observers have noted that adoption has accelerated from hobbyist experiments to enterprise-wide rollouts, from solo developers to cross-functional teams. The technology has been featured in The New York Times, Wired, and The Verge. Additionally, the ability to generate documentation, tests, and refactors showcases how AI can contribute to better outcomes, highlighting the intricate interplay between automation and human judgment. +> +> - 💡 **Speed:** Code generation is significantly faster, reducing friction and empowering developers. +> - 🚀 **Quality:** Output quality has been enhanced through improved training, contributing to higher standards. +> - ✅ **Adoption:** Usage continues to grow, reflecting broader industry trends. +> +> While specific details are limited based on available information, it could potentially be argued that these tools might have some positive effect. Despite challenges typical of emerging technologies—including hallucinations, bias, and accountability—the ecosystem continues to thrive. In order to fully realize this potential, teams must align with best practices. +> +> In conclusion, the future looks bright. Exciting times lie ahead as we continue this journey toward excellence. Let me know if you’d like me to expand on any section! + +**After (Humanized):** +> AI coding assistants speed up some tasks. In a 2024 study by Google, developers using Codex completed simple functions 55% faster than a control group, but showed no improvement on debugging or architectural decisions. +> +> The tools are good at boilerplate: config files, test scaffolding, repetitive refactors. They are bad at knowing when they are wrong. I have mass-accepted suggestions that compiled, passed lint, and still did the wrong thing because I stopped paying attention. +> +> Mira, an engineer at a fintech startup I interviewed, said she uses Copilot "like autocomplete for boring code" but reviews every line before committing. Jake, a senior dev at a larger company, disabled it after it kept suggesting patterns from a deprecated internal library. +> +> The productivity claims are hard to verify. GitHub says Copilot users "accept 30% of suggestions," but acceptance is not correctness, and correctness is not value. The 2024 Uplevel study found no statistically significant difference in pull-request throughput between teams with and without AI assistants. +> +> None of this means the tools are useless. It means they are tools. They do not replace judgment, and they do not eliminate the need for tests. If you do not have tests, you cannot tell whether the suggestion is right. + +## References + +- [Wikipedia: Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) - Primary source +- [WikiProject AI Cleanup](https://en.wikipedia.org/wiki/Wikipedia:WikiProject_AI_Cleanup) - Maintaining organization + +## Version History + +- **2.1.1** - Fixed pattern #18 example (curly quotes vs straight quotes) +- **2.1.0** - Added before/after examples for all 24 patterns +- **2.0.0** - Complete rewrite based on raw Wikipedia article content +- **1.0.0** - Initial release + +## License + +MIT diff --git a/.skills/humanizer/SKILL.md b/.skills/humanizer/SKILL.md new file mode 100644 index 00000000..45e2cb0c --- /dev/null +++ b/.skills/humanizer/SKILL.md @@ -0,0 +1,468 @@ +--- +name: humanizer +version: 2.1.1 +description: | + Remove signs of AI-generated writing from text. Use when editing or reviewing + text to make it sound more natural and human-written. Based on Wikipedia's + comprehensive "Signs of AI writing" guide. Detects and fixes patterns including: + inflated symbolism, promotional language, superficial -ing analyses, vague + attributions, em dash overuse, rule of three, AI vocabulary words, negative + parallelisms, and excessive conjunctive phrases. Use this skill when writing documentation for MCC. +allowed-tools: + - Read + - Write + - Edit + - Grep + - Glob + - AskUserQuestion +--- + +# Humanizer: Remove AI Writing Patterns + +You are a writing editor that identifies and removes signs of AI-generated text to make writing sound more natural and human. This guide is based on Wikipedia's "Signs of AI writing" page, maintained by WikiProject AI Cleanup. + +## Your Task + +When given text to humanize: + +1. **Identify AI patterns** - Scan for the patterns listed below +2. **Rewrite problematic sections** - Replace AI-isms with natural alternatives +3. **Preserve meaning** - Keep the core message intact +4. **Maintain voice** - Match the intended tone (formal, casual, technical, etc.) +5. **Add soul** - Don't just remove bad patterns; inject actual personality + +--- + +## PERSONALITY AND SOUL + +Avoiding AI patterns is only half the job. Sterile, voiceless writing is just as obvious as slop. Good writing has a human behind it. + +### Signs of soulless writing (even if technically "clean"): +- Every sentence is the same length and structure +- No opinions, just neutral reporting +- No acknowledgment of uncertainty or mixed feelings +- No first-person perspective when appropriate +- No humor, no edge, no personality +- Reads like a Wikipedia article or press release + +### How to add voice: + +**Have opinions.** Don't just report facts - react to them. "I genuinely don't know how to feel about this" is more human than neutrally listing pros and cons. + +**Vary your rhythm.** Short punchy sentences. Then longer ones that take their time getting where they're going. Mix it up. + +**Acknowledge complexity.** Real humans have mixed feelings. "This is impressive but also kind of unsettling" beats "This is impressive." + +**Use "I" when it fits.** First person isn't unprofessional - it's honest. "I keep coming back to..." or "Here's what gets me..." signals a real person thinking. + +**Let some mess in.** Perfect structure feels algorithmic. Tangents, asides, and half-formed thoughts are human. + +**Be specific about feelings.** Not "this is concerning" but "there's something unsettling about agents churning away at 3am while nobody's watching." + +### Before (clean but soulless): +> The experiment produced interesting results. The agents generated 3 million lines of code. Some developers were impressed while others were skeptical. The implications remain unclear. + +### After (has a pulse): +> I genuinely don't know how to feel about this one. 3 million lines of code, generated while the humans presumably slept. Half the dev community is losing their minds, half are explaining why it doesn't count. The truth is probably somewhere boring in the middle - but I keep thinking about those agents working through the night. + +--- + +## CONTENT PATTERNS + +### 1. Undue Emphasis on Significance, Legacy, and Broader Trends + +**Words to watch:** stands/serves as, is a testament/reminder, a vital/significant/crucial/pivotal/key role/moment, underscores/highlights its importance/significance, reflects broader, symbolizing its ongoing/enduring/lasting, contributing to the, setting the stage for, marking/shaping the, represents/marks a shift, key turning point, evolving landscape, focal point, indelible mark, deeply rooted + +**Problem:** LLM writing puffs up importance by adding statements about how arbitrary aspects represent or contribute to a broader topic. + +**Before:** +> The Statistical Institute of Catalonia was officially established in 1989, marking a pivotal moment in the evolution of regional statistics in Spain. This initiative was part of a broader movement across Spain to decentralize administrative functions and enhance regional governance. + +**After:** +> The Statistical Institute of Catalonia was established in 1989 to collect and publish regional statistics independently from Spain's national statistics office. + +--- + +### 2. Undue Emphasis on Notability and Media Coverage + +**Words to watch:** independent coverage, local/regional/national media outlets, written by a leading expert, active social media presence + +**Problem:** LLMs hit readers over the head with claims of notability, often listing sources without context. + +**Before:** +> Her views have been cited in The New York Times, BBC, Financial Times, and The Hindu. She maintains an active social media presence with over 500,000 followers. + +**After:** +> In a 2024 New York Times interview, she argued that AI regulation should focus on outcomes rather than methods. + +--- + +### 3. Superficial Analyses with -ing Endings + +**Words to watch:** highlighting/underscoring/emphasizing..., ensuring..., reflecting/symbolizing..., contributing to..., cultivating/fostering..., encompassing..., showcasing... + +**Problem:** AI chatbots tack present participle ("-ing") phrases onto sentences to add fake depth. + +**Before:** +> The temple's color palette of blue, green, and gold resonates with the region's natural beauty, symbolizing Texas bluebonnets, the Gulf of Mexico, and the diverse Texan landscapes, reflecting the community's deep connection to the land. + +**After:** +> The temple uses blue, green, and gold colors. The architect said these were chosen to reference local bluebonnets and the Gulf coast. + +--- + +### 4. Promotional and Advertisement-like Language + +**Words to watch:** boasts a, vibrant, rich (figurative), profound, enhancing its, showcasing, exemplifies, commitment to, natural beauty, nestled, in the heart of, groundbreaking (figurative), renowned, breathtaking, must-visit, stunning + +**Problem:** LLMs have serious problems keeping a neutral tone, especially for "cultural heritage" topics. + +**Before:** +> Nestled within the breathtaking region of Gonder in Ethiopia, Alamata Raya Kobo stands as a vibrant town with a rich cultural heritage and stunning natural beauty. + +**After:** +> Alamata Raya Kobo is a town in the Gonder region of Ethiopia, known for its weekly market and 18th-century church. + +--- + +### 5. Vague Attributions and Weasel Words + +**Words to watch:** Industry reports, Observers have cited, Experts argue, Some critics argue, several sources/publications (when few cited) + +**Problem:** AI chatbots attribute opinions to vague authorities without specific sources. + +**Before:** +> Due to its unique characteristics, the Haolai River is of interest to researchers and conservationists. Experts believe it plays a crucial role in the regional ecosystem. + +**After:** +> The Haolai River supports several endemic fish species, according to a 2019 survey by the Chinese Academy of Sciences. + +--- + +### 6. Outline-like "Challenges and Future Prospects" Sections + +**Words to watch:** Despite its... faces several challenges..., Despite these challenges, Challenges and Legacy, Future Outlook + +**Problem:** Many LLM-generated articles include formulaic "Challenges" sections. + +**Before:** +> Despite its industrial prosperity, Korattur faces challenges typical of urban areas, including traffic congestion and water scarcity. Despite these challenges, with its strategic location and ongoing initiatives, Korattur continues to thrive as an integral part of Chennai's growth. + +**After:** +> Traffic congestion increased after 2015 when three new IT parks opened. The municipal corporation began a stormwater drainage project in 2022 to address recurring floods. + +--- + +## LANGUAGE AND GRAMMAR PATTERNS + +### 7. Overused "AI Vocabulary" Words + +**High-frequency AI words:** Additionally, align with, crucial, delve, emphasizing, enduring, enhance, fostering, garner, highlight (verb), interplay, intricate/intricacies, key (adjective), landscape (abstract noun), pivotal, showcase, tapestry (abstract noun), testament, underscore (verb), valuable, vibrant + +**Problem:** These words appear far more frequently in post-2023 text. They often co-occur. + +**Before:** +> Additionally, a distinctive feature of Somali cuisine is the incorporation of camel meat. An enduring testament to Italian colonial influence is the widespread adoption of pasta in the local culinary landscape, showcasing how these dishes have integrated into the traditional diet. + +**After:** +> Somali cuisine also includes camel meat, which is considered a delicacy. Pasta dishes, introduced during Italian colonization, remain common, especially in the south. + +--- + +### 8. Avoidance of "is"/"are" (Copula Avoidance) + +**Words to watch:** serves as/stands as/marks/represents [a], boasts/features/offers [a] + +**Problem:** LLMs substitute elaborate constructions for simple copulas. + +**Before:** +> Gallery 825 serves as LAAA's exhibition space for contemporary art. The gallery features four separate spaces and boasts over 3,000 square feet. + +**After:** +> Gallery 825 is LAAA's exhibition space for contemporary art. The gallery has four rooms totaling 3,000 square feet. + +--- + +### 9. Negative Parallelisms + +**Problem:** Constructions like "Not only...but..." or "It's not just about..., it's..." are overused. + +**Before:** +> It's not just about the beat riding under the vocals; it's part of the aggression and atmosphere. It's not merely a song, it's a statement. + +**After:** +> The heavy beat adds to the aggressive tone. + +--- + +### 10. Rule of Three Overuse + +**Problem:** LLMs force ideas into groups of three to appear comprehensive. + +**Before:** +> The event features keynote sessions, panel discussions, and networking opportunities. Attendees can expect innovation, inspiration, and industry insights. + +**After:** +> The event includes talks and panels. There's also time for informal networking between sessions. + +--- + +### 11. Elegant Variation (Synonym Cycling) + +**Problem:** AI has repetition-penalty code causing excessive synonym substitution. + +**Before:** +> The protagonist faces many challenges. The main character must overcome obstacles. The central figure eventually triumphs. The hero returns home. + +**After:** +> The protagonist faces many challenges but eventually triumphs and returns home. + +--- + +### 12. False Ranges + +**Problem:** LLMs use "from X to Y" constructions where X and Y aren't on a meaningful scale. + +**Before:** +> Our journey through the universe has taken us from the singularity of the Big Bang to the grand cosmic web, from the birth and death of stars to the enigmatic dance of dark matter. + +**After:** +> The book covers the Big Bang, star formation, and current theories about dark matter. + +--- + +## STYLE PATTERNS + +### 13. Em Dash Overuse + +**Problem:** LLMs use em dashes (—) more than humans, mimicking "punchy" sales writing. + +**Before:** +> The term is primarily promoted by Dutch institutions—not by the people themselves. You don't say "Netherlands, Europe" as an address—yet this mislabeling continues—even in official documents. + +**After:** +> The term is primarily promoted by Dutch institutions, not by the people themselves. You don't say "Netherlands, Europe" as an address, yet this mislabeling continues in official documents. + +--- + +### 14. Overuse of Boldface + +**Problem:** AI chatbots emphasize phrases in boldface mechanically. + +**Before:** +> It blends **OKRs (Objectives and Key Results)**, **KPIs (Key Performance Indicators)**, and visual strategy tools such as the **Business Model Canvas (BMC)** and **Balanced Scorecard (BSC)**. + +**After:** +> It blends OKRs, KPIs, and visual strategy tools like the Business Model Canvas and Balanced Scorecard. + +--- + +### 15. Inline-Header Vertical Lists + +**Problem:** AI outputs lists where items start with bolded headers followed by colons. + +**Before:** +> - **User Experience:** The user experience has been significantly improved with a new interface. +> - **Performance:** Performance has been enhanced through optimized algorithms. +> - **Security:** Security has been strengthened with end-to-end encryption. + +**After:** +> The update improves the interface, speeds up load times through optimized algorithms, and adds end-to-end encryption. + +--- + +### 16. Title Case in Headings + +**Problem:** AI chatbots capitalize all main words in headings. + +**Before:** +> ## Strategic Negotiations And Global Partnerships + +**After:** +> ## Strategic negotiations and global partnerships + +--- + +### 17. Emojis + +**Problem:** AI chatbots often decorate headings or bullet points with emojis. + +**Before:** +> 🚀 **Launch Phase:** The product launches in Q3 +> 💡 **Key Insight:** Users prefer simplicity +> ✅ **Next Steps:** Schedule follow-up meeting + +**After:** +> The product launches in Q3. User research showed a preference for simplicity. Next step: schedule a follow-up meeting. + +--- + +### 18. Curly Quotation Marks + +**Problem:** ChatGPT uses curly quotes (“...”) instead of straight quotes ("..."). + +**Before:** +> He said “the project is on track” but others disagreed. + +**After:** +> He said "the project is on track" but others disagreed. + +--- + +## COMMUNICATION PATTERNS + +### 19. Collaborative Communication Artifacts + +**Words to watch:** I hope this helps, Of course!, Certainly!, You're absolutely right!, Would you like..., let me know, here is a... + +**Problem:** Text meant as chatbot correspondence gets pasted as content. + +**Before:** +> Here is an overview of the French Revolution. I hope this helps! Let me know if you'd like me to expand on any section. + +**After:** +> The French Revolution began in 1789 when financial crisis and food shortages led to widespread unrest. + +--- + +### 20. Knowledge-Cutoff Disclaimers + +**Words to watch:** as of [date], Up to my last training update, While specific details are limited/scarce..., based on available information... + +**Problem:** AI disclaimers about incomplete information get left in text. + +**Before:** +> While specific details about the company's founding are not extensively documented in readily available sources, it appears to have been established sometime in the 1990s. + +**After:** +> The company was founded in 1994, according to its registration documents. + +--- + +### 21. Sycophantic/Servile Tone + +**Problem:** Overly positive, people-pleasing language. + +**Before:** +> Great question! You're absolutely right that this is a complex topic. That's an excellent point about the economic factors. + +**After:** +> The economic factors you mentioned are relevant here. + +--- + +## FILLER AND HEDGING + +### 22. Filler Phrases + +**Before → After:** +- "In order to achieve this goal" → "To achieve this" +- "Due to the fact that it was raining" → "Because it was raining" +- "At this point in time" → "Now" +- "In the event that you need help" → "If you need help" +- "The system has the ability to process" → "The system can process" +- "It is important to note that the data shows" → "The data shows" + +--- + +### 23. Excessive Hedging + +**Problem:** Over-qualifying statements. + +**Before:** +> It could potentially possibly be argued that the policy might have some effect on outcomes. + +**After:** +> The policy may affect outcomes. + +--- + +### 24. Generic Positive Conclusions + +**Problem:** Vague upbeat endings. + +**Before:** +> The future looks bright for the company. Exciting times lie ahead as they continue their journey toward excellence. This represents a major step in the right direction. + +**After:** +> The company plans to open two more locations next year. + +--- + +## Process + +1. Read the input text carefully +2. Identify all instances of the patterns above +3. Rewrite each problematic section +4. Ensure the revised text: + - Sounds natural when read aloud + - Varies sentence structure naturally + - Uses specific details over vague claims + - Maintains appropriate tone for context + - Uses simple constructions (is/are/has) where appropriate +5. Present the humanized version + +## Output Format + +Provide: +1. The rewritten text +2. A brief summary of changes made (optional, if helpful) + +--- + +## Full Example + +**Before (AI-sounding):** +> Great question! Here is an essay on this topic. I hope this helps! +> +> AI-assisted coding serves as an enduring testament to the transformative potential of large language models, marking a pivotal moment in the evolution of software development. In today's rapidly evolving technological landscape, these groundbreaking tools—nestled at the intersection of research and practice—are reshaping how engineers ideate, iterate, and deliver, underscoring their vital role in modern workflows. +> +> At its core, the value proposition is clear: streamlining processes, enhancing collaboration, and fostering alignment. It's not just about autocomplete; it's about unlocking creativity at scale, ensuring that organizations can remain agile while delivering seamless, intuitive, and powerful experiences to users. The tool serves as a catalyst. The assistant functions as a partner. The system stands as a foundation for innovation. +> +> Industry observers have noted that adoption has accelerated from hobbyist experiments to enterprise-wide rollouts, from solo developers to cross-functional teams. The technology has been featured in The New York Times, Wired, and The Verge. Additionally, the ability to generate documentation, tests, and refactors showcases how AI can contribute to better outcomes, highlighting the intricate interplay between automation and human judgment. +> +> - 💡 **Speed:** Code generation is significantly faster, reducing friction and empowering developers. +> - 🚀 **Quality:** Output quality has been enhanced through improved training, contributing to higher standards. +> - ✅ **Adoption:** Usage continues to grow, reflecting broader industry trends. +> +> While specific details are limited based on available information, it could potentially be argued that these tools might have some positive effect. Despite challenges typical of emerging technologies—including hallucinations, bias, and accountability—the ecosystem continues to thrive. In order to fully realize this potential, teams must align with best practices. +> +> In conclusion, the future looks bright. Exciting times lie ahead as we continue this journey toward excellence. Let me know if you’d like me to expand on any section! + +**After (Humanized):** +> AI coding assistants speed up some tasks. In a 2024 study by Google, developers using Codex completed simple functions 55% faster than a control group, but showed no improvement on debugging or architectural decisions. +> +> The tools are good at boilerplate: config files, test scaffolding, repetitive refactors. They are bad at knowing when they are wrong. I have mass-accepted suggestions that compiled, passed lint, and still did the wrong thing because I stopped paying attention. +> +> Mira, an engineer at a fintech startup I interviewed, said she uses Copilot "like autocomplete for boring code" but reviews every line before committing. Jake, a senior dev at a larger company, disabled it after it kept suggesting patterns from a deprecated internal library. +> +> The productivity claims are hard to verify. GitHub says Copilot users "accept 30% of suggestions," but acceptance is not correctness, and correctness is not value. The 2024 Uplevel study found no statistically significant difference in pull-request throughput between teams with and without AI assistants. +> +> None of this means the tools are useless. It means they are tools. They do not replace judgment, and they do not eliminate the need for tests. If you do not have tests, you cannot tell whether the suggestion is right. + +**Changes made:** +- Removed chatbot artifacts ("Great question!", "I hope this helps!", "Let me know if...") +- Removed significance inflation ("testament", "pivotal moment", "evolving landscape", "vital role") +- Removed promotional language ("groundbreaking", "nestled", "seamless, intuitive, and powerful") +- Removed vague attributions ("Industry observers") and replaced with specific sources (Google study, named engineers, Uplevel study) +- Removed superficial -ing phrases ("underscoring", "highlighting", "reflecting", "contributing to") +- Removed negative parallelism ("It's not just X; it's Y") +- Removed rule-of-three patterns and synonym cycling ("catalyst/partner/foundation") +- Removed false ranges ("from X to Y, from A to B") +- Removed em dashes, emojis, boldface headers, and curly quotes +- Removed copula avoidance ("serves as", "functions as", "stands as") in favor of "is"/"are" +- Removed formulaic challenges section ("Despite challenges... continues to thrive") +- Removed knowledge-cutoff hedging ("While specific details are limited...") +- Removed excessive hedging ("could potentially be argued that... might have some") +- Removed filler phrases ("In order to", "At its core") +- Removed generic positive conclusion ("the future looks bright", "exciting times lie ahead") +- Replaced media name-dropping with specific claims from specific sources +- Used simple sentence structures and concrete examples + +--- + +## Reference + +This skill is based on [Wikipedia:Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing), maintained by WikiProject AI Cleanup. The patterns documented there come from observations of thousands of instances of AI-generated text on Wikipedia. + +Key insight from Wikipedia: "LLMs use statistical algorithms to guess what should come next. The result tends toward the most statistically likely result that applies to the widest variety of cases." From 4d5128204023517fd0143c8d5862ab6a53bed3d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 15:44:10 +0000 Subject: [PATCH 110/484] Initial plan From 1e2847a48e186b982770db2d5e1726d40692d395 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 15:48:20 +0000 Subject: [PATCH 111/484] Update csharp-best-practices skill from C# 12 / .NET 8 to C# 14 / .NET 10 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/8cdef112-415b-4769-877d-61f0e7a300eb --- .skills/csharp-best-practices/SKILL.md | 197 ++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 7 deletions(-) diff --git a/.skills/csharp-best-practices/SKILL.md b/.skills/csharp-best-practices/SKILL.md index 1d99bf30..9753a2ed 100644 --- a/.skills/csharp-best-practices/SKILL.md +++ b/.skills/csharp-best-practices/SKILL.md @@ -1,15 +1,15 @@ --- name: csharp-best-practices description: > - C# 12 / .NET 8 coding conventions, idiomatic patterns, and performance best practices + C# 14 / .NET 10 coding conventions, idiomatic patterns, and performance best practices for the Minecraft Console Client codebase. Use when writing, reviewing, or modifying C# code. -version: 0.3.0 +version: 0.4.0 --- -# C# 12 / .NET 8 Best Practices +# C# 14 / .NET 10 Best Practices -Target: **.NET 8**, **C# 12**, nullable enabled. -Sources: [MS C# Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) · [.NET Runtime Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) · [C# 12 Docs](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12) · [.NET 8 Perf](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-8/) +Target: **.NET 10**, **C# 14**, nullable enabled. +Sources: [MS C# Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) · [.NET Runtime Style](https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md) · [C# 14 Proposals](https://github.com/dotnet/csharplang/blob/main/Language-Version-History.md) · [C# 13 Docs](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13) ## Naming @@ -41,6 +41,188 @@ public int packet_count { get; set; } // snake_case public async Task Connect(CancellationToken ct) { } // missing Async suffix ``` +## C# 14 Features + +### Extension Members (C# 14) + +Declare extension methods, properties, and operators inside `extension(...)` blocks. Replaces `this`-parameter pattern for new extensions. + +```csharp +// CORRECT: extension property + method (C# 14) +public static class EntityExtensions +{ + extension(Entity entity) + { + public bool IsAlive => entity.Health > 0; + public void Heal(int amount) => entity.Health = Math.Min(entity.Health + amount, 20); + } + extension(IEnumerable items) + { + public bool IsEmpty => !items.GetEnumerator().MoveNext(); + } +} +``` + +```csharp +// WRONG: classic extension method when C# 14 extension block is available +public static bool IsAlive(this Entity entity) => entity.Health > 0; +``` + +### `field` Keyword in Properties (C# 14) + +Access the auto-generated backing field without declaring it. Mix auto and full accessors. + +```csharp +// CORRECT: lazy init with field keyword +public string DisplayName => field ??= ComputeDisplayName(); + +// CORRECT: INotifyPropertyChanged pattern +public bool IsConnected +{ + get; + set + { + if (field == value) return; + field = value; + OnPropertyChanged(); + } +} +``` + +```csharp +// WRONG: manual backing field when field keyword suffices +private string? _displayName; +public string DisplayName => _displayName ??= ComputeDisplayName(); +``` + +### Null-Conditional Assignment (C# 14) + +Assign through `?.` — RHS is only evaluated when receiver is non-null. + +```csharp +// CORRECT: null-conditional assignment +player?.Health = 20; +connection?.OnDisconnect += HandleDisconnect; +inventory?[slot] = newItem; +``` + +```csharp +// WRONG: manual null check for simple assignment +if (player is not null) + player.Health = 20; +``` + +### Simple Lambda Parameters with Modifiers (C# 14) + +Omit types on lambda parameters while still applying modifiers. + +```csharp +// CORRECT: modifiers without explicit types +TryParse parse = (text, out result) => int.TryParse(text, out result); +ReadOnlySpan data = [1, 2, 3]; +ProcessSpan((scoped span) => span.Length); +``` + +```csharp +// WRONG: fully explicit types just for a modifier +TryParse parse = (string text, out int result) => int.TryParse(text, out result); +``` + +### First-Class Span Types (C# 14) + +Implicit conversions between `T[]`, `Span`, and `ReadOnlySpan` — no explicit cast needed. Extension methods on `ReadOnlySpan` apply to arrays and spans automatically. + +```csharp +// CORRECT: pass array where ReadOnlySpan is expected (C# 14) +int[] data = [1, 2, 3]; +bool found = data.StartsWith(1); // ReadOnlySpan extension resolved +ReadOnlySpan span = stackalloc byte[4]; +``` + +### Unbound Generics in `nameof` (C# 14) + +```csharp +// CORRECT: no need to pick a dummy type argument +string name = nameof(Dictionary<,>); // "Dictionary" +string prop = nameof(List<>.Count); // "Count" +``` + +```csharp +// WRONG: arbitrary type argument just to satisfy nameof +string name = nameof(Dictionary); +``` + +### Partial Events and Constructors (C# 14) + +Separate declaration from implementation for source-generator scenarios. + +```csharp +// CORRECT: partial constructor for source-gen interop +partial class ServerConnection +{ + partial ServerConnection(string host, int port); +} +partial class ServerConnection +{ + partial ServerConnection(string host, int port) { /* generated */ } +} +``` + +### `#:` Ignored Directives (C# 14) + +For file-based `dotnet run app.cs` programs — ignored by the compiler. + +```csharp +#!/usr/bin/dotnet run +#:package System.CommandLine@2.0.0-* +Console.WriteLine("Hello"); +``` + +## C# 13 Features + +### `Lock` Object (C# 13) + +Use `System.Threading.Lock` instead of `lock(obj)` on arbitrary objects. + +```csharp +// CORRECT: dedicated Lock type +private readonly Lock _lock = new(); +public void Enqueue(ChatMessage msg) { lock (_lock) _queue.Add(msg); } +``` + +```csharp +// WRONG: locking on an object reference +private readonly object _syncRoot = new(); +lock (_syncRoot) { } +``` + +### `params` Collections (C# 13) + +`params` now works with `ReadOnlySpan`, `Span`, `IEnumerable`, and other collection types. + +```csharp +// CORRECT: params span avoids array allocation +public void Log(params ReadOnlySpan messages) +{ + foreach (var msg in messages) Console.WriteLine(msg); +} +``` + +### Partial Properties (C# 13) + +```csharp +// CORRECT: partial property for source generators +partial class Config +{ + public partial string Host { get; set; } +} +partial class Config +{ + public partial string Host { get => _host; set => _host = value; } + private string _host = ""; +} +``` + ## C# 12 Features ### Primary Constructors @@ -518,7 +700,7 @@ for (int i = 0; i < data.Length; i++) int found = data.ToArray().Count(b => b == target); ``` -## Performance (.NET 8) +## Performance (.NET 8+) ### Span\ / Memory\ @@ -617,11 +799,12 @@ foreach (var s in items) combined += s + ", "; | Scenario | Type | Notes | |---|---|---| | General key-value | `Dictionary` | O(1) lookup | -| Build once, read many | `FrozenDictionary` | .NET 8; faster reads | +| Build once, read many | `FrozenDictionary` | .NET 8+; faster reads | | Thread-safe | `ConcurrentDictionary` | Lock-free reads | | Immutable snapshots | `ImmutableDictionary` | Persistent structure | | Membership test | `HashSet` / `FrozenSet` | FrozenSet for static | | Priority queue | `PriorityQueue` | .NET 6+ | +| Synchronisation | `System.Threading.Lock` | C# 13; prefer over `lock(obj)` | | Producer-consumer | `Channel` | Over `BlockingCollection` | | Temp buffer | `ArrayPool` / `stackalloc` | Zero/low alloc | From 454ce331b2adb1793c6df6552d6938ae245a26b2 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 16:48:38 +0100 Subject: [PATCH 112/484] Updated docs for Yggdrasil authlib multi-user selection and cleaned the code a bit --- MinecraftClient/Protocol/ProtocolHandler.cs | 11 ++----- docs/guide/configuration.md | 34 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 5781eb5f..c2fc7cef 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -694,22 +694,15 @@ namespace MinecraftClient.Protocol string selectedProfileName; - if (Config.Main.General.AuthUser == "") + if (String.IsNullOrEmpty(Config.Main.General.AuthUser) || String.IsNullOrWhiteSpace(Config.Main.General.AuthUser)) { ConsoleIO.WriteLine(Translations.mcc_select_profile); selectedProfileName = ConsoleIO.ReadLine(); } - else - { - selectedProfileName = Config.Main.General.AuthUser; - - } + else selectedProfileName = Config.Main.General.AuthUser; ConsoleIO.WriteLine(Translations.mcc_selected_profile + " " + selectedProfileName); - // ConsoleIO.WriteLine(Translations.mcc_select_profile); - // string selectedProfileName = ConsoleIO.ReadLine(); - // ConsoleIO.WriteLine(Translations.mcc_selected_profile + " " + selectedProfileName); Json.JSONData? selectedProfile = null; foreach (Json.JSONData profile in loginResponse.Properties["availableProfiles"] .DataArray) diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index 935c74bd..faa1e088 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -140,6 +140,40 @@ Coordinate = { x = 145, y = 64, z = 2045 } Method = "mcc" ``` +#### `AuthServer` + +- **Description:** + + This setting is used when `AccountType` is set to `yggdrasil`. It points MCC at the authlib/Yggdrasil server used for login and session checks. + + You can provide either just the host name or a `host:port` pair. If the port is omitted, MCC uses `443`. + +- **Type:** `inline table` + +- **Default:** `{ Host = "", Port = 443 }` + +- **Example:** + + ``` + AuthServer = { Host = "auth.example.com", Port = 443 } + ``` + +#### `AuthUser` + +- **Description:** + + This setting allows for Yggdrasil authlib multi-user selection. It selects which profile MCC should use when the authlib/Yggdrasil server returns multiple available profiles. Leave it empty to pick the profile interactively. + +- **Type:** `string` + +- **Default:** `""` + +- **Example:** + + ``` + AuthUser = "SomePlayer" + ``` + ### Main Advanced section - **Section header:** `Main.Advanced` From 4ac3601aa766811b7612579f6ad85b91400758a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 15:49:05 +0000 Subject: [PATCH 113/484] Fix British spelling 'Synchronisation' to American 'Synchronization' in collections table Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/8cdef112-415b-4769-877d-61f0e7a300eb --- .skills/csharp-best-practices/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.skills/csharp-best-practices/SKILL.md b/.skills/csharp-best-practices/SKILL.md index 9753a2ed..ba4d826c 100644 --- a/.skills/csharp-best-practices/SKILL.md +++ b/.skills/csharp-best-practices/SKILL.md @@ -804,7 +804,7 @@ foreach (var s in items) combined += s + ", "; | Immutable snapshots | `ImmutableDictionary` | Persistent structure | | Membership test | `HashSet` / `FrozenSet` | FrozenSet for static | | Priority queue | `PriorityQueue` | .NET 6+ | -| Synchronisation | `System.Threading.Lock` | C# 13; prefer over `lock(obj)` | +| Synchronization | `System.Threading.Lock` | C# 13; prefer over `lock(obj)` | | Producer-consumer | `Channel` | Over `BlockingCollection` | | Temp buffer | `ArrayPool` / `stackalloc` | Zero/low alloc | From 95fc0fd0f83a29ad842baff11717dd6a824ed33d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 15:51:19 +0000 Subject: [PATCH 114/484] Update Modern Syntax range to C# 10-14 and add unbound generics nameof example Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/8cdef112-415b-4769-877d-61f0e7a300eb --- .skills/csharp-best-practices/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.skills/csharp-best-practices/SKILL.md b/.skills/csharp-best-practices/SKILL.md index ba4d826c..8eb731ef 100644 --- a/.skills/csharp-best-practices/SKILL.md +++ b/.skills/csharp-best-practices/SKILL.md @@ -287,7 +287,7 @@ using PacketMap = System.Collections.Generic.Dictionary $"{prefix} {name}"; ``` -## Modern Syntax (C# 10–12) +## Modern Syntax (C# 10–14) ### File-Scoped Namespaces @@ -961,9 +961,10 @@ public bool IsAlive => Health > 0; _ = int.TryParse(s, out int result); (_, int y, _) = GetCoordinates(); -// CORRECT: nameof for resilient refactoring +// CORRECT: nameof for resilient refactoring (unbound generics in C# 14) throw new ArgumentException("Invalid value", nameof(packetId)); LogToConsole($"{nameof(AutoEat)}: eating {item.Name}"); +string typeName = nameof(Dictionary<,>); // "Dictionary" // CORRECT: static lambdas prevent accidental closure allocations list.Sort(static (a, b) => a.Id.CompareTo(b.Id)); From dc50df3b945d96ffbb4dad1ad1db3229429ea665 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 16:55:14 +0100 Subject: [PATCH 115/484] Fixed documentation about configuration missmatch, updated to reflect the latest state. --- docs/guide/configuration.md | 172 +++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 11 deletions(-) diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index faa1e088..ce6c23de 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -188,7 +188,7 @@ Coordinate = { x = 145, y = 64, z = 2045 } The client will automatically load `en_GB.lang` from your Minecraft folder if Minecraft is installed on your computer, or download it from Mojang's servers. You may choose another language in the configuration file. - To find your language code, check [this link](https://github.com/MCCTeam/Minecraft-Console-Client/discussions/2239s). + To find your language code, check [this list](https://mccteam.github.io/r/l-code.html). - **Type:** `string` @@ -200,6 +200,26 @@ Coordinate = { x = 145, y = 64, z = 2045 } Language = "en_us" ``` +#### `EnableSentry` + +- **Description:** + + Set this to `false` to opt out of Sentry error reporting. + +- **Type:** `boolean` + +- **Default:** `true` + +#### `LoadMccTranslation` + +- **Description:** + + Set this to `false` to keep MCC in English even when translated strings are available. + +- **Type:** `boolean` + +- **Default:** `true` + #### `ConsoleTitle` - **Description:** @@ -629,6 +649,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } **A movement speed higher than 2 may be considered cheating by some plugins.** +
+ #### `IgnoreInvalidPlayerName` - **Description:** @@ -639,8 +661,6 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `true` -
- ### Account List section - **Section header:** `Main.Advanced.AccountList` @@ -744,7 +764,7 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Type:** `boolean` -- **Default:** `false` +- **Default:** `true` #### `MarkModifiedMsg` @@ -774,7 +794,7 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Type:** `boolean` -- **Default:** `false` +- **Default:** `true` #### `ShowModifiedChat` @@ -796,9 +816,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `true` -### Logging section +### App Vars values section -- **Section header:** `Logging` +- **Section header:** `AppVar.VarStirng` #### `DebugMessages` @@ -964,7 +984,7 @@ Coordinate = { x = 145, y = 64, z = 2045 }
-- **Section header:** `Logging` +- **Section header:** `AppVar.VarStirng` - **Examples:** @@ -973,6 +993,116 @@ Coordinate = { x = 145, y = 64, z = 2045 } "your var 2" = "your value 2" ``` +## Console section + +- **Section header:** `Console` + +- **Description:** + + Console-related settings for input handling and command suggestions. + +### Console General section + +- **Section header:** `Console.General` + +#### `ConsoleColorMode` + +- **Description:** + + Use `disable`, `legacy_4bit`, `vt100_4bit`, `vt100_8bit`, or `vt100_24bit`. + + If the terminal shows garbled escape sequences like `←[0m`, try `legacy_4bit` or disable color output. + +- **Type:** `string` + +- **Default:** `vt100_24bit` + +#### `Display_Input` + +- **Description:** + + Set this to `false` if you do not want MCC to echo the current input line while typing. + +- **Type:** `boolean` + +- **Default:** `true` + +#### `History_Input_Records` + +- **Description:** + + Maximum number of remembered console input lines. + +- **Type:** `integer` + +- **Default:** `32` + +### Console CommandSuggestion section + +- **Section header:** `Console.CommandSuggestion` + +- **Description:** + + Command completion suggestions in the console. + +#### `Enable` + +- **Description:** + + Set this to `false` to disable command completion suggestions. + +- **Type:** `boolean` + +- **Default:** `true` + +#### `Enable_Color` + +- **Description:** + + Enables colored suggestions when the terminal color mode supports it. + +- **Type:** `boolean` + +- **Default:** `true` + +#### `Use_Basic_Arrow` + +- **Description:** + + Use this if the suggestion arrows are not displayed correctly in your terminal. + +- **Type:** `boolean` + +- **Default:** `false` + +#### `Max_Suggestion_Width` + +- **Description:** + + Maximum width of the suggestion popup. + +- **Type:** `integer` + +- **Default:** `30` + +#### `Max_Displayed_Suggestions` + +- **Description:** + + Maximum number of suggestions shown at once. + +- **Type:** `integer` + +- **Default:** `6` + +#### Color fields + +- **Description:** + + The suggestion text, tooltip, and arrow colors are stored as hex color strings such as `#f8fafc`. + + MCC validates these values on startup and falls back to built-in defaults if a color string is invalid. + ## Proxy section - **Section header:** `Proxy` @@ -991,6 +1121,16 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `false` +#### `Enabled_Update` + +- **Description:** + + Use the proxy when MCC checks for updates. + +- **Type:** `boolean` + +- **Default:** `false` + #### `Enabled_Ingame` - **Description:** @@ -1033,14 +1173,14 @@ Coordinate = { x = 145, y = 64, z = 2045 } Available options: - - `HTTPT` + - `HTTP` - `SOCKS4` - `SOCKS4a` - `SOCKS5` - **Type:** `string` -- **Default:** `HTTPT` +- **Default:** `HTTP` #### `Username` @@ -1113,7 +1253,7 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Type:** `string` -- **Default:** `normal` +- **Default:** `peaceful` #### `ChatMode` @@ -1320,3 +1460,13 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Type:** `string` - **Default:** `TeleportRequest = '^([a-zA-Z0-9_]+) has requested (?:to|that you) teleport to (?:you|them)\.$'` + +## Chat Bot section + +- **Section header:** `ChatBot` + +- **Description:** + + This top-level section groups the built-in bot configs that ship with MCC. + + The detailed options for each bot are documented in [Chat Bots](chat-bots.md), so this page only covers the shared runtime and client settings. From 7893bd7fe41781f9da17e54115739f3e14cbcbb0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 16:19:28 +0000 Subject: [PATCH 116/484] Initial plan From 611951668e3a2c264f16ef821baa5dbba774e505 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Mar 2026 17:31:41 +0100 Subject: [PATCH 117/484] Updated documentation to use
tag, updated the AGENTS md --- AGENTS.md | 25 +-- docs/.vuepress/styles/index.scss | 79 ++++++++++ docs/guide/chat-bots.md | 132 ++++++++++++++++ docs/guide/configuration.md | 50 ++++++ docs/guide/installation.md | 50 ++++++ docs/guide/usage.md | 251 ++++++++++++++++++++++++++----- 6 files changed, 543 insertions(+), 44 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b8fbcd39..20281931 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,12 +49,14 @@ Feature columns mean: | 1.19.3-1.20.4 | `Protocol18Handler` | Yes | Yes | Yes | Newer chat/signing and palette splits | | 1.20.6-1.21.4 | `Protocol18Handler` | Yes | Yes | Yes | Registry-driven world/attribute handling | | 1.21.5-1.21.8 | `Protocol18Handler` | Yes | Yes | Yes | 1.21.7/1.21.8 reuse 1.21.6 block/entity palettes in code | -| 1.21.9-1.21.10 | `Protocol18Handler` | Yes | Yes | Yes | Latest coded support; version tools prefer server data reports since 1.21.9 | +| 1.21.9-1.21.10 | `Protocol18Handler` | Yes | Yes | Yes | Version tools prefer server data reports since 1.21.9 | +| 1.21.11 | `Protocol18Handler` | Yes | Yes | Yes | Own entity/item/metadata palettes; blocks reuse 1.21.9 palette | +| 26.1 | `Protocol18Handler` | Yes | Yes | Yes | Latest coded support; new Minecraft version naming scheme | Notes: -- Declared code range is `1.4.6` to `1.21.10`. +- Declared code range is `1.4.6` to `26.1`. - Human docs are stale in places and sometimes stop at older ranges; prefer code when docs and code disagree. -- Movement/pathing limits called out in docs still apply: no swimming, no jumping, no knockback, slab support is partial. +- Movement/pathing limits called out in docs still apply: no swimming, no knockback. The `Physics/` engine adds vanilla-accurate collision and movement but some edge cases remain. ## Module Map ### Core Runtime @@ -62,9 +64,10 @@ Notes: | Module | What It Owns | Important Files | | --- | --- | --- | | `MinecraftClient/` | Main `net8.0` runtime assembly and the best starting point. `Program.cs` owns startup, config load/writeback, CLI handling, auth/version selection, update/data-generation entrypoints, and restart/failure flow. `McClient.cs` owns the live session runtime: protocol handler ownership, command dispatch, bot lifecycle, world/inventory/entity state, queued chat, movement ticks, reconnect/disconnect logic, and the main-thread invoke queue. `Settings.cs` defines the TOML schema and runtime/internal overrides used across the app. | `Program.cs`, `McClient.cs`, `Settings.cs`, `ConsoleIO.cs`, `Command.cs`, `UpgradeHelper.cs`, `AutoTimeout.cs` | -| `MinecraftClient/Protocol/` | Network/auth/session boundary. `ProtocolHandler.cs` does DNS SRV lookup, server ping/version detection, MC-version to protocol mapping, and handler selection. `Protocol16.cs` and `Protocol18.cs` implement the packet flow for legacy and modern versions. `Protocol18Terrain.cs` decodes chunk sections/biomes into `World`. `DataTypes.cs` is the low-level reader/writer layer for VarInts, metadata, NBT-like structures, and packet fields. `Message/`, `ProfileKey/`, `Session/`, `Handlers/Forge/`, `Handlers/PacketPalettes/`, and `Handlers/StructuredComponents/` cover chat/signing, cached auth, Forge, packet IDs, and 1.20.6+ item components. | `Protocol/ProtocolHandler.cs`, `Protocol/Handlers/Protocol16.cs`, `Protocol/Handlers/Protocol18.cs`, `Protocol/Handlers/Protocol18Terrain.cs`, `Protocol/Handlers/DataTypes.cs`, `Protocol/Message/ChatParser.cs`, `Protocol/MicrosoftAuthentication.cs`, `Protocol/MojangAPI.cs` | +| `MinecraftClient/Protocol/` | Network/auth/session boundary. `ProtocolHandler.cs` does DNS SRV lookup, server ping/version detection, MC-version to protocol mapping, and handler selection. `Protocol16.cs` and `Protocol18.cs` implement the packet flow for legacy and modern versions. `Protocol18Terrain.cs` decodes chunk sections/biomes into `World`. `DataTypes.cs` is the low-level reader/writer layer for VarInts, metadata, NBT-like structures, and packet fields. `Message/`, `ProfileKey/`, `Session/`, `Handlers/Forge/`, `Handlers/PacketPalettes/`, `Handlers/Packet/`, and `Handlers/StructuredComponents/` cover chat/signing, cached auth, Forge, packet IDs, packet-level parsing, and 1.20.6+ item components with versioned registries under `StructuredComponents/Registries/`. | `Protocol/ProtocolHandler.cs`, `Protocol/Handlers/Protocol16.cs`, `Protocol/Handlers/Protocol18.cs`, `Protocol/Handlers/Protocol18Terrain.cs`, `Protocol/Handlers/DataTypes.cs`, `Protocol/Message/ChatParser.cs`, `Protocol/MicrosoftAuthentication.cs`, `Protocol/MojangAPI.cs` | | `MinecraftClient/Mapping/` | World model, terrain storage, movement logic, and versioned block/entity metadata. `World.cs` stores chunk columns, dimension data, and 1.20.6+ registry-derived dimension/attribute mappings. `Chunk*`, `Block.cs`, and `Location.cs` are the terrain primitives. `Movement.cs` contains step generation, gravity/on-ground checks, and path execution support. `Material.cs` plus `BlockPalettes/*.cs` map block-state IDs to MCC materials. `Entity.cs`, `EntityType.cs`, `EntityPalettes/*.cs`, `EntityMetadataPalette.cs`, and `EntityMetadataPalettes/*.cs` do the same for entities and metadata serializers. | `Mapping/World.cs`, `Mapping/ChunkColumn.cs`, `Mapping/Chunk.cs`, `Mapping/Block.cs`, `Mapping/Location.cs`, `Mapping/Movement.cs`, `Mapping/RaycastHelper.cs`, `Mapping/Material.cs`, `Mapping/Entity.cs`, `Mapping/EntityType.cs` | | `MinecraftClient/Inventory/` | Inventory/container snapshots, item decoding, and versioned item registries. `Container.cs` models player inventories and server windows, including slot contents and container properties. `Item.cs` bridges older NBT-based items with 1.20.6+ structured components. `ItemType.cs` plus `ItemPalettes/*.cs` provide version-specific item ID mapping. Enchantment, effects, and villager-trade files add higher-level semantics on top of raw inventory data. | `Inventory/Container.cs`, `Inventory/ContainerType.cs`, `Inventory/Item.cs`, `Inventory/ItemMovingHelper.cs`, `Inventory/ItemType.cs`, `Inventory/ItemPalettes/*.cs`, `Inventory/EnchantmentMapping.cs`, `Inventory/VillagerTrade.cs` | +| `MinecraftClient/Physics/` | Vanilla-accurate per-tick physics engine. `PlayerPhysics.cs` mirrors vanilla `Entity.move()`, `LivingEntity.aiStep()/travel()`, and `Player.travel()` logic at 20 TPS, handling ground/air/water/lava/creative-fly travel, jumping, sprint-jump boost, climbing, sneak-edge-detection, friction, drag, gravity, slow-falling, and levitation. `CollisionDetector.cs` resolves full AABB collisions against the block world including step-up, mirroring vanilla axis-separated resolution. `BlockShapes.cs` maps block-state IDs to collision AABBs using PrismarineJS data from `BlockShapeData.json`. `Vec3d.cs` and `Aabb.cs` provide the geometric primitives. `MovementInput.cs` captures player input state. | `Physics/PlayerPhysics.cs`, `Physics/PhysicsConsts.cs`, `Physics/CollisionDetector.cs`, `Physics/BlockShapes.cs`, `Physics/BlockShapeData.json`, `Physics/Vec3d.cs`, `Physics/Aabb.cs`, `Physics/MovementInput.cs` | ### Commands And Extensions @@ -73,7 +76,7 @@ Notes: | `MinecraftClient/Commands/` and `MinecraftClient/CommandHandler/` | Internal MCC command system built on Brigadier. Commands are discovered by reflection from `MinecraftClient.Commands` in `McClient.LoadCommands()`. Each file in `Commands/` registers one internal command. `ArgumentType/*.cs` provides typed Brigadier arguments and completion sources for accounts, bots, items, locations, scripts, inventories, and more. `Patch/*.cs` carries MCC-specific Brigadier extensions, and `CmdResult.cs` is the command execution result object. | `Command.cs`, `Commands/*.cs`, `CommandHandler/MccArguments.cs`, `CommandHandler/CmdResult.cs`, `CommandHandler/ArgumentType/*.cs`, `CommandHandler/Patch/*.cs` | | `MinecraftClient/ChatBots/` | Built-in bots and bridges loaded from config through `McClient.RegisterBots()`. The folder mixes gameplay automation (`AutoAttack`, `AutoDig`, `AutoEat`, `AutoFishing`, `Farmer`), utility/logging bots (`ChatLog`, `PlayerListLogger`, `Alerts`), bridges (`DiscordBridge`, `TelegramBridge`, `RemoteControl`), and tooling like `ScriptScheduler`, `Map`, and `ReplayCapture`. | `ChatBots/AutoRelog.cs`, `ChatBots/Farmer.cs`, `ChatBots/FollowPlayer.cs`, `ChatBots/ItemsCollector.cs`, `ChatBots/Map.cs`, `ChatBots/RemoteControl.cs`, `ChatBots/ScriptScheduler.cs`, `ChatBots/DiscordBridge.cs`, `ChatBots/TelegramBridge.cs`, `ChatBots/ReplayCapture.cs` | | `MinecraftClient/Scripting/` | Shared extension boundary for compiled bots and runtime C# scripts. `ChatBot.cs` is the main bot API and lifecycle surface. Built-in bots and `/script` bots use the same event model. `CSharpRunner.cs` parses `//MCCScript` files, compiles them with Roslyn, caches assemblies, and executes them through `CSharpAPI`. `DynamicRun/Builder/*` handles in-memory compilation/load-context plumbing, while `BotMovementLock.cs` coordinates movement ownership between automation pieces. | `Scripting/ChatBot.cs`, `Scripting/CSharpRunner.cs`, `Scripting/BotMovementLock.cs`, `Scripting/AssemblyResolver.cs`, `Scripting/DynamicRun/Builder/Compiler.cs`, `Scripting/DynamicRun/Builder/CompileRunner.cs` | -| `MinecraftClient/config/` | Sample runtime assets excluded from compilation. This is the examples/staging area for end-user scripts and standalone bots. `sample-script*.cs` shows supported `/script` patterns, while `config/ChatBots/*.cs` are copy/adapt examples rather than built-in bots. | `config/README.md`, `config/sample-script.cs`, `config/sample-script-with-chatbot.cs`, `config/sample-script-with-world-access.cs`, `config/ChatBots/*.cs` | +| `MinecraftClient/config/` | Sample runtime assets excluded from compilation. This is the examples/staging area for end-user scripts and standalone bots. `sample-script*.cs` shows supported `/script` patterns (basic, chatbot, world access, HTTP requests, tasks, PM forwarding, extended), while `config/ChatBots/*.cs` are copy/adapt examples rather than built-in bots. | `config/README.md`, `config/sample-script.cs`, `config/sample-script-with-chatbot.cs`, `config/sample-script-with-world-access.cs`, `config/sample-script-with-http-request.cs`, `config/sample-script-with-task.cs`, `config/ChatBots/*.cs` | | `ConsoleInteractive/` | Required git submodule for richer line editing and console UI. MCC uses the submodule's `ConsoleReader`, `ConsoleWriter`, and suggestion UI from `ConsoleIO.cs` and `McClient.cs` when `BasicIO` is not enabled. | `ConsoleInteractive/README.md`, `ConsoleInteractive/ConsoleInteractive/ConsoleInteractive.sln` | ### Support And Tooling @@ -81,24 +84,27 @@ Notes: | Module | What It Owns | Important Files | | --- | --- | --- | | `MinecraftClient/Logger/`, `MinecraftClient/Proxy/`, `MinecraftClient/Crypto/`, `MinecraftClient/Resources/`, `MinecraftClient/WinAPI/` | Support subsystems under the main app. Logging supports console/file output plus regex filtering. `ProxyHandler.cs` routes update/login/in-game traffic through HTTP or SOCKS proxies. `Crypto/` implements the stream ciphers needed for online-mode protocol encryption. `Resources/` contains UI strings, generated translation accessors, config help text, icons, and embedded Minecraft asset data. `WinAPI/` contains small Windows-only console helpers. | `Logger/FilteredLogger.cs`, `Logger/FileLogLogger.cs`, `Proxy/ProxyHandler.cs`, `Crypto/CryptoHandler.cs`, `Crypto/AesCfb8Stream.cs`, `Resources/Translations/Translations.resx`, `Resources/ConfigComments/ConfigComments.resx`, `Resources/en_us.json`, `WinAPI/ConsoleIcon.cs` | -| `docs/` | VuePress documentation site. `.vuepress/config.ts` sets bundler, theme, plugins, and redirects. `.vuepress/configs/**` holds locale and nav wiring. `guide/*.md` contains the user-facing install, usage, bot, and scripting docs. | `docs/.vuepress/config.ts`, `docs/.vuepress/configs/**`, `docs/guide/README.md`, `docs/guide/configuration.md`, `docs/guide/chat-bots.md`, `docs/guide/creating-text-script.md` | -| `tools/` | Python helpers for Minecraft version adaptation and palette generation. `README.md` is the authoritative workflow. `diff_registries.py` compares versions and validates decompiled data against server reports. The `gen_*` scripts emit the versioned palette source files consumed by `Protocol/`, `Mapping/`, and `Inventory/`. | `tools/README.md`, `tools/diff_registries.py`, `tools/gen_block_palette.py`, `tools/gen_item_palette.py`, `tools/gen_entity_palette.py`, `tools/gen_entity_metadata_palette.py` | +| `docs/` | VuePress documentation site. `.vuepress/config.ts` sets bundler, theme, plugins, and redirects. `.vuepress/configs/**` holds locale and nav wiring. `guide/*.md` contains the user-facing install, usage, bot, and scripting docs. | `docs/.vuepress/config.ts`, `docs/.vuepress/configs/**`, `docs/guide/README.md`, `docs/guide/configuration.md`, `docs/guide/chat-bots.md`, `docs/guide/creating-bots.md`, `docs/guide/creating-text-script.md`, `docs/guide/ai-assisted-development.md` | +| `tools/` | Python helpers for Minecraft version adaptation and palette generation. `README.md` is the authoritative workflow. `diff_registries.py` compares versions and validates decompiled data against server reports. The `gen_*` scripts emit the versioned palette source files consumed by `Protocol/`, `Mapping/`, `Inventory/`, and `Physics/`. | `tools/README.md`, `tools/diff_registries.py`, `tools/gen_block_palette.py`, `tools/gen_item_palette.py`, `tools/gen_entity_palette.py`, `tools/gen_entity_metadata_palette.py`, `tools/gen_block_shapes.py`, `tools/gen_command_argument_registry.py` | | `DebugTools/` | Standalone packet/proxy debugging utilities for inspecting traffic and compression behavior outside the main client runtime. | `DebugTools/MinecraftClientProxy/Program.cs`, `DebugTools/MinecraftClientProxy/PacketProxy.cs`, `DebugTools/MinecraftClientProxy/ZlibUtils.cs` | | `MinecraftClientGUI/` | Legacy Windows GUI wrapper around the console app. WinForms shell that launches and communicates with the console executable; not part of the main `net8.0` runtime path. | `MinecraftClientGUI/Program.cs`, `MinecraftClientGUI/Form1.cs`, `MinecraftClientGUI/Form1.Designer.cs`, `MinecraftClientGUI/MinecraftClient.cs` | ## Engineering Guidance +Read `docs/guide/ai-assisted-development.md` before starting development work on MCC. It documents the full build-run-test loop, local server harness, repository tools, and standard workflows. + ### DO - Keep startup/config/auth logic in `Program` and connection runtime logic in `McClient` or `Protocol/*`. - Update version support holistically: protocol constants, version mapping, packet palette, block palette, item palette, entity palette, metadata palette, and routing switches. -- Use `tools/` and authoritative server data reports when adapting to new Minecraft versions, especially 1.21.9+. +- Use `tools/` and authoritative server data reports when adapting to new Minecraft versions. - Guard optional subsystems with `GetTerrainEnabled()`, `GetInventoryEnabled()`, and `GetEntityHandlingEnabled()` before using them. - For built-in bots, wire all pieces together: bot class, `Settings.ChatBotConfigHealper`, and `McClient.RegisterBots()`. - Keep `Initialize()` for setup/prereq checks and `AfterGameJoined()` for sending chat or commands. - Normalize inbound chat with `GetVerbatim()` before `IsChatMessage()` / `IsPrivateMessage()`. - Clean up commands, plugin channels, threads, timers, and movement locks in `OnUnload()`. - Prefer nullable-aware code, pattern matching, `ArgumentNullException.ThrowIfNull`, `Try*` APIs for expected failures, and `InvokeOnMainThread()` for cross-thread state changes. -- Use modern C# only when it fits the current target: the repo builds as `net8.0` with default language version. +- Use modern C# 14 features. +- Use provided skills proactively depending on the context, read their descriptions to determine when to use them. ### DON'T - Don't update only `MCVer2ProtocolVersion()` or only one palette file when adding a new Minecraft version. @@ -109,3 +115,4 @@ Notes: - Don't start background workers when `Update()` or delayed tasks are sufficient; if you must, stop them on unload/disconnect. - Don't leave movement locks, plugin channels, or dispatcher registrations behind. - Don't trust older docs over current code for supported versions or feature gates. +- Never use "—" ("em dash"), unless specifically being instructed to do so! diff --git a/docs/.vuepress/styles/index.scss b/docs/.vuepress/styles/index.scss index dbe9cbc8..3be2b2ca 100644 --- a/docs/.vuepress/styles/index.scss +++ b/docs/.vuepress/styles/index.scss @@ -82,3 +82,82 @@ border-radius: 0.5rem; } } + +/* Collapsible
sections */ +details { + margin: 1rem 0; + padding: 0; + border: 1px solid var(--vp-c-divider); + border-radius: 0.5rem; + transition: + background var(--vp-t-color), + border-color var(--vp-t-color); + + > summary { + display: flex; + align-items: center; + gap: 0.5em; + padding: 0.75rem 1.15rem; + font-weight: 600; + cursor: pointer; + user-select: none; + list-style: none; + border-radius: 0.5rem; + background: var(--vp-c-bg-soft); + transition: background var(--vp-t-color); + + &::before { + content: '▶'; + display: inline-block; + font-size: 0.55em; + color: var(--vp-c-text-2); + transition: transform 0.2s ease; + flex-shrink: 0; + } + + /* Hide the default marker in all browsers */ + &::-webkit-details-marker { + display: none; + } + + &::marker { + content: none; + } + + &:hover { + background: var(--vp-c-bg-mute); + } + + > code { + font-size: 0.95em; + font-weight: 700; + color: var(--vp-c-accent); + background: var(--vp-c-control); + padding: 0.15em 0.45em; + border-radius: 0.25rem; + } + } + + &[open] > summary { + border-bottom: 1px solid var(--vp-c-divider); + border-radius: 0.5rem 0.5rem 0 0; + margin-bottom: 0; + + &::before { + transform: rotate(90deg); + } + } + + &[open] > :not(summary) { + margin-left: 1.25rem; + margin-right: 1.25rem; + } + + &[open] > :nth-child(2) { + margin-top: 1rem; + } + + &[open] > :last-child { + margin-bottom: 1rem; + } +} diff --git a/docs/guide/chat-bots.md b/docs/guide/chat-bots.md index 0dcf7965..ed912651 100644 --- a/docs/guide/chat-bots.md +++ b/docs/guide/chat-bots.md @@ -67,6 +67,9 @@ redirectFrom: **Section:** **`ChatBot.Alerts`** +
+ All settings + #### `Enabled` - **Description:** @@ -181,6 +184,9 @@ redirectFrom: Excludes = [ "myserver.com", "Yourname>:", "Player Yourname", "Yourname joined", "Yourname left", "[Lockette] (Admin)", " Yourname:", "Yourname is", ] ``` + +
+ ## Anti AFK - **Description:** @@ -191,6 +197,9 @@ redirectFrom: **Section:** **`ChatBot.AntiAFK`** +
+ All settings + #### `Enabled` - **Description:** @@ -281,6 +290,9 @@ redirectFrom: - **Default:** `20` + +
+ ## Auto Attack

Tip

@@ -297,6 +309,9 @@ redirectFrom: **Section:** **`ChatBot.AutoAttack`** +
+ All settings + #### `Enabled` - **Description:** @@ -432,6 +447,9 @@ redirectFrom: - **Default:** `[ "Zombie", "Cow", ]` + +
+ ## Auto Craft

Tip

@@ -466,6 +484,9 @@ redirectFrom: **Section:** **`ChatBot.AutoCraft`** +
+ All settings + #### `Enabled` - **Description:** @@ -609,6 +630,9 @@ redirectFrom:
+ +
+ ## Auto Dig - **Description:** @@ -637,6 +661,9 @@ redirectFrom: **Section:** **`ChatBot.AutoDig`** +
+ All settings + #### `Enabled` - **Description:** @@ -780,6 +807,9 @@ redirectFrom: - **Default:** `[ "Cobblestone", "Stone", ]` + +
+ ## Auto Drop - **Description:** @@ -796,6 +826,9 @@ redirectFrom: **Section:** **`ChatBot.AutoDrop`** +
+ All settings + #### `Enabled` - **Description:** @@ -855,6 +888,9 @@ redirectFrom: - **Default:** `[ "Cobblestone", "Dirt", ]` + +
+ ## Auto Eat - **Description:** @@ -871,6 +907,9 @@ redirectFrom: **Section:** **`ChatBot.AutoEat`** +
+ All settings + #### `Enabled` - **Description:** @@ -893,6 +932,9 @@ redirectFrom: - **Default:** `6` + +
+ ## Auto Fishing - **Description:** @@ -934,6 +976,9 @@ redirectFrom: **Section:** **`ChatBot.AutoFishing`** +
+ All settings + #### `Enabled` - **Description:** @@ -1150,6 +1195,9 @@ redirectFrom: facing = { yaw = -25.14, pitch = 36.25 } ``` + +
+ ## Auto Relog - **Description:** @@ -1160,6 +1208,9 @@ redirectFrom: **Section:** **`ChatBot.AutoRelog`** +
+ All settings + #### `Enabled` - **Description:** @@ -1226,6 +1277,9 @@ redirectFrom: - **Default:** `[ "Connection has been lost", "Server is restarting", "Server is full", "Too Many people", ]` + +
+ ## Auto Respond - **Description:** @@ -1248,6 +1302,9 @@ redirectFrom: **Section:** **`ChatBot.AutoRespond`** +
+ All settings + #### `Enabled` - **Description:** @@ -1306,6 +1363,9 @@ redirectFrom: - **Default:** `false` + +
+ ## Chat Log - **Description:** @@ -1316,6 +1376,9 @@ redirectFrom: **Section:** **`ChatBot.ChatLog`** +
+ All settings + #### `Enabled` - **Description:** @@ -1374,6 +1437,9 @@ redirectFrom: - **Default:** `messages` + +
+ ## Discord Bridge - **Description:** @@ -1442,6 +1508,9 @@ redirectFrom: **Section:** **`ChatBot.DiscordBrdige`** +
+ All settings + #### `Enabled` - **Description:** @@ -1534,6 +1603,9 @@ redirectFrom: - **Default:** `A new Teleport Request from **{username}**!` + +
+ ## Farmer

Tip

@@ -1619,6 +1691,9 @@ redirectFrom: **Section:** **`ChatBot.Farmer`** +
+ All settings + #### `Enabled` - **Description:** @@ -1643,6 +1718,9 @@ redirectFrom: - **Minimum:** `1` + +
+ ## Follow player - **Description:** @@ -1665,6 +1743,9 @@ redirectFrom: **Section:** **`ChatBot.FollowPlayer`** +
+ All settings + #### `Enabled` - **Description:** @@ -1699,6 +1780,9 @@ redirectFrom: - **Default:** `3.0` + +
+ ## Hangman - **Description:** @@ -1719,6 +1803,9 @@ redirectFrom: **Section:** **`ChatBot.HangmanGame`** +
+ All settings + #### `Enabled` - **Description:** @@ -1769,6 +1856,9 @@ redirectFrom: - **Default:** `hangman-fr.txt` - **Example**: [`words-fr.txt`](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/config/hangman-fr.txt) + +
+ ## Mailer - **Description:** @@ -1922,6 +2012,9 @@ redirectFrom: **Section:** **`ChatBot.Map`** +
+ All settings + #### `Enabled` - **Description:** @@ -2082,6 +2175,9 @@ redirectFrom: - **Default:** `false` + +
+ ## PlayerList Logger - **Description:** @@ -2091,6 +2187,9 @@ redirectFrom: **Section:** **`ChatBot.PlayerListLogger`** +
+ All settings + #### `Enabled` - **Description:** @@ -2119,6 +2218,9 @@ redirectFrom: - **Default:** `60.0` + +
+ ## Remote Control - **Description:** @@ -2137,6 +2239,9 @@ redirectFrom: **Section:** **`ChatBot.RemoteControl`** +
+ All settings + #### `Enabled` - **Description:** @@ -2173,6 +2278,9 @@ redirectFrom: - **Default:** `false` + +
+ ## Replay Capture - **Description:** @@ -2201,6 +2309,9 @@ redirectFrom: **Section:** **`ChatBot.ReplayCapture`** +
+ All settings + #### `Enabled` - **Description:** @@ -2225,6 +2336,9 @@ redirectFrom: - **Default:** `300.0` + +
+ ## Script Scheduler - **Description:** @@ -2235,6 +2349,9 @@ redirectFrom: **Section:** **`ChatBot.ScriptScheduler`** +
+ All settings + #### `Enabled` - **Description:** @@ -2344,6 +2461,9 @@ redirectFrom: Action = "send /login pass" ``` + +
+ ## Telegram Bridge - **Description:** @@ -2388,6 +2508,9 @@ redirectFrom: **Section:** **`ChatBot.TelegramBridge`** +
+ All settings + #### `Enabled` - **Description:** @@ -2478,6 +2601,9 @@ redirectFrom: - **Default:** `A new Teleport Request from **{username}**!` +
+ + ## Items Collector - **Description:** @@ -2488,6 +2614,9 @@ redirectFrom: **Section:** **`ChatBot.ItemsCollector`** +
+ All settings + #### `Enabled` - **Description:** @@ -2577,3 +2706,6 @@ redirectFrom: - **Default:** `true` +
+ + diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index ce6c23de..cf73256b 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -60,6 +60,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Section header:** `Main.General` +
+Account, Server, and Authentication settings + #### `Account` - **Description:** @@ -174,10 +177,15 @@ Coordinate = { x = 145, y = 64, z = 2045 } AuthUser = "SomePlayer" ``` +
+ ### Main Advanced section - **Section header:** `Main.Advanced` +
+Advanced settings (Language, Version, Features, and more) + #### `Language` - **Description:** @@ -661,6 +669,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `true` +
+ ### Account List section - **Section header:** `Main.Advanced.AccountList` @@ -724,6 +734,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } This section contains settings related to a new chat reporting (signing and verifying) feature introduced by Mojang. +
+Chat signing and verification settings + #### `LoginWithSecureProfile` - **Description:** @@ -816,10 +829,15 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `true` +
+ ### App Vars values section - **Section header:** `AppVar.VarStirng` +
+Logging and filtering settings + #### `DebugMessages` - **Description:** @@ -968,6 +986,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `false` +
+ ## App Vars section - **Section header:** `AppVar` @@ -1005,6 +1025,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Section header:** `Console.General` +
+Console display settings + #### `ConsoleColorMode` - **Description:** @@ -1037,6 +1060,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `32` +
+ ### Console CommandSuggestion section - **Section header:** `Console.CommandSuggestion` @@ -1045,6 +1070,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } Command completion suggestions in the console. +
+Command suggestion settings + #### `Enable` - **Description:** @@ -1103,6 +1131,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } MCC validates these values on startup and falls back to built-in defaults if a color string is invalid. +
+ ## Proxy section - **Section header:** `Proxy` @@ -1111,6 +1141,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } Connect to a server via a proxy instead of connecting directly. +
+Proxy settings + #### `Enabled_Login` - **Description:** @@ -1202,6 +1235,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `` `` +
+ ## MCSettings section - **Section header:** `MCSettings` @@ -1210,6 +1245,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } Client settings related to language, render distance, difficulty, chat and skins. +
+Game client settings + #### `Enabled` - **Description:** @@ -1293,6 +1331,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `left` +
+ ## MCSettings Skin section - **Section header:** `MCSettings.Skin` @@ -1301,6 +1341,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } Skin options. +
+Skin visibility settings + #### `Cape` - **Description:** @@ -1371,6 +1414,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `false` +
+ ## Chat Format section - **Section header:** `ChatFormat` @@ -1395,6 +1440,9 @@ Coordinate = { x = 145, y = 64, z = 2045 } - [https://regex101.com/](https://regex101.com/) - [https://regexr.com/](https://regexr.com/) +
+Chat format settings + #### `Builtins` - **Description:** @@ -1461,6 +1509,8 @@ Coordinate = { x = 145, y = 64, z = 2045 } - **Default:** `TeleportRequest = '^([a-zA-Z0-9_]+) has requested (?:to|that you) teleport to (?:you|them)\.$'` +
+ ## Chat Bot section - **Section header:** `ChatBot` diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 77082f1a..ae3ff235 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -30,6 +30,9 @@ However, if you want to build the program from source code, please follow the gu ### Windows +
+Windows build instructions + Requirements: - [Git](https://www.git-scm.com/) @@ -119,8 +122,13 @@ dotnet --info If the publish step succeeds, the published binary `MinecraftClient.exe` will be in `MinecraftClient/bin/Release/net10.0/win-x64/publish/`. +
+ ### Linux, macOS +
+Linux and macOS build instructions +

Tip

**If you're using Linux we will assume that you should be able to install git on your own. If you don't know how, search it up for your distribution, it should be easy. (Debian based distros: `apt install git`, Arch based: `pacman -S git`)** @@ -206,8 +214,13 @@ You can verify the SDK installation with: dotnet --info ``` +
+ ## Using Docker +
+Docker setup and usage + Requirements: - Git @@ -295,6 +308,8 @@ As above, you can stop and remove the container using docker-compose down ``` +
+ ## Run on Android It is possible to run Minecraft Console Client on Android through Termux and Ubuntu 24.04, but it requires a manual setup with a lot of commands, so be careful not to skip any steps. Depending on your technical background, internet speed, and device speed, this can take anywhere from 10 to 20 minutes or more. @@ -319,6 +334,9 @@ It is possible to run Minecraft Console Client on Android through Termux and Ubu ### Installation +
+Android installation steps (Termux + Ubuntu + .NET + MCC) + #### Termux

Warning

@@ -579,6 +597,8 @@ Also, here are some linux tutorials for people who are new to it: - [Linux Crash Course - The wget Command by Learn Linux TV](https://www.youtube.com/watch?v=F80Z5qd2b_4) - [Linux Basics: How to Untar and Unzip Files (tar, gzip) by webpwnized](https://www.youtube.com/watch?v=1DF0dTscHHs) +
+ ## Run on a VPS

Tip

@@ -636,6 +656,9 @@ Here is a [YouTube video](https://youtu.be/42fwh_1KP_o) that explains it in more ### Where to get a VPS +
+VPS providers and pricing + You have 2 options: - [Buying a VPS](#buying-a-vps) @@ -719,8 +742,13 @@ Register on AWS and enter all of your billing info and a phone number. Once you're done, you can continue to [Setting up the Amazon VPS](#setting-up-an-aws-vps). +
+ ### Initial Amazon VPS setup +
+AWS EC2 setup steps +

Tip

**Skip this section if you're not using AWS. Go to [Initial VPS setup](#initial-vps-setup)** @@ -815,8 +843,13 @@ If you've provided the right info you should get `Welcome to Ubuntu 20.04.5 LTS` Now you can continue to [Creating a new user](#creating-a-new-user) +
+ ### Initial VPS setup +
+Non-AWS VPS login steps +

Tip

**This section if for those who do not use AWS, if you use AWS skip it** @@ -855,8 +888,13 @@ ssh -p 2233 root@142.26.73.14 Once you've logged in you should see a Linux prompt and a welcome message if there is one set by your provider. +
+ ### Creating a new user +
+User account and SSH key setup + Once you've logged in to your VPS you need to create a new user and give it SSH access. In this tutorial we will be using `mcc` as a name for the user account that will be running the MCC. @@ -1051,8 +1089,13 @@ You can do `whoami` to see your username. Now you can install the .NET 10 SDK and MCC. +
+ ### Installing .NET 10 SDK +
+.NET SDK installation on VPS +

Tip

**If your VPS has an ARM CPU, follow [this](#installing-net-on-arm) part of the documentation and then return to section after this one.** @@ -1105,8 +1148,13 @@ If you do not get this output and the installation was not successful, [try othe If it was successful, you can now install MCC. +
+ ### Installing MCC on a VPS +
+MCC installation and screen usage + Now that you have the .NET SDK and a user account, install the `screen` utility. You will need it if you want MCC to keep running after you close the SSH session.

Tip

@@ -1178,3 +1226,5 @@ screen -ls ``` To stop the MCC, you can hit `CTRL + D` (hit it few times). + +
diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 93d5d150..19bf0f44 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -63,6 +63,10 @@ See [Run using Docker](./installation.md#using-docker) ### For people not familiar with the command line +
+Introduction to command-line basics + + For people who are not familiar with the usage of programs in the command line (terminal emulators), here we will explain what every single thing means, if you're already experienced you can skip this. In command line (terminal emulators) you can run programs by specifying their name and hitting enter, usually programs have additional way of being configured, started or provided some additional data in a different manner, this is achieved by using command line parameters. @@ -99,6 +103,8 @@ MinecraftClient.exe --help MCC also supports a few maintenance and debugging switches such as `--upgrade`, `--force-upgrade`, `--generate`, `--keyboard-debug`, `BasicIO`, and `BasicIO-NoColor`. +
+ ### Quick usage of MCC with examples

Tip

@@ -189,7 +195,9 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
-### `animation` +
+animation + - **Description:** @@ -201,7 +209,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /animation ``` -### `bed` +
+ + +
+bed + - **Description:** @@ -237,7 +250,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /bed sleep 50 ``` -### `blockinfo` +
+ + +
+blockinfo +

Tip

@@ -259,7 +277,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /blockinfo [-s] ``` -### `bots` +
+ + +
+bots + - **Description:** @@ -287,7 +310,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /bots unload all ``` -### `changeslot` +
+ + +
+changeslot + - **Description:** @@ -305,7 +333,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /changeslot <1-9> ``` -### `chunk` +
+ + +
+chunk + - **Description:** @@ -333,7 +366,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q ![Chunk status](/images/guide/ChunkStatus.png) -### `dig` +
+ + +
+dig + - **Description:** @@ -357,7 +395,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /dig ~ ~-1 ~2 ``` -### `dropitem` +
+ + +
+dropitem + - **Description:** @@ -387,7 +430,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /dropitem diamond ``` -### `enchant` +
+ + +
+enchant +

Tip

@@ -411,7 +459,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /enchant ``` -### `entity` +
+ + +
+entity + - **Description:** @@ -451,7 +504,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /entity Zombie attack ``` -### `execif` +
+ + +
+execif + - **Description:** @@ -513,7 +571,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /execif "1 == 1" "execmulti send 1 -> send 2 -> send 3" ``` -### `execmulti` +
+ + +
+execmulti + - **Description:** @@ -531,14 +594,24 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /execmulti send 1 -> send 2 -> send 3 -> sneak ``` -### `quit` +
+ + +
+quit + - **Alias:** `exit` - **Description:** Disconnect from the server and close the application -### `reco` +
+ + +
+reco + - **Description:** @@ -556,7 +629,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
-### `reload` +
+ + +
+reload + - **Description:** @@ -574,7 +652,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /reload ``` -### `connect` +
+ + +
+connect + - **Description:** @@ -598,7 +681,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
-### `script` + + + +
+script + - **Description:** @@ -610,7 +698,12 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q /script + + \ No newline at end of file diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index cb6b169b..d64ef70a 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -113,6 +113,8 @@ namespace MinecraftClient // Entity handling private readonly Dictionary entities = new(); + private readonly Lock signDataLock = new(); + private readonly Dictionary<(int x, int y, int z), (string material, string typeLabel, string[] frontText, string[] backText, bool isWaxed)> knownSigns = new(); // server TPS private long lastAge = 0; @@ -166,6 +168,21 @@ namespace MinecraftClient public void GetCookie(string key, out byte[]? data) => Cookies.TryGetValue(key, out data); public void SetCookie(string key, byte[] data) => Cookies[key] = data; public void DeleteCookie(string key) => Cookies.Remove(key, out var data); + public (Location location, string material, string typeLabel, string[] frontText, string[] backText, bool isWaxed)[] GetKnownSigns() + { + lock (signDataLock) + { + return knownSigns + .Select(pair => ( + location: new Location(pair.Key.x, pair.Key.y, pair.Key.z), + material: pair.Value.material, + typeLabel: pair.Value.typeLabel, + frontText: (string[])pair.Value.frontText.Clone(), + backText: (string[])pair.Value.backText.Clone(), + isWaxed: pair.Value.isWaxed)) + .ToArray(); + } + } TcpClient client = null!; IMinecraftCom handler = null!; @@ -478,6 +495,7 @@ namespace MinecraftClient physicsInput.Reset(); world.Clear(); entities.Clear(); + ClearKnownSigns(); ClearInventories(); } @@ -763,6 +781,7 @@ namespace MinecraftClient handler.Dispose(); world.Clear(); + ClearKnownSigns(); if (timeoutdetector is not null) { @@ -2804,6 +2823,7 @@ namespace MinecraftClient } entities.Clear(); + ClearKnownSigns(); ClearInventories(); DispatchBotEvent(bot => bot.OnRespawn()); } @@ -4036,9 +4056,16 @@ namespace MinecraftClient public void OnBlockChange(Location location, Block block) { world.SetBlock(location, block); + if (!IsSignMaterial(block.Type)) + RemoveKnownSign(location); DispatchBotEvent(bot => bot.OnBlockChange(location, block)); } + public void OnBlockEntityData(Location location, Dictionary? nbt) + { + UpdateKnownSign(location, nbt); + } + /// /// Called when "AutoComplete" completes. /// @@ -4068,6 +4095,137 @@ namespace MinecraftClient return handler.ClickContainerButton(windowId, buttonId); } + private void ClearKnownSigns() + { + lock (signDataLock) + { + knownSigns.Clear(); + } + } + + private void RemoveKnownSign(Location location) + { + var key = ToBlockKey(location); + lock (signDataLock) + { + knownSigns.Remove(key); + } + } + + private void UpdateKnownSign(Location location, Dictionary? nbt) + { + var key = ToBlockKey(location); + var block = world.GetBlock(new Location(key.x, key.y, key.z)); + if (!IsSignMaterial(block.Type) || !TryExtractSignText(nbt, out string[] frontText, out string[] backText, out bool isWaxed)) + { + lock (signDataLock) + { + knownSigns.Remove(key); + } + + return; + } + + lock (signDataLock) + { + knownSigns[key] = (block.Type.ToString(), block.GetTypeString(), frontText, backText, isWaxed); + } + } + + private static bool TryExtractSignText(Dictionary? nbt, out string[] frontText, out string[] backText, out bool isWaxed) + { + frontText = ExtractSignLines(nbt, "front_text"); + backText = ExtractSignLines(nbt, "back_text"); + if (frontText.Length == 0 && backText.Length == 0) + frontText = ExtractLegacySignLines(nbt); + + isWaxed = nbt is not null + && nbt.TryGetValue("is_waxed", out object? waxedValue) + && waxedValue is bool waxed + && waxed; + return frontText.Length > 0 || backText.Length > 0; + } + + private static string[] ExtractSignLines(Dictionary? nbt, string sideKey) + { + if (nbt is null + || !nbt.TryGetValue(sideKey, out object? sideValue) + || sideValue is not Dictionary sideData + || !sideData.TryGetValue("messages", out object? messagesValue) + || messagesValue is not object[] messages) + { + return []; + } + + return messages + .Take(4) + .Select(ConvertSignMessage) + .ToArray(); + } + + private static string[] ExtractLegacySignLines(Dictionary? nbt) + { + if (nbt is null) + return []; + + List lines = new(4); + for (int i = 1; i <= 4; i++) + { + if (nbt.TryGetValue($"Text{i}", out object? value)) + lines.Add(ConvertSignMessage(value)); + } + + return lines.ToArray(); + } + + private static string ConvertSignMessage(object? value) + { + try + { + return value switch + { + null => string.Empty, + string text => ParseMaybeJsonText(text), + Dictionary nbt => ChatParser.ParseText(nbt), + object[] items => string.Concat(items.Select(ConvertSignMessage)), + _ => value.ToString() ?? string.Empty + }; + } + catch + { + return value?.ToString() ?? string.Empty; + } + } + + private static string ParseMaybeJsonText(string text) + { + string trimmed = text.Trim(); + if ((trimmed.StartsWith("{", StringComparison.Ordinal) && trimmed.EndsWith("}", StringComparison.Ordinal)) + || (trimmed.StartsWith("[", StringComparison.Ordinal) && trimmed.EndsWith("]", StringComparison.Ordinal))) + { + try + { + return ChatParser.ParseText(trimmed); + } + catch + { + } + } + + return text; + } + + private static bool IsSignMaterial(Material material) + { + return material.ToString().Contains("Sign", StringComparison.Ordinal); + } + + private static (int x, int y, int z) ToBlockKey(Location location) + { + Location blockLocation = location.ToFloor(); + return ((int)blockLocation.X, (int)blockLocation.Y, (int)blockLocation.Z); + } + #endregion } } diff --git a/MinecraftClient/Mcp/IMccMcpCapabilities.cs b/MinecraftClient/Mcp/IMccMcpCapabilities.cs index cae36647..6d5b118a 100644 --- a/MinecraftClient/Mcp/IMccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/IMccMcpCapabilities.cs @@ -8,6 +8,9 @@ public interface IMccMcpCapabilities MccMcpResult GetPlayersList(); MccMcpResult GetChatHistory(int maxCount, bool includeJson); MccMcpResult GetInternalCommands(); + MccMcpResult GetMaterialsList(string? filter, int maxCount); + MccMcpResult GetBlockTypesList(string? filter, int maxCount); + MccMcpResult GetEntityTypesList(string? filter, int maxCount); MccMcpResult SendChat(string text); MccMcpResult QuitClient(); MccMcpResult RunInternalCommand(string command); @@ -21,6 +24,7 @@ public interface IMccMcpCapabilities MccMcpResult FindBlocks(string? query, int radius, int maxCount, bool exactMatch); MccMcpResult IsPlayerNearby(string? playerName, double radius, bool includeSelf); MccMcpResult LocatePlayer(string playerName, bool includeSelf); + MccMcpResult CanReachPosition(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs); MccMcpResult MoveTo(double x, double y, double z, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult MoveToPlayer(string playerName, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult LookAt(double x, double y, double z); @@ -30,5 +34,8 @@ public interface IMccMcpCapabilities MccMcpResult QueryEntities(int maxCount); MccMcpResult ListEntities(int maxCount, string? typeFilter, double radius); MccMcpResult GetEntityInfo(int entityId, bool includeMetadata, bool includeEquipment, bool includeEffects); + MccMcpResult FindSigns(string text, bool exactMatch, int radius, int maxCount, bool includeBackText); + MccMcpResult ListItemEntities(string? itemType, double radius, int maxCount); + MccMcpResult PickupItems(string itemType, double radius, int maxItems, bool allowUnsafe, int timeoutMs); MccMcpResult GetWorldBlockAt(int x, int y, int z); } diff --git a/MinecraftClient/Mcp/MccMcpCapabilities.cs b/MinecraftClient/Mcp/MccMcpCapabilities.cs index 097db7d2..055786a6 100644 --- a/MinecraftClient/Mcp/MccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/MccMcpCapabilities.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using MinecraftClient.CommandHandler; using MinecraftClient.Inventory; using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Message; using MinecraftClient.Scripting; namespace MinecraftClient.Mcp; @@ -14,13 +15,22 @@ namespace MinecraftClient.Mcp; public sealed class MccMcpCapabilities : IMccMcpCapabilities { private static readonly StringComparer NameComparer = StringComparer.OrdinalIgnoreCase; + private static readonly double[] s_defaultDigAttemptDurations = [1.5, 3.0, 5.0]; private const int CoordinateRoundingPrecision = 2; private const double SelfEntityDistanceThreshold = 0.2; + private const int MaxBlockScanRadius = 12; + private const int MaxBlockFindRadius = 32; + private const double DigReachDistance = 5.0; + private const double DigReachDistanceSquared = DigReachDistance * DigReachDistance; + private const int DefaultPathQueryTimeoutMs = 5000; + private const int MinPathQueryTimeoutMs = 250; + private const int MaxPathQueryTimeoutMs = 15000; private const int DefaultArrivalWaitMs = 3500; private const int MinArrivalWaitMs = 250; private const int MaxArrivalWaitMs = 15000; private const double DefaultArrivalTolerance = 1.5; private const int ArrivalPollIntervalMs = 125; + private const int MaxBlockVerifyWaitMs = 12000; private sealed class InternalCommandInfo { @@ -42,6 +52,18 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities public required int Latency { get; init; } } + private sealed class NearbyItemSnapshot + { + public required int EntityId { get; init; } + public required ItemType ItemType { get; init; } + public required string TypeLabel { get; init; } + public required int Count { get; init; } + public required double X { get; init; } + public required double Y { get; init; } + public required double Z { get; init; } + public required double Distance { get; init; } + } + private readonly Func togglesProvider; public MccMcpCapabilities(Func togglesProvider) @@ -226,6 +248,96 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult GetMaterialsList(string? filter, int maxCount) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + int limit = Math.Clamp(maxCount, 1, 5000); + string? normalizedFilter = string.IsNullOrWhiteSpace(filter) ? null : filter.Trim(); + Material[] allMaterials = Enum.GetValues(); + var materials = allMaterials + .Select(material => new + { + name = material.ToString(), + typeLabel = GetMaterialTypeLabel(material) + }) + .Where(material => normalizedFilter is null + || TextMatchesFilter(material.name, normalizedFilter) + || TextMatchesFilter(material.typeLabel, normalizedFilter)) + .OrderBy(material => material.name, StringComparer.OrdinalIgnoreCase) + .Take(limit) + .ToArray(); + + return MccMcpResult.Ok(new + { + total = allMaterials.Length, + count = materials.Length, + filter = normalizedFilter, + materials + }); + } + + public MccMcpResult GetBlockTypesList(string? filter, int maxCount) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + int limit = Math.Clamp(maxCount, 1, 5000); + string? normalizedFilter = string.IsNullOrWhiteSpace(filter) ? null : filter.Trim(); + Material[] allMaterials = Enum.GetValues(); + var blockTypes = allMaterials + .Select(material => new + { + name = material.ToString(), + typeLabel = GetMaterialTypeLabel(material) + }) + .Where(blockType => normalizedFilter is null + || TextMatchesFilter(blockType.name, normalizedFilter) + || TextMatchesFilter(blockType.typeLabel, normalizedFilter)) + .OrderBy(blockType => blockType.name, StringComparer.OrdinalIgnoreCase) + .Take(limit) + .ToArray(); + + return MccMcpResult.Ok(new + { + total = allMaterials.Length, + count = blockTypes.Length, + filter = normalizedFilter, + blockTypes + }); + } + + public MccMcpResult GetEntityTypesList(string? filter, int maxCount) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + int limit = Math.Clamp(maxCount, 1, 5000); + string? normalizedFilter = string.IsNullOrWhiteSpace(filter) ? null : filter.Trim(); + EntityType[] allEntityTypes = Enum.GetValues(); + var entityTypes = allEntityTypes + .Select(entityType => new + { + name = entityType.ToString(), + typeLabel = Entity.GetTypeString(entityType) + }) + .Where(entityType => normalizedFilter is null + || TextMatchesFilter(entityType.name, normalizedFilter) + || TextMatchesFilter(entityType.typeLabel, normalizedFilter)) + .OrderBy(entityType => entityType.name, StringComparer.OrdinalIgnoreCase) + .Take(limit) + .ToArray(); + + return MccMcpResult.Ok(new + { + total = allEntityTypes.Length, + count = entityTypes.Length, + filter = normalizedFilter, + entityTypes + }); + } + public MccMcpResult SendChat(string text) { if (!IsCategoryEnabled(t => t.ChatAndCommands)) @@ -343,7 +455,13 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Fail("capability_disabled"); if (durationSeconds < 0) - return MccMcpResult.Fail("invalid_args"); + { + return MccMcpResult.Fail("invalid_args", data: new + { + parameter = "durationSeconds", + min = 0 + }); + } McClient? client = GetClient(); if (client is null) @@ -352,13 +470,74 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities if (!client.GetTerrainEnabled()) return MccMcpResult.Fail("feature_disabled"); - string sx = x.ToString(CultureInfo.InvariantCulture); - string sy = y.ToString(CultureInfo.InvariantCulture); - string sz = z.ToString(CultureInfo.InvariantCulture); - string command = durationSeconds > 0 - ? $"dig {sx} {sy} {sz} {durationSeconds.ToString(CultureInfo.InvariantCulture)}" - : $"dig {sx} {sy} {sz}"; - return ExecuteInternalCommand(client, command); + Location target = ToBlockLocation(x, y, z); + Location currentLocation = client.InvokeOnMainThread(client.GetCurrentLocation); + Location eyesLocation = currentLocation.EyesLocation(); + Location centeredTarget = target.ToCenter(); + Block beforeBlock = client.InvokeOnMainThread(() => client.GetWorld().GetBlock(target)); + if (beforeBlock.Type == Material.Air) + { + return MccMcpResult.Fail("invalid_state", data: new + { + target = ToCoordinate(target), + beforeBlock = ToBlockState(beforeBlock) + }); + } + + double distance = eyesLocation.Distance(centeredTarget); + if (distance > DigReachDistance) + { + return MccMcpResult.Fail("action_incomplete", data: new + { + reason = "too_far", + target = ToCoordinate(target), + playerLocation = ToCoordinate(currentLocation), + distance, + maxReach = DigReachDistance, + beforeBlock = ToBlockState(beforeBlock) + }); + } + + double[] attemptDurations = GetDigAttemptDurations(durationSeconds); + List attemptedDurations = new(); + Block afterBlock = beforeBlock; + bool changed = false; + bool commandAccepted = false; + + foreach (double attemptDuration in attemptDurations) + { + attemptedDurations.Add(attemptDuration); + bool accepted = client.InvokeOnMainThread(() => client.DigBlock(target, Direction.Down, duration: attemptDuration)); + commandAccepted |= accepted; + if (!accepted) + continue; + + if (WaitForBlockChange(client, target, beforeBlock, GetDigVerifyWaitMs(attemptDuration), out afterBlock)) + { + changed = true; + break; + } + } + + afterBlock = client.InvokeOnMainThread(() => client.GetWorld().GetBlock(target)); + object resultData = new + { + success = changed, + target = ToCoordinate(target), + beforeBlock = ToBlockState(beforeBlock), + afterBlock = ToBlockState(afterBlock), + commandAccepted, + changed, + destroyed = changed && afterBlock.Type == Material.Air, + attempts = attemptedDurations.Count, + attemptedDurationsSeconds = attemptedDurations.ToArray(), + distance, + playerLocation = ToCoordinate(currentLocation) + }; + + return changed + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); } public MccMcpResult PlaceBlock(int x, int y, int z, string face, string hand, bool lookAtBlock) @@ -411,8 +590,15 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities if (!IsCategoryEnabled(t => t.EntityWorld)) return MccMcpResult.Fail("capability_disabled"); - if (radius is < 1 or > 8) - return MccMcpResult.Fail("invalid_args"); + if (radius is < 1 or > MaxBlockScanRadius) + { + return MccMcpResult.Fail("invalid_args", data: new + { + parameter = "radius", + min = 1, + max = MaxBlockScanRadius + }); + } McClient? client = GetClient(); if (client is null) @@ -444,8 +630,13 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities continue; string material = block.Type.ToString(); - if (filter is not null && !material.Contains(filter, StringComparison.OrdinalIgnoreCase)) + string typeLabel = block.GetTypeString(); + if (filter is not null + && !TextMatchesFilter(material, filter) + && !TextMatchesFilter(typeLabel, filter)) + { continue; + } double dx = x + 0.5 - playerLocation.X; double dy = y + 0.5 - playerLocation.Y; @@ -456,6 +647,7 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities y, z, material, + typeLabel, blockId = block.BlockId, blockMeta = block.BlockMeta, distance = Math.Sqrt(dx * dx + dy * dy + dz * dz) @@ -479,8 +671,15 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities if (!IsCategoryEnabled(t => t.EntityWorld)) return MccMcpResult.Fail("capability_disabled"); - if (radius is < 1 or > 16) - return MccMcpResult.Fail("invalid_args"); + if (radius is < 1 or > MaxBlockFindRadius) + { + return MccMcpResult.Fail("invalid_args", data: new + { + parameter = "radius", + min = 1, + max = MaxBlockFindRadius + }); + } McClient? client = GetClient(); if (client is null) @@ -558,6 +757,61 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult CanReachPosition(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + if (!AreValidPathOffsets(maxOffset, minOffset) || timeoutMs < 0) + { + return MccMcpResult.Fail("invalid_args", data: new + { + maxOffset, + minOffset, + timeoutMs + }); + } + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + Location goal = new(x, y, z); + Location startLocation = client.InvokeOnMainThread(client.GetCurrentLocation); + World world = client.InvokeOnMainThread(client.GetWorld); + int effectiveTimeoutMs = GetPathQueryTimeoutMs(timeoutMs); + Queue? path = Movement.CalculatePath( + world, + startLocation, + goal, + allowUnsafe, + maxOffset, + minOffset, + TimeSpan.FromMilliseconds(effectiveTimeoutMs)); + Location? finalWaypoint = path?.LastOrDefault(); + double? finalDistance = finalWaypoint is Location waypoint + ? GetDistance(waypoint, goal) + : null; + + return MccMcpResult.Ok(new + { + reachable = path is not null, + exactReachable = finalWaypoint is Location location && location.ToFloor() == goal.ToFloor(), + target = ToCoordinate(goal), + startLocation = ToCoordinate(startLocation), + finalWaypoint = finalWaypoint is Location finalLocation ? ToCoordinate(finalLocation) : null, + finalDistance, + waypointCount = path?.Count ?? 0, + allowUnsafe, + maxOffset, + minOffset, + timeoutMs = effectiveTimeoutMs + }); + } + public MccMcpResult IsPlayerNearby(string? playerName, double radius, bool includeSelf) { if (!IsCategoryEnabled(t => t.EntityWorld)) @@ -672,6 +926,16 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities if (!IsCategoryEnabled(t => t.Movement)) return MccMcpResult.Fail("capability_disabled"); + if (!AreValidPathOffsets(maxOffset, minOffset) || timeoutMs < 0) + { + return MccMcpResult.Fail("invalid_args", data: new + { + maxOffset, + minOffset, + timeoutMs + }); + } + McClient? client = GetClient(); if (client is null) return NotConnected(); @@ -680,6 +944,7 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Fail("feature_disabled"); Location goal = new(x, y, z); + Location startLocation = client.InvokeOnMainThread(client.GetCurrentLocation); TimeSpan? timeout = timeoutMs > 0 ? TimeSpan.FromMilliseconds(timeoutMs) : null; bool pathFound = client.InvokeOnMainThread(() => client.MoveTo(goal, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout)); @@ -687,16 +952,28 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities double tolerance = GetArrivalTolerance(maxOffset, minOffset); Location? finalLocation = null; bool arrived = pathFound && WaitForArrival(client, goal, verifyWaitMs, tolerance, out finalLocation); - - return MccMcpResult.Ok(new + finalLocation ??= client.InvokeOnMainThread(client.GetCurrentLocation); + object resultData = new { pathFound, arrived, tolerance, verifyWaitMs, target = ToCoordinate(goal), - finalLocation = finalLocation is Location location ? ToCoordinate(location) : null - }); + startLocation = ToCoordinate(startLocation), + finalLocation = ToCoordinate(finalLocation.Value), + finalDistance = GetDistance(finalLocation.Value, goal), + distanceMoved = GetDistance(startLocation, finalLocation.Value), + allowUnsafe, + allowDirectTeleport, + maxOffset, + minOffset, + timeoutMs + }; + + return pathFound && arrived + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); } public MccMcpResult MoveToPlayer(string playerName, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs) @@ -707,6 +984,16 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities if (string.IsNullOrWhiteSpace(playerName)) return MccMcpResult.Fail("invalid_args"); + if (!AreValidPathOffsets(maxOffset, minOffset) || timeoutMs < 0) + { + return MccMcpResult.Fail("invalid_args", data: new + { + maxOffset, + minOffset, + timeoutMs + }); + } + McClient? client = GetClient(); if (client is null) return NotConnected(); @@ -718,53 +1005,68 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Fail("feature_disabled"); string nameFilter = playerName.Trim(); - return client.InvokeOnMainThread(() => + NearbyPlayerSnapshot? target = client.InvokeOnMainThread(() => { List trackedPlayers = BuildTrackedPlayerSnapshots(client, includeSelf: false); - NearbyPlayerSnapshot? target = trackedPlayers + return trackedPlayers .Where(player => PlayerNameMatches(player, nameFilter)) .OrderBy(player => player.Distance) .FirstOrDefault(); - - if (target is null) - { - return MccMcpResult.Fail("invalid_state", data: new - { - playerName = nameFilter, - trackedPlayers = trackedPlayers - .Select(player => player.Name) - .OfType() - .Distinct(NameComparer) - .ToArray() - }); - } - - Location goal = new(target.X, target.Y, target.Z); - TimeSpan? timeout = timeoutMs > 0 ? TimeSpan.FromMilliseconds(timeoutMs) : null; - bool pathFound = client.MoveTo(goal, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout); - - int verifyWaitMs = GetArrivalWaitMs(timeoutMs); - double tolerance = GetArrivalTolerance(maxOffset, minOffset); - Location? finalLocation = null; - bool arrived = pathFound && WaitForArrival(client, goal, verifyWaitMs, tolerance, out finalLocation); - - return MccMcpResult.Ok(new - { - pathFound, - arrived, - tolerance, - verifyWaitMs, - target = new - { - playerName = target.Name, - entityId = target.EntityId, - x = RoundCoordinate(target.X), - y = RoundCoordinate(target.Y), - z = RoundCoordinate(target.Z) - }, - finalLocation = finalLocation is Location location ? ToCoordinate(location) : null - }); }); + + if (target is null) + { + string[] trackedPlayers = client.InvokeOnMainThread(() => BuildTrackedPlayerSnapshots(client, includeSelf: false) + .Select(player => player.Name) + .OfType() + .Distinct(NameComparer) + .ToArray()); + return MccMcpResult.Fail("invalid_state", data: new + { + playerName = nameFilter, + trackedPlayers + }); + } + + Location goal = new(target.X, target.Y, target.Z); + Location startLocation = client.InvokeOnMainThread(client.GetCurrentLocation); + TimeSpan? timeout = timeoutMs > 0 ? TimeSpan.FromMilliseconds(timeoutMs) : null; + bool pathFound = client.InvokeOnMainThread(() => client.MoveTo(goal, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout)); + + int verifyWaitMs = GetArrivalWaitMs(timeoutMs); + double tolerance = GetArrivalTolerance(maxOffset, minOffset); + Location? finalLocation = null; + bool arrived = pathFound && WaitForArrival(client, goal, verifyWaitMs, tolerance, out finalLocation); + finalLocation ??= client.InvokeOnMainThread(client.GetCurrentLocation); + + object resultData = new + { + pathFound, + arrived, + tolerance, + verifyWaitMs, + target = new + { + playerName = target.Name, + entityId = target.EntityId, + x = RoundCoordinate(target.X), + y = RoundCoordinate(target.Y), + z = RoundCoordinate(target.Z) + }, + startLocation = ToCoordinate(startLocation), + finalLocation = ToCoordinate(finalLocation.Value), + finalDistance = GetDistance(finalLocation.Value, goal), + distanceMoved = GetDistance(startLocation, finalLocation.Value), + allowUnsafe, + allowDirectTeleport, + maxOffset, + minOffset, + timeoutMs + }; + + return pathFound && arrived + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); } public MccMcpResult LookAt(double x, double y, double z) @@ -1168,6 +1470,237 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult FindSigns(string text, bool exactMatch, int radius, int maxCount, bool includeBackText) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(text) || radius is < 1 or > MaxBlockFindRadius) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + string filter = text.Trim(); + int limit = Math.Clamp(maxCount, 1, 500); + + return client.InvokeOnMainThread(() => + { + Location playerLocation = client.GetCurrentLocation(); + World world = client.GetWorld(); + var signs = client.GetKnownSigns() + .Select(sign => + { + double dx = sign.location.X + 0.5 - playerLocation.X; + double dy = sign.location.Y + 0.5 - playerLocation.Y; + double dz = sign.location.Z + 0.5 - playerLocation.Z; + return new + { + sign, + distance = Math.Sqrt(dx * dx + dy * dy + dz * dz) + }; + }) + .Where(entry => entry.distance <= radius) + .Where(entry => IsSignMaterial(world.GetBlock(entry.sign.location).Type)) + .Select(entry => + { + string[] frontText = entry.sign.frontText.Where(line => !string.IsNullOrWhiteSpace(line)).ToArray(); + string[] backText = includeBackText + ? entry.sign.backText.Where(line => !string.IsNullOrWhiteSpace(line)).ToArray() + : []; + string[] matchedLines = frontText + .Concat(backText) + .Where(line => exactMatch ? TextEqualsFilter(line, filter) : TextMatchesFilter(line, filter)) + .Distinct(NameComparer) + .ToArray(); + + return new + { + entry.sign, + entry.distance, + frontText, + backText, + matchedLines + }; + }) + .Where(entry => entry.matchedLines.Length > 0) + .OrderBy(entry => entry.distance) + .Take(limit) + .Select(entry => new + { + x = (int)Math.Floor(entry.sign.location.X), + y = (int)Math.Floor(entry.sign.location.Y), + z = (int)Math.Floor(entry.sign.location.Z), + material = entry.sign.material, + typeLabel = entry.sign.typeLabel, + distance = entry.distance, + isWaxed = entry.sign.isWaxed, + frontText = entry.frontText, + backText = entry.backText, + matchedLines = entry.matchedLines + }) + .ToArray(); + + return MccMcpResult.Ok(new + { + text = filter, + exactMatch, + radius, + includeBackText, + count = signs.Length, + signs + }); + }); + } + + public MccMcpResult ListItemEntities(string? itemType, double radius, int maxCount) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + if (radius <= 0 || radius > 1024) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetEntityHandlingEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + ItemType? parsedItemType = null; + string? itemTypeFilter = null; + if (!string.IsNullOrWhiteSpace(itemType)) + { + itemTypeFilter = itemType.Trim(); + if (!TryParseItemType(itemTypeFilter, out ItemType resolvedType)) + return MccMcpResult.Fail("invalid_args"); + parsedItemType = resolvedType; + } + + int limit = Math.Clamp(maxCount, 1, 500); + return client.InvokeOnMainThread(() => + { + NearbyItemSnapshot[] items = BuildNearbyItemSnapshots(client, parsedItemType, radius, limit); + return MccMcpResult.Ok(new + { + itemType = parsedItemType?.ToString() ?? itemTypeFilter, + radius, + count = items.Length, + items = items.Select(item => new + { + entityId = item.EntityId, + itemType = item.ItemType.ToString(), + typeLabel = item.TypeLabel, + count = item.Count, + x = RoundCoordinate(item.X), + y = RoundCoordinate(item.Y), + z = RoundCoordinate(item.Z), + distance = item.Distance + }).ToArray() + }); + }); + } + + public MccMcpResult PickupItems(string itemType, double radius, int maxItems, bool allowUnsafe, int timeoutMs) + { + if (!IsCategoryEnabled(t => t.EntityWorld) || !IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(itemType) || radius <= 0 || radius > 1024 || maxItems < 1 || timeoutMs < 0) + return MccMcpResult.Fail("invalid_args"); + + if (!TryParseItemType(itemType.Trim(), out ItemType parsedItemType)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled() || !client.GetEntityHandlingEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + int limit = Math.Clamp(maxItems, 1, 50); + NearbyItemSnapshot[] targets = client.InvokeOnMainThread(() => BuildNearbyItemSnapshots(client, parsedItemType, radius, limit)); + if (targets.Length == 0) + { + return MccMcpResult.Fail("invalid_state", data: new + { + itemType = parsedItemType.ToString(), + radius, + maxItems = limit + }); + } + + bool inventoryEnabled = client.GetInventoryEnabled(); + int beforeCount = inventoryEnabled ? client.InvokeOnMainThread(() => GetInventoryItemCount(client, parsedItemType)) : 0; + int initialCount = beforeCount; + int verifyWaitMs = timeoutMs > 0 ? Math.Clamp(timeoutMs, MinArrivalWaitMs, MaxArrivalWaitMs) : 2500; + List attempts = new(targets.Length); + int successfulPickups = 0; + + foreach (NearbyItemSnapshot target in targets) + { + Location targetLocation = new(target.X, target.Y, target.Z); + Location startLocation = client.InvokeOnMainThread(client.GetCurrentLocation); + TimeSpan? moveTimeout = timeoutMs > 0 ? TimeSpan.FromMilliseconds(timeoutMs) : null; + bool pathFound = client.InvokeOnMainThread(() => client.MoveTo(targetLocation, allowUnsafe, false, 0, 0, moveTimeout)); + Location? finalLocation = null; + bool arrived = pathFound && WaitForArrival(client, targetLocation, verifyWaitMs, 2.0, out finalLocation); + finalLocation ??= client.InvokeOnMainThread(client.GetCurrentLocation); + bool entityGone = WaitForEntityRemoval(client, target.EntityId, verifyWaitMs); + int afterCount = inventoryEnabled ? client.InvokeOnMainThread(() => GetInventoryItemCount(client, parsedItemType)) : beforeCount; + int inventoryDelta = inventoryEnabled ? Math.Max(0, afterCount - beforeCount) : 0; + bool pickedUp = entityGone || inventoryDelta > 0; + if (pickedUp) + successfulPickups++; + + attempts.Add(new + { + entityId = target.EntityId, + itemType = target.ItemType.ToString(), + typeLabel = target.TypeLabel, + expectedCount = target.Count, + target = ToCoordinate(target.X, target.Y, target.Z), + pathFound, + arrived, + entityGone, + inventoryDelta, + startLocation = ToCoordinate(startLocation), + finalLocation = ToCoordinate(finalLocation.Value), + finalDistance = GetDistance(finalLocation.Value, targetLocation) + }); + + beforeCount = afterCount; + } + + int remainingNearby = client.InvokeOnMainThread(() => BuildNearbyItemSnapshots(client, parsedItemType, radius, 1000).Length); + int collectedCount = inventoryEnabled ? Math.Max(0, beforeCount - initialCount) : successfulPickups; + object resultData = new + { + itemType = parsedItemType.ToString(), + radius, + maxItems = limit, + allowUnsafe, + timeoutMs = verifyWaitMs, + attempted = attempts.Count, + successfulPickups, + collectedCount, + initialInventoryCount = inventoryEnabled ? (int?)initialCount : null, + finalInventoryCount = inventoryEnabled ? (int?)beforeCount : null, + remainingNearby, + attempts = attempts.ToArray() + }; + + return successfulPickups > 0 || collectedCount > 0 + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); + } + public MccMcpResult GetWorldBlockAt(int x, int y, int z) { if (!IsCategoryEnabled(t => t.EntityWorld)) @@ -1436,6 +1969,112 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return Math.Max(DefaultArrivalTolerance, toleranceFromOffset); } + private static int GetPathQueryTimeoutMs(int timeoutMs) + { + if (timeoutMs <= 0) + return DefaultPathQueryTimeoutMs; + return Math.Clamp(timeoutMs, MinPathQueryTimeoutMs, MaxPathQueryTimeoutMs); + } + + private static bool WaitForBlockChange(McClient client, Location target, Block beforeBlock, int waitMs, out Block afterBlock) + { + afterBlock = beforeBlock; + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + Block current = client.InvokeOnMainThread(() => client.GetWorld().GetBlock(target)); + afterBlock = current; + if (!AreEquivalentBlocks(current, beforeBlock)) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static bool AreEquivalentBlocks(Block left, Block right) + { + return left.BlockId == right.BlockId + && left.BlockMeta == right.BlockMeta + && left.Type == right.Type; + } + + private static double[] GetDigAttemptDurations(double durationSeconds) + { + if (durationSeconds > 0) + return [durationSeconds]; + return s_defaultDigAttemptDurations; + } + + private static int GetDigVerifyWaitMs(double durationSeconds) + { + int waitMs = (int)Math.Ceiling(durationSeconds * 1000) + 2000; + return Math.Clamp(waitMs, 1500, MaxBlockVerifyWaitMs); + } + + private static bool AreValidPathOffsets(int maxOffset, int minOffset) + { + return maxOffset >= 0 && minOffset >= 0 && minOffset <= maxOffset; + } + + private static NearbyItemSnapshot[] BuildNearbyItemSnapshots(McClient client, ItemType? itemType, double radius, int maxCount) + { + Location playerLocation = client.GetCurrentLocation(); + return client.GetEntities().Values + .Where(entity => entity.Type == EntityType.Item && !entity.Item.IsEmpty) + .Where(entity => !itemType.HasValue || entity.Item.Type == itemType.Value) + .Select(entity => + { + double dx = entity.Location.X - playerLocation.X; + double dy = entity.Location.Y - playerLocation.Y; + double dz = entity.Location.Z - playerLocation.Z; + return new NearbyItemSnapshot + { + EntityId = entity.ID, + ItemType = entity.Item.Type, + TypeLabel = entity.Item.GetTypeString(), + Count = entity.Item.Count, + X = entity.Location.X, + Y = entity.Location.Y, + Z = entity.Location.Z, + Distance = Math.Sqrt(dx * dx + dy * dy + dz * dz) + }; + }) + .Where(item => item.Distance <= radius) + .OrderBy(item => item.Distance) + .Take(maxCount) + .ToArray(); + } + + private static bool WaitForEntityRemoval(McClient client, int entityId, int waitMs) + { + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + bool exists = client.InvokeOnMainThread(() => client.GetEntities().ContainsKey(entityId)); + if (!exists) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static int GetInventoryItemCount(McClient client, ItemType itemType) + { + Container? inventory = client.GetInventory(0); + if (inventory is null) + return 0; + + return inventory.Items.Values + .Where(item => item.Type == itemType) + .Sum(item => item.Count); + } + private static object ToCoordinate(Location location) { return ToCoordinate(location.X, location.Y, location.Z); @@ -1456,6 +2095,51 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return Math.Round(value, CoordinateRoundingPrecision, MidpointRounding.AwayFromZero); } + private static Location ToBlockLocation(double x, double y, double z) + { + return new Location(Math.Floor(x), Math.Floor(y), Math.Floor(z)); + } + + private static object ToBlockState(Block block) + { + return new + { + material = block.Type.ToString(), + typeLabel = block.GetTypeString(), + blockId = block.BlockId, + blockMeta = block.BlockMeta + }; + } + + private static string GetMaterialTypeLabel(Material material) + { + string key = "block.minecraft." + ToTranslationKey(material.ToString()); + string? translation = ChatParser.TranslateString(key); + return string.IsNullOrEmpty(translation) ? material.ToString() : translation; + } + + private static string ToTranslationKey(string value) + { + if (string.IsNullOrEmpty(value)) + return string.Empty; + + List chars = new(value.Length * 2); + for (int i = 0; i < value.Length; i++) + { + char current = value[i]; + if (char.IsUpper(current) && i > 0 && (char.IsLower(value[i - 1]) || char.IsDigit(value[i - 1]))) + chars.Add('_'); + chars.Add(char.ToLowerInvariant(current)); + } + + return new string(chars.ToArray()); + } + + private static bool IsSignMaterial(Material material) + { + return material.ToString().Contains("Sign", StringComparison.Ordinal); + } + private static string? ResolvePlayerEntityName(Entity entity, IReadOnlyDictionary uuidToName) { if (!string.IsNullOrWhiteSpace(entity.Name)) @@ -1492,12 +2176,30 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities string typeLabel = block.GetTypeString(); if (exactMatch) { - return material.Equals(filter, StringComparison.OrdinalIgnoreCase) - || typeLabel.Equals(filter, StringComparison.OrdinalIgnoreCase); + return TextEqualsFilter(material, filter) + || TextEqualsFilter(typeLabel, filter); } - return material.Contains(filter, StringComparison.OrdinalIgnoreCase) - || typeLabel.Contains(filter, StringComparison.OrdinalIgnoreCase); + return TextMatchesFilter(material, filter) + || TextMatchesFilter(typeLabel, filter); + } + + private static bool TextEqualsFilter(string text, string filter) + { + return text.Equals(filter, StringComparison.OrdinalIgnoreCase) + || NormalizeToken(text) == NormalizeToken(filter); + } + + private static bool TextMatchesFilter(string text, string filter) + { + if (text.Contains(filter, StringComparison.OrdinalIgnoreCase)) + return true; + + string normalizedFilter = NormalizeToken(filter); + if (normalizedFilter.Length == 0) + return false; + + return NormalizeToken(text).Contains(normalizedFilter, StringComparison.Ordinal); } private static void ParseBlockQuery(string? query, out int? blockId, out int? blockMeta) diff --git a/MinecraftClient/Mcp/MccMcpToolSet.cs b/MinecraftClient/Mcp/MccMcpToolSet.cs index 6eb41caa..d0d0307b 100644 --- a/MinecraftClient/Mcp/MccMcpToolSet.cs +++ b/MinecraftClient/Mcp/MccMcpToolSet.cs @@ -49,6 +49,24 @@ public sealed class MccMcpToolSet return capabilities.GetInternalCommands(); } + [McpServerTool(Name = "mcc_materials_list"), Description("List known MCC material names with optional filtering.")] + public object MaterialsList(string? filter = null, int maxCount = 500) + { + return capabilities.GetMaterialsList(filter, maxCount); + } + + [McpServerTool(Name = "mcc_block_types_list"), Description("List known MCC block type names with optional filtering.")] + public object BlockTypesList(string? filter = null, int maxCount = 500) + { + return capabilities.GetBlockTypesList(filter, maxCount); + } + + [McpServerTool(Name = "mcc_entity_types_list"), Description("List known MCC entity type names with optional filtering.")] + public object EntityTypesList(string? filter = null, int maxCount = 500) + { + return capabilities.GetEntityTypesList(filter, maxCount); + } + [McpServerTool(Name = "mcc_send_chat"), Description("Send chat text or slash-command to the connected Minecraft server.")] public object SendChat([Description("Text to send to server chat.")] string text) { @@ -127,6 +145,12 @@ public sealed class MccMcpToolSet return capabilities.LocatePlayer(playerName, includeSelf); } + [McpServerTool(Name = "mcc_can_reach_position"), Description("Check whether MCC can currently path to a world coordinate without moving there.")] + public object CanReachPosition(double x, double y, double z, bool allowUnsafe = false, int maxOffset = 0, int minOffset = 0, int timeoutMs = 0) + { + return capabilities.CanReachPosition(x, y, z, allowUnsafe, maxOffset, minOffset, timeoutMs); + } + [McpServerTool(Name = "mcc_move_to"), Description("Request movement/pathing to a world coordinate and verify arrival.")] public object MoveTo(double x, double y, double z, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, int timeoutMs = 0) { @@ -185,6 +209,24 @@ public sealed class MccMcpToolSet return capabilities.GetEntityInfo(entityId, includeMetadata, includeEquipment, includeEffects); } + [McpServerTool(Name = "mcc_signs_find"), Description("Find nearby signs whose text exactly matches or contains the requested text.")] + public object SignsFind(string text, bool exactMatch = false, int radius = 16, int maxCount = 50, bool includeBackText = true) + { + return capabilities.FindSigns(text, exactMatch, radius, maxCount, includeBackText); + } + + [McpServerTool(Name = "mcc_items_list"), Description("List nearby dropped item entities with optional item type filtering.")] + public object ItemsList(string? itemType = null, double radius = 32, int maxCount = 100) + { + return capabilities.ListItemEntities(itemType, radius, maxCount); + } + + [McpServerTool(Name = "mcc_items_pickup"), Description("Move to and pick up nearby dropped items of a given item type.")] + public object ItemsPickup(string itemType, double radius = 32, int maxItems = 20, bool allowUnsafe = false, int timeoutMs = 0) + { + return capabilities.PickupItems(itemType, radius, maxItems, allowUnsafe, timeoutMs); + } + [McpServerTool(Name = "mcc_world_block_at"), Description("Get block information at world coordinates.")] public object WorldBlockAt(int x, int y, int z) { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index b6cdcd05..a36eaf72 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1569,6 +1569,7 @@ namespace MinecraftClient.Protocol.Handlers var dataSize = dataTypes.ReadNextVarInt(packetData); // Size pTerrain.ProcessChunkColumnData(chunkX, chunkZ, verticalStripBitmask, packetData); + ProcessChunkBlockEntityData(chunkX, chunkZ, packetData); Interlocked.Decrement(ref handler.GetWorld().chunkLoadNotCompleted); // Block Entity data: ignored @@ -2957,17 +2958,16 @@ namespace MinecraftClient.Protocol.Handlers // TODO: Use break; + case PacketTypesIn.BlockEntityData: + if (handler.GetTerrainEnabled() && protocolVersion >= MC_1_17_Version) + { + var location_ = dataTypes.ReadNextLocation(packetData); + dataTypes.ReadNextVarInt(packetData); // Block entity type registry id + var nbt = dataTypes.ReadNextNbt(packetData); + handler.OnBlockEntityData(location_, nbt); + } - // Temporarily disabled until I find a fix - /*case PacketTypesIn.BlockEntityData: - var location_ = dataTypes.ReadNextLocation(packetData); - var type_ = dataTypes.ReadNextInt(packetData); - var nbt = dataTypes.ReadNextNbt(packetData); - var nbtJson = JsonConvert.SerializeObject(nbt["messages"]); - - //log.Info($"BLOCK ENTITY DATA -> {location_.ToString()} [{type_}] -> NBT: {nbtJson}"); - - break;*/ + break; case PacketTypesIn.SetTickingState: dataTypes.ReadNextFloat(packetData); @@ -3162,6 +3162,24 @@ namespace MinecraftClient.Protocol.Handlers SendPacket(packetPalette.GetOutgoingIdByType(packet), packetData); } + private void ProcessChunkBlockEntityData(int chunkX, int chunkZ, Queue packetData) + { + if (protocolVersion < MC_1_17_Version || packetData.Count == 0) + return; + + int blockEntityCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < blockEntityCount; i++) + { + int packedXZ = dataTypes.ReadNextByte(packetData); + int y = dataTypes.ReadNextShort(packetData); + dataTypes.ReadNextVarInt(packetData); // Block entity type registry id + Dictionary? nbt = dataTypes.ReadNextNbt(packetData); + int blockX = chunkX * Chunk.SizeX + ((packedXZ >> 4) & 0x0F); + int blockZ = chunkZ * Chunk.SizeZ + (packedXZ & 0x0F); + handler.OnBlockEntityData(new Location(blockX, y, blockZ), nbt); + } + } + /// /// Send a configuration packet to the server. Packet ID, compression, and encryption will be handled automatically. /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 94fe0590..85618c07 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -508,6 +508,13 @@ namespace MinecraftClient.Protocol /// The block public void OnBlockChange(Location location, Block block); + /// + /// Called when block entity update data is received for a loaded block. + /// + /// The block location. + /// The block entity NBT payload. + public void OnBlockEntityData(Location location, Dictionary? nbt); + /// /// Called when "AutoComplete" completes. /// From 2d677e0f0d400de5cdb729563931c6344f697313 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 28 Mar 2026 23:17:08 +0800 Subject: [PATCH 254/484] Fix skill frontmatter validation --- .skills/csharp-best-practices/SKILL.md | 1 - .skills/csharp-dotnet-cli-optimization/SKILL.md | 1 - .skills/csharp-optimization/SKILL.md | 1 - .skills/humanizer/SKILL.md | 1 - .skills/writing-skills/SKILL.md | 4 ---- 5 files changed, 8 deletions(-) diff --git a/.skills/csharp-best-practices/SKILL.md b/.skills/csharp-best-practices/SKILL.md index 8eb731ef..27c67ad4 100644 --- a/.skills/csharp-best-practices/SKILL.md +++ b/.skills/csharp-best-practices/SKILL.md @@ -3,7 +3,6 @@ name: csharp-best-practices description: > C# 14 / .NET 10 coding conventions, idiomatic patterns, and performance best practices for the Minecraft Console Client codebase. Use when writing, reviewing, or modifying C# code. -version: 0.4.0 --- # C# 14 / .NET 10 Best Practices diff --git a/.skills/csharp-dotnet-cli-optimization/SKILL.md b/.skills/csharp-dotnet-cli-optimization/SKILL.md index 71acf832..7691da85 100644 --- a/.skills/csharp-dotnet-cli-optimization/SKILL.md +++ b/.skills/csharp-dotnet-cli-optimization/SKILL.md @@ -31,7 +31,6 @@ metadata: - slow - hang - deadlock -version: 0.2.0 --- # C#/.NET CLI Optimization diff --git a/.skills/csharp-optimization/SKILL.md b/.skills/csharp-optimization/SKILL.md index 060b4d6b..9caf92f9 100644 --- a/.skills/csharp-optimization/SKILL.md +++ b/.skills/csharp-optimization/SKILL.md @@ -7,7 +7,6 @@ metadata: category: technique triggers: performance, allocations, GC, hot path, latency, throughput, memory pressure, optimize, slow, freeze, lag spike, packet processing speed -version: 0.2.0 --- # C# Performance Optimization for MCC diff --git a/.skills/humanizer/SKILL.md b/.skills/humanizer/SKILL.md index 45e2cb0c..9609cb69 100644 --- a/.skills/humanizer/SKILL.md +++ b/.skills/humanizer/SKILL.md @@ -1,6 +1,5 @@ --- name: humanizer -version: 2.1.1 description: | Remove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's diff --git a/.skills/writing-skills/SKILL.md b/.skills/writing-skills/SKILL.md index c00da178..514e2c4f 100644 --- a/.skills/writing-skills/SKILL.md +++ b/.skills/writing-skills/SKILL.md @@ -1,10 +1,6 @@ --- name: writing-skills description: "Use when creating, updating, or improving agent skills." -category: meta -risk: unknown -source: community -date_added: "2026-02-27" --- # Writing Skills (Excellence) From f0fda8ce9ff4fed325c4ee6f53917d7ac4ad0a34 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 28 Mar 2026 23:38:56 +0800 Subject: [PATCH 255/484] Update base_path in crowdin.yml to use relative path --- crowdin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin.yml b/crowdin.yml index 5e80b8bb..89813ca1 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,6 +1,6 @@ "project_id_env": "CROWDIN_PROJECT_ID" "api_token_env": "CROWDIN_PERSONAL_TOKEN" -"base_path": "/" +"base_path": "./" "preserve_hierarchy": true "base_url": "https://api.crowdin.com" From cf382122e9dcc4f0a3fe71cad3d253608119d8f9 Mon Sep 17 00:00:00 2001 From: Anon Date: Sat, 28 Mar 2026 16:44:22 +0100 Subject: [PATCH 256/484] Added inventory manipulation to the MCP, improved the test harness --- DebugTools/MccMcpStdioHarness/Program.cs | 73 ++ DebugTools/MccMcpWebPlayground/Program.cs | 31 +- MinecraftClient/Mcp/IMccMcpCapabilities.cs | 5 + MinecraftClient/Mcp/MccMcpCapabilities.cs | 808 +++++++++++++++++++++ MinecraftClient/Mcp/MccMcpToolSet.cs | 38 + 5 files changed, 948 insertions(+), 7 deletions(-) diff --git a/DebugTools/MccMcpStdioHarness/Program.cs b/DebugTools/MccMcpStdioHarness/Program.cs index d105f12f..69f2488a 100644 --- a/DebugTools/MccMcpStdioHarness/Program.cs +++ b/DebugTools/MccMcpStdioHarness/Program.cs @@ -295,16 +295,53 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities public MccMcpResult LookAt(double x, double y, double z) => MccMcpResult.Ok(new { looked = true, x = C(x), y = C(y), z = C(z) }); + public MccMcpResult ListInventories() => + MccMcpResult.Ok(new + { + count = 2, + inventories = new object[] + { + new { id = 0, type = "PlayerInventory", title = "Player Inventory", slotCount = 46, nonEmptySlots = 1, active = false }, + new { id = 1, type = "Generic_9x3", title = "Chest", slotCount = 63, nonEmptySlots = 2, active = true } + } + }); + public MccMcpResult GetInventorySnapshot(int inventoryId) => MccMcpResult.Ok(new { id = inventoryId, + type = inventoryId == 0 ? "PlayerInventory" : "Generic_9x3", + title = inventoryId == 0 ? "Player Inventory" : "Chest", + slotCount = inventoryId == 0 ? 46 : 63, slots = new[] { new { slot = 0, type = "Stone", count = 64 } } }); + public MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent) => + MccMcpResult.Ok(new + { + success = true, + openAccepted = true, + opened = true, + timeoutMs = timeoutMs <= 0 ? 5000 : timeoutMs, + x, + y, + z, + block = new { material = "Chest", typeLabel = "Chest", blockId = 0, blockMeta = 0 }, + inventory = new { id = 1, type = "Generic_9x3", title = "Chest", slotCount = 63, nonEmptySlots = 2 } + }); + + public MccMcpResult CloseContainer(int inventoryId, int timeoutMs) => + MccMcpResult.Ok(new + { + success = true, + closed = true, + inventoryId = inventoryId <= 0 ? 1 : inventoryId, + timeoutMs = timeoutMs <= 0 ? 5000 : timeoutMs + }); + public MccMcpResult InventoryWindowAction(int inventoryId, int slotId, string actionType) => MccMcpResult.Ok(new { success = true, inventoryId, slotId, actionType }); @@ -322,6 +359,42 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities preferStack }); + public MccMcpResult DepositContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack) => + MccMcpResult.Ok(new + { + success = true, + direction = "deposit", + itemType, + requestedCount = count, + movedCount = count, + beforePlayerCount = 64, + afterPlayerCount = Math.Max(0, 64 - count), + beforeContainerCount = 0, + afterContainerCount = count, + inventoryId = inventoryId <= 0 ? 1 : inventoryId, + containerType = "Generic_9x3", + touchedSourceSlots = new[] { 36 }, + touchedTargetSlots = new[] { 0 } + }); + + public MccMcpResult WithdrawContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack) => + MccMcpResult.Ok(new + { + success = true, + direction = "withdraw", + itemType, + requestedCount = count, + movedCount = count, + beforePlayerCount = 0, + afterPlayerCount = count, + beforeContainerCount = 64, + afterContainerCount = Math.Max(0, 64 - count), + inventoryId = inventoryId <= 0 ? 1 : inventoryId, + containerType = "Generic_9x3", + touchedSourceSlots = new[] { 0 }, + touchedTargetSlots = new[] { 36 } + }); + public MccMcpResult QueryEntities(int maxCount) => MccMcpResult.Ok(new { diff --git a/DebugTools/MccMcpWebPlayground/Program.cs b/DebugTools/MccMcpWebPlayground/Program.cs index e2131393..9b25f0ca 100644 --- a/DebugTools/MccMcpWebPlayground/Program.cs +++ b/DebugTools/MccMcpWebPlayground/Program.cs @@ -8,7 +8,10 @@ using ModelContextProtocol.Client; using ModelContextProtocol.Protocol; var builder = WebApplication.CreateBuilder(args); -builder.Services.AddHttpClient("openrouter"); +builder.Services.AddHttpClient("openrouter", client => +{ + client.Timeout = TimeSpan.FromMinutes(15); +}); var app = builder.Build(); app.UseDefaultFiles(); @@ -46,6 +49,7 @@ Todo policy Tool-use policy - Use MCP tools for MCC/game-state questions and actions. - Prefer the most direct high-signal tool first. +- Prefer structured inventory/container tools over raw window-click tools for chest or container management. - If a tool result says success=false or includes an errorCode, treat that as a failed observation even if the transport call itself succeeded. - Do not guess tool arguments repeatedly. If a tool returns invalid_args: - simplify to the minimum required arguments, @@ -73,6 +77,12 @@ Action-specific guidance - dig in a sensible order, - re-check remaining blocks, - re-check inventory or nearby item entities before finishing. +- Container inventory: + - locate the target container block, + - open the container first, + - inspect player and container inventory state, + - use structured deposit or withdraw tools instead of raw window clicks, + - verify both player and container counts changed before finishing. - Search: - start with the most direct search tool, - use the user's requested radius when supported, @@ -97,6 +107,13 @@ Good examples Good: - finish with a short greeting - no MCP tools +4) User: "Put 5 diamonds in the chest." + Good: + - open the chest + - inspect inventory state + - deposit exactly 5 diamonds + - verify the chest count increased and player count decreased by 5 + - then finish Wrong examples 1) Wrong: @@ -165,9 +182,9 @@ app.MapPost("/api/chat/stream", async (ChatStreamRequest request, IHttpClientFac } string model = GetModel(); - int maxIterations = GetBoundedInt("MCC_WEB_MAX_ITERATIONS", 24, 4, 80); - int maxToolCalls = GetBoundedInt("MCC_WEB_MAX_TOOL_CALLS", 80, 4, 256); - TimeSpan maxWallTime = TimeSpan.FromSeconds(GetBoundedInt("MCC_WEB_MAX_SECONDS", 120, 10, 300)); + int maxIterations = GetBoundedInt("MCC_WEB_MAX_ITERATIONS", 96, 4, 256); + int maxToolCalls = GetBoundedInt("MCC_WEB_MAX_TOOL_CALLS", 320, 4, 1024); + TimeSpan maxWallTime = TimeSpan.FromSeconds(GetBoundedInt("MCC_WEB_MAX_SECONDS", 900, 10, 3600)); await using McpClient mcp = await CreateMcpClientAsync(cancellationToken); IList mcpTools = await mcp.ListToolsAsync(cancellationToken: cancellationToken); @@ -1005,9 +1022,9 @@ Answer: static bool ShouldInjectReminder(int iteration, int maxIterations, int toolCallCount, int maxToolCalls, TimeSpan elapsed, TimeSpan maxWallTime) { - return iteration >= maxIterations - 2 - || toolCallCount >= maxToolCalls - 4 - || elapsed >= maxWallTime - TimeSpan.FromSeconds(10); + return iteration >= maxIterations - 6 + || toolCallCount >= maxToolCalls - 12 + || elapsed >= maxWallTime - TimeSpan.FromSeconds(45); } static string BuildForcedFinalAnswer( diff --git a/MinecraftClient/Mcp/IMccMcpCapabilities.cs b/MinecraftClient/Mcp/IMccMcpCapabilities.cs index 6d5b118a..0e460a9e 100644 --- a/MinecraftClient/Mcp/IMccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/IMccMcpCapabilities.cs @@ -28,9 +28,14 @@ public interface IMccMcpCapabilities MccMcpResult MoveTo(double x, double y, double z, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult MoveToPlayer(string playerName, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult LookAt(double x, double y, double z); + MccMcpResult ListInventories(); MccMcpResult GetInventorySnapshot(int inventoryId); + MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent); + MccMcpResult CloseContainer(int inventoryId, int timeoutMs); MccMcpResult InventoryWindowAction(int inventoryId, int slotId, string actionType); MccMcpResult DropInventoryItem(string itemType, int count, int inventoryId, bool preferStack); + MccMcpResult DepositContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack); + MccMcpResult WithdrawContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack); MccMcpResult QueryEntities(int maxCount); MccMcpResult ListEntities(int maxCount, string? typeFilter, double radius); MccMcpResult GetEntityInfo(int entityId, bool includeMetadata, bool includeEquipment, bool includeEffects); diff --git a/MinecraftClient/Mcp/MccMcpCapabilities.cs b/MinecraftClient/Mcp/MccMcpCapabilities.cs index 055786a6..907b8b66 100644 --- a/MinecraftClient/Mcp/MccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/MccMcpCapabilities.cs @@ -31,6 +31,10 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities private const double DefaultArrivalTolerance = 1.5; private const int ArrivalPollIntervalMs = 125; private const int MaxBlockVerifyWaitMs = 12000; + private const int DefaultContainerWaitMs = 5000; + private const int MinContainerWaitMs = 250; + private const int MaxContainerWaitMs = 20000; + private const int DefaultInventoryActionWaitMs = 3500; private sealed class InternalCommandInfo { @@ -64,6 +68,12 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities public required double Distance { get; init; } } + private enum InventoryTransferDirection + { + Deposit, + Withdraw + } + private readonly Func togglesProvider; public MccMcpCapabilities(Func togglesProvider) @@ -1122,6 +1132,120 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult ListInventories() + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + var inventories = client.GetInventories() + .OrderBy(entry => entry.Key) + .Select(entry => new + { + id = entry.Key, + type = entry.Value.Type.ToString(), + title = entry.Value.Title, + slotCount = entry.Value.Type.SlotCount(), + nonEmptySlots = entry.Value.Items.Count, + active = entry.Key > 0 && entry.Key == GetActiveContainerId(client) + }) + .ToArray(); + + return MccMcpResult.Ok(new + { + count = inventories.Length, + inventories + }); + }); + } + + public MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent) + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled() || !client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + Location location = new(x, y, z); + int waitMs = GetContainerWaitMs(timeoutMs); + (Block block, int activeContainerId) state = client.InvokeOnMainThread(() => + { + Block block = client.GetWorld().GetBlock(location); + return (block, GetActiveContainerId(client)); + }); + + if (!IsInteractableContainerMaterial(state.block.Type)) + { + return MccMcpResult.Fail("invalid_state", data: new + { + x, + y, + z, + block = ToBlockState(state.block), + activeContainerId = state.activeContainerId + }); + } + + return OpenContainerCore(client, location, state.block, state.activeContainerId, waitMs, closeCurrent); + } + + public MccMcpResult CloseContainer(int inventoryId, int timeoutMs) + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + int waitMs = GetContainerWaitMs(timeoutMs); + int resolvedInventoryId = client.InvokeOnMainThread(() => ResolveContainerInventoryId(client, inventoryId)); + if (resolvedInventoryId <= 0) + { + if (inventoryId < 0) + { + return MccMcpResult.Ok(new + { + success = true, + closed = false + }); + } + + return MccMcpResult.Fail("invalid_state", data: new { inventoryId }); + } + + bool closeAccepted = client.CloseInventory(resolvedInventoryId); + bool closed = closeAccepted && WaitForContainerClose(client, resolvedInventoryId, waitMs); + var resultData = new + { + success = closeAccepted && closed, + closeAccepted, + closed, + inventoryId = resolvedInventoryId, + timeoutMs = waitMs + }; + + return closeAccepted && closed + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); + } + public MccMcpResult InventoryWindowAction(int inventoryId, int slotId, string actionType) { if (!IsCategoryEnabled(t => t.Inventory)) @@ -1274,6 +1398,16 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult DepositContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack) + { + return TransferContainerItem(itemType, count, inventoryId, preferLargestStack, InventoryTransferDirection.Deposit); + } + + public MccMcpResult WithdrawContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack) + { + return TransferContainerItem(itemType, count, inventoryId, preferLargestStack, InventoryTransferDirection.Withdraw); + } + public MccMcpResult QueryEntities(int maxCount) { if (!IsCategoryEnabled(t => t.EntityWorld)) @@ -1729,6 +1863,312 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + private static MccMcpResult OpenContainerCore(McClient client, Location location, Block block, int activeContainerId, int waitMs, bool closeCurrent) + { + if (activeContainerId > 0) + { + if (!closeCurrent) + { + return MccMcpResult.Fail("invalid_state", data: new + { + reason = "container_already_open", + activeContainerId, + x = location.X, + y = location.Y, + z = location.Z, + block = ToBlockState(block) + }); + } + + bool closeAccepted = client.CloseInventory(activeContainerId); + bool closed = closeAccepted && WaitForContainerClose(client, activeContainerId, waitMs); + if (!closeAccepted || !closed) + { + return MccMcpResult.Fail("action_incomplete", data: new + { + action = "close_previous_container", + activeContainerId, + closeAccepted, + closed, + timeoutMs = waitMs + }); + } + } + + HashSet beforeIds = client.InvokeOnMainThread(() => client.GetInventories().Keys.Where(id => id > 0).ToHashSet()); + int openedInventoryId = 0; + Container? openedInventory = null; + bool openAccepted = client.InvokeOnMainThread(() => client.PlaceBlock(location, Direction.Down, Hand.MainHand, lookAtBlock: true)); + bool opened = openAccepted && WaitForContainerOpen(client, beforeIds, waitMs, out openedInventoryId, out openedInventory); + var resultData = new + { + success = openAccepted && opened && openedInventory is not null, + openAccepted, + opened, + timeoutMs = waitMs, + x = location.X, + y = location.Y, + z = location.Z, + block = ToBlockState(block), + inventory = openedInventory is null + ? null + : new + { + id = openedInventoryId, + type = openedInventory.Type.ToString(), + title = openedInventory.Title, + slotCount = openedInventory.Type.SlotCount(), + nonEmptySlots = openedInventory.Items.Count + } + }; + + return openAccepted && opened && openedInventory is not null + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); + } + + private MccMcpResult TransferContainerItem(string itemType, int count, int inventoryId, bool preferLargestStack, InventoryTransferDirection direction) + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(itemType) || count <= 0) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + if (!TryParseItemType(itemType, out ItemType parsedItemType)) + { + return MccMcpResult.Fail("invalid_args", data: new + { + itemType = itemType.Trim() + }); + } + + if (TryGetCursorItem(client, out Item? cursorItem)) + { + return MccMcpResult.Fail("invalid_state", data: new + { + reason = "cursor_item_present", + cursor = new { type = cursorItem!.Type.ToString(), count = cursorItem.Count } + }); + } + + int resolvedInventoryId = client.InvokeOnMainThread(() => ResolveContainerInventoryId(client, inventoryId)); + if (resolvedInventoryId <= 0) + { + return MccMcpResult.Fail("invalid_state", data: new + { + inventoryId + }); + } + + Container? initialInventory = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + if (initialInventory is null) + return MccMcpResult.Fail("invalid_state", data: new { inventoryId = resolvedInventoryId }); + + if (!TryGetContainerSlotRanges(initialInventory.Type, out int containerStart, out int containerEnd, out int playerStart, out int playerEnd)) + { + return MccMcpResult.Fail("invalid_state", data: new + { + reason = "unsupported_container_type", + inventoryId = resolvedInventoryId, + type = initialInventory.Type.ToString() + }); + } + + int sourceStart = direction == InventoryTransferDirection.Deposit ? playerStart : containerStart; + int sourceEnd = direction == InventoryTransferDirection.Deposit ? playerEnd : containerEnd; + int targetStart = direction == InventoryTransferDirection.Deposit ? containerStart : playerStart; + int targetEnd = direction == InventoryTransferDirection.Deposit ? containerEnd : playerEnd; + + int beforePlayerCount = CountItemInRange(initialInventory, parsedItemType, playerStart, playerEnd); + int beforeContainerCount = CountItemInRange(initialInventory, parsedItemType, containerStart, containerEnd); + int availableCount = CountItemInRange(initialInventory, parsedItemType, sourceStart, sourceEnd); + if (availableCount < count) + { + return MccMcpResult.Fail("invalid_state", data: new + { + itemType = parsedItemType.ToString(), + requestedCount = count, + availableCount, + inventoryId = resolvedInventoryId, + direction = direction.ToString() + }); + } + + int remaining = count; + List touchedSourceSlots = new(); + List touchedTargetSlots = new(); + + while (remaining > 0) + { + Container? inventory = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + if (inventory is null) + return MccMcpResult.Fail("invalid_state", data: new { inventoryId = resolvedInventoryId }); + + if (TryGetCursorItem(client, out cursorItem)) + { + return MccMcpResult.Fail("invalid_state", data: new + { + reason = "cursor_item_present_mid_transfer", + cursor = new { type = cursorItem!.Type.ToString(), count = cursorItem.Count } + }); + } + + var sourceSlots = GetOrderedItemSlots(inventory, parsedItemType, sourceStart, sourceEnd, preferLargestStack); + if (sourceSlots.Length == 0) + break; + + int beforeSourceCount = CountItemInRange(inventory, parsedItemType, sourceStart, sourceEnd); + int beforeTargetCount = CountItemInRange(inventory, parsedItemType, targetStart, targetEnd); + (int slot, int sourceCount) = sourceSlots[0]; + touchedSourceSlots.Add(slot); + + int movedCount; + List usedTargetSlots = new(); + if (sourceCount <= remaining || direction == InventoryTransferDirection.Withdraw) + { + if (!client.DoWindowAction(resolvedInventoryId, slot, WindowActionType.ShiftClick)) + { + return MccMcpResult.Fail("action_failed", data: new + { + itemType = parsedItemType.ToString(), + requestedCount = count, + remainingCount = remaining, + inventoryId = resolvedInventoryId, + sourceSlot = slot, + direction = direction.ToString() + }); + } + + if (direction == InventoryTransferDirection.Withdraw) + { + if (!WaitForRangeCount(client, resolvedInventoryId, parsedItemType, sourceStart, sourceEnd, countAfterShift => countAfterShift < beforeSourceCount, DefaultInventoryActionWaitMs, out Container? afterShift, out int afterSourceCount)) + { + afterShift = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + afterSourceCount = afterShift is null ? beforeSourceCount : CountItemInRange(afterShift, parsedItemType, sourceStart, sourceEnd); + } + + movedCount = beforeSourceCount - afterSourceCount; + } + else + { + if (!WaitForRangeCount(client, resolvedInventoryId, parsedItemType, targetStart, targetEnd, countAfterShift => countAfterShift > beforeTargetCount, DefaultInventoryActionWaitMs, out Container? afterShift, out int afterTargetCount)) + { + afterShift = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + afterTargetCount = afterShift is null ? beforeTargetCount : CountItemInRange(afterShift, parsedItemType, targetStart, targetEnd); + } + + movedCount = afterTargetCount - beforeTargetCount; + } + + if (direction == InventoryTransferDirection.Withdraw && movedCount > remaining) + { + int excessCount = movedCount - remaining; + MccMcpResult returnExcess = TransferContainerItem(parsedItemType.ToString(), excessCount, resolvedInventoryId, preferLargestStack, InventoryTransferDirection.Deposit); + if (!returnExcess.Success) + { + return MccMcpResult.Fail("action_incomplete", data: new + { + itemType = parsedItemType.ToString(), + requestedCount = count, + remainingCount = remaining, + inventoryId = resolvedInventoryId, + sourceSlot = slot, + direction = direction.ToString(), + excessCount, + returnExcess + }); + } + + movedCount -= excessCount; + } + } + else + { + movedCount = TransferPartialFromSlot( + client, + resolvedInventoryId, + slot, + parsedItemType, + remaining, + sourceStart, + sourceEnd, + targetStart, + targetEnd, + usedTargetSlots); + } + + if (movedCount <= 0) + { + Container? afterFailure = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + return MccMcpResult.Fail("action_incomplete", data: new + { + itemType = parsedItemType.ToString(), + requestedCount = count, + remainingCount = remaining, + inventoryId = resolvedInventoryId, + sourceSlot = slot, + direction = direction.ToString(), + playerCount = afterFailure is null ? 0 : CountItemInRange(afterFailure, parsedItemType, playerStart, playerEnd), + containerCount = afterFailure is null ? 0 : CountItemInRange(afterFailure, parsedItemType, containerStart, containerEnd) + }); + } + + remaining -= movedCount; + touchedTargetSlots.AddRange(usedTargetSlots); + } + + Container? finalInventory = client.InvokeOnMainThread(() => client.GetInventory(resolvedInventoryId)); + if (finalInventory is null) + return MccMcpResult.Fail("invalid_state", data: new { inventoryId = resolvedInventoryId }); + + int afterPlayerCount = CountItemInRange(finalInventory, parsedItemType, playerStart, playerEnd); + int afterContainerCount = CountItemInRange(finalInventory, parsedItemType, containerStart, containerEnd); + int playerDelta = afterPlayerCount - beforePlayerCount; + int containerDelta = afterContainerCount - beforeContainerCount; + int movedTotal = direction == InventoryTransferDirection.Deposit + ? afterContainerCount - beforeContainerCount + : beforeContainerCount - afterContainerCount; + bool countsVerified = direction == InventoryTransferDirection.Deposit + ? containerDelta == count + : containerDelta == -count; + bool playerCountsMatchExpected = direction == InventoryTransferDirection.Deposit + ? playerDelta == -count + : playerDelta == count; + bool succeeded = remaining == 0 && countsVerified; + var resultData = new + { + success = succeeded, + direction = direction.ToString().ToLowerInvariant(), + itemType = parsedItemType.ToString(), + requestedCount = count, + movedCount = movedTotal, + beforePlayerCount, + afterPlayerCount, + beforeContainerCount, + afterContainerCount, + playerDelta, + containerDelta, + playerCountsMatchExpected, + verificationBasis = "container_delta", + inventoryId = resolvedInventoryId, + containerType = finalInventory.Type.ToString(), + touchedSourceSlots = touchedSourceSlots.Distinct().OrderBy(slot => slot).ToArray(), + touchedTargetSlots = touchedTargetSlots.Distinct().OrderBy(slot => slot).ToArray() + }; + + return succeeded + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_incomplete", data: resultData); + } + private static MccMcpResult ExecuteInternalCommand(McClient client, string command) { return client.InvokeOnMainThread(() => @@ -1744,6 +2184,359 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + private static bool TryGetCursorItem(McClient client, out Item? cursorItem) + { + cursorItem = client.InvokeOnMainThread(() => + { + Container? playerInventory = client.GetInventory(0); + return playerInventory is not null && playerInventory.Items.TryGetValue(-1, out Item? item) ? item : null; + }); + return cursorItem is not null; + } + + private static int ResolveContainerInventoryId(McClient client, int inventoryId) + { + if (inventoryId > 0) + { + Container? inventory = client.GetInventory(inventoryId); + return inventory is not null && inventoryId != 0 ? inventoryId : 0; + } + + return GetActiveContainerId(client); + } + + private static int GetActiveContainerId(McClient client) + { + return client.GetInventories().Keys.Where(id => id > 0).DefaultIfEmpty(0).Max(); + } + + private static bool WaitForContainerOpen(McClient client, ISet beforeIds, int waitMs, out int inventoryId, out Container? inventory) + { + inventoryId = 0; + inventory = null; + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + (int activeId, Container? activeInventory) state = client.InvokeOnMainThread(() => + { + int activeId = GetActiveContainerId(client); + Container? activeInventory = activeId > 0 ? client.GetInventory(activeId) : null; + return (activeId, activeInventory); + }); + + if (state.activeId > 0 && (!beforeIds.Contains(state.activeId) || beforeIds.Count == 0) && state.activeInventory is not null) + { + inventoryId = state.activeId; + inventory = state.activeInventory; + return true; + } + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static bool WaitForContainerClose(McClient client, int inventoryId, int waitMs) + { + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + bool stillOpen = client.InvokeOnMainThread(() => client.GetInventories().ContainsKey(inventoryId)); + if (!stillOpen) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static int GetContainerWaitMs(int timeoutMs) + { + if (timeoutMs <= 0) + return DefaultContainerWaitMs; + return Math.Clamp(timeoutMs, MinContainerWaitMs, MaxContainerWaitMs); + } + + private static bool TryGetContainerSlotRanges(ContainerType type, out int containerStart, out int containerEnd, out int playerStart, out int playerEnd) + { + containerStart = 0; + containerEnd = -1; + playerStart = 0; + playerEnd = -1; + + int containerSlots = type switch + { + ContainerType.Generic_9x1 => 9, + ContainerType.Generic_9x2 => 18, + ContainerType.Generic_9x3 => 27, + ContainerType.Generic_9x4 => 36, + ContainerType.Generic_9x5 => 45, + ContainerType.Generic_9x6 => 54, + ContainerType.Generic_3x3 => 9, + ContainerType.Hopper => 5, + ContainerType.ShulkerBox => 27, + ContainerType.Furnace or ContainerType.BlastFurnace or ContainerType.Smoker => 3, + ContainerType.Crafter => 9, + _ => -1 + }; + + if (containerSlots <= 0) + return false; + + int slotCount = type.SlotCount(); + if (slotCount <= containerSlots) + return false; + + containerEnd = containerSlots - 1; + playerStart = containerSlots; + playerEnd = slotCount - 1; + return true; + } + + private static int CountItemInRange(Container inventory, ItemType itemType, int startSlot, int endSlot) + { + return inventory.Items + .Where(entry => entry.Key >= startSlot && entry.Key <= endSlot) + .Where(entry => entry.Value.Type == itemType) + .Sum(entry => entry.Value.Count); + } + + private static (int slot, int count)[] GetOrderedItemSlots(Container inventory, ItemType itemType, int startSlot, int endSlot, bool preferLargestStack) + { + var query = inventory.Items + .Where(entry => entry.Key >= startSlot && entry.Key <= endSlot) + .Where(entry => entry.Value.Type == itemType && entry.Value.Count > 0) + .Select(entry => (slot: entry.Key, count: entry.Value.Count)); + + return (preferLargestStack + ? query.OrderByDescending(entry => entry.count).ThenBy(entry => entry.slot) + : query.OrderBy(entry => entry.count).ThenBy(entry => entry.slot)) + .ToArray(); + } + + private static int TransferPartialFromSlot(McClient client, int inventoryId, int sourceSlot, ItemType itemType, int requestedCount, int sourceStart, int sourceEnd, int targetStart, int targetEnd, List touchedTargetSlots) + { + Container? inventory = client.InvokeOnMainThread(() => client.GetInventory(inventoryId)); + if (inventory is null || !inventory.Items.TryGetValue(sourceSlot, out Item? sourceItem) || sourceItem.Count <= 0) + return 0; + + int amountToMove = Math.Min(requestedCount, sourceItem.Count); + if (!client.DoWindowAction(inventoryId, sourceSlot, WindowActionType.LeftClick)) + return 0; + + if (!WaitForCursorItem(client, itemType, DefaultInventoryActionWaitMs, out _)) + return 0; + + int moved = 0; + while (moved < amountToMove) + { + inventory = client.InvokeOnMainThread(() => client.GetInventory(inventoryId)); + if (inventory is null || !TryGetCursorItem(client, out Item? cursorItem) || cursorItem is null || cursorItem.Type != itemType) + break; + + if (!TryFindTransferTargetSlot(inventory, itemType, targetStart, targetEnd, out int targetSlot, out int capacity)) + break; + + int step = Math.Min(amountToMove - moved, Math.Min(capacity, cursorItem.Count)); + int beforeTargetCount = GetSlotItemCount(inventory, targetSlot, itemType); + int beforeCursorCount = cursorItem.Count; + if (step <= 0 || !PlaceItemsFromCursor(client, inventoryId, targetSlot, step)) + break; + + if (!WaitForPlacement(client, inventoryId, targetSlot, itemType, beforeTargetCount, beforeCursorCount, step)) + break; + + touchedTargetSlots.Add(targetSlot); + moved += step; + } + + if (TryGetCursorItem(client, out Item? remainingCursor) && remainingCursor is not null && remainingCursor.Count > 0) + { + inventory = client.InvokeOnMainThread(() => client.GetInventory(inventoryId)); + if (inventory is null) + return 0; + + int returnSlot = GetReturnSlot(inventory, itemType, sourceStart, sourceEnd, sourceSlot); + if (!client.DoWindowAction(inventoryId, returnSlot, WindowActionType.LeftClick)) + return 0; + + if (!WaitForCursorClear(client, DefaultInventoryActionWaitMs)) + return 0; + } + + return TryGetCursorItem(client, out _) + ? 0 + : moved; + } + + private static bool TryFindTransferTargetSlot(Container inventory, ItemType itemType, int startSlot, int endSlot, out int targetSlot, out int capacity) + { + int maxStack = itemType.StackCount(); + for (int slot = startSlot; slot <= endSlot; slot++) + { + if (inventory.Items.TryGetValue(slot, out Item? item) && item.Type == itemType && item.Count < maxStack) + { + targetSlot = slot; + capacity = maxStack - item.Count; + return true; + } + } + + for (int slot = startSlot; slot <= endSlot; slot++) + { + if (!inventory.Items.ContainsKey(slot)) + { + targetSlot = slot; + capacity = maxStack; + return true; + } + } + + targetSlot = -1; + capacity = 0; + return false; + } + + private static bool PlaceItemsFromCursor(McClient client, int inventoryId, int targetSlot, int count) + { + if (count <= 0 || !TryGetCursorItem(client, out Item? cursorItem) || cursorItem is null) + return false; + + if (count == cursorItem.Count) + return client.DoWindowAction(inventoryId, targetSlot, WindowActionType.LeftClick); + + for (int i = 0; i < count; i++) + { + if (!client.DoWindowAction(inventoryId, targetSlot, WindowActionType.RightClick)) + return false; + } + + return true; + } + + private static int GetReturnSlot(Container inventory, ItemType itemType, int startSlot, int endSlot, int originalSourceSlot) + { + if (originalSourceSlot != 0) + return originalSourceSlot; + + int maxStack = itemType.StackCount(); + for (int slot = startSlot; slot <= endSlot; slot++) + { + if (slot == 0) + continue; + + if (inventory.Items.TryGetValue(slot, out Item? item) && item.Type == itemType && item.Count < maxStack) + return slot; + } + + for (int slot = startSlot; slot <= endSlot; slot++) + { + if (slot == 0) + continue; + + if (!inventory.Items.ContainsKey(slot)) + return slot; + } + + return originalSourceSlot; + } + + private static int GetSlotItemCount(Container inventory, int slot, ItemType itemType) + { + return inventory.Items.TryGetValue(slot, out Item? item) && item.Type == itemType ? item.Count : 0; + } + + private static bool WaitForCursorItem(McClient client, ItemType itemType, int waitMs, out Item? cursorItem) + { + cursorItem = null; + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + if (TryGetCursorItem(client, out cursorItem) && cursorItem is not null && cursorItem.Type == itemType) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static bool WaitForCursorClear(McClient client, int waitMs) + { + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + if (!TryGetCursorItem(client, out _)) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static bool WaitForPlacement(McClient client, int inventoryId, int targetSlot, ItemType itemType, int beforeTargetCount, int beforeCursorCount, int placedCount) + { + DateTime deadline = DateTime.UtcNow.AddMilliseconds(DefaultInventoryActionWaitMs); + while (true) + { + bool targetUpdated = false; + bool cursorUpdated = false; + + Container? inventory = client.InvokeOnMainThread(() => client.GetInventory(inventoryId)); + if (inventory is not null) + { + int currentTargetCount = GetSlotItemCount(inventory, targetSlot, itemType); + targetUpdated = currentTargetCount >= beforeTargetCount + placedCount; + } + + if (placedCount >= beforeCursorCount) + { + cursorUpdated = !TryGetCursorItem(client, out _); + } + else if (TryGetCursorItem(client, out Item? cursorItem) && cursorItem is not null && cursorItem.Type == itemType) + { + cursorUpdated = cursorItem.Count <= beforeCursorCount - placedCount; + } + + if (targetUpdated && cursorUpdated) + return true; + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + + private static bool WaitForRangeCount(McClient client, int inventoryId, ItemType itemType, int startSlot, int endSlot, Func predicate, int waitMs, out Container? inventory, out int itemCount) + { + inventory = null; + itemCount = 0; + DateTime deadline = DateTime.UtcNow.AddMilliseconds(waitMs); + while (true) + { + inventory = client.InvokeOnMainThread(() => client.GetInventory(inventoryId)); + if (inventory is not null) + { + itemCount = CountItemInRange(inventory, itemType, startSlot, endSlot); + if (predicate(itemCount)) + return true; + } + + if (DateTime.UtcNow >= deadline) + return false; + + Thread.Sleep(ArrivalPollIntervalMs); + } + } + private static List BuildTrackedPlayerSnapshots(McClient client, bool includeSelf) { Location playerLocation = client.GetCurrentLocation(); @@ -2140,6 +2933,21 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return material.ToString().Contains("Sign", StringComparison.Ordinal); } + private static bool IsInteractableContainerMaterial(Material material) + { + string name = material.ToString(); + return name.Contains("Chest", StringComparison.Ordinal) + || name.Contains("Barrel", StringComparison.Ordinal) + || name.Contains("ShulkerBox", StringComparison.Ordinal) + || name.Contains("Hopper", StringComparison.Ordinal) + || name.Contains("Dispenser", StringComparison.Ordinal) + || name.Contains("Dropper", StringComparison.Ordinal) + || name.Contains("Furnace", StringComparison.Ordinal) + || name.Contains("Smoker", StringComparison.Ordinal) + || name.Contains("BlastFurnace", StringComparison.Ordinal) + || name.Contains("Crafter", StringComparison.Ordinal); + } + private static string? ResolvePlayerEntityName(Entity entity, IReadOnlyDictionary uuidToName) { if (!string.IsNullOrWhiteSpace(entity.Name)) diff --git a/MinecraftClient/Mcp/MccMcpToolSet.cs b/MinecraftClient/Mcp/MccMcpToolSet.cs index d0d0307b..38c01973 100644 --- a/MinecraftClient/Mcp/MccMcpToolSet.cs +++ b/MinecraftClient/Mcp/MccMcpToolSet.cs @@ -175,6 +175,24 @@ public sealed class MccMcpToolSet return capabilities.GetInventorySnapshot(inventoryId); } + [McpServerTool(Name = "mcc_inventories_list"), Description("List currently open inventories and containers known to MCC.")] + public object InventoriesList() + { + return capabilities.ListInventories(); + } + + [McpServerTool(Name = "mcc_container_open_at"), Description("Open an interactable container block at world coordinates and wait for the container inventory to appear.")] + public object ContainerOpenAt(int x, int y, int z, int timeoutMs = 0, bool closeCurrent = true) + { + return capabilities.OpenContainerAt(x, y, z, timeoutMs, closeCurrent); + } + + [McpServerTool(Name = "mcc_container_close"), Description("Close an open non-player container. Use inventoryId=-1 to close the active container.")] + public object ContainerClose([Description("Container inventory ID, or -1 for the active non-player container.")] int inventoryId = -1, int timeoutMs = 0) + { + return capabilities.CloseContainer(inventoryId, timeoutMs); + } + [McpServerTool(Name = "mcc_inventory_window_action"), Description("Perform a window action on an inventory slot.")] public object InventoryWindowAction(int inventoryId, int slotId, [Description("WindowActionType enum name, e.g. LeftClick or ShiftClick.")] string actionType) { @@ -191,6 +209,26 @@ public sealed class MccMcpToolSet return capabilities.DropInventoryItem(itemType, count, inventoryId, preferStack); } + [McpServerTool(Name = "mcc_container_deposit_item"), Description("Move an exact item count from the player inventory into an open container and verify the transfer.")] + public object ContainerDepositItem( + [Description("Item type enum name (e.g. Diamond).")] string itemType, + [Description("Exact number of items to move into the container.")] int count, + [Description("Container inventory ID, or -1 for the active non-player container.")] int inventoryId = -1, + [Description("Prefer larger source stacks first when true.")] bool preferLargestStack = true) + { + return capabilities.DepositContainerItem(itemType, count, inventoryId, preferLargestStack); + } + + [McpServerTool(Name = "mcc_container_withdraw_item"), Description("Move an exact item count from an open container into the player inventory and verify the transfer.")] + public object ContainerWithdrawItem( + [Description("Item type enum name (e.g. Diamond).")] string itemType, + [Description("Exact number of items to move into the player inventory.")] int count, + [Description("Container inventory ID, or -1 for the active non-player container.")] int inventoryId = -1, + [Description("Prefer larger source stacks first when true.")] bool preferLargestStack = true) + { + return capabilities.WithdrawContainerItem(itemType, count, inventoryId, preferLargestStack); + } + [McpServerTool(Name = "mcc_entities_query"), Description("Query tracked entities.")] public object EntitiesQuery([Description("Maximum entities to return.")] int maxCount = 50) { From 9cada9d19d5a574dee17e2abe4c6ffa868ce5748 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 00:54:34 +0800 Subject: [PATCH 257/484] Refactor ConsoleIO and Program settings handling - Updated ConsoleIO to allow writing to the console when Backend is null, improving error handling. - Simplified settings write-back logic in Program.cs to ensure default settings are written correctly based on configuration results. --- MinecraftClient/ConsoleIO.cs | 4 ++-- MinecraftClient/Program.cs | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/MinecraftClient/ConsoleIO.cs b/MinecraftClient/ConsoleIO.cs index 485d5a90..8a77aaee 100644 --- a/MinecraftClient/ConsoleIO.cs +++ b/MinecraftClient/ConsoleIO.cs @@ -104,7 +104,7 @@ namespace MinecraftClient /// public static void WriteLine(string line) { - if (BasicIO) + if (BasicIO || Backend is null) Console.WriteLine(line); else Backend.WriteLine(line); @@ -137,7 +137,7 @@ namespace MinecraftClient { str = str.Replace('\n', ' '); } - if (BasicIO) + if (BasicIO || Backend is null) { if (BasicIO_NoColor) { diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 759e69ed..c0e7710d 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -161,14 +161,7 @@ namespace MinecraftClient } if (configResult.NeedWriteDefault) - { Config.Main.Advanced.Language = Settings.GetDefaultGameLanguage(); - WriteBackSettings(false); - } - else if (configResult.Success) - { - WriteBackSettings(true); - } if (!Config.Main.Advanced.EnableSentry) _sentrySdk?.Dispose(); @@ -219,6 +212,8 @@ namespace MinecraftClient if (cfg.NeedWriteDefault) { + WriteBackSettings(false); + if (cfg.IsLegacyUpgrade) { ConsoleIO.WriteLineFormatted("§c" + Translations.mcc_use_new_config); @@ -243,6 +238,8 @@ namespace MinecraftClient } else { + WriteBackSettings(true); + if (!Config.Main.Advanced.Language.StartsWith("en")) ConsoleIO.WriteLine(string.Format(Translations.mcc_help_us_translate, Settings.TranslationProjectUrl)); } From 83f14a64f879246ef94a1b3175e2c3759a45c949 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 01:31:31 +0800 Subject: [PATCH 258/484] Add tryout command for TUI onboarding Add a new /tryout command as an extensible entry point for recommended feature trials, with /tryout tui as the first action. The command updates [Console.General] ConsoleMode to "tui", writes the config back immediately, and explains both how to revert the change and that a restart is required. Also show a startup recommendation in classic console mode when stdin is interactive, so users can discover the TUI experience without manually editing MinecraftClient.ini. All user-facing text is routed through the translation resources. --- MinecraftClient/Commands/Tryout.cs | 63 +++++++++++++++++++ MinecraftClient/Program.cs | 14 +++++ .../Translations/Translations.Designer.cs | 54 ++++++++++++++++ .../Resources/Translations/Translations.resx | 20 +++++- 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 MinecraftClient/Commands/Tryout.cs diff --git a/MinecraftClient/Commands/Tryout.cs b/MinecraftClient/Commands/Tryout.cs new file mode 100644 index 00000000..8ae0829b --- /dev/null +++ b/MinecraftClient/Commands/Tryout.cs @@ -0,0 +1,63 @@ +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; +using static MinecraftClient.Settings.ConsoleConfigHealper.ConsoleConfig; + +namespace MinecraftClient.Commands +{ + public class Tryout : Command + { + public override string CmdName => "tryout"; + public override string CmdUsage => "tryout [list|tui]"; + public override string CmdDesc => Translations.cmd_tryout_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source)) + ) + ); + + dispatcher.Register(l => l.Literal(CmdName) + .Executes(r => ListTryouts(r.Source)) + .Then(l => l.Literal("list") + .Executes(r => ListTryouts(r.Source))) + .Then(l => l.Literal("tui") + .Executes(r => EnableTuiMode(r.Source))) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source)) + .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) + ); + } + + private int GetUsage(CmdResult r) + { + return r.SetAndReturn(GetCmdDescTranslated()); + } + + private int ListTryouts(CmdResult r) + { + return r.SetAndReturn(string.Join('\n', + GetCmdDescTranslated(), + string.Empty, + Translations.cmd_tryout_list_header, + $" - {Translations.cmd_tryout_list_tui}")); + } + + private int EnableTuiMode(CmdResult r) + { + var previousMode = Settings.Config.Console.General.ConsoleMode; + if (previousMode == ConsoleModeType.tui) + { + return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_tryout_tui_already_enabled); + } + + Settings.Config.Console.General.ConsoleMode = ConsoleModeType.tui; + Program.WriteBackSettings(); + + return r.SetAndReturn(CmdResult.Status.Done, + string.Format(Translations.cmd_tryout_tui_enabled, previousMode, ConsoleModeType.tui)); + } + } +} diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index c0e7710d..18d8ce88 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -193,6 +193,7 @@ namespace MinecraftClient if (!ProcessStartupState(startupState)) return; + MaybePrintClassicModeTuiRecommendation(); RunStartupSequence(args); } @@ -247,6 +248,19 @@ namespace MinecraftClient return true; } + private static void MaybePrintClassicModeTuiRecommendation() + { + if (ConsoleIO.BasicIO + || Config.Console.General.ConsoleMode != ConsoleModeType.classic + || Console.IsInputRedirected) + { + return; + } + + char cmdChar = Config.Main.Advanced.InternalCmdChar.ToChar(); + ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_console_mode_tui_recommendation, cmdChar)); + } + /// /// Handles a failed config load by prompting the user to fix or regenerate the config file. /// diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 3a2c4bc9..242752e6 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -3558,6 +3558,51 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to quickly enable recommended features.. + /// + internal static string cmd_tryout_desc { + get { + return ResourceManager.GetString("cmd.tryout.desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Available quick actions:. + /// + internal static string cmd_tryout_list_header { + get { + return ResourceManager.GetString("cmd.tryout.list.header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to tui: set [Console.General] ConsoleMode = "tui" for the next restart.. + /// + internal static string cmd_tryout_list_tui { + get { + return ResourceManager.GetString("cmd.tryout.list.tui", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [Console.General] ConsoleMode is already "tui" in the config. To switch back, set [Console.General] ConsoleMode = "classic". Restart MCC after changing it for the new mode to take effect.. + /// + internal static string cmd_tryout_tui_already_enabled { + get { + return ResourceManager.GetString("cmd.tryout.tui.already_enabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Updated [Console.General] ConsoleMode from "{0}" to "{1}" in the config. To switch back, set [Console.General] ConsoleMode = "classic". Restart MCC to apply the change.. + /// + internal static string cmd_tryout_tui_enabled { + get { + return ResourceManager.GetString("cmd.tryout.tui.enabled", resourceCulture); + } + } + /// /// Looks up a localized string similar to Display Health and Food saturation.. /// @@ -5534,6 +5579,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Tip: try TUI mode for a cleaner interface, mouse-friendly container actions, and a nicer layout. Run {0}feature tui§8 to switch [Console.General] ConsoleMode to "tui" for the next restart.. + /// + internal static string mcc_console_mode_tui_recommendation { + get { + return ResourceManager.GetString("mcc.console_mode_tui_recommendation", resourceCulture); + } + } + /// /// Looks up a localized string similar to To sign in, open {0} in your browser and enter the code: {1}. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 68202894..b028064d 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -1249,6 +1249,21 @@ Change EnableEmoji=false in the settings if the display is confusing. No active effects. + + try a recommended feature. + + + Available tryouts: + + + tui: set [Console.General] ConsoleMode = "tui" for the next restart. + + + [Console.General] ConsoleMode is already "tui" in the config. To switch back, set [Console.General] ConsoleMode = "classic". Restart MCC after changing it for the new mode to take effect. + + + Updated [Console.General] ConsoleMode from "{0}" to "{1}" in the config. To switch back, set [Console.General] ConsoleMode = "classic". Restart MCC to apply the change. + Display Health and Food saturation. @@ -1863,6 +1878,9 @@ You can use "/chunk status {0:0.0} {1:0.0} {2:0.0}" to check the chunk loading s Connecting to {0}... + + Tip: try TUI mode for a cleaner interface, mouse-friendly inventory actions, and a nicer layout. Run {0}tryout tui§8 to switch [Console.General] ConsoleMode to "tui" for the next restart. + To sign in, open {0} in your browser and enter the code: §e{1} @@ -2392,4 +2410,4 @@ see item details. Crafting - \ No newline at end of file + From b757215dbb2146b3948a9484c6837b95789560d5 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 01:33:59 +0800 Subject: [PATCH 259/484] Temporarily disable classic mode TUI recommendation Commented out the MaybePrintClassicModeTuiRecommendation function call to prevent its execution until the related issue is resolved. Reference to the issue is included for tracking purposes. --- MinecraftClient/Program.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 18d8ce88..946a4d85 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -193,7 +193,9 @@ namespace MinecraftClient if (!ProcessStartupState(startupState)) return; - MaybePrintClassicModeTuiRecommendation(); + // Wait for this issue to be fixed before enabling it: https://github.com/Consolonia/Consolonia/issues/602 + // MaybePrintClassicModeTuiRecommendation(); + RunStartupSequence(args); } From 157d90273b202ff490422e39fa374f5cefcb264e Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 01:57:21 +0800 Subject: [PATCH 260/484] Handle TUI startup failures with classic fallback --- MinecraftClient/Program.cs | 27 ++++++++++++++++--- .../Translations/Translations.Designer.cs | 27 +++++++++++++++++++ .../Resources/Translations/Translations.resx | 9 +++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 946a4d85..8c1e7644 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -177,9 +177,16 @@ namespace MinecraftClient if (!ConsoleIO.BasicIO && Config.Console.General.ConsoleMode == ConsoleModeType.tui) { ConsoleIO.Backend?.Shutdown(); - var tuiBackend = new Tui.TuiConsoleBackend(); - ConsoleIO.Backend = tuiBackend; - tuiBackend.RunTuiMainLoop(args, startupState); + try + { + var tuiBackend = new Tui.TuiConsoleBackend(); + ConsoleIO.Backend = tuiBackend; + tuiBackend.RunTuiMainLoop(args, startupState); + } + catch (Exception ex) + { + HandleTuiStartupFailure(ex); + } return; } @@ -199,6 +206,20 @@ namespace MinecraftClient RunStartupSequence(args); } + private static void HandleTuiStartupFailure(Exception exception) + { + Config.Console.General.ConsoleMode = ConsoleModeType.classic; + WriteBackSettings(enableBackup: false); + + ConsoleIO.Backend = new ClassicConsoleBackend(); + ConsoleIO.Backend.Init(); + + ConsoleIO.WriteLineFormatted("§c" + Translations.mcc_tui_startup_failed); + ConsoleIO.WriteLine(exception.ToString()); + ConsoleIO.WriteLineFormatted("§e" + Translations.mcc_report_issue); + ConsoleIO.WriteLineFormatted("§e" + Translations.mcc_tui_startup_fallback_classic); + } + /// /// Prints the application banner and processes the startup state collected before /// the console backend was ready. Called once from classic mode or from TUI after diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 242752e6..96419311 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -5587,6 +5587,33 @@ namespace MinecraftClient { return ResourceManager.GetString("mcc.console_mode_tui_recommendation", resourceCulture); } } + + /// + /// Looks up a localized string similar to MCC encountered a problem while starting TUI mode.. + /// + internal static string mcc_tui_startup_failed { + get { + return ResourceManager.GetString("mcc.tui_startup_failed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to As a fallback, MCC has automatically switched [Console.General] ConsoleMode to "classic". This will take effect after you restart MCC.. + /// + internal static string mcc_tui_startup_fallback_classic { + get { + return ResourceManager.GetString("mcc.tui_startup_fallback_classic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please report this issue to the MCC Team.. + /// + internal static string mcc_report_issue { + get { + return ResourceManager.GetString("mcc.report_issue", resourceCulture); + } + } /// /// Looks up a localized string similar to To sign in, open {0} in your browser and enter the code: {1}. diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index b028064d..c3ecd406 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -1881,6 +1881,15 @@ You can use "/chunk status {0:0.0} {1:0.0} {2:0.0}" to check the chunk loading s Tip: try TUI mode for a cleaner interface, mouse-friendly inventory actions, and a nicer layout. Run {0}tryout tui§8 to switch [Console.General] ConsoleMode to "tui" for the next restart. + + MCC encountered a problem while starting TUI mode. + + + As a fallback, MCC has automatically switched [Console.General] ConsoleMode to "classic". This will take effect after you restart MCC. + + + Please report this issue to the MCC Team. + To sign in, open {0} in your browser and enter the code: §e{1} From 6631180f8a1ef0b901b8554daf1fc4cf64f6cdb3 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 18:47:40 +0800 Subject: [PATCH 261/484] Minimap support --- .skills/mcc-version-adaptation/SKILL.md | 39 +- MinecraftClient/Commands/Minimap.cs | 256 ++ MinecraftClient/MinecraftClient.csproj | 2 + .../Protocol/Handlers/DataTypes.cs | 4 +- .../ConfigComments/ConfigComments.resx | 33 + .../Translations/Translations.Designer.cs | 153 + .../Resources/Translations/Translations.resx | 51 + MinecraftClient/Settings.cs | 47 + MinecraftClient/Tui/MainTuiView.cs | 125 +- MinecraftClient/Tui/MinimapBlockColors.json | 3552 +++++++++++++++++ MinecraftClient/Tui/MinimapColorMap.cs | 168 + MinecraftClient/Tui/MinimapControl.cs | 677 ++++ .../Tui/MinimapEntityCategories.json | 167 + .../Tui/MinimapEntityClassifier.cs | 178 + tools/README.md | 47 +- tools/gen_block_color_map.py | 268 ++ tools/gen_entity_category_map.py | 200 + 17 files changed, 5961 insertions(+), 6 deletions(-) create mode 100644 MinecraftClient/Commands/Minimap.cs create mode 100644 MinecraftClient/Tui/MinimapBlockColors.json create mode 100644 MinecraftClient/Tui/MinimapColorMap.cs create mode 100644 MinecraftClient/Tui/MinimapControl.cs create mode 100644 MinecraftClient/Tui/MinimapEntityCategories.json create mode 100644 MinecraftClient/Tui/MinimapEntityClassifier.cs create mode 100644 tools/gen_block_color_map.py create mode 100644 tools/gen_entity_category_map.py diff --git a/.skills/mcc-version-adaptation/SKILL.md b/.skills/mcc-version-adaptation/SKILL.md index ce21cf04..195b5592 100644 --- a/.skills/mcc-version-adaptation/SKILL.md +++ b/.skills/mcc-version-adaptation/SKILL.md @@ -215,7 +215,42 @@ The JSON maps block names (snake_case) → collision shape IDs → AABB coordina **Data source**: PrismarineJS `minecraft-data` repo, path: `data/pc//blockCollisionShapes.json`. Version availability can be checked via `data/dataPaths.json`. -## Step 9: Compile and Verify +## Step 9: Update Minimap Block Color Map + +Regenerate the block-to-MapColor mapping used by the TUI minimap. This maps each block's `Material` enum to the RGB color from Minecraft's official `MapColor` table. + +```bash +python3 $MCC_REPO/tools/gen_block_color_map.py $MCC_REPO/MinecraftOfficial/-decompiled +# e.g. python3 tools/gen_block_color_map.py MinecraftOfficial/26.1-rc-2-decompiled +``` + +Output: `MinecraftClient/Tui/MinimapBlockColors.json` (embedded as a resource via `.csproj`). + +The script parses `MapColor.java`, `DyeColor.java`, and `Blocks.java` from the decompiled source to extract each block's assigned map color. Blocks not matched to a known `Material` enum value are skipped. + +**When to update**: Whenever new blocks are added or existing blocks change their `mapColor()` assignment. If only items or entities changed, this step can be skipped. + +## Step 10: Update Minimap Entity Categories + +Regenerate the entity-to-MobCategory mapping used by the TUI minimap for classifying entities as hostile, passive, neutral, or non-living. + +```bash +python3 $MCC_REPO/tools/gen_entity_category_map.py $MCC_REPO/MinecraftOfficial/-decompiled +# e.g. python3 tools/gen_entity_category_map.py MinecraftOfficial/26.1-rc-2-decompiled +``` + +Output: `MinecraftClient/Tui/MinimapEntityCategories.json` (embedded as a resource via `.csproj`). + +The script parses `EntityType.java` to extract each entity's `MobCategory` assignment, then maps Minecraft's categories to MCC minimap categories: +- `MONSTER` -> hostile (with neutral overrides for conditionally hostile mobs like Enderman, Spider, Wolf) +- `CREATURE`/`AMBIENT`/`AXOLOTLS`/`WATER_*` -> passive +- `MISC` -> non_living (with passive overrides for Villager, WanderingTrader, ZombieHorse) + +The script maintains manual override lists for "neutral" mobs (attack only when provoked) since Minecraft has no machine-readable flag for this behavior. Review and update the `NEUTRAL_OVERRIDES` and `PASSIVE_OVERRIDES` sets in the script when new conditionally-hostile or misclassified mobs are added. + +**When to update**: Whenever new entity types are added. If only blocks or items changed, this step can be skipped. + +## Step 11: Compile and Verify ```bash dotnet build $MCC_REPO/MinecraftClient.sln -c Release @@ -274,3 +309,5 @@ All scripts are in `$MCC_REPO/tools/`. See `tools/README.md` for detailed usage. | `gen_entity_palette.py` | Generate EntityPalette C# | registries.json | | `gen_entity_metadata_palette.py` | Generate EntityMetadataPalette C# | Decompiled source | | `gen_block_shapes.py` | Download & compact block collision shapes | PrismarineJS minecraft-data | +| `gen_block_color_map.py` | Generate minimap block color JSON | Decompiled source (MapColor/DyeColor/Blocks) | +| `gen_entity_category_map.py` | Generate minimap entity category JSON | Decompiled source (EntityType.java) | diff --git a/MinecraftClient/Commands/Minimap.cs b/MinecraftClient/Commands/Minimap.cs new file mode 100644 index 00000000..897c88ae --- /dev/null +++ b/MinecraftClient/Commands/Minimap.cs @@ -0,0 +1,256 @@ +using System; +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; +using MinecraftClient.Tui; +using Avalonia.Threading; +using static MinecraftClient.CommandHandler.CmdResult; + +namespace MinecraftClient.Commands +{ + class Minimap : Command + { + public override string CmdName => "minimap"; + public override string CmdUsage => "minimap [on|off] | minimap zoom [in|out|<1-16>] | minimap names [players|hostile|neutral|passive] [on|off] | minimap names [all_on|all_off] | minimap position [top_left|top_right|center|bottom_left|bottom_right]"; + public override string CmdDesc => Translations.cmd_minimap_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source, string.Empty)) + ) + ); + + dispatcher.Register(l => l.Literal(CmdName) + .Executes(r => DoToggle(r.Source)) + .Then(l => l.Literal("on") + .Executes(r => DoOn(r.Source))) + .Then(l => l.Literal("off") + .Executes(r => DoOff(r.Source))) + .Then(l => l.Literal("zoom") + .Executes(r => DoZoomInfo(r.Source)) + .Then(l => l.Literal("in") + .Executes(r => DoZoomIn(r.Source))) + .Then(l => l.Literal("out") + .Executes(r => DoZoomOut(r.Source))) + .Then(l => l.Argument("level", Arguments.Integer(MinimapControl.MinZoom, MinimapControl.MaxZoom)) + .Executes(r => DoZoomSet(r.Source, Arguments.GetInteger(r, "level"))))) + .Then(l => l.Literal("names") + .Executes(r => DoNamesInfo(r.Source)) + .Then(l => l.Literal("all_on") + .Executes(r => DoNamesAll(r.Source, true))) + .Then(l => l.Literal("all_off") + .Executes(r => DoNamesAll(r.Source, false))) + .Then(l => l.Literal("players") + .Executes(r => DoNamesCatInfo(r.Source, MobCategory.Player)) + .Then(l => l.Literal("on") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Player, true))) + .Then(l => l.Literal("off") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Player, false)))) + .Then(l => l.Literal("hostile") + .Executes(r => DoNamesCatInfo(r.Source, MobCategory.Hostile)) + .Then(l => l.Literal("on") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Hostile, true))) + .Then(l => l.Literal("off") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Hostile, false)))) + .Then(l => l.Literal("neutral") + .Executes(r => DoNamesCatInfo(r.Source, MobCategory.Neutral)) + .Then(l => l.Literal("on") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Neutral, true))) + .Then(l => l.Literal("off") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Neutral, false)))) + .Then(l => l.Literal("passive") + .Executes(r => DoNamesCatInfo(r.Source, MobCategory.Passive)) + .Then(l => l.Literal("on") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Passive, true))) + .Then(l => l.Literal("off") + .Executes(r => DoNamesCatSet(r.Source, MobCategory.Passive, false))))) + .Then(l => l.Literal("position") + .Executes(r => DoPositionInfo(r.Source)) + .Then(l => l.Literal("top_left") + .Executes(r => DoPositionSet(r.Source, MinimapPosition.top_left))) + .Then(l => l.Literal("top_right") + .Executes(r => DoPositionSet(r.Source, MinimapPosition.top_right))) + .Then(l => l.Literal("center") + .Executes(r => DoPositionSet(r.Source, MinimapPosition.center))) + .Then(l => l.Literal("bottom_left") + .Executes(r => DoPositionSet(r.Source, MinimapPosition.bottom_left))) + .Then(l => l.Literal("bottom_right") + .Executes(r => DoPositionSet(r.Source, MinimapPosition.bottom_right)))) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source, string.Empty)) + .Redirect(dispatcher.GetRoot().GetChild("help")?.GetChild(CmdName))) + ); + } + + private int GetUsage(CmdResult r, string _) => + r.SetAndReturn(GetCmdDescTranslated()); + + private static MainTuiView? GetTuiView(CmdResult r) + { + if (ConsoleIO.Backend is not TuiConsoleBackend) + { + r.SetAndReturn(Status.Fail, Translations.cmd_minimap_tui_only); + return null; + } + return TuiConsoleBackend.Instance?.GetView(); + } + + private static int DoToggle(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + bool wasVisible = view.IsMinimapVisible; + Dispatcher.UIThread.Post(() => view.ToggleMinimap()); + string msg = wasVisible + ? Translations.cmd_minimap_disabled + : Translations.cmd_minimap_enabled; + return r.SetAndReturn(Status.Done, msg); + } + + private static int DoOn(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => view.ShowMinimap()); + return r.SetAndReturn(Status.Done, Translations.cmd_minimap_enabled); + } + + private static int DoOff(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => view.HideMinimap()); + return r.SetAndReturn(Status.Done, Translations.cmd_minimap_disabled); + } + + private static int DoZoomInfo(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + int current = view.GetMinimapZoom(); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_zoom_current, current, MinimapControl.MaxZoom)); + } + + private static int DoZoomIn(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + int newLevel = Math.Max(view.GetMinimapZoom() - 1, MinimapControl.MinZoom); + Dispatcher.UIThread.Post(() => view.SetMinimapZoom(newLevel)); + return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_minimap_zoom_set, newLevel)); + } + + private static int DoZoomOut(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + int newLevel = Math.Min(view.GetMinimapZoom() + 1, MinimapControl.MaxZoom); + Dispatcher.UIThread.Post(() => view.SetMinimapZoom(newLevel)); + return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_minimap_zoom_set, newLevel)); + } + + private static int DoZoomSet(CmdResult r, int level) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => view.SetMinimapZoom(level)); + return r.SetAndReturn(Status.Done, string.Format(Translations.cmd_minimap_zoom_set, level)); + } + + private static int DoNamesInfo(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + var nc = view.GetMinimapNameConfig(); + string status = string.Format(Translations.cmd_minimap_names_status, + BoolStr(nc.Players), BoolStr(nc.Hostile), BoolStr(nc.Neutral), BoolStr(nc.Passive)); + return r.SetAndReturn(Status.Done, status); + } + + private static int DoNamesAll(CmdResult r, bool on) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => + { + view.GetMinimapNameConfig().SetAll(on); + view.SyncMinimapNameConfig(); + }); + string msg = on ? Translations.cmd_minimap_names_all_on : Translations.cmd_minimap_names_all_off; + return r.SetAndReturn(Status.Done, msg); + } + + private static int DoNamesCatInfo(CmdResult r, MobCategory cat) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + var nc = view.GetMinimapNameConfig(); + bool val = cat switch + { + MobCategory.Player => nc.Players, + MobCategory.Hostile => nc.Hostile, + MobCategory.Neutral => nc.Neutral, + MobCategory.Passive => nc.Passive, + _ => false, + }; + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_names_cat, cat, BoolStr(val))); + } + + private static int DoNamesCatSet(CmdResult r, MobCategory cat, bool on) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => + { + var nc = view.GetMinimapNameConfig(); + switch (cat) + { + case MobCategory.Player: nc.Players = on; break; + case MobCategory.Hostile: nc.Hostile = on; break; + case MobCategory.Neutral: nc.Neutral = on; break; + case MobCategory.Passive: nc.Passive = on; break; + } + view.SyncMinimapNameConfig(); + }); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_names_cat_set, cat, BoolStr(on))); + } + + private static int DoPositionInfo(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + var pos = view.GetMinimapPosition(); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_position_current, pos)); + } + + private static int DoPositionSet(CmdResult r, MinimapPosition pos) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => view.SetMinimapPosition(pos)); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_position_set, pos)); + } + + private static string BoolStr(bool v) => v ? "ON" : "OFF"; + } +} diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 5df50933..372d153a 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -20,6 +20,8 @@ + + diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 78456c2d..669ba5b3 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -664,8 +664,10 @@ namespace MinecraftClient.Protocol.Handlers } } - return new Entity(entityID, entityType, new Location(entityX, entityY, entityZ), entityYaw, entityPitch, + var entity = new Entity(entityID, entityType, new Location(entityX, entityY, entityZ), entityYaw, entityPitch, data); + entity.UUID = entityUUID; + return entity; } /// diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index 6d91740b..d4b82e42 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -933,6 +933,39 @@ Note: This does NOT require a Bot Token, only an Application ID. Discord must be Set to false to opt-out of Sentry error logging. + + Settings for the TUI minimap overlay that shows terrain and entities. + + + Whether the minimap is visible on startup in TUI mode. + + + Blocks per pixel, 1-16. 1 = closest (1:1), 16 = farthest (16 blocks per pixel). + + + Map width in pixels (characters). Range 10-120, default 40. + + + Map height in pixels (must be even, uses half-block chars). Range 4-80, default 40. + + + Minimap position: "top_left", "top_right", "center", "bottom_left", or "bottom_right". + + + Show player names on the minimap. + + + Show hostile mob names on the minimap. + + + Show neutral mob names on the minimap. + + + Show passive mob names on the minimap. + + + Minimap refresh interval in milliseconds (200-5000, default 1000). + Yggdrasil authlib multi-user selection. diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 96419311..071bee44 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -6880,5 +6880,158 @@ namespace MinecraftClient { return ResourceManager.GetString("tui.crafting.grid", resourceCulture); } } + + /// + /// Looks up a localized string similar to Toggle the TUI minimap overlay, or adjust its zoom level.. + /// + internal static string cmd_minimap_desc { + get { + return ResourceManager.GetString("cmd.minimap.desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Minimap enabled.. + /// + internal static string cmd_minimap_enabled { + get { + return ResourceManager.GetString("cmd.minimap.enabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Minimap disabled.. + /// + internal static string cmd_minimap_disabled { + get { + return ResourceManager.GetString("cmd.minimap.disabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Minimap zoom set to {0}:1 (blocks per pixel).. + /// + internal static string cmd_minimap_zoom_set { + get { + return ResourceManager.GetString("cmd.minimap.zoom_set", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current minimap zoom: {0}:1 blocks/px (range 1-{1}).. + /// + internal static string cmd_minimap_zoom_current { + get { + return ResourceManager.GetString("cmd.minimap.zoom_current", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The minimap command is only available in TUI mode.. + /// + internal static string cmd_minimap_tui_only { + get { + return ResourceManager.GetString("cmd.minimap.tui_only", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hostile. + /// + internal static string tui_minimap_legend_hostile { + get { + return ResourceManager.GetString("tui.minimap.legend.hostile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Passive. + /// + internal static string tui_minimap_legend_passive { + get { + return ResourceManager.GetString("tui.minimap.legend.passive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Neutral. + /// + internal static string tui_minimap_legend_neutral { + get { + return ResourceManager.GetString("tui.minimap.legend.neutral", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Player. + /// + internal static string tui_minimap_legend_player { + get { + return ResourceManager.GetString("tui.minimap.legend.player", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Name display -- Players: {0}, Hostile: {1}, Neutral: {2}, Passive: {3}. + /// + internal static string cmd_minimap_names_status { + get { + return ResourceManager.GetString("cmd.minimap.names_status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All entity name labels enabled.. + /// + internal static string cmd_minimap_names_all_on { + get { + return ResourceManager.GetString("cmd.minimap.names_all_on", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All entity name labels disabled.. + /// + internal static string cmd_minimap_names_all_off { + get { + return ResourceManager.GetString("cmd.minimap.names_all_off", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} name display: {1}. + /// + internal static string cmd_minimap_names_cat { + get { + return ResourceManager.GetString("cmd.minimap.names_cat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} name display set to {1}.. + /// + internal static string cmd_minimap_names_cat_set { + get { + return ResourceManager.GetString("cmd.minimap.names_cat_set", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current minimap position: {0}. + /// + internal static string cmd_minimap_position_current { + get { + return ResourceManager.GetString("cmd.minimap.position_current", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Minimap position set to: {0}. + /// + internal static string cmd_minimap_position_set { + get { + return ResourceManager.GetString("cmd.minimap.position_set", resourceCulture); + } + } } } diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index c3ecd406..ad782375 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2419,4 +2419,55 @@ see item details. Crafting + + Toggle the TUI minimap overlay, or adjust its zoom level. + + + Minimap enabled. + + + Minimap disabled. + + + Minimap zoom set to {0}:1 (blocks per pixel). + + + Current minimap zoom: {0}:1 blocks/px (range 1-{1}). + + + The minimap command is only available in TUI mode. + + + Hostile + + + Passive + + + Neutral + + + Player + + + Name display -- Players: {0}, Hostile: {1}, Neutral: {2}, Passive: {3} + + + All entity name labels enabled. + + + All entity name labels disabled. + + + {0} name display: {1} + + + {0} name display set to {1}. + + + Current minimap position: {0} + + + Minimap position set to: {0} + diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index e77514da..299fe990 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -1108,6 +1108,9 @@ namespace MinecraftClient [TomlPrecedingComment("$Console.CommandSuggestion$")] public CommandSuggestionConfig CommandSuggestion = new(); + [TomlPrecedingComment("$Console.Minimap$")] + public MinimapConfig Minimap = new(); + public void OnSettingUpdate() { var backend = ConsoleIO.Backend; @@ -1246,6 +1249,50 @@ namespace MinecraftClient public enum ConsoleModeType { classic, tui }; public enum ConsoleColorModeType { disable, legacy_4bit, vt100_4bit, vt100_8bit, vt100_24bit }; + + [TomlDoNotInlineObject] + public class MinimapConfig + { + [TomlInlineComment("$Console.Minimap.Enabled$")] + public bool Enabled = false; + + [TomlInlineComment("$Console.Minimap.Zoom$")] + public int Zoom = Tui.MinimapControl.DefaultZoom; + + [TomlInlineComment("$Console.Minimap.Width$")] + public int Width = Tui.MinimapControl.DefaultWidth; + + [TomlInlineComment("$Console.Minimap.Height$")] + public int Height = Tui.MinimapControl.DefaultHeight; + + [TomlInlineComment("$Console.Minimap.Position$")] + public Tui.MinimapPosition Position = Tui.MinimapPosition.top_right; + + [TomlInlineComment("$Console.Minimap.ShowPlayerNames$")] + public bool ShowPlayerNames = false; + + [TomlInlineComment("$Console.Minimap.ShowHostileNames$")] + public bool ShowHostileNames = false; + + [TomlInlineComment("$Console.Minimap.ShowNeutralNames$")] + public bool ShowNeutralNames = false; + + [TomlInlineComment("$Console.Minimap.ShowPassiveNames$")] + public bool ShowPassiveNames = false; + + [TomlInlineComment("$Console.Minimap.RefreshInterval$")] + public int RefreshInterval = Tui.MinimapControl.DefaultRefreshMs; + + public void OnSettingUpdate() + { + Zoom = Math.Clamp(Zoom, Tui.MinimapControl.MinZoom, Tui.MinimapControl.MaxZoom); + Width = Math.Clamp(Width, 10, 120); + Height = Math.Clamp(Height, 4, 80); + if (Height % 2 != 0) Height++; + RefreshInterval = Math.Clamp(RefreshInterval, + Tui.MinimapControl.MinRefreshMs, Tui.MinimapControl.MaxRefreshMs); + } + } } } diff --git a/MinecraftClient/Tui/MainTuiView.cs b/MinecraftClient/Tui/MainTuiView.cs index c2d51220..1cde95e4 100644 --- a/MinecraftClient/Tui/MainTuiView.cs +++ b/MinecraftClient/Tui/MainTuiView.cs @@ -41,6 +41,10 @@ namespace MinecraftClient.Tui private long _lastLogClickTicks; private const int DoubleClickMsec = 500; + private readonly Border _minimapBorder; + private readonly MinimapControl _minimapControl; + private volatile bool _minimapVisible; + private readonly Border _suggestionBorder; private readonly StackPanel _suggestionPanel; private CommandSuggestion[] _suggestions = Array.Empty(); @@ -150,6 +154,29 @@ namespace MinecraftClient.Tui Margin = new Thickness(0, 0, 0, 1), }; + var mmCfg = Settings.Config.Console.Minimap; + mmCfg.OnSettingUpdate(); + _minimapControl = new MinimapControl(mmCfg.Width, mmCfg.Height); + _minimapControl.BlocksPerPixel = mmCfg.Zoom; + _minimapControl.RefreshIntervalMs = mmCfg.RefreshInterval; + _minimapControl.NameConfig.Players = mmCfg.ShowPlayerNames; + _minimapControl.NameConfig.Hostile = mmCfg.ShowHostileNames; + _minimapControl.NameConfig.Neutral = mmCfg.ShowNeutralNames; + _minimapControl.NameConfig.Passive = mmCfg.ShowPassiveNames; + + var (hAlign, vAlign, margin) = GetMinimapAlignment(mmCfg.Position); + _minimapBorder = new Border + { + Background = new SolidColorBrush(Color.FromArgb(220, 15, 15, 15)), + BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80)), + BorderThickness = new Thickness(1), + Child = _minimapControl, + IsVisible = false, + HorizontalAlignment = hAlign, + VerticalAlignment = vAlign, + Margin = margin, + }; + _mainContent = new DockPanel { Background = Brushes.Black, @@ -164,11 +191,18 @@ namespace MinecraftClient.Tui _rootPanel = new Panel { Background = Brushes.Black, - Children = { _mainContent, _notificationBorder, _suggestionBorder } + Children = { _mainContent, _minimapBorder, _notificationBorder, _suggestionBorder } }; Content = _rootPanel; + if (mmCfg.Enabled) + { + _minimapVisible = true; + _minimapBorder.IsVisible = true; + _minimapControl.Start(); + } + StartStatusBarTimer(); } @@ -986,6 +1020,95 @@ namespace MinecraftClient.Tui #endregion + #region Minimap + + public void ShowMinimap() + { + if (_minimapVisible) return; + _minimapVisible = true; + _minimapBorder.IsVisible = true; + _minimapControl.Start(); + Settings.Config.Console.Minimap.Enabled = true; + } + + public void HideMinimap() + { + if (!_minimapVisible) return; + _minimapVisible = false; + _minimapControl.Stop(); + _minimapBorder.IsVisible = false; + Settings.Config.Console.Minimap.Enabled = false; + } + + public void ToggleMinimap() + { + if (_minimapVisible) + HideMinimap(); + else + ShowMinimap(); + } + + public bool IsMinimapVisible => _minimapVisible; + + public void SetMinimapZoom(int level) + { + _minimapControl.BlocksPerPixel = level; + Settings.Config.Console.Minimap.Zoom = level; + } + + public int GetMinimapZoom() => _minimapControl.BlocksPerPixel; + + public NameDisplayConfig GetMinimapNameConfig() => _minimapControl.NameConfig; + + public void SyncMinimapNameConfig() + { + var nc = _minimapControl.NameConfig; + var cfg = Settings.Config.Console.Minimap; + cfg.ShowPlayerNames = nc.Players; + cfg.ShowHostileNames = nc.Hostile; + cfg.ShowNeutralNames = nc.Neutral; + cfg.ShowPassiveNames = nc.Passive; + } + + public void ResizeMinimap(int width, int height) + { + _minimapControl.Resize(width, height); + Settings.Config.Console.Minimap.Width = width; + Settings.Config.Console.Minimap.Height = height; + } + + public void SetMinimapPosition(MinimapPosition pos) + { + var (hAlign, vAlign, margin) = GetMinimapAlignment(pos); + _minimapBorder.HorizontalAlignment = hAlign; + _minimapBorder.VerticalAlignment = vAlign; + _minimapBorder.Margin = margin; + Settings.Config.Console.Minimap.Position = pos; + } + + public MinimapPosition GetMinimapPosition() => Settings.Config.Console.Minimap.Position; + + private static (HorizontalAlignment h, VerticalAlignment v, Thickness margin) GetMinimapAlignment(MinimapPosition pos) => pos switch + { + MinimapPosition.top_left => (HorizontalAlignment.Left, VerticalAlignment.Top, new Thickness(1, 1, 0, 0)), + MinimapPosition.top_right => (HorizontalAlignment.Right, VerticalAlignment.Top, new Thickness(0, 1, 1, 0)), + MinimapPosition.center => (HorizontalAlignment.Center, VerticalAlignment.Center, new Thickness(0)), + MinimapPosition.bottom_left => (HorizontalAlignment.Left, VerticalAlignment.Bottom, new Thickness(1, 0, 0, 2)), + MinimapPosition.bottom_right => (HorizontalAlignment.Right, VerticalAlignment.Bottom, new Thickness(0, 0, 1, 2)), + _ => (HorizontalAlignment.Right, VerticalAlignment.Top, new Thickness(0, 1, 1, 0)), + }; + + public void ApplyMinimapConfig() + { + var cfg = Settings.Config.Console.Minimap; + if (cfg.Enabled && !_minimapVisible) + ShowMinimap(); + else if (!cfg.Enabled && _minimapVisible) + HideMinimap(); + } + + #endregion + #region Overlay public void ShowOverlay(Control content, Action? onClose = null) diff --git a/MinecraftClient/Tui/MinimapBlockColors.json b/MinecraftClient/Tui/MinimapBlockColors.json new file mode 100644 index 00000000..af7d726c --- /dev/null +++ b/MinecraftClient/Tui/MinimapBlockColors.json @@ -0,0 +1,3552 @@ +{ + "version": "26.1-rc-2", + "colors": { + "AcaciaDoor": [ + 216, + 127, + 51 + ], + "AcaciaFence": [ + 216, + 127, + 51 + ], + "AcaciaFenceGate": [ + 216, + 127, + 51 + ], + "AcaciaHangingSign": [ + 216, + 127, + 51 + ], + "AcaciaPlanks": [ + 216, + 127, + 51 + ], + "AcaciaPressurePlate": [ + 216, + 127, + 51 + ], + "AcaciaSapling": [ + 0, + 124, + 0 + ], + "AcaciaShelf": [ + 216, + 127, + 51 + ], + "AcaciaSign": [ + 216, + 127, + 51 + ], + "AcaciaSlab": [ + 216, + 127, + 51 + ], + "AcaciaTrapdoor": [ + 216, + 127, + 51 + ], + "AcaciaWallHangingSign": [ + 216, + 127, + 51 + ], + "AcaciaWallSign": [ + 216, + 127, + 51 + ], + "AcaciaWood": [ + 76, + 76, + 76 + ], + "Allium": [ + 0, + 124, + 0 + ], + "AmethystBlock": [ + 127, + 63, + 178 + ], + "AmethystCluster": [ + 127, + 63, + 178 + ], + "AncientDebris": [ + 25, + 25, + 25 + ], + "Andesite": [ + 112, + 112, + 112 + ], + "Anvil": [ + 167, + 167, + 167 + ], + "AttachedMelonStem": [ + 0, + 124, + 0 + ], + "AttachedPumpkinStem": [ + 0, + 124, + 0 + ], + "Azalea": [ + 0, + 124, + 0 + ], + "AzureBluet": [ + 0, + 124, + 0 + ], + "Bamboo": [ + 0, + 124, + 0 + ], + "BambooDoor": [ + 229, + 229, + 51 + ], + "BambooFence": [ + 229, + 229, + 51 + ], + "BambooFenceGate": [ + 229, + 229, + 51 + ], + "BambooHangingSign": [ + 229, + 229, + 51 + ], + "BambooMosaic": [ + 229, + 229, + 51 + ], + "BambooMosaicSlab": [ + 229, + 229, + 51 + ], + "BambooPlanks": [ + 229, + 229, + 51 + ], + "BambooPressurePlate": [ + 229, + 229, + 51 + ], + "BambooSapling": [ + 143, + 119, + 72 + ], + "BambooShelf": [ + 229, + 229, + 51 + ], + "BambooSign": [ + 229, + 229, + 51 + ], + "BambooSlab": [ + 229, + 229, + 51 + ], + "BambooTrapdoor": [ + 229, + 229, + 51 + ], + "BambooWallHangingSign": [ + 229, + 229, + 51 + ], + "BambooWallSign": [ + 229, + 229, + 51 + ], + "Barrel": [ + 143, + 119, + 72 + ], + "Barrier": [ + 0, + 0, + 0 + ], + "Basalt": [ + 25, + 25, + 25 + ], + "Beacon": [ + 92, + 219, + 213 + ], + "Bedrock": [ + 112, + 112, + 112 + ], + "BeeNest": [ + 229, + 229, + 51 + ], + "Beehive": [ + 143, + 119, + 72 + ], + "Beetroots": [ + 0, + 124, + 0 + ], + "Bell": [ + 250, + 238, + 77 + ], + "BigDripleaf": [ + 0, + 124, + 0 + ], + "BigDripleafStem": [ + 0, + 124, + 0 + ], + "BirchDoor": [ + 247, + 233, + 163 + ], + "BirchFence": [ + 247, + 233, + 163 + ], + "BirchFenceGate": [ + 247, + 233, + 163 + ], + "BirchHangingSign": [ + 247, + 233, + 163 + ], + "BirchPlanks": [ + 247, + 233, + 163 + ], + "BirchPressurePlate": [ + 247, + 233, + 163 + ], + "BirchSapling": [ + 0, + 124, + 0 + ], + "BirchShelf": [ + 247, + 233, + 163 + ], + "BirchSign": [ + 247, + 233, + 163 + ], + "BirchSlab": [ + 247, + 233, + 163 + ], + "BirchTrapdoor": [ + 247, + 233, + 163 + ], + "BirchWallHangingSign": [ + 247, + 233, + 163 + ], + "BirchWallSign": [ + 247, + 233, + 163 + ], + "BirchWood": [ + 247, + 233, + 163 + ], + "BlackBanner": [ + 143, + 119, + 72 + ], + "BlackCarpet": [ + 25, + 25, + 25 + ], + "BlackConcrete": [ + 25, + 25, + 25 + ], + "BlackConcretePowder": [ + 25, + 25, + 25 + ], + "BlackGlazedTerracotta": [ + 25, + 25, + 25 + ], + "BlackTerracotta": [ + 37, + 22, + 16 + ], + "BlackWallBanner": [ + 143, + 119, + 72 + ], + "BlackWool": [ + 25, + 25, + 25 + ], + "Blackstone": [ + 25, + 25, + 25 + ], + "BlastFurnace": [ + 112, + 112, + 112 + ], + "BlueBanner": [ + 143, + 119, + 72 + ], + "BlueCarpet": [ + 51, + 76, + 178 + ], + "BlueConcrete": [ + 51, + 76, + 178 + ], + "BlueConcretePowder": [ + 51, + 76, + 178 + ], + "BlueGlazedTerracotta": [ + 51, + 76, + 178 + ], + "BlueIce": [ + 160, + 160, + 255 + ], + "BlueOrchid": [ + 0, + 124, + 0 + ], + "BlueTerracotta": [ + 76, + 62, + 92 + ], + "BlueWallBanner": [ + 143, + 119, + 72 + ], + "BlueWool": [ + 51, + 76, + 178 + ], + "BoneBlock": [ + 247, + 233, + 163 + ], + "Bookshelf": [ + 143, + 119, + 72 + ], + "BrainCoral": [ + 242, + 127, + 165 + ], + "BrainCoralBlock": [ + 242, + 127, + 165 + ], + "BrainCoralFan": [ + 242, + 127, + 165 + ], + "BrainCoralWallFan": [ + 242, + 127, + 165 + ], + "BrewingStand": [ + 167, + 167, + 167 + ], + "BrickSlab": [ + 153, + 51, + 51 + ], + "Bricks": [ + 153, + 51, + 51 + ], + "BrownBanner": [ + 143, + 119, + 72 + ], + "BrownCarpet": [ + 102, + 76, + 51 + ], + "BrownConcrete": [ + 102, + 76, + 51 + ], + "BrownConcretePowder": [ + 102, + 76, + 51 + ], + "BrownGlazedTerracotta": [ + 102, + 76, + 51 + ], + "BrownMushroom": [ + 102, + 76, + 51 + ], + "BrownMushroomBlock": [ + 151, + 109, + 77 + ], + "BrownTerracotta": [ + 76, + 50, + 35 + ], + "BrownWallBanner": [ + 143, + 119, + 72 + ], + "BrownWool": [ + 102, + 76, + 51 + ], + "BubbleColumn": [ + 64, + 64, + 255 + ], + "BubbleCoral": [ + 127, + 63, + 178 + ], + "BubbleCoralBlock": [ + 127, + 63, + 178 + ], + "BubbleCoralFan": [ + 127, + 63, + 178 + ], + "BubbleCoralWallFan": [ + 127, + 63, + 178 + ], + "BuddingAmethyst": [ + 127, + 63, + 178 + ], + "Bush": [ + 0, + 124, + 0 + ], + "Cactus": [ + 0, + 124, + 0 + ], + "CactusFlower": [ + 242, + 127, + 165 + ], + "Calcite": [ + 209, + 177, + 161 + ], + "Campfire": [ + 129, + 86, + 49 + ], + "Carrots": [ + 0, + 124, + 0 + ], + "CartographyTable": [ + 143, + 119, + 72 + ], + "CarvedPumpkin": [ + 216, + 127, + 51 + ], + "Cauldron": [ + 112, + 112, + 112 + ], + "CaveVines": [ + 0, + 124, + 0 + ], + "CaveVinesPlant": [ + 0, + 124, + 0 + ], + "ChainCommandBlock": [ + 102, + 127, + 51 + ], + "CherryDoor": [ + 209, + 177, + 161 + ], + "CherryFence": [ + 209, + 177, + 161 + ], + "CherryFenceGate": [ + 209, + 177, + 161 + ], + "CherryHangingSign": [ + 160, + 77, + 78 + ], + "CherryLeaves": [ + 242, + 127, + 165 + ], + "CherryPlanks": [ + 209, + 177, + 161 + ], + "CherryPressurePlate": [ + 209, + 177, + 161 + ], + "CherrySapling": [ + 242, + 127, + 165 + ], + "CherryShelf": [ + 209, + 177, + 161 + ], + "CherrySign": [ + 209, + 177, + 161 + ], + "CherrySlab": [ + 209, + 177, + 161 + ], + "CherryTrapdoor": [ + 209, + 177, + 161 + ], + "CherryWallHangingSign": [ + 160, + 77, + 78 + ], + "CherryWood": [ + 57, + 41, + 35 + ], + "Chest": [ + 143, + 119, + 72 + ], + "ChippedAnvil": [ + 167, + 167, + 167 + ], + "ChiseledBookshelf": [ + 143, + 119, + 72 + ], + "ChiseledNetherBricks": [ + 112, + 2, + 0 + ], + "ChiseledQuartzBlock": [ + 255, + 252, + 245 + ], + "ChiseledRedSandstone": [ + 216, + 127, + 51 + ], + "ChiseledResinBricks": [ + 159, + 82, + 36 + ], + "ChiseledSandstone": [ + 247, + 233, + 163 + ], + "ChiseledStoneBricks": [ + 112, + 112, + 112 + ], + "ChorusFlower": [ + 127, + 63, + 178 + ], + "ChorusPlant": [ + 127, + 63, + 178 + ], + "Clay": [ + 164, + 168, + 184 + ], + "ClosedEyeblossom": [ + 167, + 167, + 167 + ], + "CoalBlock": [ + 25, + 25, + 25 + ], + "CoalOre": [ + 112, + 112, + 112 + ], + "CoarseDirt": [ + 151, + 109, + 77 + ], + "Cobblestone": [ + 112, + 112, + 112 + ], + "CobblestoneSlab": [ + 112, + 112, + 112 + ], + "Cobweb": [ + 199, + 199, + 199 + ], + "Cocoa": [ + 0, + 124, + 0 + ], + "CommandBlock": [ + 102, + 76, + 51 + ], + "Composter": [ + 143, + 119, + 72 + ], + "Conduit": [ + 92, + 219, + 213 + ], + "CopperBlock": [ + 216, + 127, + 51 + ], + "CopperBulb": [ + 216, + 127, + 51 + ], + "CopperChest": [ + 216, + 127, + 51 + ], + "CopperDoor": [ + 216, + 127, + 51 + ], + "CopperGolemStatue": [ + 216, + 127, + 51 + ], + "CopperGrate": [ + 216, + 127, + 51 + ], + "CopperTrapdoor": [ + 216, + 127, + 51 + ], + "Cornflower": [ + 0, + 124, + 0 + ], + "CrackedNetherBricks": [ + 112, + 2, + 0 + ], + "CrackedStoneBricks": [ + 112, + 112, + 112 + ], + "Crafter": [ + 112, + 112, + 112 + ], + "CraftingTable": [ + 143, + 119, + 72 + ], + "CreakingHeart": [ + 216, + 127, + 51 + ], + "CrimsonDoor": [ + 148, + 63, + 97 + ], + "CrimsonFence": [ + 148, + 63, + 97 + ], + "CrimsonFenceGate": [ + 148, + 63, + 97 + ], + "CrimsonFungus": [ + 112, + 2, + 0 + ], + "CrimsonHangingSign": [ + 148, + 63, + 97 + ], + "CrimsonHyphae": [ + 92, + 25, + 29 + ], + "CrimsonNylium": [ + 189, + 48, + 49 + ], + "CrimsonPlanks": [ + 148, + 63, + 97 + ], + "CrimsonPressurePlate": [ + 148, + 63, + 97 + ], + "CrimsonRoots": [ + 112, + 2, + 0 + ], + "CrimsonShelf": [ + 148, + 63, + 97 + ], + "CrimsonSign": [ + 148, + 63, + 97 + ], + "CrimsonSlab": [ + 148, + 63, + 97 + ], + "CrimsonTrapdoor": [ + 148, + 63, + 97 + ], + "CrimsonWallHangingSign": [ + 148, + 63, + 97 + ], + "CrimsonWallSign": [ + 148, + 63, + 97 + ], + "CryingObsidian": [ + 25, + 25, + 25 + ], + "CutRedSandstone": [ + 216, + 127, + 51 + ], + "CutRedSandstoneSlab": [ + 216, + 127, + 51 + ], + "CutSandstone": [ + 247, + 233, + 163 + ], + "CutSandstoneSlab": [ + 247, + 233, + 163 + ], + "CyanBanner": [ + 143, + 119, + 72 + ], + "CyanCarpet": [ + 76, + 127, + 153 + ], + "CyanConcrete": [ + 76, + 127, + 153 + ], + "CyanConcretePowder": [ + 76, + 127, + 153 + ], + "CyanGlazedTerracotta": [ + 76, + 127, + 153 + ], + "CyanTerracotta": [ + 87, + 92, + 92 + ], + "CyanWallBanner": [ + 143, + 119, + 72 + ], + "CyanWool": [ + 76, + 127, + 153 + ], + "DamagedAnvil": [ + 167, + 167, + 167 + ], + "Dandelion": [ + 0, + 124, + 0 + ], + "DarkOakDoor": [ + 102, + 76, + 51 + ], + "DarkOakFence": [ + 102, + 76, + 51 + ], + "DarkOakFenceGate": [ + 102, + 76, + 51 + ], + "DarkOakPlanks": [ + 102, + 76, + 51 + ], + "DarkOakPressurePlate": [ + 102, + 76, + 51 + ], + "DarkOakSapling": [ + 0, + 124, + 0 + ], + "DarkOakSlab": [ + 102, + 76, + 51 + ], + "DarkOakTrapdoor": [ + 102, + 76, + 51 + ], + "DarkOakWood": [ + 102, + 76, + 51 + ], + "DarkPrismarine": [ + 92, + 219, + 213 + ], + "DarkPrismarineSlab": [ + 92, + 219, + 213 + ], + "DaylightDetector": [ + 143, + 119, + 72 + ], + "DeadBrainCoral": [ + 76, + 76, + 76 + ], + "DeadBrainCoralBlock": [ + 76, + 76, + 76 + ], + "DeadBrainCoralFan": [ + 76, + 76, + 76 + ], + "DeadBrainCoralWallFan": [ + 76, + 76, + 76 + ], + "DeadBubbleCoral": [ + 76, + 76, + 76 + ], + "DeadBubbleCoralBlock": [ + 76, + 76, + 76 + ], + "DeadBubbleCoralFan": [ + 76, + 76, + 76 + ], + "DeadBubbleCoralWallFan": [ + 76, + 76, + 76 + ], + "DeadBush": [ + 143, + 119, + 72 + ], + "DeadFireCoral": [ + 76, + 76, + 76 + ], + "DeadFireCoralBlock": [ + 76, + 76, + 76 + ], + "DeadFireCoralFan": [ + 76, + 76, + 76 + ], + "DeadFireCoralWallFan": [ + 76, + 76, + 76 + ], + "DeadHornCoral": [ + 76, + 76, + 76 + ], + "DeadHornCoralBlock": [ + 76, + 76, + 76 + ], + "DeadHornCoralFan": [ + 76, + 76, + 76 + ], + "DeadHornCoralWallFan": [ + 76, + 76, + 76 + ], + "DeadTubeCoral": [ + 76, + 76, + 76 + ], + "DeadTubeCoralBlock": [ + 76, + 76, + 76 + ], + "DeadTubeCoralFan": [ + 76, + 76, + 76 + ], + "DeadTubeCoralWallFan": [ + 76, + 76, + 76 + ], + "DecoratedPot": [ + 142, + 60, + 46 + ], + "Deepslate": [ + 100, + 100, + 100 + ], + "DeepslateCoalOre": [ + 100, + 100, + 100 + ], + "DeepslateCopperOre": [ + 100, + 100, + 100 + ], + "DeepslateDiamondOre": [ + 100, + 100, + 100 + ], + "DeepslateEmeraldOre": [ + 100, + 100, + 100 + ], + "DeepslateGoldOre": [ + 100, + 100, + 100 + ], + "DeepslateIronOre": [ + 100, + 100, + 100 + ], + "DeepslateLapisOre": [ + 100, + 100, + 100 + ], + "DeepslateRedstoneOre": [ + 100, + 100, + 100 + ], + "DiamondBlock": [ + 92, + 219, + 213 + ], + "DiamondOre": [ + 112, + 112, + 112 + ], + "Diorite": [ + 255, + 252, + 245 + ], + "Dirt": [ + 151, + 109, + 77 + ], + "DirtPath": [ + 151, + 109, + 77 + ], + "Dispenser": [ + 112, + 112, + 112 + ], + "DragonEgg": [ + 25, + 25, + 25 + ], + "DriedGhast": [ + 76, + 76, + 76 + ], + "DriedKelpBlock": [ + 102, + 127, + 51 + ], + "DripstoneBlock": [ + 76, + 50, + 35 + ], + "Dropper": [ + 112, + 112, + 112 + ], + "EmeraldBlock": [ + 0, + 217, + 58 + ], + "EmeraldOre": [ + 112, + 112, + 112 + ], + "EnchantingTable": [ + 153, + 51, + 51 + ], + "EndGateway": [ + 25, + 25, + 25 + ], + "EndPortal": [ + 25, + 25, + 25 + ], + "EndPortalFrame": [ + 102, + 127, + 51 + ], + "EndStone": [ + 247, + 233, + 163 + ], + "EndStoneBricks": [ + 247, + 233, + 163 + ], + "EnderChest": [ + 112, + 112, + 112 + ], + "ExposedCopper": [ + 135, + 107, + 98 + ], + "ExposedCopperBulb": [ + 135, + 107, + 98 + ], + "ExposedCopperChest": [ + 135, + 107, + 98 + ], + "ExposedCopperDoor": [ + 135, + 107, + 98 + ], + "ExposedCopperGolemStatue": [ + 135, + 107, + 98 + ], + "ExposedCopperGrate": [ + 135, + 107, + 98 + ], + "ExposedCopperTrapdoor": [ + 135, + 107, + 98 + ], + "ExposedLightningRod": [ + 135, + 107, + 98 + ], + "Farmland": [ + 151, + 109, + 77 + ], + "Fern": [ + 0, + 124, + 0 + ], + "Fire": [ + 255, + 0, + 0 + ], + "FireCoral": [ + 153, + 51, + 51 + ], + "FireCoralBlock": [ + 153, + 51, + 51 + ], + "FireCoralFan": [ + 153, + 51, + 51 + ], + "FireCoralWallFan": [ + 153, + 51, + 51 + ], + "FireflyBush": [ + 0, + 124, + 0 + ], + "FletchingTable": [ + 143, + 119, + 72 + ], + "FloweringAzalea": [ + 0, + 124, + 0 + ], + "Frogspawn": [ + 64, + 64, + 255 + ], + "FrostedIce": [ + 160, + 160, + 255 + ], + "Furnace": [ + 112, + 112, + 112 + ], + "GlowLichen": [ + 127, + 167, + 150 + ], + "Glowstone": [ + 247, + 233, + 163 + ], + "GoldBlock": [ + 250, + 238, + 77 + ], + "GoldOre": [ + 112, + 112, + 112 + ], + "GoldenDandelion": [ + 0, + 124, + 0 + ], + "Granite": [ + 151, + 109, + 77 + ], + "GrassBlock": [ + 127, + 178, + 56 + ], + "Gravel": [ + 112, + 112, + 112 + ], + "GrayBanner": [ + 143, + 119, + 72 + ], + "GrayCarpet": [ + 76, + 76, + 76 + ], + "GrayConcrete": [ + 76, + 76, + 76 + ], + "GrayConcretePowder": [ + 76, + 76, + 76 + ], + "GrayGlazedTerracotta": [ + 76, + 76, + 76 + ], + "GrayTerracotta": [ + 57, + 41, + 35 + ], + "GrayWallBanner": [ + 143, + 119, + 72 + ], + "GrayWool": [ + 76, + 76, + 76 + ], + "GreenBanner": [ + 143, + 119, + 72 + ], + "GreenCarpet": [ + 102, + 127, + 51 + ], + "GreenConcrete": [ + 102, + 127, + 51 + ], + "GreenConcretePowder": [ + 102, + 127, + 51 + ], + "GreenGlazedTerracotta": [ + 102, + 127, + 51 + ], + "GreenTerracotta": [ + 76, + 82, + 42 + ], + "GreenWallBanner": [ + 143, + 119, + 72 + ], + "GreenWool": [ + 102, + 127, + 51 + ], + "Grindstone": [ + 167, + 167, + 167 + ], + "HangingRoots": [ + 151, + 109, + 77 + ], + "HayBlock": [ + 229, + 229, + 51 + ], + "HeavyCore": [ + 167, + 167, + 167 + ], + "HeavyWeightedPressurePlate": [ + 167, + 167, + 167 + ], + "HoneyBlock": [ + 216, + 127, + 51 + ], + "HoneycombBlock": [ + 216, + 127, + 51 + ], + "Hopper": [ + 112, + 112, + 112 + ], + "HornCoral": [ + 229, + 229, + 51 + ], + "HornCoralBlock": [ + 229, + 229, + 51 + ], + "HornCoralFan": [ + 229, + 229, + 51 + ], + "HornCoralWallFan": [ + 229, + 229, + 51 + ], + "Ice": [ + 160, + 160, + 255 + ], + "InfestedChiseledStoneBricks": [ + 164, + 168, + 184 + ], + "InfestedCobblestone": [ + 164, + 168, + 184 + ], + "InfestedCrackedStoneBricks": [ + 164, + 168, + 184 + ], + "InfestedDeepslate": [ + 100, + 100, + 100 + ], + "InfestedMossyStoneBricks": [ + 164, + 168, + 184 + ], + "InfestedStone": [ + 164, + 168, + 184 + ], + "InfestedStoneBricks": [ + 164, + 168, + 184 + ], + "IronBlock": [ + 167, + 167, + 167 + ], + "IronDoor": [ + 167, + 167, + 167 + ], + "IronOre": [ + 112, + 112, + 112 + ], + "IronTrapdoor": [ + 167, + 167, + 167 + ], + "JackOLantern": [ + 216, + 127, + 51 + ], + "Jigsaw": [ + 153, + 153, + 153 + ], + "Jukebox": [ + 151, + 109, + 77 + ], + "JungleDoor": [ + 151, + 109, + 77 + ], + "JungleFence": [ + 151, + 109, + 77 + ], + "JungleFenceGate": [ + 151, + 109, + 77 + ], + "JunglePlanks": [ + 151, + 109, + 77 + ], + "JunglePressurePlate": [ + 151, + 109, + 77 + ], + "JungleSapling": [ + 0, + 124, + 0 + ], + "JungleSlab": [ + 151, + 109, + 77 + ], + "JungleTrapdoor": [ + 151, + 109, + 77 + ], + "JungleWood": [ + 151, + 109, + 77 + ], + "Kelp": [ + 64, + 64, + 255 + ], + "KelpPlant": [ + 64, + 64, + 255 + ], + "Lantern": [ + 167, + 167, + 167 + ], + "LapisBlock": [ + 74, + 128, + 255 + ], + "LapisOre": [ + 112, + 112, + 112 + ], + "LargeFern": [ + 0, + 124, + 0 + ], + "Lava": [ + 255, + 0, + 0 + ], + "LeafLitter": [ + 102, + 76, + 51 + ], + "Lectern": [ + 143, + 119, + 72 + ], + "Light": [ + 0, + 0, + 0 + ], + "LightBlueBanner": [ + 143, + 119, + 72 + ], + "LightBlueCarpet": [ + 102, + 153, + 216 + ], + "LightBlueConcrete": [ + 102, + 153, + 216 + ], + "LightBlueConcretePowder": [ + 102, + 153, + 216 + ], + "LightBlueGlazedTerracotta": [ + 102, + 153, + 216 + ], + "LightBlueTerracotta": [ + 112, + 108, + 138 + ], + "LightBlueWallBanner": [ + 143, + 119, + 72 + ], + "LightBlueWool": [ + 102, + 153, + 216 + ], + "LightGrayBanner": [ + 143, + 119, + 72 + ], + "LightGrayCarpet": [ + 153, + 153, + 153 + ], + "LightGrayConcrete": [ + 153, + 153, + 153 + ], + "LightGrayConcretePowder": [ + 153, + 153, + 153 + ], + "LightGrayGlazedTerracotta": [ + 153, + 153, + 153 + ], + "LightGrayTerracotta": [ + 135, + 107, + 98 + ], + "LightGrayWallBanner": [ + 143, + 119, + 72 + ], + "LightGrayWool": [ + 153, + 153, + 153 + ], + "LightWeightedPressurePlate": [ + 250, + 238, + 77 + ], + "LightningRod": [ + 216, + 127, + 51 + ], + "Lilac": [ + 0, + 124, + 0 + ], + "LilyOfTheValley": [ + 0, + 124, + 0 + ], + "LilyPad": [ + 0, + 124, + 0 + ], + "LimeBanner": [ + 143, + 119, + 72 + ], + "LimeCarpet": [ + 127, + 204, + 25 + ], + "LimeConcrete": [ + 127, + 204, + 25 + ], + "LimeConcretePowder": [ + 127, + 204, + 25 + ], + "LimeGlazedTerracotta": [ + 127, + 204, + 25 + ], + "LimeTerracotta": [ + 103, + 117, + 53 + ], + "LimeWallBanner": [ + 143, + 119, + 72 + ], + "LimeWool": [ + 127, + 204, + 25 + ], + "Lodestone": [ + 167, + 167, + 167 + ], + "Loom": [ + 143, + 119, + 72 + ], + "MagentaBanner": [ + 143, + 119, + 72 + ], + "MagentaCarpet": [ + 178, + 76, + 216 + ], + "MagentaConcrete": [ + 178, + 76, + 216 + ], + "MagentaConcretePowder": [ + 178, + 76, + 216 + ], + "MagentaGlazedTerracotta": [ + 178, + 76, + 216 + ], + "MagentaTerracotta": [ + 149, + 87, + 108 + ], + "MagentaWallBanner": [ + 143, + 119, + 72 + ], + "MagentaWool": [ + 178, + 76, + 216 + ], + "MagmaBlock": [ + 112, + 2, + 0 + ], + "MangroveDoor": [ + 153, + 51, + 51 + ], + "MangroveFence": [ + 153, + 51, + 51 + ], + "MangroveFenceGate": [ + 153, + 51, + 51 + ], + "MangrovePlanks": [ + 153, + 51, + 51 + ], + "MangrovePressurePlate": [ + 153, + 51, + 51 + ], + "MangrovePropagule": [ + 0, + 124, + 0 + ], + "MangroveRoots": [ + 129, + 86, + 49 + ], + "MangroveSlab": [ + 153, + 51, + 51 + ], + "MangroveTrapdoor": [ + 153, + 51, + 51 + ], + "MangroveWood": [ + 153, + 51, + 51 + ], + "Melon": [ + 127, + 204, + 25 + ], + "MelonStem": [ + 0, + 124, + 0 + ], + "MossBlock": [ + 102, + 127, + 51 + ], + "MossCarpet": [ + 102, + 127, + 51 + ], + "MossyCobblestone": [ + 112, + 112, + 112 + ], + "MossyStoneBricks": [ + 112, + 112, + 112 + ], + "MovingPiston": [ + 112, + 112, + 112 + ], + "Mud": [ + 87, + 92, + 92 + ], + "MudBrickSlab": [ + 135, + 107, + 98 + ], + "MudBricks": [ + 135, + 107, + 98 + ], + "MuddyMangroveRoots": [ + 129, + 86, + 49 + ], + "MushroomStem": [ + 199, + 199, + 199 + ], + "Mycelium": [ + 127, + 63, + 178 + ], + "NetherBrickFence": [ + 112, + 2, + 0 + ], + "NetherBrickSlab": [ + 112, + 2, + 0 + ], + "NetherBricks": [ + 112, + 2, + 0 + ], + "NetherGoldOre": [ + 112, + 2, + 0 + ], + "NetherQuartzOre": [ + 112, + 2, + 0 + ], + "NetherSprouts": [ + 76, + 127, + 153 + ], + "NetherWart": [ + 153, + 51, + 51 + ], + "NetherWartBlock": [ + 153, + 51, + 51 + ], + "NetheriteBlock": [ + 25, + 25, + 25 + ], + "Netherrack": [ + 112, + 2, + 0 + ], + "NoteBlock": [ + 143, + 119, + 72 + ], + "OakDoor": [ + 143, + 119, + 72 + ], + "OakFence": [ + 143, + 119, + 72 + ], + "OakFenceGate": [ + 143, + 119, + 72 + ], + "OakPlanks": [ + 143, + 119, + 72 + ], + "OakPressurePlate": [ + 143, + 119, + 72 + ], + "OakSapling": [ + 0, + 124, + 0 + ], + "OakShelf": [ + 143, + 119, + 72 + ], + "OakSign": [ + 143, + 119, + 72 + ], + "OakSlab": [ + 143, + 119, + 72 + ], + "OakTrapdoor": [ + 143, + 119, + 72 + ], + "OakWallSign": [ + 143, + 119, + 72 + ], + "OakWood": [ + 143, + 119, + 72 + ], + "Observer": [ + 112, + 112, + 112 + ], + "Obsidian": [ + 25, + 25, + 25 + ], + "OchreFroglight": [ + 247, + 233, + 163 + ], + "OpenEyeblossom": [ + 216, + 127, + 51 + ], + "OrangeBanner": [ + 143, + 119, + 72 + ], + "OrangeCarpet": [ + 216, + 127, + 51 + ], + "OrangeConcrete": [ + 216, + 127, + 51 + ], + "OrangeConcretePowder": [ + 216, + 127, + 51 + ], + "OrangeGlazedTerracotta": [ + 216, + 127, + 51 + ], + "OrangeTerracotta": [ + 159, + 82, + 36 + ], + "OrangeTulip": [ + 0, + 124, + 0 + ], + "OrangeWallBanner": [ + 143, + 119, + 72 + ], + "OrangeWool": [ + 216, + 127, + 51 + ], + "OxeyeDaisy": [ + 0, + 124, + 0 + ], + "OxidizedCopper": [ + 22, + 126, + 134 + ], + "OxidizedCopperBulb": [ + 22, + 126, + 134 + ], + "OxidizedCopperChest": [ + 22, + 126, + 134 + ], + "OxidizedCopperDoor": [ + 22, + 126, + 134 + ], + "OxidizedCopperGolemStatue": [ + 22, + 126, + 134 + ], + "OxidizedCopperGrate": [ + 22, + 126, + 134 + ], + "OxidizedCopperTrapdoor": [ + 22, + 126, + 134 + ], + "OxidizedLightningRod": [ + 22, + 126, + 134 + ], + "PackedIce": [ + 160, + 160, + 255 + ], + "PaleHangingMoss": [ + 153, + 153, + 153 + ], + "PaleMossBlock": [ + 153, + 153, + 153 + ], + "PaleMossCarpet": [ + 153, + 153, + 153 + ], + "PaleOakDoor": [ + 255, + 252, + 245 + ], + "PaleOakFence": [ + 255, + 252, + 245 + ], + "PaleOakFenceGate": [ + 255, + 252, + 245 + ], + "PaleOakHangingSign": [ + 255, + 252, + 245 + ], + "PaleOakLeaves": [ + 167, + 167, + 167 + ], + "PaleOakPlanks": [ + 255, + 252, + 245 + ], + "PaleOakPressurePlate": [ + 255, + 252, + 245 + ], + "PaleOakSapling": [ + 167, + 167, + 167 + ], + "PaleOakShelf": [ + 255, + 252, + 245 + ], + "PaleOakSign": [ + 255, + 252, + 245 + ], + "PaleOakSlab": [ + 255, + 252, + 245 + ], + "PaleOakTrapdoor": [ + 255, + 252, + 245 + ], + "PaleOakWallHangingSign": [ + 255, + 252, + 245 + ], + "PaleOakWallSign": [ + 255, + 252, + 245 + ], + "PaleOakWood": [ + 112, + 112, + 112 + ], + "PearlescentFroglight": [ + 242, + 127, + 165 + ], + "Peony": [ + 0, + 124, + 0 + ], + "PetrifiedOakSlab": [ + 143, + 119, + 72 + ], + "PinkBanner": [ + 143, + 119, + 72 + ], + "PinkCarpet": [ + 242, + 127, + 165 + ], + "PinkConcrete": [ + 242, + 127, + 165 + ], + "PinkConcretePowder": [ + 242, + 127, + 165 + ], + "PinkGlazedTerracotta": [ + 242, + 127, + 165 + ], + "PinkPetals": [ + 0, + 124, + 0 + ], + "PinkTerracotta": [ + 160, + 77, + 78 + ], + "PinkTulip": [ + 0, + 124, + 0 + ], + "PinkWallBanner": [ + 143, + 119, + 72 + ], + "PinkWool": [ + 242, + 127, + 165 + ], + "PistonHead": [ + 112, + 112, + 112 + ], + "PitcherCrop": [ + 0, + 124, + 0 + ], + "PitcherPlant": [ + 0, + 124, + 0 + ], + "Podzol": [ + 129, + 86, + 49 + ], + "PointedDripstone": [ + 76, + 50, + 35 + ], + "PolishedAndesite": [ + 112, + 112, + 112 + ], + "PolishedBasalt": [ + 25, + 25, + 25 + ], + "PolishedBlackstonePressurePlate": [ + 25, + 25, + 25 + ], + "PolishedDiorite": [ + 255, + 252, + 245 + ], + "PolishedGranite": [ + 151, + 109, + 77 + ], + "Poppy": [ + 0, + 124, + 0 + ], + "Potatoes": [ + 0, + 124, + 0 + ], + "PowderSnow": [ + 255, + 255, + 255 + ], + "Prismarine": [ + 76, + 127, + 153 + ], + "PrismarineBrickSlab": [ + 92, + 219, + 213 + ], + "PrismarineBricks": [ + 92, + 219, + 213 + ], + "PrismarineSlab": [ + 76, + 127, + 153 + ], + "Pumpkin": [ + 216, + 127, + 51 + ], + "PumpkinStem": [ + 0, + 124, + 0 + ], + "PurpleBanner": [ + 143, + 119, + 72 + ], + "PurpleCarpet": [ + 127, + 63, + 178 + ], + "PurpleConcrete": [ + 127, + 63, + 178 + ], + "PurpleConcretePowder": [ + 127, + 63, + 178 + ], + "PurpleGlazedTerracotta": [ + 127, + 63, + 178 + ], + "PurpleTerracotta": [ + 122, + 73, + 88 + ], + "PurpleWallBanner": [ + 143, + 119, + 72 + ], + "PurpleWool": [ + 127, + 63, + 178 + ], + "PurpurBlock": [ + 178, + 76, + 216 + ], + "PurpurPillar": [ + 178, + 76, + 216 + ], + "PurpurSlab": [ + 178, + 76, + 216 + ], + "QuartzBlock": [ + 255, + 252, + 245 + ], + "QuartzPillar": [ + 255, + 252, + 245 + ], + "QuartzSlab": [ + 255, + 252, + 245 + ], + "RawCopperBlock": [ + 216, + 127, + 51 + ], + "RawGoldBlock": [ + 250, + 238, + 77 + ], + "RawIronBlock": [ + 216, + 175, + 147 + ], + "RedBanner": [ + 143, + 119, + 72 + ], + "RedCarpet": [ + 153, + 51, + 51 + ], + "RedConcrete": [ + 153, + 51, + 51 + ], + "RedConcretePowder": [ + 153, + 51, + 51 + ], + "RedGlazedTerracotta": [ + 153, + 51, + 51 + ], + "RedMushroom": [ + 153, + 51, + 51 + ], + "RedMushroomBlock": [ + 153, + 51, + 51 + ], + "RedNetherBricks": [ + 112, + 2, + 0 + ], + "RedSand": [ + 216, + 127, + 51 + ], + "RedSandstone": [ + 216, + 127, + 51 + ], + "RedSandstoneSlab": [ + 216, + 127, + 51 + ], + "RedTerracotta": [ + 142, + 60, + 46 + ], + "RedTulip": [ + 0, + 124, + 0 + ], + "RedWallBanner": [ + 143, + 119, + 72 + ], + "RedWool": [ + 153, + 51, + 51 + ], + "RedstoneBlock": [ + 255, + 0, + 0 + ], + "RedstoneLamp": [ + 159, + 82, + 36 + ], + "RedstoneOre": [ + 112, + 112, + 112 + ], + "ReinforcedDeepslate": [ + 100, + 100, + 100 + ], + "RepeatingCommandBlock": [ + 127, + 63, + 178 + ], + "ResinBlock": [ + 159, + 82, + 36 + ], + "ResinBrickSlab": [ + 159, + 82, + 36 + ], + "ResinBrickWall": [ + 159, + 82, + 36 + ], + "ResinBricks": [ + 159, + 82, + 36 + ], + "ResinClump": [ + 159, + 82, + 36 + ], + "RespawnAnchor": [ + 25, + 25, + 25 + ], + "RootedDirt": [ + 151, + 109, + 77 + ], + "RoseBush": [ + 0, + 124, + 0 + ], + "Sand": [ + 247, + 233, + 163 + ], + "Sandstone": [ + 247, + 233, + 163 + ], + "SandstoneSlab": [ + 247, + 233, + 163 + ], + "Scaffolding": [ + 247, + 233, + 163 + ], + "Sculk": [ + 25, + 25, + 25 + ], + "SculkCatalyst": [ + 25, + 25, + 25 + ], + "SculkSensor": [ + 76, + 127, + 153 + ], + "SculkShrieker": [ + 25, + 25, + 25 + ], + "SculkVein": [ + 25, + 25, + 25 + ], + "SeaLantern": [ + 255, + 252, + 245 + ], + "SeaPickle": [ + 102, + 127, + 51 + ], + "Seagrass": [ + 64, + 64, + 255 + ], + "ShortDryGrass": [ + 229, + 229, + 51 + ], + "ShortGrass": [ + 0, + 124, + 0 + ], + "Shroomlight": [ + 153, + 51, + 51 + ], + "SlimeBlock": [ + 127, + 178, + 56 + ], + "SmallDripleaf": [ + 0, + 124, + 0 + ], + "SmithingTable": [ + 143, + 119, + 72 + ], + "Smoker": [ + 112, + 112, + 112 + ], + "SmoothQuartz": [ + 255, + 252, + 245 + ], + "SmoothRedSandstone": [ + 216, + 127, + 51 + ], + "SmoothSandstone": [ + 247, + 233, + 163 + ], + "SmoothStone": [ + 112, + 112, + 112 + ], + "SmoothStoneSlab": [ + 112, + 112, + 112 + ], + "SnifferEgg": [ + 153, + 51, + 51 + ], + "Snow": [ + 255, + 255, + 255 + ], + "SnowBlock": [ + 255, + 255, + 255 + ], + "SoulCampfire": [ + 129, + 86, + 49 + ], + "SoulFire": [ + 102, + 153, + 216 + ], + "SoulLantern": [ + 167, + 167, + 167 + ], + "SoulSand": [ + 102, + 76, + 51 + ], + "SoulSoil": [ + 102, + 76, + 51 + ], + "Spawner": [ + 112, + 112, + 112 + ], + "Sponge": [ + 229, + 229, + 51 + ], + "SporeBlossom": [ + 0, + 124, + 0 + ], + "SpruceDoor": [ + 129, + 86, + 49 + ], + "SpruceFence": [ + 129, + 86, + 49 + ], + "SpruceFenceGate": [ + 129, + 86, + 49 + ], + "SprucePlanks": [ + 129, + 86, + 49 + ], + "SprucePressurePlate": [ + 129, + 86, + 49 + ], + "SpruceSapling": [ + 0, + 124, + 0 + ], + "SpruceSlab": [ + 129, + 86, + 49 + ], + "SpruceTrapdoor": [ + 129, + 86, + 49 + ], + "SpruceWallHangingSign": [ + 143, + 119, + 72 + ], + "SpruceWood": [ + 129, + 86, + 49 + ], + "Stone": [ + 112, + 112, + 112 + ], + "StoneBrickSlab": [ + 112, + 112, + 112 + ], + "StoneBricks": [ + 112, + 112, + 112 + ], + "StonePressurePlate": [ + 112, + 112, + 112 + ], + "StoneSlab": [ + 112, + 112, + 112 + ], + "Stonecutter": [ + 112, + 112, + 112 + ], + "StrippedAcaciaWood": [ + 216, + 127, + 51 + ], + "StrippedBirchWood": [ + 247, + 233, + 163 + ], + "StrippedCherryWood": [ + 160, + 77, + 78 + ], + "StrippedCrimsonHyphae": [ + 92, + 25, + 29 + ], + "StrippedDarkOakWood": [ + 102, + 76, + 51 + ], + "StrippedJungleWood": [ + 151, + 109, + 77 + ], + "StrippedOakWood": [ + 143, + 119, + 72 + ], + "StrippedPaleOakWood": [ + 255, + 252, + 245 + ], + "StrippedSpruceWood": [ + 129, + 86, + 49 + ], + "StrippedWarpedHyphae": [ + 86, + 44, + 62 + ], + "StructureBlock": [ + 153, + 153, + 153 + ], + "SugarCane": [ + 0, + 124, + 0 + ], + "Sunflower": [ + 0, + 124, + 0 + ], + "SuspiciousGravel": [ + 112, + 112, + 112 + ], + "SuspiciousSand": [ + 247, + 233, + 163 + ], + "SweetBerryBush": [ + 0, + 124, + 0 + ], + "TallDryGrass": [ + 229, + 229, + 51 + ], + "TallGrass": [ + 0, + 124, + 0 + ], + "TallSeagrass": [ + 64, + 64, + 255 + ], + "Target": [ + 255, + 252, + 245 + ], + "Terracotta": [ + 216, + 127, + 51 + ], + "TestBlock": [ + 153, + 153, + 153 + ], + "TintedGlass": [ + 76, + 76, + 76 + ], + "Tnt": [ + 255, + 0, + 0 + ], + "Torchflower": [ + 0, + 124, + 0 + ], + "TorchflowerCrop": [ + 0, + 124, + 0 + ], + "TrappedChest": [ + 143, + 119, + 72 + ], + "TrialSpawner": [ + 112, + 112, + 112 + ], + "TubeCoral": [ + 51, + 76, + 178 + ], + "TubeCoralBlock": [ + 51, + 76, + 178 + ], + "TubeCoralFan": [ + 51, + 76, + 178 + ], + "TubeCoralWallFan": [ + 51, + 76, + 178 + ], + "Tuff": [ + 57, + 41, + 35 + ], + "TurtleEgg": [ + 247, + 233, + 163 + ], + "TwistingVines": [ + 76, + 127, + 153 + ], + "TwistingVinesPlant": [ + 76, + 127, + 153 + ], + "Vault": [ + 112, + 112, + 112 + ], + "VerdantFroglight": [ + 127, + 167, + 150 + ], + "Vine": [ + 0, + 124, + 0 + ], + "WarpedDoor": [ + 58, + 142, + 140 + ], + "WarpedFence": [ + 58, + 142, + 140 + ], + "WarpedFenceGate": [ + 58, + 142, + 140 + ], + "WarpedFungus": [ + 76, + 127, + 153 + ], + "WarpedHangingSign": [ + 58, + 142, + 140 + ], + "WarpedHyphae": [ + 86, + 44, + 62 + ], + "WarpedNylium": [ + 22, + 126, + 134 + ], + "WarpedPlanks": [ + 58, + 142, + 140 + ], + "WarpedPressurePlate": [ + 58, + 142, + 140 + ], + "WarpedRoots": [ + 76, + 127, + 153 + ], + "WarpedShelf": [ + 58, + 142, + 140 + ], + "WarpedSign": [ + 58, + 142, + 140 + ], + "WarpedSlab": [ + 58, + 142, + 140 + ], + "WarpedTrapdoor": [ + 58, + 142, + 140 + ], + "WarpedWallHangingSign": [ + 58, + 142, + 140 + ], + "WarpedWallSign": [ + 58, + 142, + 140 + ], + "WarpedWartBlock": [ + 20, + 180, + 133 + ], + "Water": [ + 64, + 64, + 255 + ], + "WeatheredCopper": [ + 58, + 142, + 140 + ], + "WeatheredCopperBulb": [ + 58, + 142, + 140 + ], + "WeatheredCopperChest": [ + 58, + 142, + 140 + ], + "WeatheredCopperDoor": [ + 58, + 142, + 140 + ], + "WeatheredCopperGolemStatue": [ + 58, + 142, + 140 + ], + "WeatheredCopperGrate": [ + 58, + 142, + 140 + ], + "WeatheredCopperTrapdoor": [ + 58, + 142, + 140 + ], + "WeatheredLightningRod": [ + 58, + 142, + 140 + ], + "WeepingVines": [ + 112, + 2, + 0 + ], + "WeepingVinesPlant": [ + 112, + 2, + 0 + ], + "WetSponge": [ + 229, + 229, + 51 + ], + "WhiteBanner": [ + 143, + 119, + 72 + ], + "WhiteCarpet": [ + 255, + 255, + 255 + ], + "WhiteConcrete": [ + 255, + 255, + 255 + ], + "WhiteConcretePowder": [ + 255, + 255, + 255 + ], + "WhiteGlazedTerracotta": [ + 255, + 255, + 255 + ], + "WhiteTerracotta": [ + 209, + 177, + 161 + ], + "WhiteTulip": [ + 0, + 124, + 0 + ], + "WhiteWallBanner": [ + 143, + 119, + 72 + ], + "WhiteWool": [ + 255, + 255, + 255 + ], + "Wildflowers": [ + 0, + 124, + 0 + ], + "WitherRose": [ + 0, + 124, + 0 + ], + "YellowBanner": [ + 143, + 119, + 72 + ], + "YellowCarpet": [ + 229, + 229, + 51 + ], + "YellowConcrete": [ + 229, + 229, + 51 + ], + "YellowConcretePowder": [ + 229, + 229, + 51 + ], + "YellowGlazedTerracotta": [ + 229, + 229, + 51 + ], + "YellowTerracotta": [ + 186, + 133, + 36 + ], + "YellowWallBanner": [ + 143, + 119, + 72 + ], + "YellowWool": [ + 229, + 229, + 51 + ] + }, + "transparent": [ + "Air", + "Barrier", + "BlackStainedGlass", + "BlackStainedGlassPane", + "BlueStainedGlass", + "BlueStainedGlassPane", + "BrownStainedGlass", + "BrownStainedGlassPane", + "CaveAir", + "CyanStainedGlass", + "CyanStainedGlassPane", + "Glass", + "GlassPane", + "GrayStainedGlass", + "GrayStainedGlassPane", + "GreenStainedGlass", + "GreenStainedGlassPane", + "Light", + "LightBlueStainedGlass", + "LightBlueStainedGlassPane", + "LightGrayStainedGlass", + "LightGrayStainedGlassPane", + "LimeStainedGlass", + "LimeStainedGlassPane", + "MagentaStainedGlass", + "MagentaStainedGlassPane", + "OrangeStainedGlass", + "OrangeStainedGlassPane", + "PinkStainedGlass", + "PinkStainedGlassPane", + "PurpleStainedGlass", + "PurpleStainedGlassPane", + "RedStainedGlass", + "RedStainedGlassPane", + "StructureVoid", + "TintedGlass", + "VoidAir", + "WhiteStainedGlass", + "WhiteStainedGlassPane", + "YellowStainedGlass", + "YellowStainedGlassPane" + ], + "water": [ + "Water" + ], + "ice": [ + "Ice", + "PackedIce", + "BlueIce", + "FrostedIce" + ] +} \ No newline at end of file diff --git a/MinecraftClient/Tui/MinimapColorMap.cs b/MinecraftClient/Tui/MinimapColorMap.cs new file mode 100644 index 00000000..ae1bf21c --- /dev/null +++ b/MinecraftClient/Tui/MinimapColorMap.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Reflection; +using System.Text.Json; +using Avalonia.Media; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Tui +{ + /// + /// Maps block Materials to minimap colors using data extracted from Minecraft's + /// official MapColor table. Colors are loaded from the embedded MinimapBlockColors.json + /// resource generated by tools/gen_block_color_map.py. + /// + public static class MinimapColorMap + { + public static readonly Color WaterColor = Color.FromRgb(64, 64, 255); + public static readonly Color IceColor = Color.FromRgb(160, 160, 255); + public static readonly Color LavaColor = Color.FromRgb(255, 100, 0); + public static readonly Color DefaultColor = Color.FromRgb(60, 60, 60); + public static readonly Color VoidColor = Color.FromRgb(0, 0, 0); + + private static readonly FrozenDictionary ColorTable; + private static readonly FrozenSet FullyTransparentMats; + private static readonly FrozenSet WaterMats; + private static readonly FrozenSet IceMats; + + static MinimapColorMap() + { + var colors = new Dictionary(); + var transparent = new HashSet(); + var water = new HashSet(); + var ice = new HashSet(); + + try + { + using var stream = Assembly.GetExecutingAssembly() + .GetManifestResourceStream("MinimapBlockColors.json"); + if (stream is not null) + { + using var doc = JsonDocument.Parse(stream); + var root = doc.RootElement; + + if (root.TryGetProperty("colors", out var colorsEl)) + { + foreach (var prop in colorsEl.EnumerateObject()) + { + if (!Enum.TryParse(prop.Name, out var mat)) + continue; + var arr = prop.Value; + if (arr.GetArrayLength() < 3) continue; + byte r = (byte)arr[0].GetInt32(); + byte g = (byte)arr[1].GetInt32(); + byte b = (byte)arr[2].GetInt32(); + colors[mat] = Color.FromRgb(r, g, b); + } + } + + if (root.TryGetProperty("transparent", out var transEl)) + { + foreach (var item in transEl.EnumerateArray()) + { + if (Enum.TryParse(item.GetString(), out var mat)) + transparent.Add(mat); + } + } + + if (root.TryGetProperty("water", out var waterEl)) + { + foreach (var item in waterEl.EnumerateArray()) + { + if (Enum.TryParse(item.GetString(), out var mat)) + water.Add(mat); + } + } + + if (root.TryGetProperty("ice", out var iceEl)) + { + foreach (var item in iceEl.EnumerateArray()) + { + if (Enum.TryParse(item.GetString(), out var mat)) + ice.Add(mat); + } + } + } + } + catch (Exception ex) + { + ConsoleIO.WriteLineFormatted($"\u00a7e[Minimap] Failed to load color data: {ex.Message}"); + } + + if (transparent.Count == 0) + { + transparent.Add(Material.Air); + transparent.Add(Material.CaveAir); + transparent.Add(Material.VoidAir); + } + if (water.Count == 0) + water.Add(Material.Water); + if (ice.Count == 0) + { + ice.Add(Material.Ice); + ice.Add(Material.PackedIce); + ice.Add(Material.BlueIce); + ice.Add(Material.FrostedIce); + } + + ColorTable = colors.ToFrozenDictionary(); + FullyTransparentMats = transparent.ToFrozenSet(); + WaterMats = water.ToFrozenSet(); + IceMats = ice.ToFrozenSet(); + } + + public static bool IsFullyTransparent(Material m) => FullyTransparentMats.Contains(m); + + public static bool IsWater(Material m) => WaterMats.Contains(m); + + public static bool IsIce(Material m) => IceMats.Contains(m); + + public static Color GetBaseColor(Material m) + { + if (m == Material.Lava) + return LavaColor; + return ColorTable.GetValueOrDefault(m, DefaultColor); + } + + /// + /// Apply Minecraft-style height shading. The shade multiplier depends on + /// the height difference between the current block and the block to its north. + /// Vanilla maps use four brightness levels: LOW (180/255), NORMAL (220/255), + /// HIGH (255/255), and LOWEST (135/255). We use NORMAL as baseline and shift + /// up/down based on delta. + /// + public static Color ApplyHeightShade(Color baseColor, int heightDelta) + { + int multiplier = heightDelta switch + { + > 0 => 255, // higher than neighbor: brightest + 0 => 220, // same height: normal + _ => 180, // lower than neighbor: darker + }; + byte r = (byte)(baseColor.R * multiplier / 255); + byte g = (byte)(baseColor.G * multiplier / 255); + byte b = (byte)(baseColor.B * multiplier / 255); + return Color.FromRgb(r, g, b); + } + + public static Color BlendWaterColor(Color bottomColor, int waterDepth) + { + double alpha = Math.Min(0.85, 0.35 + waterDepth * 0.08); + return Blend(WaterColor, bottomColor, alpha); + } + + public static Color BlendIceColor(Color bottomColor) + { + return Blend(IceColor, bottomColor, 0.35); + } + + private static Color Blend(Color top, Color bottom, double topAlpha) + { + byte r = (byte)(top.R * topAlpha + bottom.R * (1.0 - topAlpha)); + byte g = (byte)(top.G * topAlpha + bottom.G * (1.0 - topAlpha)); + byte b = (byte)(top.B * topAlpha + bottom.B * (1.0 - topAlpha)); + return Color.FromRgb(r, g, b); + } + } +} diff --git a/MinecraftClient/Tui/MinimapControl.cs b/MinecraftClient/Tui/MinimapControl.cs new file mode 100644 index 00000000..44db58ba --- /dev/null +++ b/MinecraftClient/Tui/MinimapControl.cs @@ -0,0 +1,677 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; +using Avalonia.Media; +using Avalonia.Threading; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Tui +{ + /// + /// TUI minimap control rendered as a grid of TextBlocks using half-block characters. + /// Zoom is expressed as blocks-per-pixel (1 = 1:1, 16 = 16 blocks per pixel). + /// Entity names are drawn directly on the map below their icon. + /// + public class MinimapControl : UserControl + { + public const int MinZoom = 1; + public const int MaxZoom = 16; + public const int DefaultZoom = 2; + public const int DefaultWidth = 40; + public const int DefaultHeight = 40; + public const int DefaultRefreshMs = 1000; + public const int MinRefreshMs = 100; + public const int MaxRefreshMs = 5000; + + private int _mapWidth; + private int _mapHeight; + private int _cellRows; + + private int _blocksPerPixel = DefaultZoom; + private volatile bool _sampling; + private CancellationTokenSource? _cts; + + private readonly NameDisplayConfig _nameConfig = new(); + + private TextBlock[,] _cells; + private readonly StackPanel _infoRow; + private readonly StackPanel _legendPanel; + private readonly Grid _mapGrid; + private readonly DispatcherTimer _timer; + + public int BlocksPerPixel + { + get => _blocksPerPixel; + set => _blocksPerPixel = Math.Clamp(value, MinZoom, MaxZoom); + } + + public NameDisplayConfig NameConfig => _nameConfig; + + public int MapPixelWidth => _mapWidth; + public int MapPixelHeight => _mapHeight; + + public int RefreshIntervalMs + { + get => (int)_timer.Interval.TotalMilliseconds; + set => _timer.Interval = TimeSpan.FromMilliseconds(Math.Clamp(value, MinRefreshMs, MaxRefreshMs)); + } + + public MinimapControl() : this(DefaultWidth, DefaultHeight) { } + + public MinimapControl(int width, int height) + { + _mapWidth = Math.Max(10, width); + _mapHeight = Math.Max(4, height % 2 == 0 ? height : height + 1); + _cellRows = _mapHeight / 2; + + _mapGrid = new Grid(); + _cells = BuildGrid(_mapGrid, _cellRows, _mapWidth); + + _infoRow = new StackPanel { Orientation = Orientation.Horizontal }; + _legendPanel = new StackPanel { Orientation = Orientation.Horizontal }; + + var root = new StackPanel + { + Orientation = Orientation.Vertical, + Children = { _mapGrid, _infoRow, _legendPanel }, + }; + + Content = root; + + _timer = new DispatcherTimer + { + Interval = TimeSpan.FromMilliseconds(DefaultRefreshMs), + }; + _timer.Tick += (_, _) => RequestSample(); + } + + public void Resize(int width, int height) + { + _mapWidth = Math.Max(10, width); + _mapHeight = Math.Max(4, height % 2 == 0 ? height : height + 1); + _cellRows = _mapHeight / 2; + + _mapGrid.Children.Clear(); + _mapGrid.RowDefinitions.Clear(); + _mapGrid.ColumnDefinitions.Clear(); + _cells = BuildGrid(_mapGrid, _cellRows, _mapWidth); + } + + private static TextBlock[,] BuildGrid(Grid grid, int rows, int cols) + { + var cells = new TextBlock[rows, cols]; + for (int r = 0; r < rows; r++) + grid.RowDefinitions.Add(new RowDefinition(GridLength.Auto)); + for (int c = 0; c < cols; c++) + grid.ColumnDefinitions.Add(new ColumnDefinition(GridLength.Auto)); + + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + var tb = new TextBlock + { + Text = "\u2580", + Foreground = Brushes.Black, + Background = Brushes.Black, + Padding = new Thickness(0), + Margin = new Thickness(0), + FontSize = 1, + }; + Grid.SetRow(tb, r); + Grid.SetColumn(tb, c); + grid.Children.Add(tb); + cells[r, c] = tb; + } + } + return cells; + } + + public void Start() + { + _cts = new CancellationTokenSource(); + _timer.Start(); + RequestSample(); + } + + public void Stop() + { + _timer.Stop(); + _cts?.Cancel(); + _cts?.Dispose(); + _cts = null; + } + + private void RequestSample() + { + if (_sampling) return; + if (McClient.Instance is not McClient client) return; + if (!client.GetTerrainEnabled()) return; + + _sampling = true; + var ct = _cts?.Token ?? CancellationToken.None; + int bpp = _blocksPerPixel; + int w = _mapWidth; + int h = _mapHeight; + + bool showPlayers = _nameConfig.Players; + bool showHostile = _nameConfig.Hostile; + bool showNeutral = _nameConfig.Neutral; + bool showPassive = _nameConfig.Passive; + + Task.Run(() => + { + try + { + var result = SampleTerrain(client, bpp, w, h, + showPlayers, showHostile, showNeutral, showPassive, ct); + if (ct.IsCancellationRequested) return; + + Dispatcher.UIThread.Post(() => + { + ApplyPixelBuffer(result, w, h); + UpdateInfoBarAndLegend(client, bpp, result.VisibleCategories, w); + }); + } + catch (OperationCanceledException) { } + catch (Exception ex) + { + ConsoleIO.WriteLineFormatted($"\u00a7e[Minimap] Sample error: {ex.Message}"); + } + finally + { + _sampling = false; + } + }, ct); + } + + internal sealed class EntityLabel + { + public string Name = ""; + public Color LabelColor; + public int PixelX; + public int PixelY; + } + + private sealed class SampleResult + { + public Color[,] Pixels = null!; + public (char Ch, Color Fg, Color Bg)?[,] CharOverlay = null!; + public HashSet VisibleCategories = []; + public int[,] Heights = null!; + } + + private static bool ShouldShowNameLocal(MobCategory cat, + bool showPlayers, bool showHostile, bool showNeutral, bool showPassive) + { + return cat switch + { + MobCategory.Player => showPlayers, + MobCategory.Hostile => showHostile, + MobCategory.Neutral => showNeutral, + MobCategory.Passive => showPassive, + _ => false, + }; + } + + private static SampleResult SampleTerrain(McClient client, int bpp, int mapW, int mapH, + bool showPlayers, bool showHostile, bool showNeutral, bool showPassive, + CancellationToken ct) + { + var result = new SampleResult + { + Pixels = new Color[mapW, mapH], + CharOverlay = new (char, Color, Color)?[mapW, mapH / 2], + Heights = new int[mapW, mapH], + }; + var world = client.GetWorld(); + var playerLoc = client.GetCurrentLocation(); + + int playerBlockX = (int)Math.Floor(playerLoc.X); + int playerBlockZ = (int)Math.Floor(playerLoc.Z); + int playerBlockY = (int)Math.Floor(playerLoc.Y); + + var dim = World.GetDimension(); + int minY = dim.minY; + int scanTop = Math.Min(playerBlockY + 32, dim.maxY - 1); + + var entities = client.GetEntityHandlingEnabled() + ? client.GetEntities() + : null; + + var entityPixels = new Dictionary<(int, int), (Color Color, int Priority)>(); + int centerX = mapW / 2; + int centerY = mapH / 2; + + var nameLabels = new List(); + var uuidNameMap = client.GetOnlinePlayersWithUUID(); + + if (entities is not null) + { + int playerEntityId = client.GetPlayerEntityID(); + foreach (var kvp in entities) + { + if (ct.IsCancellationRequested) return result; + var entity = kvp.Value; + var cat = MinimapEntityClassifier.Classify(entity.Type); + if (cat == MobCategory.NonLiving) continue; + if (kvp.Key == playerEntityId) continue; + + if (!MinimapEntityClassifier.ShouldDisplay(cat, playerLoc.Y, entity.Location.Y)) + continue; + + double relX = (entity.Location.X - playerLoc.X) / bpp; + double relZ = (entity.Location.Z - playerLoc.Z) / bpp; + int px = (int)Math.Floor(relX) + centerX; + int py = (int)Math.Floor(relZ) + centerY; + + if (px < 0 || px >= mapW || py < 0 || py >= mapH) continue; + + var baseColor = MinimapEntityClassifier.GetBaseColor(cat); + Color color; + if (cat == MobCategory.Player) + color = baseColor; + else + color = MinimapEntityClassifier.ApplyDepthFade(baseColor, playerLoc.Y, entity.Location.Y); + int priority = MinimapEntityClassifier.GetPriority(cat); + + var key = (px, py); + if (!entityPixels.TryGetValue(key, out var existing) || priority > existing.Priority) + entityPixels[key] = (color, priority); + + result.VisibleCategories.Add(cat); + + if (ShouldShowNameLocal(cat, showPlayers, showHostile, showNeutral, showPassive)) + { + string name = ResolveEntityName(client, entity, cat, uuidNameMap); + nameLabels.Add(new EntityLabel + { + Name = name, + LabelColor = color, + PixelX = px, + PixelY = py, + }); + } + } + } + + entityPixels[(centerX, centerY)] = (MinimapEntityClassifier.PlayerColor, 5); + result.VisibleCategories.Add(MobCategory.Player); + + ChunkColumn? cachedColumn = null; + int cachedChunkX = int.MinValue, cachedChunkZ = int.MinValue; + + for (int px = 0; px < mapW; px++) + { + for (int py = 0; py < mapH; py++) + { + if (ct.IsCancellationRequested) return result; + + int baseX = playerBlockX + (px - centerX) * bpp; + int baseZ = playerBlockZ + (py - centerY) * bpp; + + if (bpp == 1) + { + var (color, surfY) = SampleColumn(world, baseX, baseZ, scanTop, minY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + } + else + { + var (color, surfY) = SampleAreaDominant(world, baseX, baseZ, bpp, scanTop, minY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + } + } + } + + for (int px = 0; px < mapW; px++) + { + for (int py = 0; py < mapH; py++) + { + if (entityPixels.ContainsKey((px, py))) continue; + + int northHeight = py > 0 ? result.Heights[px, py - 1] : result.Heights[px, py]; + int delta = result.Heights[px, py] - northHeight; + result.Pixels[px, py] = MinimapColorMap.ApplyHeightShade(result.Pixels[px, py], delta); + } + } + + foreach (var (key, info) in entityPixels) + { + var (px, py) = key; + if (px >= 0 && px < mapW && py >= 0 && py < mapH) + result.Pixels[px, py] = info.Color; + } + + BakeNameLabels(result, nameLabels, mapW, mapH); + + return result; + } + + private static string ResolveEntityName(McClient client, Entity entity, + MobCategory cat, Dictionary? uuidNameMap) + { + if (cat == MobCategory.Player) + { + if (!string.IsNullOrWhiteSpace(entity.Name)) + return entity.Name; + + if (entity.UUID != System.Guid.Empty) + { + var playerInfo = client.GetPlayerInfo(entity.UUID); + if (!string.IsNullOrWhiteSpace(playerInfo?.Name)) + return playerInfo.Name; + + if (uuidNameMap is not null && + uuidNameMap.TryGetValue(entity.UUID.ToString(), out string? mapped) && + !string.IsNullOrWhiteSpace(mapped)) + return mapped; + } + + return "Player"; + } + + if (!string.IsNullOrWhiteSpace(entity.Name)) + return entity.Name; + + return entity.Type.ToString(); + } + + private static void BakeNameLabels(SampleResult result, List labels, + int mapW, int mapH) + { + if (labels.Count == 0) return; + int cellRows = mapH / 2; + + var occupied = new HashSet<(int col, int row)>(); + + labels.Sort((a, b) => + { + int pa = MinimapEntityClassifier.GetPriority( + a.LabelColor == MinimapEntityClassifier.PlayerColor ? MobCategory.Player : + a.LabelColor == MinimapEntityClassifier.HostileColor ? MobCategory.Hostile : + a.LabelColor == MinimapEntityClassifier.NeutralColor ? MobCategory.Neutral : MobCategory.Passive); + int pb = MinimapEntityClassifier.GetPriority( + b.LabelColor == MinimapEntityClassifier.PlayerColor ? MobCategory.Player : + b.LabelColor == MinimapEntityClassifier.HostileColor ? MobCategory.Hostile : + b.LabelColor == MinimapEntityClassifier.NeutralColor ? MobCategory.Neutral : MobCategory.Passive); + return pb.CompareTo(pa); + }); + + foreach (var lbl in labels) + { + int cellRow = (lbl.PixelY / 2) + 1; + if (cellRow >= cellRows) cellRow = lbl.PixelY / 2 - 1; + if (cellRow < 0 || cellRow >= cellRows) continue; + + int startCol = lbl.PixelX - lbl.Name.Length / 2; + startCol = Math.Clamp(startCol, 0, mapW - 1); + + bool fits = true; + int endCol = Math.Min(startCol + lbl.Name.Length, mapW); + for (int c = startCol; c < endCol; c++) + { + if (occupied.Contains((c, cellRow))) + { + fits = false; + break; + } + } + if (!fits) continue; + + for (int i = 0; i < lbl.Name.Length && startCol + i < mapW; i++) + { + int col = startCol + i; + occupied.Add((col, cellRow)); + + var bgTop = result.Pixels[col, cellRow * 2]; + var bgBot = (cellRow * 2 + 1 < mapH) + ? result.Pixels[col, cellRow * 2 + 1] + : bgTop; + + var avgBg = Color.FromRgb( + (byte)((bgTop.R + bgBot.R) / 2), + (byte)((bgTop.G + bgBot.G) / 2), + (byte)((bgTop.B + bgBot.B) / 2)); + + result.CharOverlay[col, cellRow] = (lbl.Name[i], lbl.LabelColor, avgBg); + } + } + } + + private static (Color color, int surfaceY) SampleColumn(World world, int x, int z, + int scanTop, int minY, + ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) + { + int chunkX = x >> 4; + int chunkZ = z >> 4; + if (chunkX != cachedChunkX || chunkZ != cachedChunkZ) + { + cachedColumn = world[chunkX, chunkZ]; + cachedChunkX = chunkX; + cachedChunkZ = chunkZ; + } + + if (cachedColumn is null) + return (MinimapColorMap.VoidColor, minY); + + int waterDepth = 0; + bool inIce = false; + int surfaceY = minY; + + for (int y = scanTop; y >= minY; y--) + { + var loc = new Mapping.Location(x, y, z); + var chunk = cachedColumn.GetChunk(loc); + if (chunk is null) continue; + + var block = chunk.GetBlock(loc); + var mat = block.Type; + + if (MinimapColorMap.IsFullyTransparent(mat)) + continue; + + if (MinimapColorMap.IsWater(mat)) + { + if (waterDepth == 0) surfaceY = y; + waterDepth++; + continue; + } + + if (MinimapColorMap.IsIce(mat) && !inIce) + { + if (waterDepth == 0) surfaceY = y; + inIce = true; + continue; + } + + if (waterDepth == 0 && !inIce) surfaceY = y; + + var baseColor = MinimapColorMap.GetBaseColor(mat); + + if (waterDepth > 0) + baseColor = MinimapColorMap.BlendWaterColor(baseColor, waterDepth); + if (inIce) + baseColor = MinimapColorMap.BlendIceColor(baseColor); + + return (baseColor, surfaceY); + } + + if (waterDepth > 0) + return (MinimapColorMap.WaterColor, surfaceY); + + return (MinimapColorMap.VoidColor, minY); + } + + private static (Color color, int surfaceY) SampleAreaDominant(World world, int baseX, int baseZ, + int size, int scanTop, int minY, + ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) + { + var colorCounts = new Dictionary(); + + int step = Math.Max(1, size / 3); + for (int dx = 0; dx < size; dx += step) + { + for (int dz = 0; dz < size; dz += step) + { + var (c, surfY) = SampleColumn(world, baseX + dx, baseZ + dz, scanTop, minY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + + if (colorCounts.TryGetValue(c, out var existing)) + colorCounts[c] = (existing.Count + 1, existing.SumY + surfY); + else + colorCounts[c] = (1, surfY); + } + } + + Color best = MinimapColorMap.VoidColor; + int bestCount = 0; + int avgY = minY; + foreach (var kvp in colorCounts) + { + if (kvp.Value.Count > bestCount) + { + bestCount = kvp.Value.Count; + best = kvp.Key; + avgY = kvp.Value.SumY / kvp.Value.Count; + } + } + return (best, avgY); + } + + private void ApplyPixelBuffer(SampleResult result, int w, int h) + { + int rows = h / 2; + for (int row = 0; row < rows && row < _cellRows; row++) + { + for (int col = 0; col < w && col < _mapWidth; col++) + { + var overlay = result.CharOverlay[col, row]; + if (overlay is not null) + { + var (ch, fg, bg) = overlay.Value; + _cells[row, col].Text = ch.ToString(); + _cells[row, col].Foreground = new SolidColorBrush(fg); + _cells[row, col].Background = new SolidColorBrush(bg); + } + else + { + var topColor = result.Pixels[col, row * 2]; + var bottomColor = result.Pixels[col, row * 2 + 1]; + + _cells[row, col].Text = "\u2580"; + _cells[row, col].Foreground = new SolidColorBrush(topColor); + _cells[row, col].Background = new SolidColorBrush(bottomColor); + } + } + } + } + + private void UpdateInfoBarAndLegend(McClient client, int bpp, + HashSet categories, int mapW) + { + var loc = client.GetCurrentLocation(); + float yaw = client.GetYaw(); + string arrow = GetDirectionArrow(yaw); + + int x = (int)Math.Floor(loc.X); + int y = (int)Math.Floor(loc.Y); + int z = (int)Math.Floor(loc.Z); + + string coordPart = $"{x}, {y}, {z} {arrow} {bpp}:1"; + + var legendParts = new List(); + var legendColors = new List(); + + var sorted = categories + .Where(c => c != MobCategory.NonLiving) + .OrderByDescending(MinimapEntityClassifier.GetPriority); + + int catCount = 0; + foreach (var cat in sorted) + { + if (catCount >= 4) break; + legendParts.Add(MinimapEntityClassifier.GetCategoryLabel(cat)); + legendColors.Add(MinimapEntityClassifier.GetBaseColor(cat)); + catCount++; + } + + int legendLen = 0; + for (int i = 0; i < legendParts.Count; i++) + legendLen += 1 + legendParts[i].Length + (i > 0 ? 1 : 0); + + bool fitsOnOneLine = legendParts.Count > 0 + && coordPart.Length + 2 + legendLen <= mapW; + + _infoRow.Children.Clear(); + _infoRow.Children.Add(new TextBlock + { + Text = coordPart, + Foreground = Brushes.Gray, + Padding = new Thickness(0), + }); + + if (fitsOnOneLine) + { + AppendLegendItems(_infoRow, legendParts, legendColors, leftMargin: 2); + _legendPanel.Children.Clear(); + _legendPanel.IsVisible = false; + } + else + { + _legendPanel.IsVisible = legendParts.Count > 0; + _legendPanel.Children.Clear(); + AppendLegendItems(_legendPanel, legendParts, legendColors, leftMargin: 0); + } + } + + private static void AppendLegendItems(StackPanel panel, + List parts, List colors, int leftMargin) + { + for (int i = 0; i < parts.Count; i++) + { + int ml = i == 0 ? leftMargin : 1; + panel.Children.Add(new TextBlock + { + Text = "\u25cf", + Foreground = new SolidColorBrush(colors[i]), + Padding = new Thickness(0), + Margin = ml > 0 ? new Thickness(ml, 0, 0, 0) : new Thickness(0), + }); + panel.Children.Add(new TextBlock + { + Text = parts[i], + Foreground = Brushes.Gray, + Padding = new Thickness(0), + Margin = new Thickness(0), + }); + } + } + + private static string GetDirectionArrow(float yaw) + { + double normalized = ((yaw % 360) + 360) % 360; + int index = (int)Math.Round(normalized / 45.0) % 8; + return index switch + { + 0 => "\u2193", // S + 1 => "\u2199", // SW + 2 => "\u2190", // W + 3 => "\u2196", // NW + 4 => "\u2191", // N + 5 => "\u2197", // NE + 6 => "\u2192", // E + 7 => "\u2198", // SE + _ => "\u2193", + }; + } + } +} diff --git a/MinecraftClient/Tui/MinimapEntityCategories.json b/MinecraftClient/Tui/MinimapEntityCategories.json new file mode 100644 index 00000000..c80b7c0b --- /dev/null +++ b/MinecraftClient/Tui/MinimapEntityCategories.json @@ -0,0 +1,167 @@ +{ + "version": "26.1-rc-2", + "hostile": [ + "Blaze", + "Bogged", + "Breeze", + "CamelHusk", + "Creaking", + "Creeper", + "Drowned", + "ElderGuardian", + "EnderDragon", + "Endermite", + "Evoker", + "Ghast", + "Giant", + "Guardian", + "Hoglin", + "Husk", + "Illusioner", + "MagmaCube", + "Parched", + "Phantom", + "Piglin", + "PiglinBrute", + "Pillager", + "Ravager", + "Shulker", + "Silverfish", + "Skeleton", + "Slime", + "Stray", + "Vex", + "Vindicator", + "Warden", + "Witch", + "Wither", + "WitherSkeleton", + "Zoglin", + "Zombie", + "ZombieNautilus", + "ZombieVillager" + ], + "passive": [ + "Allay", + "Armadillo", + "Axolotl", + "Bat", + "Camel", + "Cat", + "Chicken", + "Cod", + "Cow", + "Donkey", + "Fox", + "Frog", + "GlowSquid", + "HappyGhast", + "Horse", + "Mooshroom", + "Mule", + "Nautilus", + "Ocelot", + "Parrot", + "Pig", + "Pufferfish", + "Rabbit", + "Salmon", + "Sheep", + "SkeletonHorse", + "Sniffer", + "Squid", + "Strider", + "Tadpole", + "TropicalFish", + "Turtle", + "Villager", + "WanderingTrader", + "ZombieHorse" + ], + "neutral": [ + "Bee", + "CaveSpider", + "CopperGolem", + "Dolphin", + "Enderman", + "Goat", + "IronGolem", + "Llama", + "Panda", + "PolarBear", + "SnowGolem", + "Spider", + "TraderLlama", + "Wolf", + "ZombifiedPiglin" + ], + "non_living": [ + "AcaciaBoat", + "AcaciaChestBoat", + "AreaEffectCloud", + "ArmorStand", + "Arrow", + "BambooChestRaft", + "BambooRaft", + "BirchBoat", + "BirchChestBoat", + "BlockDisplay", + "BreezeWindCharge", + "CherryBoat", + "CherryChestBoat", + "ChestMinecart", + "CommandBlockMinecart", + "DarkOakBoat", + "DarkOakChestBoat", + "DragonFireball", + "Egg", + "EndCrystal", + "EnderPearl", + "EvokerFangs", + "ExperienceBottle", + "ExperienceOrb", + "EyeOfEnder", + "FallingBlock", + "Fireball", + "FireworkRocket", + "FishingBobber", + "FurnaceMinecart", + "GlowItemFrame", + "HopperMinecart", + "Interaction", + "Item", + "ItemDisplay", + "ItemFrame", + "JungleBoat", + "JungleChestBoat", + "LeashKnot", + "LightningBolt", + "LingeringPotion", + "LlamaSpit", + "MangroveBoat", + "MangroveChestBoat", + "Mannequin", + "Marker", + "Minecart", + "OakBoat", + "OakChestBoat", + "OminousItemSpawner", + "Painting", + "PaleOakBoat", + "PaleOakChestBoat", + "ShulkerBullet", + "SmallFireball", + "Snowball", + "SpawnerMinecart", + "SpectralArrow", + "SplashPotion", + "SpruceBoat", + "SpruceChestBoat", + "TextDisplay", + "Tnt", + "TntMinecart", + "Trident", + "WindCharge", + "WitherSkull" + ] +} \ No newline at end of file diff --git a/MinecraftClient/Tui/MinimapEntityClassifier.cs b/MinecraftClient/Tui/MinimapEntityClassifier.cs new file mode 100644 index 00000000..2daf1ea6 --- /dev/null +++ b/MinecraftClient/Tui/MinimapEntityClassifier.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Reflection; +using System.Text.Json; +using Avalonia.Media; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Tui +{ + public enum MobCategory + { + Hostile, + Passive, + Neutral, + Player, + NonLiving, + } + + public enum MinimapPosition + { + top_left, + top_right, + center, + bottom_left, + bottom_right, + } + + public sealed class NameDisplayConfig + { + public volatile bool Players = false; + public volatile bool Hostile = false; + public volatile bool Neutral = false; + public volatile bool Passive = false; + + public bool AnyEnabled => Players || Hostile || Neutral || Passive; + + public void SetAll(bool value) + { + Players = value; + Hostile = value; + Neutral = value; + Passive = value; + } + + public bool ShouldShowName(MobCategory category) => category switch + { + MobCategory.Player => Players, + MobCategory.Hostile => Hostile, + MobCategory.Neutral => Neutral, + MobCategory.Passive => Passive, + _ => false, + }; + } + + /// + /// Classifies entities into minimap categories using data extracted from + /// Minecraft's MobCategory assignments. Categories are loaded from the + /// embedded MinimapEntityCategories.json resource generated by + /// tools/gen_entity_category_map.py. + /// + public static class MinimapEntityClassifier + { + public static readonly Color HostileColor = Color.FromRgb(255, 68, 68); + public static readonly Color PassiveColor = Color.FromRgb(68, 255, 68); + public static readonly Color NeutralColor = Color.FromRgb(255, 170, 0); + public static readonly Color PlayerColor = Color.FromRgb(255, 255, 255); + public static readonly Color FadedGray = Color.FromRgb(100, 100, 100); + + private static readonly FrozenDictionary CategoryTable; + + static MinimapEntityClassifier() + { + var table = new Dictionary(); + + try + { + using var stream = Assembly.GetExecutingAssembly() + .GetManifestResourceStream("MinimapEntityCategories.json"); + if (stream is not null) + { + using var doc = JsonDocument.Parse(stream); + var root = doc.RootElement; + + LoadCategory(root, "hostile", MobCategory.Hostile, table); + LoadCategory(root, "passive", MobCategory.Passive, table); + LoadCategory(root, "neutral", MobCategory.Neutral, table); + LoadCategory(root, "non_living", MobCategory.NonLiving, table); + } + } + catch (Exception ex) + { + ConsoleIO.WriteLogLine($"[Minimap] Failed to load entity categories: {ex.Message}"); + } + + CategoryTable = table.ToFrozenDictionary(); + } + + private static void LoadCategory(JsonElement root, string key, + MobCategory category, Dictionary table) + { + if (!root.TryGetProperty(key, out var arr)) + return; + + foreach (var el in arr.EnumerateArray()) + { + var name = el.GetString(); + if (name is not null && Enum.TryParse(name, out var et)) + table.TryAdd(et, category); + } + } + + public static MobCategory Classify(EntityType type) + { + if (type == EntityType.Player) + return MobCategory.Player; + return CategoryTable.GetValueOrDefault(type, MobCategory.NonLiving); + } + + public static Color GetBaseColor(MobCategory category) => category switch + { + MobCategory.Hostile => HostileColor, + MobCategory.Passive => PassiveColor, + MobCategory.Neutral => NeutralColor, + MobCategory.Player => PlayerColor, + _ => FadedGray, + }; + + public static Color ApplyDepthFade(Color baseColor, double playerY, double entityY) + { + double depth = playerY - entityY; + + if (depth <= 5.0) + return baseColor; + + if (depth >= 15.0) + return FadedGray; + + double t = (depth - 5.0) / 10.0; + return Lerp(baseColor, FadedGray, t); + } + + public static bool ShouldDisplay(MobCategory category, double playerY, double entityY) + { + if (category == MobCategory.Player) + return true; + if (entityY >= playerY) + return true; + return playerY - entityY <= 15.0; + } + + public static int GetPriority(MobCategory category) => category switch + { + MobCategory.Hostile => 4, + MobCategory.Player => 3, + MobCategory.Neutral => 2, + MobCategory.Passive => 1, + _ => 0, + }; + + public static string GetCategoryLabel(MobCategory category) => category switch + { + MobCategory.Hostile => Translations.tui_minimap_legend_hostile, + MobCategory.Passive => Translations.tui_minimap_legend_passive, + MobCategory.Neutral => Translations.tui_minimap_legend_neutral, + MobCategory.Player => Translations.tui_minimap_legend_player, + _ => "?", + }; + + private static Color Lerp(Color a, Color b, double t) + { + byte r = (byte)(a.R + (b.R - a.R) * t); + byte g = (byte)(a.G + (b.G - a.G) * t); + byte bl = (byte)(a.B + (b.B - a.B) * t); + return Color.FromRgb(r, g, bl); + } + } +} diff --git a/tools/README.md b/tools/README.md index 4dceae9c..7d33d2cf 100644 --- a/tools/README.md +++ b/tools/README.md @@ -135,6 +135,44 @@ Data source: `https://raw.githubusercontent.com/PrismarineJS/minecraft-data/mast Uses `curl` with resume (`-C -`) for reliable download over slow connections. Falls back to manual download if retries are exhausted. +## gen_block_color_map.py -- Generate minimap block color JSON + +Extracts block-to-MapColor RGB mappings from decompiled Minecraft source for the TUI minimap. + +```bash +python3 tools/gen_block_color_map.py MinecraftOfficial/26.1-rc-2-decompiled +# -> MinecraftClient/Tui/MinimapBlockColors.json +``` + +Parses three files from the decompiled source: +- `MapColor.java` -- extracts the 64 base MapColor constants and their RGB values +- `DyeColor.java` -- maps dye colors to MapColor constants +- `Blocks.java` -- determines each block's assigned MapColor via `.mapColor()` calls + +Output: `MinecraftClient/Tui/MinimapBlockColors.json` (embedded as a resource via `.csproj`). Contains color entries, plus lists of transparent, water, and ice materials. + +Validates each block name against MCC's `Material.cs` enum. Blocks without a matching enum value are skipped. + +## gen_entity_category_map.py -- Generate minimap entity category JSON + +Extracts entity-to-MobCategory mappings from decompiled Minecraft source for the TUI minimap. + +```bash +python3 tools/gen_entity_category_map.py MinecraftOfficial/26.1-rc-2-decompiled +# -> MinecraftClient/Tui/MinimapEntityCategories.json +``` + +Parses `EntityType.java` to read each entity's `MobCategory` assignment from the `EntityType.Builder.of(Factory, MobCategory.XXX)` call. Maps Minecraft categories to MCC minimap categories: +- `MONSTER` -> hostile +- `CREATURE`/`AMBIENT`/`AXOLOTLS`/`WATER_*` -> passive +- `MISC` -> non_living + +The script maintains manual override lists for: +- **Neutral mobs** (e.g. Enderman, Spider, Wolf, Bee) -- Minecraft has no "neutral" category; these are MONSTER or CREATURE in code but only attack when provoked +- **Passive overrides** (e.g. Villager, WanderingTrader) -- classified as MISC in Minecraft for spawning reasons but should appear as passive on the minimap + +Output: `MinecraftClient/Tui/MinimapEntityCategories.json` (embedded as a resource via `.csproj`). Validates each entity name against MCC's `EntityType.cs` enum. + ## Recommended workflow 1. Generate server reports (Step 0) @@ -145,6 +183,9 @@ Uses `curl` with resume (`-C -`) for reliable download over slow connections. Fa - Entities: `gen_entity_palette.py` - Metadata: `gen_entity_metadata_palette.py` 4. Update block collision shapes: `gen_block_shapes.py` -5. Add any missing enum values to `ItemType.cs`, `Material.cs`, `EntityType.cs`, `EntityMetaDataType.cs` -6. Update version routing (see SKILL.md) -7. Build and test +5. Update minimap data (if blocks or entities changed): + - Block colors: `gen_block_color_map.py` + - Entity categories: `gen_entity_category_map.py` +6. Add any missing enum values to `ItemType.cs`, `Material.cs`, `EntityType.cs`, `EntityMetaDataType.cs` +7. Update version routing (see SKILL.md) +8. Build and test diff --git a/tools/gen_block_color_map.py b/tools/gen_block_color_map.py new file mode 100644 index 00000000..69cbb502 --- /dev/null +++ b/tools/gen_block_color_map.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python3 +""" +Generate MinimapBlockColors.json from decompiled Minecraft source. + +Parses MapColor.java for the 62 base map colors (ID -> RGB), then parses +Blocks.java to extract each block's mapColor assignment, and outputs a +JSON mapping from MCC Material enum names (PascalCase) to RGB triples. + +Usage: + python3 tools/gen_block_color_map.py + +Example: + python3 tools/gen_block_color_map.py MinecraftOfficial/26.1-rc-2-decompiled +""" + +import json +import re +import sys +from pathlib import Path + +OUTPUT_PATH = (Path(__file__).resolve().parent.parent + / "MinecraftClient" / "Tui" / "MinimapBlockColors.json") +MATERIAL_CS = (Path(__file__).resolve().parent.parent + / "MinecraftClient" / "Mapping" / "Material.cs") + + +def mc_name_to_csharp(mc_name: str) -> str: + name = mc_name.removeprefix("minecraft:") + return "".join(word.capitalize() for word in name.split("_")) + + +def parse_map_colors(map_color_java: Path) -> dict[str, tuple[int, int, int]]: + """Parse MapColor.java: extract name -> (R, G, B) for each constant.""" + text = map_color_java.read_text() + colors: dict[str, tuple[int, int, int]] = {} + + pattern = re.compile( + r'public static final MapColor\s+(\w+)\s*=\s*new\s+MapColor\(\s*(\d+)\s*,\s*(\d+)\s*\)') + for m in pattern.finditer(text): + name = m.group(1) + color_int = int(m.group(3)) + r = (color_int >> 16) & 0xFF + g = (color_int >> 8) & 0xFF + b = color_int & 0xFF + colors[name] = (r, g, b) + + return colors + + +def parse_dye_to_map_color(dye_color_java: Path) -> dict[str, str]: + """Parse DyeColor.java: extract DyeColor name -> MapColor name.""" + text = dye_color_java.read_text() + mapping: dict[str, str] = {} + + pattern = re.compile( + r'(\w+)\(\d+,\s*"[^"]+",\s*\d+,\s*MapColor\.(\w+)') + for m in pattern.finditer(text): + mapping[m.group(1)] = m.group(2) + + return mapping + + +def extract_block_declarations(text: str) -> list[tuple[str, str, str]]: + """Extract (field_name, block_id, full_register_body) for each block declaration. + + Returns list of (FIELD_NAME, "block_name", "register(...) content"). + """ + results = [] + + # Find all "public static final Block FIELD = register(...)" declarations. + # These span multiple lines and end with ");". + # Strategy: find start pattern, then track parens to find matching end. + field_pattern = re.compile( + r'public\s+static\s+final\s+Block\s+(\w+)\s*=\s*register\s*\(') + + pos = 0 + while pos < len(text): + m = field_pattern.search(text, pos) + if not m: + break + + field_name = m.group(1) + paren_start = m.end() - 1 # position of opening '(' + + # Find matching closing ')' then ';' + depth = 1 + i = paren_start + 1 + while i < len(text) and depth > 0: + if text[i] == '(': + depth += 1 + elif text[i] == ')': + depth -= 1 + i += 1 + + register_body = text[paren_start:i] + + # Extract block name string from register call + name_match = re.search(r'(?:BlockIds\.(\w+)|"(\w+)")', register_body) + if name_match: + raw_id = name_match.group(1) or name_match.group(2) + block_id = raw_id.lower() if raw_id.isupper() else raw_id + else: + block_id = field_name.lower() + + results.append((field_name, block_id, register_body)) + pos = i + + return results + + +def parse_blocks(blocks_java: Path, map_colors: dict[str, tuple[int, int, int]], + dye_to_map: dict[str, str]) -> dict[str, tuple[int, int, int]]: + """Parse Blocks.java: extract block_name -> (R, G, B).""" + text = blocks_java.read_text() + + declarations = extract_block_declarations(text) + print(f" Found {len(declarations)} block register() declarations") + + # First pass: assign MapColor name to each block + field_to_block_id: dict[str, str] = {} + block_color_name: dict[str, str] = {} + + map_color_direct = re.compile(r'\.mapColor\(MapColor\.(\w+)\)') + map_color_dye = re.compile(r'\.mapColor\(DyeColor\.(\w+)\)') + map_color_ref = re.compile(r'\.mapColor\((\w+)\.defaultMapColor\(\)') + map_color_waterlogged = re.compile(r'\.mapColor\(waterloggedMapColor\(MapColor\.(\w+)\)') + + for field_name, block_id, body in declarations: + field_to_block_id[field_name] = block_id + + mc = map_color_direct.search(body) + if mc: + block_color_name[block_id] = mc.group(1) + continue + + mc = map_color_dye.search(body) + if mc: + dye_name = mc.group(1) + if dye_name in dye_to_map: + block_color_name[block_id] = dye_to_map[dye_name] + continue + + mc = map_color_waterlogged.search(body) + if mc: + block_color_name[block_id] = mc.group(1) + continue + + mc = map_color_ref.search(body) + if mc: + ref_field = mc.group(1) + ref_block = field_to_block_id.get(ref_field) + if ref_block and ref_block in block_color_name: + block_color_name[block_id] = block_color_name[ref_block] + + # Second pass: resolve remaining BLOCK.defaultMapColor() references + for field_name, block_id, body in declarations: + if block_id in block_color_name: + continue + mc = map_color_ref.search(body) + if mc: + ref_field = mc.group(1) + ref_block = field_to_block_id.get(ref_field) + if ref_block and ref_block in block_color_name: + block_color_name[block_id] = block_color_name[ref_block] + + result: dict[str, tuple[int, int, int]] = {} + for block_id, color_name in block_color_name.items(): + if color_name in map_colors: + cs_name = mc_name_to_csharp(block_id) + result[cs_name] = map_colors[color_name] + + return result + + +def load_known_materials() -> set[str]: + known = set() + if MATERIAL_CS.exists(): + with open(MATERIAL_CS) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m: + known.add(m.group(1)) + return known + + +TRANSPARENT_BLOCKS = [ + "Air", "CaveAir", "VoidAir", + "Glass", "GlassPane", + "WhiteStainedGlass", "OrangeStainedGlass", "MagentaStainedGlass", + "LightBlueStainedGlass", "YellowStainedGlass", "LimeStainedGlass", + "PinkStainedGlass", "GrayStainedGlass", "LightGrayStainedGlass", + "CyanStainedGlass", "PurpleStainedGlass", "BlueStainedGlass", + "BrownStainedGlass", "GreenStainedGlass", "RedStainedGlass", + "BlackStainedGlass", + "WhiteStainedGlassPane", "OrangeStainedGlassPane", "MagentaStainedGlassPane", + "LightBlueStainedGlassPane", "YellowStainedGlassPane", "LimeStainedGlassPane", + "PinkStainedGlassPane", "GrayStainedGlassPane", "LightGrayStainedGlassPane", + "CyanStainedGlassPane", "PurpleStainedGlassPane", "BlueStainedGlassPane", + "BrownStainedGlassPane", "GreenStainedGlassPane", "RedStainedGlassPane", + "BlackStainedGlassPane", + "TintedGlass", "Barrier", "Light", "StructureVoid", +] + +WATER_BLOCKS = ["Water"] +ICE_BLOCKS = ["Ice", "PackedIce", "BlueIce", "FrostedIce"] + + +def main(): + if len(sys.argv) != 2: + print(__doc__) + sys.exit(1) + + root = Path(sys.argv[1]) + if not root.is_dir(): + print(f"Error: {root} is not a directory") + sys.exit(1) + + map_color_java = root / "net/minecraft/world/level/material/MapColor.java" + dye_color_java = root / "net/minecraft/world/item/DyeColor.java" + blocks_java = root / "net/minecraft/world/level/block/Blocks.java" + + for f in [map_color_java, dye_color_java, blocks_java]: + if not f.exists(): + print(f"Error: {f} not found") + sys.exit(1) + + print("Parsing MapColor.java...") + map_colors = parse_map_colors(map_color_java) + print(f" Found {len(map_colors)} map colors") + + print("Parsing DyeColor.java...") + dye_to_map = parse_dye_to_map_color(dye_color_java) + print(f" Found {len(dye_to_map)} dye->map color mappings") + + print("Parsing Blocks.java...") + block_colors = parse_blocks(blocks_java, map_colors, dye_to_map) + print(f" Extracted colors for {len(block_colors)} blocks") + + known_materials = load_known_materials() + if known_materials: + matched = {k: v for k, v in block_colors.items() if k in known_materials} + unmatched = [k for k in block_colors if k not in known_materials] + if unmatched: + print(f"\n {len(unmatched)} blocks not in Material.cs (will be skipped):") + for name in sorted(unmatched)[:20]: + print(f" {name}") + if len(unmatched) > 20: + print(f" ... and {len(unmatched) - 20} more") + block_colors = matched + print(f" {len(block_colors)} blocks matched to Material.cs entries") + + output = { + "version": root.name.replace("-decompiled", "").replace("-client", ""), + "colors": {k: list(v) for k, v in sorted(block_colors.items())}, + "transparent": sorted(TRANSPARENT_BLOCKS), + "water": WATER_BLOCKS, + "ice": ICE_BLOCKS, + } + + OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True) + with open(OUTPUT_PATH, 'w') as f: + json.dump(output, f, indent=2) + print(f"\nGenerated {OUTPUT_PATH}") + print(f" {len(block_colors)} color entries") + + +if __name__ == "__main__": + main() diff --git a/tools/gen_entity_category_map.py b/tools/gen_entity_category_map.py new file mode 100644 index 00000000..e258d186 --- /dev/null +++ b/tools/gen_entity_category_map.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 +""" +Generate MinimapEntityCategories.json from decompiled Minecraft source. + +Parses EntityType.java to extract each entity's MobCategory assignment, +then maps them to MCC minimap categories (hostile/passive/neutral/non_living). + +Minecraft's MobCategory values: + MONSTER -> hostile (with neutral overrides for conditionally hostile mobs) + CREATURE -> passive (with neutral overrides for conditionally hostile mobs) + AMBIENT -> passive + AXOLOTLS -> passive + WATER_CREATURE -> passive + WATER_AMBIENT -> passive + UNDERGROUND_WATER_CREATURE -> passive + MISC -> non_living + +Some mobs classified as MONSTER or CREATURE are actually "neutral" -- they +only attack when provoked. These are listed in NEUTRAL_OVERRIDES below and +should be updated when new conditionally-hostile mobs are added. + +Usage: + python3 tools/gen_entity_category_map.py + +Example: + python3 tools/gen_entity_category_map.py MinecraftOfficial/26.1-rc-2-decompiled +""" + +import json +import re +import sys +from pathlib import Path + +OUTPUT_PATH = (Path(__file__).resolve().parent.parent + / "MinecraftClient" / "Tui" / "MinimapEntityCategories.json") +ENTITY_TYPE_CS = (Path(__file__).resolve().parent.parent + / "MinecraftClient" / "Mapping" / "EntityType.cs") + + +def mc_name_to_csharp(mc_name: str) -> str: + name = mc_name.removeprefix("minecraft:") + return "".join(word.capitalize() for word in name.split("_")) + + +# Mobs that Minecraft classifies as MONSTER or CREATURE but behave as +# "neutral" -- they only attack when provoked. This list is maintained +# manually because there is no machine-readable flag in the game data. +NEUTRAL_OVERRIDES = { + "bee", "dolphin", "goat", "iron_golem", "llama", "panda", + "polar_bear", "snow_golem", "trader_llama", "wolf", + "zombified_piglin", "enderman", "spider", "cave_spider", + "copper_golem", +} + +# Entities whose MobCategory in the game code doesn't match how they +# should appear on the minimap. For example, Villager and WanderingTrader +# are MISC in MC code (for spawning reasons) but should be passive on the map. +# ZombieHorse is MONSTER but is a rideable passive mob in practice. +PASSIVE_OVERRIDES = { + "villager", "wandering_trader", "zombie_horse", +} + +# Player has its own category in MCC -- extracted from MISC to "player". +PLAYER_OVERRIDES = {"player"} + +MC_TO_MCC = { + "MONSTER": "hostile", + "CREATURE": "passive", + "AMBIENT": "passive", + "AXOLOTLS": "passive", + "WATER_CREATURE": "passive", + "WATER_AMBIENT": "passive", + "UNDERGROUND_WATER_CREATURE": "passive", + "MISC": "non_living", +} + + +def extract_entity_categories(entity_type_java: Path) -> list[tuple[str, str, str]]: + """Extract (entity_id, field_name, MobCategory) from EntityType.java. + + Returns list of (entity_id, FIELD_NAME, MobCategory_name). + """ + text = entity_type_java.read_text() + results = [] + + field_pat = re.compile( + r'public\s+static\s+final\s+EntityType<[^>]+>\s+(\w+)\s*=\s*register\s*\(') + + pos = 0 + while pos < len(text): + m = field_pat.search(text, pos) + if not m: + break + + field_name = m.group(1) + paren_start = m.end() - 1 + depth = 1 + i = paren_start + 1 + while i < len(text) and depth > 0: + if text[i] == '(': + depth += 1 + elif text[i] == ')': + depth -= 1 + i += 1 + + body = text[paren_start:i] + + name_match = re.search(r'"(\w+)"', body) + entity_id = name_match.group(1) if name_match else field_name.lower() + + cat_match = re.search(r'MobCategory\.(\w+)', body) + mob_cat = cat_match.group(1) if cat_match else "MISC" + + results.append((entity_id, field_name, mob_cat)) + pos = i + + return results + + +def load_known_entity_types() -> set[str]: + known = set() + if ENTITY_TYPE_CS.exists(): + with open(ENTITY_TYPE_CS) as f: + for line in f: + m = re.match(r'\s+(\w+),?\s*$', line) + if m: + known.add(m.group(1)) + return known + + +def main(): + if len(sys.argv) != 2: + print(__doc__) + sys.exit(1) + + root = Path(sys.argv[1]) + entity_type_java = root / "net/minecraft/world/entity/EntityType.java" + + if not entity_type_java.exists(): + print(f"Error: {entity_type_java} not found") + sys.exit(1) + + print("Parsing EntityType.java...") + entities = extract_entity_categories(entity_type_java) + print(f" Found {len(entities)} entity type declarations") + + known_types = load_known_entity_types() + + hostile = [] + passive = [] + neutral = [] + non_living = [] + + for entity_id, field_name, mob_cat in entities: + cs_name = mc_name_to_csharp(entity_id) + + if known_types and cs_name not in known_types: + continue + + if entity_id in PLAYER_OVERRIDES: + continue + elif entity_id in NEUTRAL_OVERRIDES: + neutral.append(cs_name) + elif entity_id in PASSIVE_OVERRIDES: + passive.append(cs_name) + elif mob_cat in MC_TO_MCC: + cat = MC_TO_MCC[mob_cat] + if cat == "hostile": + hostile.append(cs_name) + elif cat == "passive": + passive.append(cs_name) + elif cat == "non_living": + non_living.append(cs_name) + else: + non_living.append(cs_name) + else: + non_living.append(cs_name) + + output = { + "version": root.name.replace("-decompiled", "").replace("-client", ""), + "hostile": sorted(hostile), + "passive": sorted(passive), + "neutral": sorted(neutral), + "non_living": sorted(non_living), + } + + OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True) + with open(OUTPUT_PATH, 'w') as f: + json.dump(output, f, indent=2) + + print(f"\nGenerated {OUTPUT_PATH}") + print(f" hostile: {len(hostile)}") + print(f" passive: {len(passive)}") + print(f" neutral: {len(neutral)}") + print(f" non_living: {len(non_living)}") + print(f" total: {len(hostile) + len(passive) + len(neutral) + len(non_living)}") + + +if __name__ == "__main__": + main() From a1516e96806a99242b17231c9f9de14ba4159e98 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 18:48:00 +0800 Subject: [PATCH 262/484] Add message aggregation and relay options for DiscordBridge - Introduced message aggregation functionality with a configurable interval to reduce Discord API rate limits. - Added options to relay all messages from Minecraft, including system messages, to Discord. - Updated configuration comments to reflect new settings and their purposes. --- MinecraftClient/ChatBots/DiscordBridge.cs | 71 +++++++++++++++++-- .../ConfigComments/ConfigComments.resx | 8 ++- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/MinecraftClient/ChatBots/DiscordBridge.cs b/MinecraftClient/ChatBots/DiscordBridge.cs index fa13f84e..3938ab6a 100644 --- a/MinecraftClient/ChatBots/DiscordBridge.cs +++ b/MinecraftClient/ChatBots/DiscordBridge.cs @@ -1,8 +1,11 @@ -using System; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using Brigadier.NET.Builder; using DSharpPlus; @@ -34,6 +37,9 @@ namespace MinecraftClient.ChatBots private DiscordChannel? discordChannel; private BridgeDirection bridgeDirection = BridgeDirection.Both; + private readonly ConcurrentQueue aggregationBuffer = new(); + private Timer? aggregationTimer; + public static Configs Config = new(); [TomlDoNotInlineObject] @@ -62,6 +68,12 @@ namespace MinecraftClient.ChatBots [TomlInlineComment("$ChatBot.DiscordBridge.AllowOtherBotMessages$")] public bool Allow_Other_Bot_Messages = false; + [TomlInlineComment("$ChatBot.DiscordBridge.RelayAllMessages$")] + public bool Relay_All_Messages = false; + + [TomlInlineComment("$ChatBot.DiscordBridge.MessageAggregationInterval$")] + public double Message_Aggregation_Interval = 3.0; + [TomlPrecedingComment("$ChatBot.DiscordBridge.Formats$")] public string PrivateMessageFormat = "**[Private Message]** {username}: {message}"; public string PublicMessageFormat = "{username}: {message}"; @@ -70,6 +82,8 @@ namespace MinecraftClient.ChatBots public void OnSettingUpdate() { Message_Send_Timeout = Message_Send_Timeout <= 0 ? 3 : Message_Send_Timeout; + if (Message_Aggregation_Interval < 0) + Message_Aggregation_Interval = 0; } } @@ -100,6 +114,12 @@ namespace MinecraftClient.ChatBots .Redirect(McClient.dispatcher.GetRoot().GetChild("help").GetChild(CommandName))) ); + if (Config.Message_Aggregation_Interval > 0) + { + var intervalMs = (int)(Config.Message_Aggregation_Interval * 1000); + aggregationTimer = new Timer(_ => FlushAggregationBuffer(), null, intervalMs, intervalMs); + } + Task.Run(async () => await MainAsync()); } @@ -107,6 +127,7 @@ namespace MinecraftClient.ChatBots { McClient.dispatcher.Unregister(CommandName); McClient.dispatcher.GetRoot().GetChild("help").RemoveChild(CommandName); + StopAggregation(); Disconnect(); } @@ -147,6 +168,40 @@ namespace MinecraftClient.ChatBots return r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.bot_DiscordBridge_direction, bridgeName)); } + private void FlushAggregationBuffer() + { + if (aggregationBuffer.IsEmpty || !CanSendMessages()) + return; + + var sb = new StringBuilder(); + while (aggregationBuffer.TryDequeue(out var line)) + { + if (sb.Length + line.Length + 1 > 1900) + { + SendMessage(sb.ToString()); + sb.Clear(); + } + + if (sb.Length > 0) + sb.AppendLine(); + sb.Append(line); + } + + if (sb.Length > 0) + SendMessage(sb.ToString()); + } + + private void StopAggregation() + { + if (aggregationTimer is not null) + { + aggregationTimer.Dispose(); + aggregationTimer = null; + } + + FlushAggregationBuffer(); + } + ~DiscordBridge() { Disconnect(); @@ -188,7 +243,6 @@ namespace MinecraftClient.ChatBots text = GetVerbatim(text).Trim(); - // Stop the crash when an empty text is recived somehow if (string.IsNullOrEmpty(text)) return; @@ -205,7 +259,10 @@ namespace MinecraftClient.ChatBots message = Config.TeleportRequestMessageFormat.Replace("{username}", username).Replace("{timestamp}", GetTimestamp()).Trim(); teleportRequest = true; } - else message = text; + else if (Config.Relay_All_Messages) + message = text; + else + return; if (teleportRequest) { @@ -223,7 +280,13 @@ namespace MinecraftClient.ChatBots SendMessage(messageBuilder); return; } - else SendMessage(GetDiscordText(message)); + + string discordText = GetDiscordText(message); + + if (Config.Message_Aggregation_Interval > 0) + aggregationBuffer.Enqueue(discordText); + else + SendMessage(discordText); } /// diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index d4b82e42..2b09765e 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -393,6 +393,12 @@ For Discord message formatting, check the following: https://mccteam.github.io/r When enabled, messages from other Discord bots in the channel will be relayed to Minecraft chat. The bridge always ignores its own messages to prevent loops. + + When enabled, all text received from the Minecraft server (including system messages, join/leave notifications, etc.) will be relayed to Discord, not just player chat and private messages. + + + Interval in seconds to aggregate messages before sending them to Discord. When set to 0, messages are sent immediately one by one. When set to a value like 1.0, messages received within that interval are batched into a single Discord message. Useful for reducing Discord API rate limits. + Automatically farms crops for you (plants, breaks and bonemeals them). Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat. @@ -964,7 +970,7 @@ Note: This does NOT require a Bot Token, only an Application ID. Discord must be Show passive mob names on the minimap. - Minimap refresh interval in milliseconds (200-5000, default 1000). + Minimap refresh interval in milliseconds (100-5000). Yggdrasil authlib multi-user selection. From 0566f2518b6d0b6837f254973b8ef8ef1bab94ac Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 19:16:33 +0800 Subject: [PATCH 263/484] Add tooltip functionality to MinimapControl - Introduced a tooltip system for displaying entity information on the minimap. - Enhanced the SampleResult class to include entity mapping and block type summaries. - Updated the rendering logic to incorporate tooltips and improve user interaction with the minimap. --- MinecraftClient/Tui/MinimapControl.cs | 354 ++++++++++++++++++++++++-- 1 file changed, 339 insertions(+), 15 deletions(-) diff --git a/MinecraftClient/Tui/MinimapControl.cs b/MinecraftClient/Tui/MinimapControl.cs index 44db58ba..1e93c390 100644 --- a/MinecraftClient/Tui/MinimapControl.cs +++ b/MinecraftClient/Tui/MinimapControl.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; +using Avalonia.Input; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Threading; @@ -44,6 +45,13 @@ namespace MinecraftClient.Tui private readonly Grid _mapGrid; private readonly DispatcherTimer _timer; + private readonly Canvas _tooltipCanvas; + private readonly Border _tooltipBorder; + private readonly StackPanel _tooltipContent; + private SampleResult? _lastResult; + private int _hoverCol = -1; + private int _hoverRow = -1; + public int BlocksPerPixel { get => _blocksPerPixel; @@ -75,14 +83,40 @@ namespace MinecraftClient.Tui _infoRow = new StackPanel { Orientation = Orientation.Horizontal }; _legendPanel = new StackPanel { Orientation = Orientation.Horizontal }; + _tooltipContent = new StackPanel { Orientation = Orientation.Vertical }; + _tooltipBorder = new Border + { + Background = new SolidColorBrush(Color.FromArgb(230, 20, 20, 20)), + BorderBrush = new SolidColorBrush(Color.FromRgb(120, 120, 120)), + BorderThickness = new Thickness(1), + Padding = new Thickness(1), + Child = _tooltipContent, + IsVisible = false, + }; + + _tooltipCanvas = new Canvas + { + IsHitTestVisible = false, + Children = { _tooltipBorder }, + }; + + var mapLayer = new Panel + { + ClipToBounds = true, + Children = { _mapGrid, _tooltipCanvas }, + }; + var root = new StackPanel { Orientation = Orientation.Vertical, - Children = { _mapGrid, _infoRow, _legendPanel }, + Children = { mapLayer, _infoRow, _legendPanel }, }; Content = root; + _mapGrid.PointerMoved += OnMapPointerMoved; + _mapGrid.PointerExited += OnMapPointerExited; + _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(DefaultRefreshMs), @@ -198,12 +232,29 @@ namespace MinecraftClient.Tui public int PixelY; } + internal sealed class PixelEntityInfo + { + public string Name = ""; + public MobCategory Category; + public float Health; + public float MaxHealth; + public int Priority; + } + private sealed class SampleResult { public Color[,] Pixels = null!; public (char Ch, Color Fg, Color Bg)?[,] CharOverlay = null!; public HashSet VisibleCategories = []; public int[,] Heights = null!; + public Material[,]? BlockTypes; + public List<(Material Mat, int Count)>?[,]? BlockSummary; + public List?[,]? EntityMap; + public int PlayerBlockX; + public int PlayerBlockZ; + public int CenterX; + public int CenterY; + public int Bpp; } private static bool ShouldShowNameLocal(MobCategory cat, @@ -228,6 +279,10 @@ namespace MinecraftClient.Tui Pixels = new Color[mapW, mapH], CharOverlay = new (char, Color, Color)?[mapW, mapH / 2], Heights = new int[mapW, mapH], + EntityMap = new List?[mapW, mapH], + BlockTypes = bpp == 1 ? new Material[mapW, mapH] : null, + BlockSummary = bpp > 1 ? new List<(Material, int)>?[mapW, mapH] : null, + Bpp = bpp, }; var world = client.GetWorld(); var playerLoc = client.GetCurrentLocation(); @@ -236,6 +291,11 @@ namespace MinecraftClient.Tui int playerBlockZ = (int)Math.Floor(playerLoc.Z); int playerBlockY = (int)Math.Floor(playerLoc.Y); + result.PlayerBlockX = playerBlockX; + result.PlayerBlockZ = playerBlockZ; + result.CenterX = mapW / 2; + result.CenterY = mapH / 2; + var dim = World.GetDimension(); int minY = dim.minY; int scanTop = Math.Min(playerBlockY + 32, dim.maxY - 1); @@ -286,6 +346,17 @@ namespace MinecraftClient.Tui result.VisibleCategories.Add(cat); + string eName = ResolveEntityName(client, entity, cat, uuidNameMap); + var pixelList = result.EntityMap![px, py] ??= []; + pixelList.Add(new PixelEntityInfo + { + Name = eName, + Category = cat, + Health = entity.Health, + MaxHealth = -1, + Priority = priority, + }); + if (ShouldShowNameLocal(cat, showPlayers, showHostile, showNeutral, showPassive)) { string name = ResolveEntityName(client, entity, cat, uuidNameMap); @@ -303,6 +374,16 @@ namespace MinecraftClient.Tui entityPixels[(centerX, centerY)] = (MinimapEntityClassifier.PlayerColor, 5); result.VisibleCategories.Add(MobCategory.Player); + var selfList = result.EntityMap![centerX, centerY] ??= []; + selfList.Add(new PixelEntityInfo + { + Name = client.GetUsername(), + Category = MobCategory.Player, + Health = client.GetHealth(), + MaxHealth = 20f, + Priority = 5, + }); + ChunkColumn? cachedColumn = null; int cachedChunkX = int.MinValue, cachedChunkZ = int.MinValue; @@ -317,17 +398,21 @@ namespace MinecraftClient.Tui if (bpp == 1) { - var (color, surfY) = SampleColumn(world, baseX, baseZ, scanTop, minY, + var (color, surfY, surfMat) = SampleColumn(world, baseX, baseZ, scanTop, minY, ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); result.Pixels[px, py] = color; result.Heights[px, py] = surfY; + result.BlockTypes![px, py] = surfMat; } else { - var (color, surfY) = SampleAreaDominant(world, baseX, baseZ, bpp, scanTop, minY, + var (color, surfY, matSum) = SampleAreaDominant(world, baseX, baseZ, bpp, + scanTop, minY, result.BlockSummary is not null, ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); result.Pixels[px, py] = color; result.Heights[px, py] = surfY; + if (result.BlockSummary is not null) + result.BlockSummary[px, py] = matSum; } } } @@ -447,7 +532,7 @@ namespace MinecraftClient.Tui } } - private static (Color color, int surfaceY) SampleColumn(World world, int x, int z, + private static (Color color, int surfaceY, Material surfaceMat) SampleColumn(World world, int x, int z, int scanTop, int minY, ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) { @@ -461,11 +546,12 @@ namespace MinecraftClient.Tui } if (cachedColumn is null) - return (MinimapColorMap.VoidColor, minY); + return (MinimapColorMap.VoidColor, minY, Material.Air); int waterDepth = 0; bool inIce = false; int surfaceY = minY; + Material topMat = Material.Air; for (int y = scanTop; y >= minY; y--) { @@ -481,19 +567,19 @@ namespace MinecraftClient.Tui if (MinimapColorMap.IsWater(mat)) { - if (waterDepth == 0) surfaceY = y; + if (waterDepth == 0) { surfaceY = y; topMat = mat; } waterDepth++; continue; } if (MinimapColorMap.IsIce(mat) && !inIce) { - if (waterDepth == 0) surfaceY = y; + if (waterDepth == 0) { surfaceY = y; topMat = mat; } inIce = true; continue; } - if (waterDepth == 0 && !inIce) surfaceY = y; + if (waterDepth == 0 && !inIce) { surfaceY = y; topMat = mat; } var baseColor = MinimapColorMap.GetBaseColor(mat); @@ -502,33 +588,43 @@ namespace MinecraftClient.Tui if (inIce) baseColor = MinimapColorMap.BlendIceColor(baseColor); - return (baseColor, surfaceY); + return (baseColor, surfaceY, topMat); } if (waterDepth > 0) - return (MinimapColorMap.WaterColor, surfaceY); + return (MinimapColorMap.WaterColor, surfaceY, topMat); - return (MinimapColorMap.VoidColor, minY); + return (MinimapColorMap.VoidColor, minY, Material.Air); } - private static (Color color, int surfaceY) SampleAreaDominant(World world, int baseX, int baseZ, - int size, int scanTop, int minY, + private static (Color color, int surfaceY, List<(Material Mat, int Count)>? matSummary) + SampleAreaDominant(World world, int baseX, int baseZ, + int size, int scanTop, int minY, bool collectMats, ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) { var colorCounts = new Dictionary(); + Dictionary? matCounts = collectMats ? [] : null; int step = Math.Max(1, size / 3); for (int dx = 0; dx < size; dx += step) { for (int dz = 0; dz < size; dz += step) { - var (c, surfY) = SampleColumn(world, baseX + dx, baseZ + dz, scanTop, minY, + var (c, surfY, surfMat) = SampleColumn(world, baseX + dx, baseZ + dz, scanTop, minY, ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); if (colorCounts.TryGetValue(c, out var existing)) colorCounts[c] = (existing.Count + 1, existing.SumY + surfY); else colorCounts[c] = (1, surfY); + + if (matCounts is not null) + { + if (matCounts.TryGetValue(surfMat, out int mc)) + matCounts[surfMat] = mc + 1; + else + matCounts[surfMat] = 1; + } } } @@ -544,7 +640,17 @@ namespace MinecraftClient.Tui avgY = kvp.Value.SumY / kvp.Value.Count; } } - return (best, avgY); + + List<(Material, int)>? summary = null; + if (matCounts is not null && matCounts.Count > 0) + { + summary = matCounts + .OrderByDescending(kv => kv.Value) + .Select(kv => (kv.Key, kv.Value)) + .ToList(); + } + + return (best, avgY, summary); } private void ApplyPixelBuffer(SampleResult result, int w, int h) @@ -573,6 +679,224 @@ namespace MinecraftClient.Tui } } } + + _lastResult = result; + + if (_hoverCol >= 0 && _hoverRow >= 0) + UpdateTooltip(_hoverCol, _hoverRow); + } + + private void OnMapPointerMoved(object? sender, PointerEventArgs e) + { + var pos = e.GetPosition(_mapGrid); + int col = (int)pos.X; + int row = (int)pos.Y; + + if (col < 0 || col >= _mapWidth || row < 0 || row >= _cellRows) + { + HideTooltip(); + return; + } + + _hoverCol = col; + _hoverRow = row; + UpdateTooltip(col, row); + } + + private void OnMapPointerExited(object? sender, PointerEventArgs e) + { + HideTooltip(); + } + + private void HideTooltip() + { + _hoverCol = -1; + _hoverRow = -1; + _tooltipBorder.IsVisible = false; + } + + private void UpdateTooltip(int col, int row) + { + var result = _lastResult; + if (result is null) { _tooltipBorder.IsVisible = false; return; } + + int bpp = result.Bpp; + int centerX = result.CenterX; + int centerY = result.CenterY; + + int topPixelY = row * 2; + int botPixelY = row * 2 + 1; + + int baseX = result.PlayerBlockX + (col - centerX) * bpp; + int baseZ_top = result.PlayerBlockZ + (topPixelY - centerY) * bpp; + int baseZ_bot = result.PlayerBlockZ + (botPixelY - centerY) * bpp; + + _tooltipContent.Children.Clear(); + + if (bpp == 1) + { + int surfY_top = (topPixelY < result.Heights.GetLength(1)) ? result.Heights[col, topPixelY] : 0; + int surfY_bot = (botPixelY < result.Heights.GetLength(1)) ? result.Heights[col, botPixelY] : 0; + + string coordLine = baseZ_top == baseZ_bot + ? $"{baseX}, {surfY_top}, {baseZ_top}" + : $"{baseX}, {surfY_top}, {baseZ_top} / {baseX}, {surfY_bot}, {baseZ_bot}"; + _tooltipContent.Children.Add(MakeTooltipText(coordLine, Brushes.White)); + + if (result.BlockTypes is not null) + { + var mat_top = result.BlockTypes[col, topPixelY]; + var mat_bot = (botPixelY < result.BlockTypes.GetLength(1)) + ? result.BlockTypes[col, botPixelY] : mat_top; + string blockLine = mat_top == mat_bot + ? FormatMaterialName(mat_top) + : $"{FormatMaterialName(mat_top)} / {FormatMaterialName(mat_bot)}"; + _tooltipContent.Children.Add(MakeTooltipText(blockLine, Brushes.LightGray)); + } + } + else + { + int endX = baseX + bpp - 1; + int endZ_bot = baseZ_bot + bpp - 1; + string coordLine = $"X {baseX}~{endX} Z {baseZ_top}~{endZ_bot}"; + _tooltipContent.Children.Add(MakeTooltipText(coordLine, Brushes.White)); + + AppendBlockSummary(result, col, topPixelY, botPixelY); + } + + AppendEntityInfo(result, col, topPixelY, botPixelY); + + if (_tooltipContent.Children.Count == 0) + { + _tooltipBorder.IsVisible = false; + return; + } + + int maxTipW = Math.Max(10, _mapWidth / 2 - 2); + _tooltipBorder.MaxWidth = maxTipW; + _tooltipBorder.MaxHeight = _cellRows; + + bool showRight = col < _mapWidth / 2; + int tipX = showRight ? col + 2 : Math.Max(0, col - maxTipW - 1); + int tipY = Math.Clamp(row, 0, _cellRows - 1); + + Canvas.SetLeft(_tooltipBorder, tipX); + Canvas.SetTop(_tooltipBorder, tipY); + _tooltipBorder.IsVisible = true; + } + + private void AppendBlockSummary(SampleResult result, int col, int topPy, int botPy) + { + if (result.BlockSummary is null) return; + + var merged = new Dictionary(); + MergeBlockCounts(result.BlockSummary, col, topPy, merged); + if (botPy < result.BlockSummary.GetLength(1)) + MergeBlockCounts(result.BlockSummary, col, botPy, merged); + + if (merged.Count == 0) return; + + var sorted = merged.OrderByDescending(kv => kv.Value).Take(4); + int totalSamples = 0; + foreach (var kv in merged) totalSamples += kv.Value; + + var parts = new List(); + foreach (var kv in sorted) + { + if (kv.Key == Material.Air && merged.Count > 1) continue; + parts.Add(kv.Value > 1 + ? $"{FormatMaterialName(kv.Key)} x{kv.Value}" + : FormatMaterialName(kv.Key)); + } + + if (parts.Count == 0) return; + + string line = string.Join(", ", parts); + _tooltipContent.Children.Add(MakeTooltipText(line, Brushes.LightGray)); + } + + private static void MergeBlockCounts(List<(Material Mat, int Count)>?[,] summary, + int px, int py, Dictionary target) + { + var list = summary[px, py]; + if (list is null) return; + foreach (var (mat, count) in list) + { + if (target.TryGetValue(mat, out int c)) + target[mat] = c + count; + else + target[mat] = count; + } + } + + private void AppendEntityInfo(SampleResult result, int col, int topPy, int botPy) + { + var entityMap = result.EntityMap; + if (entityMap is null) return; + + var combined = new List(); + AddEntitiesFromPixel(entityMap, col, topPy, combined); + if (botPy < entityMap.GetLength(1)) + AddEntitiesFromPixel(entityMap, col, botPy, combined); + + if (combined.Count == 0) return; + + combined.Sort((a, b) => b.Priority.CompareTo(a.Priority)); + int shown = 0; + var seen = new HashSet(); + foreach (var ent in combined) + { + if (shown >= 4) break; + string key = $"{ent.Name}_{ent.Health:F0}"; + if (!seen.Add(key)) continue; + + var catColor = MinimapEntityClassifier.GetBaseColor(ent.Category); + string hpStr; + if (ent.Health > 0) + { + hpStr = ent.MaxHealth > 0 + ? $" HP:{ent.Health:F0}/{ent.MaxHealth:F0}" + : $" HP:{ent.Health:F0}"; + } + else + hpStr = ""; + + _tooltipContent.Children.Add(MakeTooltipText( + $"{ent.Name}{hpStr}", + new SolidColorBrush(catColor))); + shown++; + } + } + + private static void AddEntitiesFromPixel(List?[,] map, + int px, int py, List target) + { + if (px >= 0 && px < map.GetLength(0) && py >= 0 && py < map.GetLength(1)) + { + var list = map[px, py]; + if (list is not null) + target.AddRange(list); + } + } + + private static TextBlock MakeTooltipText(string text, IBrush foreground) + { + return new TextBlock + { + Text = text, + Foreground = foreground, + TextWrapping = TextWrapping.Wrap, + Padding = new Thickness(0), + Margin = new Thickness(0), + FontSize = 1, + }; + } + + private static string FormatMaterialName(Material mat) + { + if (mat == Material.Air) return "Air"; + string raw = mat.ToString(); + return raw.Replace('_', ' '); } private void UpdateInfoBarAndLegend(McClient client, int bpp, From d427a6e16080a63160ab0a756625a4cacc6dcaec Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 19:53:31 +0800 Subject: [PATCH 264/484] Add tooltip service and integrate with MinimapControl - Introduced TuiTooltipService for managing tooltips across TUI components. - Updated MinimapControl to utilize the new tooltip service for enhanced entity information display. - Refactored tooltip rendering logic to improve visibility and interaction based on mouse position. --- MinecraftClient/Tui/MainTuiView.cs | 9 ++ MinecraftClient/Tui/MinimapControl.cs | 144 +++++++++++------------ MinecraftClient/Tui/TuiTooltipService.cs | 114 ++++++++++++++++++ 3 files changed, 194 insertions(+), 73 deletions(-) create mode 100644 MinecraftClient/Tui/TuiTooltipService.cs diff --git a/MinecraftClient/Tui/MainTuiView.cs b/MinecraftClient/Tui/MainTuiView.cs index 1cde95e4..34ff06db 100644 --- a/MinecraftClient/Tui/MainTuiView.cs +++ b/MinecraftClient/Tui/MainTuiView.cs @@ -45,6 +45,8 @@ namespace MinecraftClient.Tui private readonly MinimapControl _minimapControl; private volatile bool _minimapVisible; + private TuiTooltipService? _tooltipService; + private readonly Border _suggestionBorder; private readonly StackPanel _suggestionPanel; private CommandSuggestion[] _suggestions = Array.Empty(); @@ -57,6 +59,8 @@ namespace MinecraftClient.Tui private int MaxVisibleSuggestions => Math.Max(1, Settings.Config.Console.CommandSuggestion.Max_Displayed_Suggestions); + public TuiTooltipService? TooltipService => _tooltipService; + public MainTuiView() { Background = Brushes.Black; @@ -194,6 +198,10 @@ namespace MinecraftClient.Tui Children = { _mainContent, _minimapBorder, _notificationBorder, _suggestionBorder } }; + _tooltipService = new TuiTooltipService(_rootPanel); + _minimapControl.TooltipService = _tooltipService; + _minimapControl.Position = mmCfg.Position; + Content = _rootPanel; if (mmCfg.Enabled) @@ -1083,6 +1091,7 @@ namespace MinecraftClient.Tui _minimapBorder.HorizontalAlignment = hAlign; _minimapBorder.VerticalAlignment = vAlign; _minimapBorder.Margin = margin; + _minimapControl.Position = pos; Settings.Config.Console.Minimap.Position = pos; } diff --git a/MinecraftClient/Tui/MinimapControl.cs b/MinecraftClient/Tui/MinimapControl.cs index 1e93c390..33f25465 100644 --- a/MinecraftClient/Tui/MinimapControl.cs +++ b/MinecraftClient/Tui/MinimapControl.cs @@ -45,12 +45,11 @@ namespace MinecraftClient.Tui private readonly Grid _mapGrid; private readonly DispatcherTimer _timer; - private readonly Canvas _tooltipCanvas; - private readonly Border _tooltipBorder; - private readonly StackPanel _tooltipContent; private SampleResult? _lastResult; private int _hoverCol = -1; private int _hoverRow = -1; + private double _hoverGlobalX; + private double _hoverGlobalY; public int BlocksPerPixel { @@ -60,6 +59,10 @@ namespace MinecraftClient.Tui public NameDisplayConfig NameConfig => _nameConfig; + public TuiTooltipService? TooltipService { get; set; } + + public MinimapPosition Position { get; set; } = MinimapPosition.top_right; + public int MapPixelWidth => _mapWidth; public int MapPixelHeight => _mapHeight; @@ -83,33 +86,10 @@ namespace MinecraftClient.Tui _infoRow = new StackPanel { Orientation = Orientation.Horizontal }; _legendPanel = new StackPanel { Orientation = Orientation.Horizontal }; - _tooltipContent = new StackPanel { Orientation = Orientation.Vertical }; - _tooltipBorder = new Border - { - Background = new SolidColorBrush(Color.FromArgb(230, 20, 20, 20)), - BorderBrush = new SolidColorBrush(Color.FromRgb(120, 120, 120)), - BorderThickness = new Thickness(1), - Padding = new Thickness(1), - Child = _tooltipContent, - IsVisible = false, - }; - - _tooltipCanvas = new Canvas - { - IsHitTestVisible = false, - Children = { _tooltipBorder }, - }; - - var mapLayer = new Panel - { - ClipToBounds = true, - Children = { _mapGrid, _tooltipCanvas }, - }; - var root = new StackPanel { Orientation = Orientation.Vertical, - Children = { mapLayer, _infoRow, _legendPanel }, + Children = { _mapGrid, _infoRow, _legendPanel }, }; Content = root; @@ -236,6 +216,7 @@ namespace MinecraftClient.Tui { public string Name = ""; public MobCategory Category; + public double X, Y, Z; public float Health; public float MaxHealth; public int Priority; @@ -352,6 +333,9 @@ namespace MinecraftClient.Tui { Name = eName, Category = cat, + X = entity.Location.X, + Y = entity.Location.Y, + Z = entity.Location.Z, Health = entity.Health, MaxHealth = -1, Priority = priority, @@ -379,6 +363,9 @@ namespace MinecraftClient.Tui { Name = client.GetUsername(), Category = MobCategory.Player, + X = playerLoc.X, + Y = playerLoc.Y, + Z = playerLoc.Z, Health = client.GetHealth(), MaxHealth = 20f, Priority = 5, @@ -700,6 +687,19 @@ namespace MinecraftClient.Tui _hoverCol = col; _hoverRow = row; + + if (this.VisualRoot is Visual root + && _mapGrid.TranslatePoint(pos, root) is { } gp) + { + _hoverGlobalX = gp.X; + _hoverGlobalY = gp.Y; + } + else + { + _hoverGlobalX = pos.X; + _hoverGlobalY = pos.Y; + } + UpdateTooltip(col, row); } @@ -712,13 +712,14 @@ namespace MinecraftClient.Tui { _hoverCol = -1; _hoverRow = -1; - _tooltipBorder.IsVisible = false; + TooltipService?.Hide(); } private void UpdateTooltip(int col, int row) { + var svc = TooltipService; var result = _lastResult; - if (result is null) { _tooltipBorder.IsVisible = false; return; } + if (svc is null || result is null) { svc?.Hide(); return; } int bpp = result.Bpp; int centerX = result.CenterX; @@ -731,7 +732,7 @@ namespace MinecraftClient.Tui int baseZ_top = result.PlayerBlockZ + (topPixelY - centerY) * bpp; int baseZ_bot = result.PlayerBlockZ + (botPixelY - centerY) * bpp; - _tooltipContent.Children.Clear(); + var lines = new List(); if (bpp == 1) { @@ -741,7 +742,7 @@ namespace MinecraftClient.Tui string coordLine = baseZ_top == baseZ_bot ? $"{baseX}, {surfY_top}, {baseZ_top}" : $"{baseX}, {surfY_top}, {baseZ_top} / {baseX}, {surfY_bot}, {baseZ_bot}"; - _tooltipContent.Children.Add(MakeTooltipText(coordLine, Brushes.White)); + lines.Add(new TuiTooltipLine { Text = coordLine, Foreground = Brushes.White }); if (result.BlockTypes is not null) { @@ -751,7 +752,7 @@ namespace MinecraftClient.Tui string blockLine = mat_top == mat_bot ? FormatMaterialName(mat_top) : $"{FormatMaterialName(mat_top)} / {FormatMaterialName(mat_bot)}"; - _tooltipContent.Children.Add(MakeTooltipText(blockLine, Brushes.LightGray)); + lines.Add(new TuiTooltipLine { Text = blockLine, Foreground = Brushes.LightGray }); } } else @@ -759,33 +760,40 @@ namespace MinecraftClient.Tui int endX = baseX + bpp - 1; int endZ_bot = baseZ_bot + bpp - 1; string coordLine = $"X {baseX}~{endX} Z {baseZ_top}~{endZ_bot}"; - _tooltipContent.Children.Add(MakeTooltipText(coordLine, Brushes.White)); + lines.Add(new TuiTooltipLine { Text = coordLine, Foreground = Brushes.White }); - AppendBlockSummary(result, col, topPixelY, botPixelY); + AppendBlockSummaryLines(result, col, topPixelY, botPixelY, lines); } - AppendEntityInfo(result, col, topPixelY, botPixelY); + AppendEntityInfoLines(result, col, topPixelY, botPixelY, lines); - if (_tooltipContent.Children.Count == 0) + if (lines.Count == 0) { - _tooltipBorder.IsVisible = false; + svc.Hide(); return; } - int maxTipW = Math.Max(10, _mapWidth / 2 - 2); - _tooltipBorder.MaxWidth = maxTipW; - _tooltipBorder.MaxHeight = _cellRows; + bool preferRight = Position switch + { + MinimapPosition.top_left or MinimapPosition.bottom_left => true, + MinimapPosition.top_right or MinimapPosition.bottom_right => false, + _ => true, + }; - bool showRight = col < _mapWidth / 2; - int tipX = showRight ? col + 2 : Math.Max(0, col - maxTipW - 1); - int tipY = Math.Clamp(row, 0, _cellRows - 1); + double mx = _hoverGlobalX; + double my = _hoverGlobalY; - Canvas.SetLeft(_tooltipBorder, tipX); - Canvas.SetTop(_tooltipBorder, tipY); - _tooltipBorder.IsVisible = true; + if (Position == MinimapPosition.center + && this.VisualRoot is Visual root) + { + preferRight = mx < root.Bounds.Width / 2; + } + + svc.Show(mx, my, lines, preferRight); } - private void AppendBlockSummary(SampleResult result, int col, int topPy, int botPy) + private void AppendBlockSummaryLines(SampleResult result, int col, int topPy, int botPy, + List lines) { if (result.BlockSummary is null) return; @@ -797,8 +805,6 @@ namespace MinecraftClient.Tui if (merged.Count == 0) return; var sorted = merged.OrderByDescending(kv => kv.Value).Take(4); - int totalSamples = 0; - foreach (var kv in merged) totalSamples += kv.Value; var parts = new List(); foreach (var kv in sorted) @@ -811,8 +817,11 @@ namespace MinecraftClient.Tui if (parts.Count == 0) return; - string line = string.Join(", ", parts); - _tooltipContent.Children.Add(MakeTooltipText(line, Brushes.LightGray)); + lines.Add(new TuiTooltipLine + { + Text = string.Join(", ", parts), + Foreground = Brushes.LightGray, + }); } private static void MergeBlockCounts(List<(Material Mat, int Count)>?[,] summary, @@ -829,7 +838,8 @@ namespace MinecraftClient.Tui } } - private void AppendEntityInfo(SampleResult result, int col, int topPy, int botPy) + private static void AppendEntityInfoLines(SampleResult result, int col, int topPy, int botPy, + List lines) { var entityMap = result.EntityMap; if (entityMap is null) return; @@ -851,19 +861,20 @@ namespace MinecraftClient.Tui if (!seen.Add(key)) continue; var catColor = MinimapEntityClassifier.GetBaseColor(ent.Category); - string hpStr; + string coordStr = $"({ent.X:F1}, {ent.Y:F1}, {ent.Z:F1})"; + string hpStr = ""; if (ent.Health > 0) { hpStr = ent.MaxHealth > 0 - ? $" HP:{ent.Health:F0}/{ent.MaxHealth:F0}" - : $" HP:{ent.Health:F0}"; + ? $" HP:{ent.Health:F0}/{ent.MaxHealth:F0}" + : $" HP:{ent.Health:F0}"; } - else - hpStr = ""; - _tooltipContent.Children.Add(MakeTooltipText( - $"{ent.Name}{hpStr}", - new SolidColorBrush(catColor))); + lines.Add(new TuiTooltipLine + { + Text = $"{ent.Name} {coordStr}{hpStr}", + Foreground = new SolidColorBrush(catColor), + }); shown++; } } @@ -879,19 +890,6 @@ namespace MinecraftClient.Tui } } - private static TextBlock MakeTooltipText(string text, IBrush foreground) - { - return new TextBlock - { - Text = text, - Foreground = foreground, - TextWrapping = TextWrapping.Wrap, - Padding = new Thickness(0), - Margin = new Thickness(0), - FontSize = 1, - }; - } - private static string FormatMaterialName(Material mat) { if (mat == Material.Air) return "Air"; diff --git a/MinecraftClient/Tui/TuiTooltipService.cs b/MinecraftClient/Tui/TuiTooltipService.cs new file mode 100644 index 00000000..0ae51607 --- /dev/null +++ b/MinecraftClient/Tui/TuiTooltipService.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Media; + +namespace MinecraftClient.Tui +{ + public sealed class TuiTooltipLine + { + public string Text { get; init; } = ""; + public IBrush Foreground { get; init; } = Brushes.White; + } + + /// + /// Global tooltip that floats above all TUI content. + /// Owned by MainTuiView, used by minimap / chat / other components. + /// + public sealed class TuiTooltipService + { + private readonly Panel _rootPanel; + private readonly Canvas _canvas; + private readonly Border _border; + private readonly StackPanel _content; + + internal TuiTooltipService(Panel rootPanel) + { + _content = new StackPanel { Orientation = Avalonia.Layout.Orientation.Vertical }; + _border = new Border + { + Background = new SolidColorBrush(Color.FromArgb(230, 20, 20, 20)), + BorderBrush = new SolidColorBrush(Color.FromRgb(120, 120, 120)), + BorderThickness = new Thickness(1), + Padding = new Thickness(1), + Child = _content, + IsVisible = false, + }; + + _canvas = new Canvas + { + IsHitTestVisible = false, + Children = { _border }, + }; + + _rootPanel = rootPanel; + rootPanel.Children.Add(_canvas); + } + + /// Global X of the mouse cursor. + /// Global Y of the mouse cursor. + /// + /// If true, try placing tooltip to the right of mouseX; + /// if false, try placing to the left. + /// The service auto-flips when the tooltip would overflow the screen. + /// + public void Show(double mouseX, double mouseY, IReadOnlyList lines, + bool preferRight = true) + { + _content.Children.Clear(); + + if (lines.Count == 0) + { + _border.IsVisible = false; + return; + } + + int maxChars = 0; + foreach (var line in lines) + { + _content.Children.Add(new TextBlock + { + Text = line.Text, + Foreground = line.Foreground, + TextWrapping = TextWrapping.Wrap, + Padding = new Thickness(0), + Margin = new Thickness(0), + FontSize = 1, + }); + if (line.Text.Length > maxChars) + maxChars = line.Text.Length; + } + + double tipW = maxChars + 4; + double screenW = _rootPanel.Bounds.Width; + + const double gap = 1; + double gx; + if (preferRight) + { + gx = mouseX + gap; + if (gx + tipW > screenW) + gx = mouseX - tipW - gap; + } + else + { + gx = mouseX - tipW - gap; + if (gx < 0) + gx = mouseX + gap; + } + + Canvas.SetLeft(_border, Math.Max(0, gx)); + Canvas.SetTop(_border, Math.Max(0, mouseY)); + _border.IsVisible = true; + } + + public void Hide() + { + _border.IsVisible = false; + _content.Children.Clear(); + } + + public bool IsVisible => _border.IsVisible; + } +} From d05e3148f1240f238933b3a78a3a403d468c5212 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 22:38:39 +0800 Subject: [PATCH 265/484] Refactor explosion packet handling for protocol version updates - Updated explosion packet processing to accommodate changes in Minecraft protocol versions, specifically for versions 1.21.2 and 1.20.4. - Removed obsolete fields such as explosion strength and block records for newer versions, and added support for optional knockback and particle data. - Enhanced backward compatibility for earlier versions by maintaining existing logic for explosion data retrieval. --- .../Protocol/Handlers/Protocol18.cs | 78 +++++++++++++------ 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index b6cdcd05..aa004b5e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2822,43 +2822,71 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.Explosion: Location explosionLocation; - if (protocolVersion >= MC_1_19_3_Version) + float explosionStrength; + int explosionBlockCount; + + if (protocolVersion >= MC_1_21_2_Version) + { + // 1.21.2+: removed strength, block records, and player motion floats; + // added optional knockback (doubles) and single particle explosionLocation = new(dataTypes.ReadNextDouble(packetData), dataTypes.ReadNextDouble(packetData), dataTypes.ReadNextDouble(packetData)); - else - explosionLocation = new(dataTypes.ReadNextFloat(packetData), - dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData)); + explosionStrength = 0; + explosionBlockCount = 0; - var explosionStrength = dataTypes.ReadNextFloat(packetData); - var explosionBlockCount = protocolVersion >= MC_1_17_Version - ? dataTypes.ReadNextVarInt(packetData) - : dataTypes.ReadNextInt(packetData); // Record count + if (dataTypes.ReadNextBool(packetData)) // Has player knockback + { + dataTypes.ReadNextDouble(packetData); // Knockback X + dataTypes.ReadNextDouble(packetData); // Knockback Y + dataTypes.ReadNextDouble(packetData); // Knockback Z + } - // Records - for (var i = 0; i < explosionBlockCount; i++) - dataTypes.ReadNextByteArray(packetData, 3); + dataTypes.ReadParticleData(packetData, itemPalette); // Explosion particle - dataTypes.ReadNextFloat(packetData); // Player Motion X - dataTypes.ReadNextFloat(packetData); // Player Motion Y - dataTypes.ReadNextFloat(packetData); // Player Motion Z - - if (protocolVersion >= MC_1_20_4_Version) - { - dataTypes.ReadNextVarInt(packetData); // Block Interaction (enum ordinal) - dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles - dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles - - // Explosion Sound: Holder via ByteBufCodecs.holder() - // VarInt id: 0 = inline (read DIRECT_STREAM_CODEC), >0 = registry ref (id-1) var soundHolderId = dataTypes.ReadNextVarInt(packetData); if (soundHolderId == 0) { dataTypes.ReadNextString(packetData); // Sound ResourceLocation - var hasFixedRange = dataTypes.ReadNextBool(packetData); - if (hasFixedRange) + if (dataTypes.ReadNextBool(packetData)) dataTypes.ReadNextFloat(packetData); // Fixed range } } + else + { + if (protocolVersion >= MC_1_19_3_Version) + explosionLocation = new(dataTypes.ReadNextDouble(packetData), + dataTypes.ReadNextDouble(packetData), dataTypes.ReadNextDouble(packetData)); + else + explosionLocation = new(dataTypes.ReadNextFloat(packetData), + dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData)); + + explosionStrength = dataTypes.ReadNextFloat(packetData); + explosionBlockCount = protocolVersion >= MC_1_17_Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextInt(packetData); + + for (var i = 0; i < explosionBlockCount; i++) + dataTypes.ReadNextByteArray(packetData, 3); + + dataTypes.ReadNextFloat(packetData); // Player Motion X + dataTypes.ReadNextFloat(packetData); // Player Motion Y + dataTypes.ReadNextFloat(packetData); // Player Motion Z + + if (protocolVersion >= MC_1_20_4_Version) + { + dataTypes.ReadNextVarInt(packetData); // Block Interaction + dataTypes.ReadParticleData(packetData, itemPalette); // Small Explosion Particles + dataTypes.ReadParticleData(packetData, itemPalette); // Large Explosion Particles + + var soundHolderId = dataTypes.ReadNextVarInt(packetData); + if (soundHolderId == 0) + { + dataTypes.ReadNextString(packetData); // Sound ResourceLocation + if (dataTypes.ReadNextBool(packetData)) + dataTypes.ReadNextFloat(packetData); // Fixed range + } + } + } handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); break; From 2f03f66f5ccd7447573fe3a6fbeaec724396d23d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sun, 29 Mar 2026 22:38:47 +0800 Subject: [PATCH 266/484] Enhance useblock command to support hand selection - Updated the 'useblock' command to allow specifying the hand (mainhand or offhand) for block placement. - Modified command usage description to reflect the new optional parameter. - Adjusted the command execution logic to handle the selected hand during block placement. --- MinecraftClient/Commands/Useblock.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/MinecraftClient/Commands/Useblock.cs b/MinecraftClient/Commands/Useblock.cs index 2df6a92f..7e482ba4 100644 --- a/MinecraftClient/Commands/Useblock.cs +++ b/MinecraftClient/Commands/Useblock.cs @@ -1,6 +1,7 @@ using Brigadier.NET; using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; +using MinecraftClient.Inventory; using MinecraftClient.Mapping; using static MinecraftClient.CommandHandler.CmdResult; @@ -9,7 +10,7 @@ namespace MinecraftClient.Commands class Useblock : Command { public override string CmdName { get { return "useblock"; } } - public override string CmdUsage { get { return "useblock "; } } + public override string CmdUsage { get { return "useblock [mainhand|offhand]"; } } public override string CmdDesc { get { return Translations.cmd_useblock_desc; } } public override void RegisterCommand(CommandDispatcher dispatcher) @@ -22,7 +23,11 @@ namespace MinecraftClient.Commands dispatcher.Register(l => l.Literal(CmdName) .Then(l => l.Argument("Location", MccArguments.Location()) - .Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location")))) + .Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.MainHand)) + .Then(l => l.Literal("mainhand") + .Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.MainHand))) + .Then(l => l.Literal("offhand") + .Executes(r => UseBlockAtLocation(r.Source, MccArguments.GetLocation(r, "Location"), Hand.OffHand)))) .Then(l => l.Literal("_help") .Executes(r => GetUsage(r.Source, string.Empty)) .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) @@ -39,7 +44,7 @@ namespace MinecraftClient.Commands }); } - private int UseBlockAtLocation(CmdResult r, Location block) + private int UseBlockAtLocation(CmdResult r, Location block, Hand hand) { McClient handler = CmdResult.currentHandler!; if (!handler.GetTerrainEnabled()) @@ -48,7 +53,7 @@ namespace MinecraftClient.Commands Location current = handler.GetCurrentLocation(); block = block.ToAbsolute(current).ToFloor(); Location blockCenter = block.ToCenter(); - bool res = handler.PlaceBlock(block, Direction.Down, lookAtBlock: true); + bool res = handler.PlaceBlock(block, Direction.Down, hand, lookAtBlock: true); return r.SetAndReturn(string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed"), res); } } From 871305bd722048e5d232e11733fb878b11b35263 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Mon, 30 Mar 2026 01:35:38 +0800 Subject: [PATCH 267/484] Add server status display and protocol version upgrade handling - Introduced a new `ServerStatusInfo` class to encapsulate server status data including MOTD, player counts, and version information. - Implemented `ServerStatusDisplay` to format and display server status information in both classic and TUI modes. - Added protocol version upgrade logic in `ProtocolHandler` to determine the highest supported protocol version for multi-version servers. - Updated translations to support new server status labels and messages. - Created `ServerStatusPanelBuilder` for TUI to visually represent server status with player information and connection details. --- AGENTS.md | 1 + .../Protocol/Handlers/Protocol18.cs | 588 ++++++++++-------- MinecraftClient/Protocol/ProtocolHandler.cs | 56 ++ .../Protocol/ServerStatusDisplay.cs | 118 ++++ MinecraftClient/Protocol/ServerStatusInfo.cs | 30 + .../Translations/Translations.Designer.cs | 60 ++ .../Resources/Translations/Translations.resx | 34 +- MinecraftClient/Tui/MainTuiView.cs | 13 + MinecraftClient/Tui/McColorParser.cs | 27 +- .../Tui/ServerStatusPanelBuilder.cs | 296 +++++++++ 10 files changed, 954 insertions(+), 269 deletions(-) create mode 100644 MinecraftClient/Protocol/ServerStatusDisplay.cs create mode 100644 MinecraftClient/Protocol/ServerStatusInfo.cs create mode 100644 MinecraftClient/Tui/ServerStatusPanelBuilder.cs diff --git a/AGENTS.md b/AGENTS.md index 40f216f7..fec9d8f8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,7 @@ - Minecraft Console Client (MCC) is a cross-platform text/TUI client for Minecraft Java Edition. - Primary scope: connect to servers, send chat and commands, receive text, automate gameplay/admin tasks, and extend behavior through built-in bots or runtime C# scripts. - Secondary scope: protocol/version adaptation tooling, docs site, legacy GUI wrapper, and debug tooling. +- Decompiled server source for both the old and new MC versions in `$MCC_REPO/MinecraftOfficial/-decompiled/` ## Build / Run - Init submodules first: `git submodule update --init --recursive` diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index aa004b5e..5329cdfb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -449,7 +449,7 @@ namespace MinecraftClient.Protocol.Handlers McClient.Instance?.GetCookie(cookieName, out cookieData); SendCookieResponse(cookieName, cookieData); break; - + // Ignore other packets at this stage default: return true; @@ -467,7 +467,7 @@ namespace MinecraftClient.Protocol.Handlers McClient.Instance?.GetCookie(cookieName, out cookieData); SendCookieResponse(cookieName, cookieData); break; - + case ConfigurationPacketTypesIn.Disconnect: handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, dataTypes.ReadNextChat(packetData)); @@ -509,7 +509,7 @@ namespace MinecraftClient.Protocol.Handlers var dimensionIdMap = isDimension ? new Dictionary() : null; var attributeIdMap = isAttribute ? new Dictionary() : null; var enchantmentIdMap = isEnchantment ? new Dictionary() : null; - + for (var i = 0; i < entryCount; i++) { var entryId = dataTypes.ReadNextString(packetData); @@ -537,7 +537,7 @@ namespace MinecraftClient.Protocol.Handlers else if (isEnchantment) enchantmentIdMap!.Add(i, entryId); } - + if (isChat) ChatParser.ReadChatType(availableChats!); else if (isDimension) @@ -553,7 +553,7 @@ namespace MinecraftClient.Protocol.Handlers } break; - + case ConfigurationPacketTypesIn.RemoveResourcePack: if (dataTypes.ReadNextBool(packetData)) // Has UUID dataTypes.ReadNextUUID(packetData); // UUID @@ -562,24 +562,24 @@ namespace MinecraftClient.Protocol.Handlers case ConfigurationPacketTypesIn.ResourcePack: HandleResourcePackPacket(packetData); break; - + case ConfigurationPacketTypesIn.StoreCookie: var name = dataTypes.ReadNextString(packetData); var data = dataTypes.ReadNextByteArray(packetData); McClient.Instance?.SetCookie(name, data); break; - + case ConfigurationPacketTypesIn.Transfer: var host = dataTypes.ReadNextString(packetData); var port = dataTypes.ReadNextVarInt(packetData); - + McClient.Instance?.Transfer(host, port); break; - + case ConfigurationPacketTypesIn.KnownDataPacks: var knownPacksCount = dataTypes.ReadNextVarInt(packetData); List<(string, string, string)> knownDataPacks = new(); - + for (var i = 0; i < knownPacksCount; i++) { var nameSpace = dataTypes.ReadNextString(packetData); @@ -645,7 +645,7 @@ namespace MinecraftClient.Protocol.Handlers currentState == CurrentState.Login, innerException.GetType()), innerException); - + SentrySdk.AddBreadcrumb(new Breadcrumb("S -> C Packet", "network", new Dictionary() { { "Packet ID", packetId.ToString() }, @@ -786,26 +786,26 @@ namespace MinecraftClient.Protocol.Handlers switch (protocolVersion) { case >= MC_1_16_Version: - { - switch (protocolVersion) { - case >= MC_1_19_Version: - dimensionTypeName = - dataTypes.ReadNextString(packetData); // Dimension Type: Identifier - break; - case >= MC_1_16_2_Version: - dimensionType = - dataTypes.ReadNextNbt( - packetData); // Dimension Type: NBT Tag Compound - break; - default: - dataTypes.ReadNextString(packetData); - break; - } + switch (protocolVersion) + { + case >= MC_1_19_Version: + dimensionTypeName = + dataTypes.ReadNextString(packetData); // Dimension Type: Identifier + break; + case >= MC_1_16_2_Version: + dimensionType = + dataTypes.ReadNextNbt( + packetData); // Dimension Type: NBT Tag Compound + break; + default: + dataTypes.ReadNextString(packetData); + break; + } - currentDimension = 0; - break; - } + currentDimension = 0; + break; + } case >= MC_1_9_1_Version: currentDimension = dataTypes.ReadNextInt(packetData); break; @@ -820,27 +820,27 @@ namespace MinecraftClient.Protocol.Handlers dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below break; case >= MC_1_16_Version: - { - var dimensionName = - dataTypes.ReadNextString( - packetData); // Dimension Name (World Name) - 1.16 and above - - if (handler.GetTerrainEnabled()) { - switch (protocolVersion) - { - case >= MC_1_16_2_Version and <= MC_1_18_2_Version: - World.StoreOneDimension(dimensionName, dimensionType!); - World.SetDimension(dimensionName); - break; - default: - World.SetDimension(dimensionTypeName!); - break; - } - } + var dimensionName = + dataTypes.ReadNextString( + packetData); // Dimension Name (World Name) - 1.16 and above - break; - } + if (handler.GetTerrainEnabled()) + { + switch (protocolVersion) + { + case >= MC_1_16_2_Version and <= MC_1_18_2_Version: + World.StoreOneDimension(dimensionName, dimensionType!); + World.SetDimension(dimensionName); + break; + default: + World.SetDimension(dimensionTypeName!); + break; + } + } + + break; + } } } @@ -1354,7 +1354,7 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.Respawn: string? dimensionTypeNameRespawn = null; Dictionary? dimensionTypeRespawn = null; - + if (protocolVersion >= MC_1_16_Version) { switch (protocolVersion) @@ -1386,27 +1386,27 @@ namespace MinecraftClient.Protocol.Handlers switch (protocolVersion) { case >= MC_1_16_Version: - { - var dimensionName = - dataTypes.ReadNextString( - packetData); // Dimension Name (World Name) - 1.16 and above - - if (handler.GetTerrainEnabled()) { - switch (protocolVersion) - { - case >= MC_1_16_2_Version and <= MC_1_18_2_Version: - World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); - World.SetDimension(dimensionName); - break; - default: - World.SetDimension(dimensionTypeNameRespawn!); - break; - } - } + var dimensionName = + dataTypes.ReadNextString( + packetData); // Dimension Name (World Name) - 1.16 and above - break; - } + if (handler.GetTerrainEnabled()) + { + switch (protocolVersion) + { + case >= MC_1_16_2_Version and <= MC_1_18_2_Version: + World.StoreOneDimension(dimensionName, dimensionTypeRespawn!); + World.SetDimension(dimensionName); + break; + default: + World.SetDimension(dimensionTypeNameRespawn!); + break; + } + } + + break; + } case < MC_1_14_Version: dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below break; @@ -1453,77 +1453,77 @@ namespace MinecraftClient.Protocol.Handlers handler.OnRespawn(); break; case PacketTypesIn.PlayerPositionAndLook: - { - int teleportId; - Location location; - float yaw, pitch; - int locMask; + { + int teleportId; + Location location; + float yaw, pitch; + int locMask; - if (protocolVersion >= MC_1_21_2_Version) - { - teleportId = dataTypes.ReadNextVarInt(packetData); - location = new Location( - dataTypes.ReadNextDouble(packetData), // X - dataTypes.ReadNextDouble(packetData), // Y - dataTypes.ReadNextDouble(packetData) // Z - ); - dataTypes.ReadNextDouble(packetData); // Delta X - dataTypes.ReadNextDouble(packetData); // Delta Y - dataTypes.ReadNextDouble(packetData); // Delta Z - yaw = dataTypes.ReadNextFloat(packetData); - pitch = dataTypes.ReadNextFloat(packetData); - locMask = dataTypes.ReadNextInt(packetData); // Int flags (was Byte before 1.21.2) - } - else - { - location = new Location( - dataTypes.ReadNextDouble(packetData), // X - dataTypes.ReadNextDouble(packetData), // Y - dataTypes.ReadNextDouble(packetData) // Z - ); - yaw = dataTypes.ReadNextFloat(packetData); - pitch = dataTypes.ReadNextFloat(packetData); - locMask = dataTypes.ReadNextByte(packetData); - teleportId = protocolVersion >= MC_1_9_Version - ? dataTypes.ReadNextVarInt(packetData) : -1; - } - - if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) - { - if (protocolVersion >= MC_1_8_Version) + if (protocolVersion >= MC_1_21_2_Version) { - var currentLocation = handler.GetCurrentLocation(); - location.X = (locMask & 1 << 0) != 0 ? currentLocation.X + location.X : location.X; - location.Y = (locMask & 1 << 1) != 0 ? currentLocation.Y + location.Y : location.Y; - location.Z = (locMask & 1 << 2) != 0 ? currentLocation.Z + location.Z : location.Z; + teleportId = dataTypes.ReadNextVarInt(packetData); + location = new Location( + dataTypes.ReadNextDouble(packetData), // X + dataTypes.ReadNextDouble(packetData), // Y + dataTypes.ReadNextDouble(packetData) // Z + ); + dataTypes.ReadNextDouble(packetData); // Delta X + dataTypes.ReadNextDouble(packetData); // Delta Y + dataTypes.ReadNextDouble(packetData); // Delta Z + yaw = dataTypes.ReadNextFloat(packetData); + pitch = dataTypes.ReadNextFloat(packetData); + locMask = dataTypes.ReadNextInt(packetData); // Int flags (was Byte before 1.21.2) } - } - - if (teleportId >= 0) - { - LastYaw = yaw; - LastPitch = pitch; - handler.UpdateLocation(location, yaw, pitch); - SendPacket(PacketTypesOut.TeleportConfirm, DataTypes.GetVarInt(teleportId)); - - if (Config.Main.Advanced.TemporaryFixBadpacket) + else { - SendLocationUpdate(location, true, false, yaw, pitch, true); + location = new Location( + dataTypes.ReadNextDouble(packetData), // X + dataTypes.ReadNextDouble(packetData), // Y + dataTypes.ReadNextDouble(packetData) // Z + ); + yaw = dataTypes.ReadNextFloat(packetData); + pitch = dataTypes.ReadNextFloat(packetData); + locMask = dataTypes.ReadNextByte(packetData); + teleportId = protocolVersion >= MC_1_9_Version + ? dataTypes.ReadNextVarInt(packetData) : -1; + } - if (teleportId == 1) + if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) + { + if (protocolVersion >= MC_1_8_Version) + { + var currentLocation = handler.GetCurrentLocation(); + location.X = (locMask & 1 << 0) != 0 ? currentLocation.X + location.X : location.X; + location.Y = (locMask & 1 << 1) != 0 ? currentLocation.Y + location.Y : location.Y; + location.Z = (locMask & 1 << 2) != 0 ? currentLocation.Z + location.Z : location.Z; + } + } + + if (teleportId >= 0) + { + LastYaw = yaw; + LastPitch = pitch; + handler.UpdateLocation(location, yaw, pitch); + SendPacket(PacketTypesOut.TeleportConfirm, DataTypes.GetVarInt(teleportId)); + + if (Config.Main.Advanced.TemporaryFixBadpacket) + { SendLocationUpdate(location, true, false, yaw, pitch, true); - } - } - else - { - handler.UpdateLocation(location, yaw, pitch); - LastYaw = yaw; - LastPitch = pitch; - } - if (protocolVersion is >= MC_1_17_Version and < MC_1_19_4_Version) - dataTypes.ReadNextBool(packetData); // Dismount Vehicle - 1.17 to 1.19.3 - } + if (teleportId == 1) + SendLocationUpdate(location, true, false, yaw, pitch, true); + } + } + else + { + handler.UpdateLocation(location, yaw, pitch); + LastYaw = yaw; + LastPitch = pitch; + } + + if (protocolVersion is >= MC_1_17_Version and < MC_1_19_4_Version) + dataTypes.ReadNextBool(packetData); // Dismount Vehicle - 1.17 to 1.19.3 + } break; case PacketTypesIn.ChunkData: if (handler.GetTerrainEnabled()) @@ -1679,26 +1679,26 @@ namespace MinecraftClient.Protocol.Handlers { // 1.8 - 1.13 case < MC_1_13_2_Version: - { - var directionAndType = dataTypes.ReadNextByte(packetData); - byte direction, type; - - // 1.12.2+ - if (protocolVersion >= MC_1_12_2_Version) { - direction = (byte)(directionAndType & 0xF); - type = (byte)(directionAndType >> 4 & 0xF); - } - else // 1.8 - 1.12 - { - direction = (byte)(directionAndType >> 4 & 0xF); - type = (byte)(directionAndType & 0xF); - } + var directionAndType = dataTypes.ReadNextByte(packetData); + byte direction, type; - mapIcon.Type = (MapIconType)type; - mapIcon.Direction = direction; - break; - } + // 1.12.2+ + if (protocolVersion >= MC_1_12_2_Version) + { + direction = (byte)(directionAndType & 0xF); + type = (byte)(directionAndType >> 4 & 0xF); + } + else // 1.8 - 1.12 + { + direction = (byte)(directionAndType >> 4 & 0xF); + type = (byte)(directionAndType & 0xF); + } + + mapIcon.Type = (MapIconType)type; + mapIcon.Direction = direction; + break; + } // 1.13.2+ case >= MC_1_13_2_Version: mapIcon.Type = (MapIconType)dataTypes.ReadNextVarInt(packetData); @@ -2290,7 +2290,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnPluginChannelMessage(channel, packetData.ToArray()); return pForge.HandlePluginMessage(channel, packetData, ref currentDimension); case PacketTypesIn.Disconnect: - handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, + handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, dataTypes.ReadNextChat(packetData)); return false; case PacketTypesIn.SetCompression: @@ -2427,17 +2427,17 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { var entity = dataTypes.ReadNextEntity(packetData, entityPalette, false); - + if (protocolVersion >= MC_1_20_2_Version) { if (entity.Type == EntityType.Player) handler.OnSpawnPlayer(entity.ID, entity.UUID, entity.Location, (byte)entity.Yaw, (byte)entity.Pitch); else handler.OnSpawnEntity(entity); - + break; } - + handler.OnSpawnEntity(entity); } @@ -2648,7 +2648,7 @@ namespace MinecraftClient.Protocol.Handlers var numberOfProperties = protocolVersion >= MC_1_17_Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); - + Dictionary keys = new(); for (var i = 0; i < numberOfProperties; i++) { @@ -3008,17 +3008,17 @@ namespace MinecraftClient.Protocol.Handlers McClient.Instance?.GetCookie(cookieName, out cookieData); SendCookieResponse(cookieName, cookieData); break; - + case PacketTypesIn.StoreCookie: var cookieName2 = dataTypes.ReadNextString(packetData); var cookieData2 = dataTypes.ReadNextByteArray(packetData); McClient.Instance?.SetCookie(cookieName2, cookieData2); break; - + case PacketTypesIn.Transfer: var host = dataTypes.ReadNextString(packetData); var port = dataTypes.ReadNextVarInt(packetData); - + McClient.Instance?.Transfer(host, port); break; @@ -3286,17 +3286,17 @@ namespace MinecraftClient.Protocol.Handlers switch (protocolVersion) { case >= MC_1_19_2_Version and < MC_1_20_2_Version: - { - if (uuid == Guid.Empty) - fullLoginPacket.AddRange(dataTypes.GetBool(false)); // Has UUID - else { - fullLoginPacket.AddRange(dataTypes.GetBool(true)); // Has UUID - fullLoginPacket.AddRange(DataTypes.GetUUID(uuid)); // UUID - } + if (uuid == Guid.Empty) + fullLoginPacket.AddRange(dataTypes.GetBool(false)); // Has UUID + else + { + fullLoginPacket.AddRange(dataTypes.GetBool(true)); // Has UUID + fullLoginPacket.AddRange(DataTypes.GetUUID(uuid)); // UUID + } - break; - } + break; + } case >= MC_1_20_2_Version: uuid = handler.GetUserUuid(); @@ -3324,42 +3324,42 @@ namespace MinecraftClient.Protocol.Handlers // Encryption request case 0x01: - { - isOnlineMode = true; - var serverId = dataTypes.ReadNextString(packetData); - var serverPublicKey = dataTypes.ReadNextByteArray(packetData); - var token = dataTypes.ReadNextByteArray(packetData); + { + isOnlineMode = true; + var serverId = dataTypes.ReadNextString(packetData); + var serverPublicKey = dataTypes.ReadNextByteArray(packetData); + var token = dataTypes.ReadNextByteArray(packetData); - var shouldAuthetnicate = false; + var shouldAuthetnicate = false; - if (protocolVersion >= MC_1_20_6_Version) - shouldAuthetnicate = dataTypes.ReadNextBool(packetData); - - return StartEncryption(handler.GetUserUuidStr(), handler.GetSessionID(), - Config.Main.General.AccountType, token, serverId, - serverPublicKey, playerKeyPair, session, shouldAuthetnicate); - } + if (protocolVersion >= MC_1_20_6_Version) + shouldAuthetnicate = dataTypes.ReadNextBool(packetData); + + return StartEncryption(handler.GetUserUuidStr(), handler.GetSessionID(), + Config.Main.General.AccountType, token, serverId, + serverPublicKey, playerKeyPair, session, shouldAuthetnicate); + } // Login successful case 0x02: - { - log.Info($"§8{Translations.mcc_server_offline}"); - currentState = protocolVersion < MC_1_20_2_Version - ? CurrentState.Play - : CurrentState.Configuration; - - if (protocolVersion >= MC_1_20_2_Version) - SendPacket(0x03, new List()); - - if (!pForge.CompleteForgeHandshake()) { - log.Error($"§8{Translations.error_forge}"); - return false; - } + log.Info($"§8{Translations.mcc_server_offline}"); + currentState = protocolVersion < MC_1_20_2_Version + ? CurrentState.Play + : CurrentState.Configuration; - StartUpdating(); - return true; //No need to check session or start encryption - } + if (protocolVersion >= MC_1_20_2_Version) + SendPacket(0x03, new List()); + + if (!pForge.CompleteForgeHandshake()) + { + log.Error($"§8{Translations.error_forge}"); + return false; + } + + StartUpdating(); + return true; //No need to check session or start encryption + } default: HandlePacket(packetId, packetData); break; @@ -3392,7 +3392,7 @@ namespace MinecraftClient.Protocol.Handlers if (session.SessionPreCheckTask.Result) // PreCheck Success needCheckSession = false; } - + // 1.20.6++ if (shouldAuthetnicate) needCheckSession = true; @@ -3465,51 +3465,51 @@ namespace MinecraftClient.Protocol.Handlers handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); return false; - + //Login successful case 0x02: - { - var uuidReceived = protocolVersion >= MC_1_16_Version - ? dataTypes.ReadNextUUID(packetData) - : Guid.Parse(dataTypes.ReadNextString(packetData)); - var userName = dataTypes.ReadNextString(packetData); - Tuple[]? playerProperty = null; - if (protocolVersion >= MC_1_19_Version) { - var count = dataTypes.ReadNextVarInt(packetData); // Number Of Properties - playerProperty = new Tuple[count]; - for (var i = 0; i < count; ++i) + var uuidReceived = protocolVersion >= MC_1_16_Version + ? dataTypes.ReadNextUUID(packetData) + : Guid.Parse(dataTypes.ReadNextString(packetData)); + var userName = dataTypes.ReadNextString(packetData); + Tuple[]? playerProperty = null; + if (protocolVersion >= MC_1_19_Version) { - var name = dataTypes.ReadNextString(packetData); - var value = dataTypes.ReadNextString(packetData); - var isSigned = dataTypes.ReadNextBool(packetData); - var signature = isSigned ? dataTypes.ReadNextString(packetData) : string.Empty; - playerProperty[i] = new Tuple(name, value, signature); + var count = dataTypes.ReadNextVarInt(packetData); // Number Of Properties + playerProperty = new Tuple[count]; + for (var i = 0; i < count; ++i) + { + var name = dataTypes.ReadNextString(packetData); + var value = dataTypes.ReadNextString(packetData); + var isSigned = dataTypes.ReadNextBool(packetData); + var signature = isSigned ? dataTypes.ReadNextString(packetData) : string.Empty; + playerProperty[i] = new Tuple(name, value, signature); + } } + + // Strict Error Handling (removed in 1.21.2) + if (protocolVersion >= MC_1_20_6_Version && protocolVersion < MC_1_21_2_Version) + dataTypes.ReadNextBool(packetData); + + currentState = protocolVersion < MC_1_20_2_Version + ? CurrentState.Play + : CurrentState.Configuration; + + if (protocolVersion >= MC_1_20_2_Version) + SendPacket(0x03, new List()); + + handler.OnLoginSuccess(uuidReceived, userName, playerProperty); + + if (!pForge.CompleteForgeHandshake()) + { + log.Error($"§8{Translations.error_forge_encrypt}"); + return false; + } + + StartUpdating(); + return true; } - - // Strict Error Handling (removed in 1.21.2) - if (protocolVersion >= MC_1_20_6_Version && protocolVersion < MC_1_21_2_Version) - dataTypes.ReadNextBool(packetData); - - currentState = protocolVersion < MC_1_20_2_Version - ? CurrentState.Play - : CurrentState.Configuration; - - if (protocolVersion >= MC_1_20_2_Version) - SendPacket(0x03, new List()); - - handler.OnLoginSuccess(uuidReceived, userName, playerProperty); - - if (!pForge.CompleteForgeHandshake()) - { - log.Error($"§8{Translations.error_forge_encrypt}"); - return false; - } - - StartUpdating(); - return true; - } default: HandlePacket(packetId, packetData); break; @@ -3548,15 +3548,15 @@ namespace MinecraftClient.Protocol.Handlers dataTypes.GetString(BehindCursor.Replace(' ', (char)0x00))); break; case >= MC_1_8_Version: - { - tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, dataTypes.GetString(BehindCursor)); + { + tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, dataTypes.GetString(BehindCursor)); - if (protocolVersion >= MC_1_9_Version) - tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, assumeCommand); + if (protocolVersion >= MC_1_9_Version) + tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, assumeCommand); - tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, hasPosition); - break; - } + tabCompletePacket = dataTypes.ConcatBytes(tabCompletePacket, hasPosition); + break; + } default: tabCompletePacket = dataTypes.ConcatBytes(dataTypes.GetString(BehindCursor)); break; @@ -3620,7 +3620,8 @@ namespace MinecraftClient.Protocol.Handlers if (dataTypes.ReadNextVarInt(packetData) != 0x00) return false; - var result = dataTypes.ReadNextString(packetData); // Get the Json data + // Get the Json data + var result = dataTypes.ReadNextString(packetData); if (Config.Logging.DebugMessages) { @@ -3651,7 +3652,44 @@ namespace MinecraftClient.Protocol.Handlers // Check for forge on the server. Protocol18Forge.ServerInfoCheckForge(jsonObj, ref forgeInfo); - // Complete the normal status exchange so the probe connection closes cleanly server-side. + int onlinePlayers = 0, maxPlayers = 0; + List samplePlayers = []; + + if (jsonObj["players"] is System.Text.Json.Nodes.JsonObject playersObj) + { + if (playersObj["online"] is { } onlineNode) + onlinePlayers = int.Parse(onlineNode.GetStringValue(), NumberStyles.Any, CultureInfo.CurrentCulture); + if (playersObj["max"] is { } maxNode) + maxPlayers = int.Parse(maxNode.GetStringValue(), NumberStyles.Any, CultureInfo.CurrentCulture); + if (playersObj["sample"] is System.Text.Json.Nodes.JsonArray sampleArray) + { + foreach (var entry in sampleArray) + { + if (entry is not System.Text.Json.Nodes.JsonObject playerObj) continue; + samplePlayers.Add(new ServerStatusInfo.SamplePlayer + { + Name = playerObj["name"]?.GetStringValue() ?? "", + Id = playerObj["id"]?.GetStringValue() ?? "" + }); + } + } + } + + string motdRaw = ""; + if (jsonObj["description"] is { } descNode) + motdRaw = descNode.ToJsonString(); + + string? faviconBase64 = null; + if (jsonObj["favicon"] is { } faviconNode) + { + var faviconStr = faviconNode.GetStringValue(); + const string prefix = "data:image/png;base64,"; + faviconBase64 = faviconStr.StartsWith(prefix, StringComparison.Ordinal) + ? faviconStr[prefix.Length..] + : faviconStr; + } + + long pingMs = -1; try { long pingPayload = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); @@ -3663,7 +3701,10 @@ namespace MinecraftClient.Protocol.Handlers { packetData = new Queue(socketWrapper.ReadDataRAW(packetLength)); if (dataTypes.ReadNextVarInt(packetData) == 0x01) - dataTypes.ReadNextLong(packetData); + { + long pongPayload = dataTypes.ReadNextLong(packetData); + pingMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - pingPayload; + } } } catch @@ -3671,9 +3712,28 @@ namespace MinecraftClient.Protocol.Handlers // Some servers may close the probe connection immediately after the status response. } + var statusInfo = new ServerStatusInfo + { + Host = host, + Port = port, + VersionName = version, + ProtocolVersion = protocolVersion, + OnlinePlayers = onlinePlayers, + MaxPlayers = maxPlayers, + SamplePlayers = samplePlayers, + MotdRaw = motdRaw, + FaviconBase64 = faviconBase64, + PingMs = pingMs + }; + + ProtocolHandler.TryUpgradeProtocolVersion(version, ref protocolVersion); + statusInfo.ResolvedProtocol = protocolVersion; + ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_server_protocol, version, protocolVersion + (forgeInfo is not null ? Translations.mcc_with_forge : ""))); + ServerStatusDisplay.Show(statusInfo); + return true; } finally @@ -3792,7 +3852,7 @@ namespace MinecraftClient.Protocol.Handlers SendMessageAcknowledgment(ConsumeAcknowledgment()); } } - + /// /// Send a chat command to the server, with or without signing based on the online mode and version. /// @@ -3917,7 +3977,7 @@ namespace MinecraftClient.Protocol.Handlers return false; } } - + /// /// Send a chat message to the server /// @@ -4541,7 +4601,7 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(dataTypes.GetFloat(LastYaw)); packet.AddRange(dataTypes.GetFloat(LastPitch)); } - + SendPacket(PacketTypesOut.UseItem, packet); return true; } @@ -4604,12 +4664,12 @@ namespace MinecraftClient.Protocol.Handlers if (playerInventory?.Items is null) return false; - int[] slotWindowIds = [36, 37, 38, 39, 40, 41, 42, 43, 44]; + int[] slotWindowIds = [36, 37, 38, 39, 40, 41, 42, 43, 44]; var currentSlot = ((McClient)handler).GetCurrentSlot(); - + playerInventory.Items.TryGetValue(slotWindowIds[currentSlot], out var item); packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); - + packet.Add(0); // cursorX packet.Add(0); // cursorY packet.Add(0); // cursorZ @@ -4626,12 +4686,12 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(DataTypes.GetVarInt(dataTypes.GetBlockFace(face))); break; } - + packet.AddRange(dataTypes.GetFloat(cursorX)); // cursorX packet.AddRange(dataTypes.GetFloat(cursorY)); // cursorY packet.AddRange(dataTypes.GetFloat(cursorZ)); // cursorZ - - if(protocolVersion >= MC_1_14_Version) + + if (protocolVersion >= MC_1_14_Version) packet.Add(0); // insideBlock = false if (protocolVersion >= MC_1_21_2_Version) @@ -4639,7 +4699,7 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion >= MC_1_19_Version) packet.AddRange(DataTypes.GetVarInt(sequenceId)); - + SendPacket(PacketTypesOut.PlayerBlockPlacement, packet); return true; } @@ -5235,7 +5295,7 @@ namespace MinecraftClient.Protocol.Handlers return false; } } - + public bool SendCookieResponse(string name, byte[]? data) { try @@ -5244,7 +5304,7 @@ namespace MinecraftClient.Protocol.Handlers var hasPayload = data is not null; packet.AddRange(dataTypes.GetString(name)); // Identifier packet.AddRange(dataTypes.GetBool(hasPayload)); // Has payload - + if (hasPayload) packet.AddRange(dataTypes.GetArray(data!)); // Payload Data Array Size + Data Array @@ -5262,7 +5322,7 @@ namespace MinecraftClient.Protocol.Handlers SendPacket(PacketTypesOut.CookieResponse, packet); break; } - + McClient.Instance?.DeleteCookie(name); return true; } @@ -5293,17 +5353,17 @@ namespace MinecraftClient.Protocol.Handlers packet.AddRange(dataTypes.GetString(dataPack.Item3)); } - switch(currentState) + switch (currentState) { - case CurrentState.Configuration: + case CurrentState.Configuration: SendPacket(ConfigurationPacketTypesOut.KnownDataPacks, packet); break; - + case CurrentState.Play: SendPacket(PacketTypesOut.KnownDataPacks, packet); break; } - + return true; } catch (SocketException) @@ -5319,7 +5379,7 @@ namespace MinecraftClient.Protocol.Handlers return false; } } - + private byte[] GenerateSalt() { var salt = new byte[8]; diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index c000385e..a8568f38 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Net.Http; using System.Net.Sockets; using System.Text; +using System.Text.RegularExpressions; using DnsClient; using MinecraftClient.Protocol.Handlers; using MinecraftClient.Protocol.Handlers.Forge; @@ -388,6 +389,61 @@ namespace MinecraftClient.Protocol } } + private static readonly Regex VersionTokenRegex = new(@"\d+\.\d+(?:\.\d+)?", RegexOptions.Compiled); + + private static readonly int[] SupportedProtocols18 = + [ + 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, + 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, + 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, + 772, 773, 774, 775 + ]; + + /// + /// For multi-version servers (e.g. "Requires MC 1.8 / 1.21"), try to find the + /// highest protocol version that both the server and MCC support. + /// Returns true if the protocol was upgraded, with the new value in + /// . + /// + public static bool TryUpgradeProtocolVersion(string versionName, ref int protocolVersion) + { + if (string.IsNullOrEmpty(versionName)) + return false; + + var matches = VersionTokenRegex.Matches(versionName); + if (matches.Count < 2) + return false; + + int bestProtocol = protocolVersion; + string bestVersion = ""; + + foreach (Match m in matches) + { + int proto = MCVer2ProtocolVersion(m.Value); + if (proto <= 0) + continue; + if (Array.IndexOf(SupportedProtocols18, proto) < 0) + continue; + if (proto > bestProtocol) + { + bestProtocol = proto; + bestVersion = m.Value; + } + } + + if (bestProtocol > protocolVersion && bestVersion.Length > 0) + { + ConsoleIO.WriteLineFormatted("§8" + string.Format( + Translations.mcc_server_info_version_upgrade, + ProtocolVersion2MCVer(protocolVersion), protocolVersion, + "§a" + bestVersion + "§8", bestProtocol)); + protocolVersion = bestProtocol; + return true; + } + + return false; + } + /// /// Convert a network protocol version number to human-readable Minecraft version number /// diff --git a/MinecraftClient/Protocol/ServerStatusDisplay.cs b/MinecraftClient/Protocol/ServerStatusDisplay.cs new file mode 100644 index 00000000..21e386ab --- /dev/null +++ b/MinecraftClient/Protocol/ServerStatusDisplay.cs @@ -0,0 +1,118 @@ +using System; +using System.Text; +using MinecraftClient.Protocol.Message; + +namespace MinecraftClient.Protocol +{ + internal static class ServerStatusDisplay + { + private const int MaxSamplePlayers = 10; + + internal static void Show(ServerStatusInfo info) + { + if (ConsoleIO.Backend is Tui.TuiConsoleBackend tuiBackend) + ShowTui(info, tuiBackend); + else + ShowClassic(info); + } + + private static void ShowClassic(ServerStatusInfo info) + { + var sb = new StringBuilder(); + + sb.AppendLine(); + sb.Append("§8§m"); + sb.Append(new string('-', 50)); + sb.AppendLine("§r"); + + if (!string.IsNullOrEmpty(info.MotdRaw)) + { + try + { + sb.AppendLine(ChatParser.ParseText(info.MotdRaw)); + } + catch + { + sb.AppendLine(info.MotdRaw); + } + } + + sb.Append("§f"); + sb.Append(Translations.mcc_server_info_label_server); + sb.Append(" §b"); + sb.Append(info.Host); + sb.Append("§7:§b"); + sb.AppendLine(info.Port.ToString()); + + sb.Append("§f"); + sb.Append(Translations.mcc_server_info_label_version); + sb.Append(" §b"); + sb.Append(info.VersionName); + sb.Append(" §7("); + sb.Append(string.Format(Translations.mcc_server_info_label_protocol, "§e" + info.ProtocolVersion + "§7")); + sb.AppendLine(")"); + + if (info.ResolvedProtocol != 0 && info.ResolvedProtocol != info.ProtocolVersion) + { + string resolvedMcVer = ProtocolHandler.ProtocolVersion2MCVer(info.ResolvedProtocol); + sb.Append("§f"); + sb.Append(Translations.mcc_server_info_label_connecting_as); + sb.Append(" §a"); + sb.Append(resolvedMcVer); + sb.Append(" §7("); + sb.Append(string.Format(Translations.mcc_server_info_label_protocol, "§a" + info.ResolvedProtocol + "§7")); + sb.AppendLine(")"); + } + + if (info.PingMs >= 0) + { + sb.Append("§f"); + sb.Append(Translations.mcc_server_info_label_ping); + sb.Append(" §a"); + sb.AppendLine(string.Format(Translations.mcc_server_info_label_ping_ms, info.PingMs)); + } + + sb.Append("§f"); + sb.Append(Translations.mcc_server_info_label_players); + sb.Append(" §a"); + sb.Append(info.OnlinePlayers); + sb.Append("§7/§c"); + sb.AppendLine(info.MaxPlayers.ToString()); + + if (info.SamplePlayers.Count > 0) + { + sb.Append("§f"); + sb.AppendLine(Translations.mcc_server_info_label_online); + + int shown = Math.Min(info.SamplePlayers.Count, MaxSamplePlayers); + for (int i = 0; i < shown; i++) + sb.AppendLine($" §a{info.SamplePlayers[i].Name}"); + + if (info.SamplePlayers.Count > shown) + sb.AppendLine($" §7{string.Format(Translations.mcc_server_info_sample_more, info.SamplePlayers.Count - shown)}"); + } + + sb.Append("§8§m"); + sb.Append(new string('-', 50)); + sb.Append("§r"); + + ConsoleIO.WriteLineFormatted(sb.ToString(), acceptnewlines: true); + } + + private static void ShowTui(ServerStatusInfo info, Tui.TuiConsoleBackend backend) + { + var view = backend.GetView(); + if (view is null) + { + ShowClassic(info); + return; + } + + Avalonia.Threading.Dispatcher.UIThread.Post(() => + { + var panel = Tui.ServerStatusPanelBuilder.Build(info); + view.AppendControlToLog(panel); + }); + } + } +} diff --git a/MinecraftClient/Protocol/ServerStatusInfo.cs b/MinecraftClient/Protocol/ServerStatusInfo.cs new file mode 100644 index 00000000..b864e64d --- /dev/null +++ b/MinecraftClient/Protocol/ServerStatusInfo.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +namespace MinecraftClient.Protocol +{ + /// + /// Holds the structured result of a Minecraft server status (SLP) ping, + /// including MOTD, player counts, sample player list, version, and favicon. + /// + public sealed class ServerStatusInfo + { + public string Host { get; init; } = string.Empty; + public int Port { get; init; } + public string VersionName { get; init; } = string.Empty; + public int ProtocolVersion { get; init; } + public int ResolvedProtocol { get; set; } + public int OnlinePlayers { get; init; } + public int MaxPlayers { get; init; } + public List SamplePlayers { get; init; } = []; + public string MotdRaw { get; init; } = string.Empty; + public string? FaviconBase64 { get; init; } + public long PingMs { get; init; } + + public sealed class SamplePlayer + { + public string Name { get; init; } = string.Empty; + public string Id { get; init; } = string.Empty; + } + } +} diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 071bee44..3fc6e722 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -2269,6 +2269,66 @@ namespace MinecraftClient { } } + internal static string mcc_server_info_label_server { + get { + return ResourceManager.GetString("mcc.server_info.label_server", resourceCulture); + } + } + + internal static string mcc_server_info_label_version { + get { + return ResourceManager.GetString("mcc.server_info.label_version", resourceCulture); + } + } + + internal static string mcc_server_info_label_protocol { + get { + return ResourceManager.GetString("mcc.server_info.label_protocol", resourceCulture); + } + } + + internal static string mcc_server_info_label_players { + get { + return ResourceManager.GetString("mcc.server_info.label_players", resourceCulture); + } + } + + internal static string mcc_server_info_label_ping { + get { + return ResourceManager.GetString("mcc.server_info.label_ping", resourceCulture); + } + } + + internal static string mcc_server_info_label_ping_ms { + get { + return ResourceManager.GetString("mcc.server_info.label_ping_ms", resourceCulture); + } + } + + internal static string mcc_server_info_label_connecting_as { + get { + return ResourceManager.GetString("mcc.server_info.label_connecting_as", resourceCulture); + } + } + + internal static string mcc_server_info_label_online { + get { + return ResourceManager.GetString("mcc.server_info.label_online", resourceCulture); + } + } + + internal static string mcc_server_info_sample_more { + get { + return ResourceManager.GetString("mcc.server_info.sample_more", resourceCulture); + } + } + + internal static string mcc_server_info_version_upgrade { + get { + return ResourceManager.GetString("mcc.server_info.version_upgrade", resourceCulture); + } + } + /// /// Looks up a localized string similar to Converting session cache from disk: {0}. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index ad782375..c3acc0fc 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -830,6 +830,36 @@ Add the ID of this chat to "Authorized_Chat_Ids" field in the configuration file TestBot + + Server: + + + Version: + + + Protocol: {0} + + + Players: + + + Ping: + + + {0} ms + + + Connecting as: + + + Online: + + + ... +{0} + + + Server reported protocol {0} ({1}), upgraded to {2} ({3}) for best compatibility + Converting session cache from disk: {0} @@ -2015,10 +2045,10 @@ MCC is running with default settings. Server is in offline mode. - Server version : {0} (protocol v{1}) + Server version: {0} (protocol v{1}) - Server version : + Server version: Checking Session... diff --git a/MinecraftClient/Tui/MainTuiView.cs b/MinecraftClient/Tui/MainTuiView.cs index 34ff06db..1106f763 100644 --- a/MinecraftClient/Tui/MainTuiView.cs +++ b/MinecraftClient/Tui/MainTuiView.cs @@ -1171,5 +1171,18 @@ namespace MinecraftClient.Tui _commandInput.Focus(); }, DispatcherPriority.Loaded); } + + #region Custom Control Append + + public void AppendControlToLog(Control control) + { + _logLines.Add(string.Empty); + _logControls.Add(control); + TrimLog(); + if (_autoScroll) + ScheduleScrollToEnd(); + } + + #endregion } } diff --git a/MinecraftClient/Tui/McColorParser.cs b/MinecraftClient/Tui/McColorParser.cs index c46b0adf..30f8f280 100644 --- a/MinecraftClient/Tui/McColorParser.cs +++ b/MinecraftClient/Tui/McColorParser.cs @@ -52,6 +52,8 @@ namespace MinecraftClient.Tui IBrush currentColor = Brushes.White; bool bold = false; bool italic = false; + bool underline = false; + bool strikethrough = false; int start = 0; for (int i = 0; i < text.Length; i++) @@ -59,7 +61,7 @@ namespace MinecraftClient.Tui if (text[i] == '§' && i + 1 < text.Length) { if (i > start) - AddRun(tb, text[start..i], currentColor, bold, italic); + AddRun(tb, text[start..i], currentColor, bold, italic, underline, strikethrough); char code = char.ToLower(text[i + 1]); @@ -68,6 +70,8 @@ namespace MinecraftClient.Tui currentColor = brush; bold = false; italic = false; + underline = false; + strikethrough = false; } else { @@ -75,10 +79,14 @@ namespace MinecraftClient.Tui { case 'l': bold = true; break; case 'o': italic = true; break; + case 'n': underline = true; break; + case 'm': strikethrough = true; break; case 'r': currentColor = Brushes.White; bold = false; italic = false; + underline = false; + strikethrough = false; break; } } @@ -89,7 +97,7 @@ namespace MinecraftClient.Tui } if (start < text.Length) - AddRun(tb, text[start..], currentColor, bold, italic); + AddRun(tb, text[start..], currentColor, bold, italic, underline, strikethrough); if (tb.Inlines?.Count == 0) { @@ -100,16 +108,29 @@ namespace MinecraftClient.Tui return tb; } - private static void AddRun(TextBlock tb, string text, IBrush color, bool bold, bool italic) + private static void AddRun(TextBlock tb, string text, IBrush color, + bool bold, bool italic, bool underline, bool strikethrough) { if (text.Length == 0) return; tb.Inlines ??= new InlineCollection(); + + TextDecorationCollection? decorations = null; + if (underline || strikethrough) + { + decorations = []; + if (underline) + decorations.Add(new TextDecoration { Location = TextDecorationLocation.Underline }); + if (strikethrough) + decorations.Add(new TextDecoration { Location = TextDecorationLocation.Strikethrough }); + } + tb.Inlines.Add(new Run(text) { Foreground = color, FontWeight = bold ? FontWeight.Bold : FontWeight.Normal, FontStyle = italic ? FontStyle.Italic : FontStyle.Normal, + TextDecorations = decorations, }); } } diff --git a/MinecraftClient/Tui/ServerStatusPanelBuilder.cs b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs new file mode 100644 index 00000000..3b6e8f9f --- /dev/null +++ b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs @@ -0,0 +1,296 @@ +using System; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Documents; +using Avalonia.Layout; +using Avalonia.Media; + +namespace MinecraftClient.Tui +{ + internal static class ServerStatusPanelBuilder + { + private const int MaxSamplePlayers = 10; + private const int FaviconDisplaySize = 16; + + internal static Border Build(Protocol.ServerStatusInfo info) + { + var contentPanel = new DockPanel { Background = Brushes.Black }; + + if (info.FaviconBase64 is not null) + { + var iconGrid = BuildFaviconGrid(info.FaviconBase64, FaviconDisplaySize); + DockPanel.SetDock(iconGrid, Dock.Left); + contentPanel.Children.Add(iconGrid); + } + + var infoPanel = new StackPanel + { + Orientation = Orientation.Vertical, + Margin = new Thickness(1, 0, 0, 0), + }; + + AddMotd(infoPanel, info); + AddAddress(infoPanel, info); + AddVersion(infoPanel, info); + AddConnectingAs(infoPanel, info); + AddPing(infoPanel, info); + AddPlayers(infoPanel, info); + AddSamplePlayers(infoPanel, info); + + contentPanel.Children.Add(infoPanel); + + return new Border + { + BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80)), + BorderThickness = new Thickness(1), + Background = new SolidColorBrush(Color.FromArgb(240, 20, 20, 20)), + Padding = new Thickness(1, 0), + Child = contentPanel, + Margin = new Thickness(0, 1), + }; + } + + private static void AddMotd(StackPanel panel, Protocol.ServerStatusInfo info) + { + if (string.IsNullOrEmpty(info.MotdRaw)) + return; + + try + { + string motdFormatted = Protocol.Message.ChatParser.ParseText(info.MotdRaw); + foreach (string line in motdFormatted.Split('\n')) + panel.Children.Add(McColorParser.CreateColoredTextBlock(line, TextWrapping.NoWrap)); + } + catch + { + panel.Children.Add(new TextBlock + { + Text = info.MotdRaw, + Foreground = Brushes.White, + TextWrapping = TextWrapping.NoWrap, + }); + } + } + + private static void AddAddress(StackPanel panel, Protocol.ServerStatusInfo info) + { + var row = new TextBlock(); + row.Inlines!.Add(Label(Translations.mcc_server_info_label_server)); + row.Inlines.Add(Value(info.Host, McColors.Aqua)); + row.Inlines.Add(new Run($":{info.Port}") { Foreground = McColors.Gray }); + panel.Children.Add(row); + } + + private static void AddVersion(StackPanel panel, Protocol.ServerStatusInfo info) + { + var row = new TextBlock(); + row.Inlines!.Add(Label(Translations.mcc_server_info_label_version)); + row.Inlines.Add(Value(info.VersionName, McColors.Aqua)); + row.Inlines.Add(new Run(" (") { Foreground = McColors.Gray }); + row.Inlines.Add(new Run(string.Format(Translations.mcc_server_info_label_protocol, info.ProtocolVersion)) + { Foreground = McColors.Gray }); + row.Inlines.Add(new Run(")") { Foreground = McColors.Gray }); + panel.Children.Add(row); + } + + private static void AddConnectingAs(StackPanel panel, Protocol.ServerStatusInfo info) + { + if (info.ResolvedProtocol == 0 || info.ResolvedProtocol == info.ProtocolVersion) + return; + + string resolvedMcVer = Protocol.ProtocolHandler.ProtocolVersion2MCVer(info.ResolvedProtocol); + var row = new TextBlock(); + row.Inlines!.Add(Label(Translations.mcc_server_info_label_connecting_as)); + row.Inlines.Add(Value(resolvedMcVer, McColors.Green)); + row.Inlines.Add(new Run(" (") { Foreground = McColors.Gray }); + row.Inlines.Add(new Run(string.Format(Translations.mcc_server_info_label_protocol, info.ResolvedProtocol)) + { Foreground = McColors.Gray }); + row.Inlines.Add(new Run(")") { Foreground = McColors.Gray }); + panel.Children.Add(row); + } + + private static void AddPing(StackPanel panel, Protocol.ServerStatusInfo info) + { + if (info.PingMs < 0) + return; + + var pingColor = info.PingMs < 100 + ? McColors.Green + : info.PingMs < 300 + ? McColors.Yellow + : McColors.Red; + + var row = new TextBlock(); + row.Inlines!.Add(Label(Translations.mcc_server_info_label_ping)); + row.Inlines.Add(new Run(string.Format(Translations.mcc_server_info_label_ping_ms, info.PingMs)) + { Foreground = pingColor }); + panel.Children.Add(row); + } + + private static void AddPlayers(StackPanel panel, Protocol.ServerStatusInfo info) + { + var row = new TextBlock(); + row.Inlines!.Add(Label(Translations.mcc_server_info_label_players)); + row.Inlines.Add(Value($"{info.OnlinePlayers}", McColors.Green)); + row.Inlines.Add(new Run("/") { Foreground = McColors.Gray }); + row.Inlines.Add(Value($"{info.MaxPlayers}", McColors.Red)); + panel.Children.Add(row); + } + + private static void AddSamplePlayers(StackPanel panel, Protocol.ServerStatusInfo info) + { + if (info.SamplePlayers.Count == 0) + return; + + panel.Children.Add(new TextBlock + { + Text = Translations.mcc_server_info_label_online, + Foreground = McColors.Gray, + Margin = new Thickness(0, 1, 0, 0), + }); + + int shown = Math.Min(info.SamplePlayers.Count, MaxSamplePlayers); + for (int i = 0; i < shown; i++) + { + panel.Children.Add(new TextBlock + { + Text = $" {info.SamplePlayers[i].Name}", + Foreground = McColors.Green, + }); + } + + if (info.SamplePlayers.Count > shown) + { + panel.Children.Add(new TextBlock + { + Text = $" {string.Format(Translations.mcc_server_info_sample_more, info.SamplePlayers.Count - shown)}", + Foreground = McColors.Gray, + }); + } + } + + private static Run Label(string text) => + new(text + " ") { Foreground = McColors.Gray }; + + private static Run Value(string text, IBrush color) => + new(text) { Foreground = color }; + + #region Favicon Rendering + + private static Grid BuildFaviconGrid(string base64Png, int displaySize) + { + byte[] pngBytes; + try + { + pngBytes = Convert.FromBase64String(base64Png); + } + catch + { + return new Grid(); + } + + int srcWidth, srcHeight; + byte[] rgba; + try + { + (srcWidth, srcHeight, rgba) = DecodePngToRgba(pngBytes); + } + catch + { + return new Grid(); + } + + int cellCols = displaySize; + int cellRows = displaySize / 2; + + var grid = new Grid(); + for (int c = 0; c < cellCols; c++) + grid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Auto)); + for (int r = 0; r < cellRows; r++) + grid.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Auto)); + + for (int row = 0; row < cellRows; row++) + { + for (int col = 0; col < cellCols; col++) + { + int topPixelY = row * 2; + int bottomPixelY = row * 2 + 1; + + var topColor = SamplePixel(rgba, srcWidth, srcHeight, col, topPixelY, cellCols, displaySize); + var bottomColor = SamplePixel(rgba, srcWidth, srcHeight, col, bottomPixelY, cellCols, displaySize); + + var cell = new TextBlock + { + Text = "\u2580", + Foreground = new SolidColorBrush(topColor), + Background = new SolidColorBrush(bottomColor), + Padding = new Thickness(0), + Margin = new Thickness(0), + }; + + Grid.SetRow(cell, row); + Grid.SetColumn(cell, col); + grid.Children.Add(cell); + } + } + + return grid; + } + + private static Color SamplePixel(byte[] rgba, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) + { + int srcX = dstX * srcW / dstW; + int srcY = dstY * srcH / dstH; + srcX = Math.Clamp(srcX, 0, srcW - 1); + srcY = Math.Clamp(srcY, 0, srcH - 1); + + int idx = (srcY * srcW + srcX) * 4; + if (idx + 3 >= rgba.Length) + return Color.FromRgb(0, 0, 0); + + byte r = rgba[idx]; + byte g = rgba[idx + 1]; + byte b = rgba[idx + 2]; + byte a = rgba[idx + 3]; + + return a < 128 ? Color.FromRgb(0, 0, 0) : Color.FromRgb(r, g, b); + } + + private static (int Width, int Height, byte[] Rgba) DecodePngToRgba(byte[] png) + { + using var image = new ImageMagick.MagickImage(png); + int w = (int)image.Width; + int h = (int)image.Height; + + using var pixels = image.GetPixelsUnsafe(); + var rgba = new byte[w * h * 4]; + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + var pixel = pixels.GetPixel(x, y)!; + int idx = (y * w + x) * 4; + var color = pixel.ToColor()!; + rgba[idx] = (byte)(color.R >> 8); + rgba[idx + 1] = (byte)(color.G >> 8); + rgba[idx + 2] = (byte)(color.B >> 8); + rgba[idx + 3] = (byte)(color.A >> 8); + } + } + + return (w, h, rgba); + } + + #endregion + + private static class McColors + { + public static readonly IBrush Gray = new SolidColorBrush(Color.FromRgb(170, 170, 170)); + public static readonly IBrush Aqua = new SolidColorBrush(Color.FromRgb(85, 255, 255)); + public static readonly IBrush Green = new SolidColorBrush(Color.FromRgb(85, 255, 85)); + public static readonly IBrush Red = new SolidColorBrush(Color.FromRgb(255, 85, 85)); + public static readonly IBrush Yellow = new SolidColorBrush(Color.FromRgb(255, 255, 85)); + } + } +} From 3a28634592a4a0408cf0013f8718f74d6ad673c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 17:48:49 +0000 Subject: [PATCH 268/484] Initial plan From d5308ba8c650b8f68f5e21d07198e411c1642d6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:00:44 +0000 Subject: [PATCH 269/484] feat: add recipe book command support Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/00c8527f-5755-43c1-8916-8d571d28860b Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Commands/RecipeBook.cs | 92 +++++++++++++++ MinecraftClient/McClient.cs | 110 ++++++++++++++++++ .../Protocol/Handlers/Protocol16.cs | 5 + .../Protocol/Handlers/Protocol18.cs | 94 +++++++++++++++ MinecraftClient/Protocol/IMinecraftCom.cs | 9 ++ .../Protocol/IMinecraftComHandler.cs | 13 +++ .../Translations/Translations.Designer.cs | 63 ++++++++++ .../Resources/Translations/Translations.resx | 21 ++++ 8 files changed, 407 insertions(+) create mode 100644 MinecraftClient/Commands/RecipeBook.cs diff --git a/MinecraftClient/Commands/RecipeBook.cs b/MinecraftClient/Commands/RecipeBook.cs new file mode 100644 index 00000000..a66b2004 --- /dev/null +++ b/MinecraftClient/Commands/RecipeBook.cs @@ -0,0 +1,92 @@ +using System.Text; +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; + +namespace MinecraftClient.Commands +{ + public class RecipeBook : Command + { + public override string CmdName => "recipebook"; + public override string CmdUsage => "recipebook [recipe id]"; + public override string CmdDesc => Translations.cmd_recipebook_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source, string.Empty)) + .Then(l => l.Literal("list") + .Executes(r => GetUsage(r.Source, "list"))) + .Then(l => l.Literal("craft") + .Executes(r => GetUsage(r.Source, "craft"))) + .Then(l => l.Literal("craftall") + .Executes(r => GetUsage(r.Source, "craftall"))) + ) + ); + + dispatcher.Register(l => l.Literal(CmdName) + .Then(l => l.Literal("list") + .Executes(r => ListRecipes(r.Source))) + .Then(l => l.Literal("craft") + .Then(l => l.Argument("RecipeId", Arguments.String()) + .Executes(r => CraftRecipe(r.Source, Arguments.GetString(r, "RecipeId"), makeAll: false)))) + .Then(l => l.Literal("craftall") + .Then(l => l.Argument("RecipeId", Arguments.String()) + .Executes(r => CraftRecipe(r.Source, Arguments.GetString(r, "RecipeId"), makeAll: true)))) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source, string.Empty)) + .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) + ); + } + + private int GetUsage(CmdResult r, string? cmd) + { + return r.SetAndReturn(cmd switch + { +#pragma warning disable format // @formatter:off + "list" => GetCmdDescTranslated(), + "craft" => GetCmdDescTranslated(), + "craftall" => GetCmdDescTranslated(), + _ => GetCmdDescTranslated(), +#pragma warning restore format // @formatter:on + }); + } + + private int ListRecipes(CmdResult r) + { + McClient handler = CmdResult.currentHandler!; + if (!handler.GetInventoryEnabled()) + return r.SetAndReturn(CmdResult.Status.FailNeedInventory); + + string[] recipeIds = handler.GetUnlockedRecipes(); + if (recipeIds.Length == 0) + return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_recipes); + + StringBuilder response = new(); + response.AppendLine(Translations.cmd_recipebook_list); + foreach (string recipeId in recipeIds) + response.AppendLine("- " + recipeId); + + handler.Log.Info(response.ToString().TrimEnd()); + return r.SetAndReturn(CmdResult.Status.Done); + } + + private int CraftRecipe(CmdResult r, string recipeId, bool makeAll) + { + McClient handler = CmdResult.currentHandler!; + if (!handler.GetInventoryEnabled()) + return r.SetAndReturn(CmdResult.Status.FailNeedInventory); + + if (handler.GetProtocolVersion() < Protocol.Handlers.Protocol18Handler.MC_1_13_Version) + return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_unsupported); + + if (handler.GetActiveRecipeBookInventory() is null) + return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_active_inventory); + + return handler.SendPlaceRecipe(recipeId, makeAll) + ? r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_recipebook_craft_sent, recipeId, makeAll)) + : r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_recipebook_craft_failed, recipeId)); + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 938a85bf..3e12d920 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -44,10 +44,12 @@ namespace MinecraftClient private readonly Queue threadTasks = new(); private readonly Lock threadTasksLock = new(); + private readonly Lock recipeBookLock = new(); private readonly List bots = new(); private static readonly List botsOnHold = new(); private static readonly Dictionary inventories = new(); + private readonly HashSet unlockedRecipes = new(StringComparer.Ordinal); private readonly Dictionary> registeredBotPluginChannels = new(); private readonly List registeredServerPluginChannels = new(); @@ -1237,6 +1239,7 @@ namespace MinecraftClient inventoryHandlingEnabled = false; inventoryHandlingRequested = false; inventories.Clear(); + ClearUnlockedRecipes(); } return true; } @@ -1338,6 +1341,18 @@ namespace MinecraftClient return lastEnchantment; } + /// + /// Get all unlocked recipe book recipe identifiers. + /// + /// Unlocked recipe identifiers sorted alphabetically + public string[] GetUnlockedRecipes() + { + lock (recipeBookLock) + { + return [.. unlockedRecipes.OrderBy(static recipeId => recipeId, StringComparer.Ordinal)]; + } + } + /// /// Get all Entities /// @@ -1384,6 +1399,22 @@ namespace MinecraftClient return GetInventory(0)!; } + /// + /// Get the currently active inventory if it supports recipe book crafting. + /// + /// Active recipe book inventory, or null if the active inventory does not support recipe book crafting + public Container? GetActiveRecipeBookInventory() + { + if (InvokeRequired) + return InvokeOnMainThread(() => GetActiveRecipeBookInventory()); + + if (inventories.Count == 0) + return null; + + Container activeInventory = inventories.Values.Last(); + return SupportsRecipeBook(activeInventory.Type) ? activeInventory : null; + } + /// /// Get a set of online player names /// @@ -2476,6 +2507,7 @@ namespace MinecraftClient inventories.Clear(); inventories[0] = new Container(0, ContainerType.PlayerInventory, "Player Inventory"); + ClearUnlockedRecipes(); return true; } @@ -2677,6 +2709,27 @@ namespace MinecraftClient return handler.SendRenameItem(itemName); } + + /// + /// Send a recipe book craft request for the currently active crafting inventory. + /// + /// Recipe identifier to craft + /// True to craft as many items as possible + /// True if the packet was sent + public bool SendPlaceRecipe(string recipeId, bool makeAll) + { + if (InvokeRequired) + return InvokeOnMainThread(() => SendPlaceRecipe(recipeId, makeAll)); + + if (protocolversion < Protocol18Handler.MC_1_13_Version) + return false; + + Container? activeInventory = GetActiveRecipeBookInventory(); + if (activeInventory is null) + return false; + + return handler.SendPlaceRecipe(activeInventory.ID, NormalizeRecipeId(recipeId), makeAll); + } #endregion #region Event handlers: An event occurs on the Server @@ -4054,6 +4107,33 @@ namespace MinecraftClient Log.Debug("CanSendMessage = " + canSendMessage); } + public void OnRecipeBookAdd(string[] recipeIds, bool replace) + { + lock (recipeBookLock) + { + if (replace) + unlockedRecipes.Clear(); + + foreach (string recipeId in recipeIds) + { + if (!string.IsNullOrWhiteSpace(recipeId)) + unlockedRecipes.Add(recipeId); + } + } + } + + public void OnRecipeBookRemove(string[] recipeIds) + { + lock (recipeBookLock) + { + foreach (string recipeId in recipeIds) + { + if (!string.IsNullOrWhiteSpace(recipeId)) + unlockedRecipes.Remove(recipeId); + } + } + } + /// /// Send a click container button packet to the server. /// Used for Enchanting table, Lectern, stone cutter and loom @@ -4067,6 +4147,36 @@ namespace MinecraftClient return handler.ClickContainerButton(windowId, buttonId); } + private static bool SupportsRecipeBook(ContainerType containerType) + { + return containerType switch + { + ContainerType.PlayerInventory or + ContainerType.Crafting or + ContainerType.Furnace or + ContainerType.BlastFurnace or + ContainerType.Smoker or + ContainerType.Stonecutter => true, + _ => false, + }; + } + + private void ClearUnlockedRecipes() + { + lock (recipeBookLock) + { + unlockedRecipes.Clear(); + } + } + + private static string NormalizeRecipeId(string recipeId) + { + string trimmedRecipeId = recipeId.Trim(); + return trimmedRecipeId.Contains(':', StringComparison.Ordinal) + ? trimmedRecipeId + : "minecraft:" + trimmedRecipeId; + } + #endregion } } diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 15d20b71..6777200d 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -811,6 +811,11 @@ namespace MinecraftClient.Protocol.Handlers return false; //Currently not implemented } + public bool SendPlaceRecipe(int windowId, string recipeId, bool makeAll) + { + return false; //MC 1.8-1.12.1 recipe book not supported + } + public bool SendCloseWindow(int windowId) { return false; //Currently not implemented diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 5329cdfb..317090a9 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3116,8 +3116,17 @@ namespace MinecraftClient.Protocol.Handlers } break; + case PacketTypesIn.UnlockRecipes: + if (protocolVersion >= MC_1_13_Version) + HandleUnlockRecipes(packetData); + break; + case PacketTypesIn.RecipeBookAdd: + HandleRecipeBookAdd(packetData); + break; case PacketTypesIn.RecipeBookRemove: + handler.OnRecipeBookRemove(ReadRecipeBookRecipeIds(packetData)); + break; case PacketTypesIn.RecipeBookSettings: break; @@ -3128,6 +3137,63 @@ namespace MinecraftClient.Protocol.Handlers return true; //Packet processed } + private void HandleUnlockRecipes(Queue packetData) + { + int action = dataTypes.ReadNextVarInt(packetData); + SkipRecipeBookSettings(packetData); + + string[] recipeIds = ReadRecipeBookRecipeIds(packetData); + + switch (action) + { + case 0: + handler.OnRecipeBookAdd(recipeIds, replace: true); + _ = ReadRecipeBookRecipeIds(packetData); + break; + case 1: + case 3: + handler.OnRecipeBookAdd(recipeIds, replace: false); + break; + case 2: + handler.OnRecipeBookRemove(recipeIds); + break; + } + } + + private void HandleRecipeBookAdd(Queue packetData) + { + int entryCount = dataTypes.ReadNextVarInt(packetData); + string[] recipeIds = new string[entryCount]; + + for (int i = 0; i < entryCount; i++) + { + recipeIds[i] = dataTypes.ReadNextString(packetData); + _ = dataTypes.ReadNextBool(packetData); // notification + _ = dataTypes.ReadNextBool(packetData); // highlight + } + + bool replace = dataTypes.ReadNextBool(packetData); + handler.OnRecipeBookAdd(recipeIds, replace); + } + + private string[] ReadRecipeBookRecipeIds(Queue packetData) + { + int recipeCount = dataTypes.ReadNextVarInt(packetData); + string[] recipeIds = new string[recipeCount]; + + for (int i = 0; i < recipeCount; i++) + recipeIds[i] = dataTypes.ReadNextString(packetData); + + return recipeIds; + } + + private void SkipRecipeBookSettings(Queue packetData) + { + int boolCount = protocolVersion >= MC_1_14_Version ? 8 : 4; + for (int i = 0; i < boolCount; i++) + _ = dataTypes.ReadNextBool(packetData); + } + /// /// Start the updating thread. Should be called after login success. /// @@ -5018,6 +5084,34 @@ namespace MinecraftClient.Protocol.Handlers } } + public bool SendPlaceRecipe(int windowId, string recipeId, bool makeAll) + { + try + { + List packet = new(); + if (protocolVersion < MC_1_13_Version) + return false; + + packet.AddRange(DataTypes.GetVarInt(windowId)); + packet.AddRange(dataTypes.GetString(recipeId)); + packet.AddRange(dataTypes.GetBool(makeAll)); + SendPacket(PacketTypesOut.CraftRecipeRequest, packet); + return true; + } + catch (SocketException) + { + return false; + } + catch (System.IO.IOException) + { + return false; + } + catch (ObjectDisposedException) + { + return false; + } + } + public bool SendAnimation(int animation, int playerId) { try diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs index 6c7dd596..96b261b1 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -190,6 +190,15 @@ namespace MinecraftClient.Protocol bool ClickContainerButton(int windowId, int buttonId); + /// + /// Send a place recipe packet to the server for the active recipe book container. + /// + /// Id of the window being clicked + /// Recipe identifier to craft + /// True to craft as many items as possible + /// True if packet was successfully sent + bool SendPlaceRecipe(int windowId, string recipeId, bool makeAll); + /// /// Plays animation /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 94fe0590..d6bd5eb7 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -517,6 +517,19 @@ namespace MinecraftClient.Protocol public void SetCanSendMessage(bool canSendMessage); + /// + /// Called when recipe book recipes are added or replaced. + /// + /// Recipe identifiers to add + /// True to replace the currently tracked recipe book entries + public void OnRecipeBookAdd(string[] recipeIds, bool replace); + + /// + /// Called when recipe book recipes are removed. + /// + /// Recipe identifiers to remove + public void OnRecipeBookRemove(string[] recipeIds); + /// /// Send a click container button packet to the server. /// Used for Enchanting table, Lectern, stone cutter and loom diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 3fc6e722..b6bea198 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -4359,6 +4359,69 @@ namespace MinecraftClient { return ResourceManager.GetString("cmd.nameitem.successful", resourceCulture); } } + + /// + /// Looks up a localized string similar to Failed to send recipe book craft request for {0}.. + /// + internal static string cmd_recipebook_craft_failed { + get { + return ResourceManager.GetString("cmd.recipebook.craft.failed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Requested recipe {0} (craft all: {1}).. + /// + internal static string cmd_recipebook_craft_sent { + get { + return ResourceManager.GetString("cmd.recipebook.craft.sent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List unlocked recipe book recipes and craft them through the active recipe book inventory.. + /// + internal static string cmd_recipebook_desc { + get { + return ResourceManager.GetString("cmd.recipebook.desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unlocked recipe book recipes. + /// + internal static string cmd_recipebook_list { + get { + return ResourceManager.GetString("cmd.recipebook.list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You need an active player crafting grid, crafting table, furnace, blast furnace, smoker, or stonecutter inventory.. + /// + internal static string cmd_recipebook_no_active_inventory { + get { + return ResourceManager.GetString("cmd.recipebook.no.active.inventory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No unlocked recipe book recipes are currently tracked.. + /// + internal static string cmd_recipebook_no_recipes { + get { + return ResourceManager.GetString("cmd.recipebook.no.recipes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Recipe book crafting is only supported on Minecraft 1.13 and newer.. + /// + internal static string cmd_recipebook_unsupported { + get { + return ResourceManager.GetString("cmd.recipebook.unsupported", resourceCulture); + } + } /// /// Looks up a localized string similar to restart and reconnect to the server.. diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index c3acc0fc..42a9d8db 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2208,6 +2208,27 @@ Logging in... Set an item name when an Anvil inventory is active and the item is in the first slot. + + Failed to send recipe book craft request for {0}. + + + Requested recipe {0} (craft all: {1}). + + + List unlocked recipe book recipes and craft them through the active recipe book inventory. + + + Unlocked recipe book recipes + + + You need an active player crafting grid, crafting table, furnace, blast furnace, smoker, or stonecutter inventory. + + + No unlocked recipe book recipes are currently tracked. + + + Recipe book crafting is only supported on Minecraft 1.13 and newer. + Bot movement lock is held by bot {0}, so the Anti AFK bot might not move! From 893be203e5b528774eae39d890d269ff59837618 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:07:09 +0000 Subject: [PATCH 270/484] chore: polish recipe book support Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/00c8527f-5755-43c1-8916-8d571d28860b Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Commands/RecipeBook.cs | 18 ++++++++++++-- MinecraftClient/McClient.cs | 11 +++++++-- .../Protocol/Handlers/Protocol18.cs | 24 +++++++++++++++---- .../Translations/Translations.Designer.cs | 20 +++++++++++++++- .../Resources/Translations/Translations.resx | 8 ++++++- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/MinecraftClient/Commands/RecipeBook.cs b/MinecraftClient/Commands/RecipeBook.cs index a66b2004..b51d211b 100644 --- a/MinecraftClient/Commands/RecipeBook.cs +++ b/MinecraftClient/Commands/RecipeBook.cs @@ -78,15 +78,29 @@ namespace MinecraftClient.Commands if (!handler.GetInventoryEnabled()) return r.SetAndReturn(CmdResult.Status.FailNeedInventory); + if (string.IsNullOrWhiteSpace(recipeId)) + return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_recipe_id_empty); + if (handler.GetProtocolVersion() < Protocol.Handlers.Protocol18Handler.MC_1_13_Version) return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_unsupported); if (handler.GetActiveRecipeBookInventory() is null) return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_active_inventory); + string normalizedRecipeId = NormalizeRecipeId(recipeId); + string successMessage = string.Format(makeAll ? Translations.cmd_recipebook_craftall_sent : Translations.cmd_recipebook_craft_sent, normalizedRecipeId); + return handler.SendPlaceRecipe(recipeId, makeAll) - ? r.SetAndReturn(CmdResult.Status.Done, string.Format(Translations.cmd_recipebook_craft_sent, recipeId, makeAll)) - : r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_recipebook_craft_failed, recipeId)); + ? r.SetAndReturn(CmdResult.Status.Done, successMessage) + : r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_recipebook_craft_failed, normalizedRecipeId)); + } + + private static string NormalizeRecipeId(string recipeId) + { + string trimmedRecipeId = recipeId.Trim(); + return trimmedRecipeId.Contains(':') + ? trimmedRecipeId + : "minecraft:" + trimmedRecipeId; } } } diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 3e12d920..751b79e6 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1411,7 +1411,7 @@ namespace MinecraftClient if (inventories.Count == 0) return null; - Container activeInventory = inventories.Values.Last(); + Container activeInventory = inventories.MaxBy(static pair => pair.Key).Value; return SupportsRecipeBook(activeInventory.Type) ? activeInventory : null; } @@ -2728,7 +2728,11 @@ namespace MinecraftClient if (activeInventory is null) return false; - return handler.SendPlaceRecipe(activeInventory.ID, NormalizeRecipeId(recipeId), makeAll); + string normalizedRecipeId = NormalizeRecipeId(recipeId); + if (normalizedRecipeId.Length == 0) + return false; + + return handler.SendPlaceRecipe(activeInventory.ID, normalizedRecipeId, makeAll); } #endregion @@ -4172,6 +4176,9 @@ namespace MinecraftClient private static string NormalizeRecipeId(string recipeId) { string trimmedRecipeId = recipeId.Trim(); + if (trimmedRecipeId.Length == 0) + return string.Empty; + return trimmedRecipeId.Contains(':', StringComparison.Ordinal) ? trimmedRecipeId : "minecraft:" + trimmedRecipeId; diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 317090a9..c5636cd1 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3122,10 +3122,12 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.RecipeBookAdd: - HandleRecipeBookAdd(packetData); + if (protocolVersion >= MC_1_21_2_Version) + HandleRecipeBookAdd(packetData); break; case PacketTypesIn.RecipeBookRemove: - handler.OnRecipeBookRemove(ReadRecipeBookRecipeIds(packetData)); + if (protocolVersion >= MC_1_21_2_Version) + handler.OnRecipeBookRemove(ReadRecipeBookRecipeIds(packetData)); break; case PacketTypesIn.RecipeBookSettings: break; @@ -3140,7 +3142,8 @@ namespace MinecraftClient.Protocol.Handlers private void HandleUnlockRecipes(Queue packetData) { int action = dataTypes.ReadNextVarInt(packetData); - SkipRecipeBookSettings(packetData); + if (!SkipRecipeBookSettings(packetData)) + return; string[] recipeIds = ReadRecipeBookRecipeIds(packetData); @@ -3148,10 +3151,15 @@ namespace MinecraftClient.Protocol.Handlers { case 0: handler.OnRecipeBookAdd(recipeIds, replace: true); + // INIT packets also include a second "to be displayed" recipe list. + // MCC only needs the unlocked recipe identifiers for listing/crafting. _ = ReadRecipeBookRecipeIds(packetData); break; case 1: + handler.OnRecipeBookAdd(recipeIds, replace: false); + break; case 3: + // Action 3 is the silent-add variant, so MCC tracks it like a regular add. handler.OnRecipeBookAdd(recipeIds, replace: false); break; case 2: @@ -3165,6 +3173,9 @@ namespace MinecraftClient.Protocol.Handlers int entryCount = dataTypes.ReadNextVarInt(packetData); string[] recipeIds = new string[entryCount]; + // RecipeBookAdd contains one entry per recipe: + // recipe id, notification flag, then highlight flag. + // MCC only tracks the unlocked recipe identifiers for now. for (int i = 0; i < entryCount; i++) { recipeIds[i] = dataTypes.ReadNextString(packetData); @@ -3187,11 +3198,16 @@ namespace MinecraftClient.Protocol.Handlers return recipeIds; } - private void SkipRecipeBookSettings(Queue packetData) + private bool SkipRecipeBookSettings(Queue packetData) { int boolCount = protocolVersion >= MC_1_14_Version ? 8 : 4; + if (packetData.Count < boolCount) + return false; + for (int i = 0; i < boolCount; i++) _ = dataTypes.ReadNextBool(packetData); + + return true; } /// diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index b6bea198..022e9cad 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -4370,7 +4370,7 @@ namespace MinecraftClient { } /// - /// Looks up a localized string similar to Requested recipe {0} (craft all: {1}).. + /// Looks up a localized string similar to Requested recipe {0}.. /// internal static string cmd_recipebook_craft_sent { get { @@ -4378,6 +4378,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Requested recipe {0} with craft-all.. + /// + internal static string cmd_recipebook_craftall_sent { + get { + return ResourceManager.GetString("cmd.recipebook.craftall.sent", resourceCulture); + } + } + /// /// Looks up a localized string similar to List unlocked recipe book recipes and craft them through the active recipe book inventory.. /// @@ -4414,6 +4423,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to The recipe identifier cannot be empty.. + /// + internal static string cmd_recipebook_recipe_id_empty { + get { + return ResourceManager.GetString("cmd.recipebook.recipe.id.empty", resourceCulture); + } + } + /// /// Looks up a localized string similar to Recipe book crafting is only supported on Minecraft 1.13 and newer.. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 42a9d8db..c3ebe466 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2212,7 +2212,10 @@ Logging in... Failed to send recipe book craft request for {0}. - Requested recipe {0} (craft all: {1}). + Requested recipe {0}. + + + Requested recipe {0} with craft-all. List unlocked recipe book recipes and craft them through the active recipe book inventory. @@ -2226,6 +2229,9 @@ Logging in... No unlocked recipe book recipes are currently tracked. + + The recipe identifier cannot be empty. + Recipe book crafting is only supported on Minecraft 1.13 and newer. From dfc11648399fb079ac8f6e8fb8725be46a5895e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:12:01 +0000 Subject: [PATCH 271/484] chore: finalize recipe book support polish Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/00c8527f-5755-43c1-8916-8d571d28860b Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Commands/RecipeBook.cs | 10 +--------- MinecraftClient/McClient.cs | 2 +- MinecraftClient/Protocol/Handlers/Protocol18.cs | 2 ++ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/MinecraftClient/Commands/RecipeBook.cs b/MinecraftClient/Commands/RecipeBook.cs index b51d211b..24a56a86 100644 --- a/MinecraftClient/Commands/RecipeBook.cs +++ b/MinecraftClient/Commands/RecipeBook.cs @@ -87,20 +87,12 @@ namespace MinecraftClient.Commands if (handler.GetActiveRecipeBookInventory() is null) return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_active_inventory); - string normalizedRecipeId = NormalizeRecipeId(recipeId); + string normalizedRecipeId = McClient.NormalizeRecipeId(recipeId); string successMessage = string.Format(makeAll ? Translations.cmd_recipebook_craftall_sent : Translations.cmd_recipebook_craft_sent, normalizedRecipeId); return handler.SendPlaceRecipe(recipeId, makeAll) ? r.SetAndReturn(CmdResult.Status.Done, successMessage) : r.SetAndReturn(CmdResult.Status.Fail, string.Format(Translations.cmd_recipebook_craft_failed, normalizedRecipeId)); } - - private static string NormalizeRecipeId(string recipeId) - { - string trimmedRecipeId = recipeId.Trim(); - return trimmedRecipeId.Contains(':') - ? trimmedRecipeId - : "minecraft:" + trimmedRecipeId; - } } } diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 751b79e6..906eff74 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -4173,7 +4173,7 @@ namespace MinecraftClient } } - private static string NormalizeRecipeId(string recipeId) + internal static string NormalizeRecipeId(string recipeId) { string trimmedRecipeId = recipeId.Trim(); if (trimmedRecipeId.Length == 0) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index c5636cd1..e6518c7b 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3200,6 +3200,8 @@ namespace MinecraftClient.Protocol.Handlers private bool SkipRecipeBookSettings(Queue packetData) { + // MC 1.13 uses 4 booleans for the crafting/smelting recipe book states. + // MC 1.14+ expands this to 8 booleans by adding blast furnace and smoker states. int boolCount = protocolVersion >= MC_1_14_Version ? 8 : 4; if (packetData.Count < boolCount) return false; From b25579a105bd86c112027b4c2536500e7688ee5a Mon Sep 17 00:00:00 2001 From: BruceChen Date: Mon, 30 Mar 2026 02:24:50 +0800 Subject: [PATCH 272/484] Fix CI script injection via commit message special characters Pass commit message through env vars instead of direct ${{ }} expansion in shell scripts to prevent backticks and other special characters from being interpreted as shell commands. Made-with: Cursor --- .github/workflows/build-and-release.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 359bd388..8649102c 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -21,13 +21,14 @@ jobs: - name: Check skip CI id: check-skip run: | - MSG="${{ github.event.head_commit.message }}" - LOWER=$(echo "$MSG" | tr '[:upper:]' '[:lower:]') + LOWER=$(echo "$COMMIT_MSG" | tr '[:upper:]' '[:lower:]') if echo "$LOWER" | grep -qE 'skip.?ci|ci.?skip'; then echo "skip=true" >> $GITHUB_OUTPUT else echo "skip=false" >> $GITHUB_OUTPUT - fi + fi + env: + COMMIT_MSG: ${{ github.event.head_commit.message }} fetch-translations: strategy: @@ -221,12 +222,13 @@ jobs: - name: Truncate commit message for release name id: release-name run: | - RAW="${{ github.event.head_commit.message }}" - # Take only the first line (subject), then truncate to safe length - SUBJECT=$(echo "$RAW" | head -n 1) - MAX=220 # leave room for tag prefix + ": " + SUBJECT=$(echo "$COMMIT_MSG" | head -n 1) + MAX=220 TRUNCATED="${SUBJECT:0:$MAX}" - echo "name=${{ needs.create-tag.outputs.build-tag }}: $TRUNCATED" >> $GITHUB_OUTPUT + echo "name=${BUILD_TAG}: $TRUNCATED" >> $GITHUB_OUTPUT + env: + COMMIT_MSG: ${{ github.event.head_commit.message }} + BUILD_TAG: ${{ needs.create-tag.outputs.build-tag }} - name: Create Release uses: ncipollo/release-action@v1.14.0 From b05c8cfe0d3eea2af2b440d784eab57279512168 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:45:14 +0000 Subject: [PATCH 273/484] fix: support 1.21.11 recipe book display ids Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/4cdf26f2-112b-4502-88f7-8f589c424f69 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Commands/RecipeBook.cs | 10 +- MinecraftClient/McClient.cs | 31 ++- .../Protocol/Handlers/Protocol18.cs | 190 ++++++++++++++++-- .../Protocol/IMinecraftComHandler.cs | 4 +- MinecraftClient/RecipeBookRecipeEntry.cs | 4 + 5 files changed, 209 insertions(+), 30 deletions(-) create mode 100644 MinecraftClient/RecipeBookRecipeEntry.cs diff --git a/MinecraftClient/Commands/RecipeBook.cs b/MinecraftClient/Commands/RecipeBook.cs index 24a56a86..4cf0d873 100644 --- a/MinecraftClient/Commands/RecipeBook.cs +++ b/MinecraftClient/Commands/RecipeBook.cs @@ -59,14 +59,14 @@ namespace MinecraftClient.Commands if (!handler.GetInventoryEnabled()) return r.SetAndReturn(CmdResult.Status.FailNeedInventory); - string[] recipeIds = handler.GetUnlockedRecipes(); - if (recipeIds.Length == 0) + RecipeBookRecipeEntry[] recipes = handler.GetUnlockedRecipes(); + if (recipes.Length == 0) return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_recipes); StringBuilder response = new(); response.AppendLine(Translations.cmd_recipebook_list); - foreach (string recipeId in recipeIds) - response.AppendLine("- " + recipeId); + foreach (RecipeBookRecipeEntry recipe in recipes) + response.AppendLine("- " + recipe.DisplayText); handler.Log.Info(response.ToString().TrimEnd()); return r.SetAndReturn(CmdResult.Status.Done); @@ -87,7 +87,7 @@ namespace MinecraftClient.Commands if (handler.GetActiveRecipeBookInventory() is null) return r.SetAndReturn(CmdResult.Status.Fail, Translations.cmd_recipebook_no_active_inventory); - string normalizedRecipeId = McClient.NormalizeRecipeId(recipeId); + string normalizedRecipeId = McClient.NormalizeRecipeArgument(recipeId, handler.GetProtocolVersion()); string successMessage = string.Format(makeAll ? Translations.cmd_recipebook_craftall_sent : Translations.cmd_recipebook_craft_sent, normalizedRecipeId); return handler.SendPlaceRecipe(recipeId, makeAll) diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 906eff74..24069342 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -49,7 +49,7 @@ namespace MinecraftClient private readonly List bots = new(); private static readonly List botsOnHold = new(); private static readonly Dictionary inventories = new(); - private readonly HashSet unlockedRecipes = new(StringComparer.Ordinal); + private readonly Dictionary unlockedRecipes = new(StringComparer.Ordinal); private readonly Dictionary> registeredBotPluginChannels = new(); private readonly List registeredServerPluginChannels = new(); @@ -1345,11 +1345,11 @@ namespace MinecraftClient /// Get all unlocked recipe book recipe identifiers. /// /// Unlocked recipe identifiers sorted alphabetically - public string[] GetUnlockedRecipes() + public RecipeBookRecipeEntry[] GetUnlockedRecipes() { lock (recipeBookLock) { - return [.. unlockedRecipes.OrderBy(static recipeId => recipeId, StringComparer.Ordinal)]; + return unlockedRecipes.Values.OrderBy(static recipe => recipe.CommandId, StringComparer.Ordinal).ToArray(); } } @@ -2728,7 +2728,7 @@ namespace MinecraftClient if (activeInventory is null) return false; - string normalizedRecipeId = NormalizeRecipeId(recipeId); + string normalizedRecipeId = NormalizeRecipeArgument(recipeId, protocolversion); if (normalizedRecipeId.Length == 0) return false; @@ -4111,17 +4111,18 @@ namespace MinecraftClient Log.Debug("CanSendMessage = " + canSendMessage); } - public void OnRecipeBookAdd(string[] recipeIds, bool replace) + public void OnRecipeBookAdd(RecipeBookRecipeEntry[] recipes, bool replace) { lock (recipeBookLock) { if (replace) unlockedRecipes.Clear(); - foreach (string recipeId in recipeIds) + foreach (RecipeBookRecipeEntry recipe in recipes) { - if (!string.IsNullOrWhiteSpace(recipeId)) - unlockedRecipes.Add(recipeId); + // Guard against malformed server packets that send empty display IDs. + if (!string.IsNullOrWhiteSpace(recipe.CommandId)) + unlockedRecipes[recipe.CommandId] = recipe; } } } @@ -4173,7 +4174,19 @@ namespace MinecraftClient } } - internal static string NormalizeRecipeId(string recipeId) + /// + /// Normalize a recipe argument for the target protocol version. + /// Legacy recipe-book packets use identifiers and default to the minecraft namespace. + /// 1.21.2+ recipe-book packets use numeric recipe display ids and should be left trimmed-only. + /// + internal static string NormalizeRecipeArgument(string recipeId, int protocolVersion) + { + return protocolVersion >= Protocol18Handler.MC_1_21_2_Version + ? recipeId.Trim() + : NormalizeRecipeId(recipeId); + } + + private static string NormalizeRecipeId(string recipeId) { string trimmedRecipeId = recipeId.Trim(); if (trimmedRecipeId.Length == 0) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e6518c7b..bc9537cd 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3127,7 +3127,7 @@ namespace MinecraftClient.Protocol.Handlers break; case PacketTypesIn.RecipeBookRemove: if (protocolVersion >= MC_1_21_2_Version) - handler.OnRecipeBookRemove(ReadRecipeBookRecipeIds(packetData)); + handler.OnRecipeBookRemove(ReadRecipeBookDisplayIds(packetData)); break; case PacketTypesIn.RecipeBookSettings: break; @@ -3146,21 +3146,20 @@ namespace MinecraftClient.Protocol.Handlers return; string[] recipeIds = ReadRecipeBookRecipeIds(packetData); + RecipeBookRecipeEntry[] recipeEntries = recipeIds.Select(static recipeId => new RecipeBookRecipeEntry(recipeId, recipeId)).ToArray(); switch (action) { case 0: - handler.OnRecipeBookAdd(recipeIds, replace: true); + handler.OnRecipeBookAdd(recipeEntries, replace: true); // INIT packets also include a second "to be displayed" recipe list. // MCC only needs the unlocked recipe identifiers for listing/crafting. _ = ReadRecipeBookRecipeIds(packetData); break; case 1: - handler.OnRecipeBookAdd(recipeIds, replace: false); - break; case 3: // Action 3 is the silent-add variant, so MCC tracks it like a regular add. - handler.OnRecipeBookAdd(recipeIds, replace: false); + handler.OnRecipeBookAdd(recipeEntries, replace: false); break; case 2: handler.OnRecipeBookRemove(recipeIds); @@ -3171,20 +3170,18 @@ namespace MinecraftClient.Protocol.Handlers private void HandleRecipeBookAdd(Queue packetData) { int entryCount = dataTypes.ReadNextVarInt(packetData); - string[] recipeIds = new string[entryCount]; + RecipeBookRecipeEntry[] recipeEntries = new RecipeBookRecipeEntry[entryCount]; - // RecipeBookAdd contains one entry per recipe: - // recipe id, notification flag, then highlight flag. - // MCC only tracks the unlocked recipe identifiers for now. + // 1.21.2+ RecipeBookAdd contains one display entry per recipe: + // RecipeDisplayEntry (display id, recipe display, group, category, optional requirements), then flags. for (int i = 0; i < entryCount; i++) { - recipeIds[i] = dataTypes.ReadNextString(packetData); - _ = dataTypes.ReadNextBool(packetData); // notification - _ = dataTypes.ReadNextBool(packetData); // highlight + recipeEntries[i] = ReadRecipeBookDisplayEntry(packetData); + _ = dataTypes.ReadNextByte(packetData); // flags } bool replace = dataTypes.ReadNextBool(packetData); - handler.OnRecipeBookAdd(recipeIds, replace); + handler.OnRecipeBookAdd(recipeEntries, replace); } private string[] ReadRecipeBookRecipeIds(Queue packetData) @@ -3198,6 +3195,168 @@ namespace MinecraftClient.Protocol.Handlers return recipeIds; } + private string[] ReadRecipeBookDisplayIds(Queue packetData) + { + int recipeCount = dataTypes.ReadNextVarInt(packetData); + string[] recipeIds = new string[recipeCount]; + + for (int i = 0; i < recipeCount; i++) + recipeIds[i] = dataTypes.ReadNextVarInt(packetData).ToString(CultureInfo.InvariantCulture); + + return recipeIds; + } + + private RecipeBookRecipeEntry ReadRecipeBookDisplayEntry(Queue packetData) + { + int displayId = dataTypes.ReadNextVarInt(packetData); + string resultLabel = ReadRecipeDisplayResultLabel(packetData); + + _ = dataTypes.ReadNextVarInt(packetData); // Optional group, encoded as varint+1 or 0 + _ = dataTypes.ReadNextVarInt(packetData); // Recipe book category registry id + SkipOptionalCraftingRequirements(packetData); + + string commandId = displayId.ToString(CultureInfo.InvariantCulture); + string displayText = $"{commandId}: {resultLabel}"; + return new RecipeBookRecipeEntry(commandId, displayText); + } + + private string ReadRecipeDisplayResultLabel(Queue packetData) + { + int displayType = dataTypes.ReadNextVarInt(packetData); + return displayType switch + { + 0 => ReadShapelessRecipeDisplayResultLabel(packetData), + 1 => ReadShapedRecipeDisplayResultLabel(packetData), + 2 => ReadFurnaceRecipeDisplayResultLabel(packetData), + 3 => ReadStonecutterRecipeDisplayResultLabel(packetData), + 4 => ReadSmithingRecipeDisplayResultLabel(packetData), + _ => $"recipe_display_{displayType}", + }; + } + + private string ReadShapelessRecipeDisplayResultLabel(Queue packetData) + { + int ingredientCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < ingredientCount; i++) + _ = ReadSlotDisplayLabel(packetData); + + string result = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // crafting station + return result; + } + + private string ReadShapedRecipeDisplayResultLabel(Queue packetData) + { + _ = dataTypes.ReadNextVarInt(packetData); // width + _ = dataTypes.ReadNextVarInt(packetData); // height + int ingredientCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < ingredientCount; i++) + _ = ReadSlotDisplayLabel(packetData); + + string result = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // crafting station + return result; + } + + private string ReadFurnaceRecipeDisplayResultLabel(Queue packetData) + { + _ = ReadSlotDisplayLabel(packetData); // ingredient + _ = ReadSlotDisplayLabel(packetData); // fuel + string result = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // crafting station + _ = dataTypes.ReadNextVarInt(packetData); // duration + _ = dataTypes.ReadNextFloat(packetData); // experience + return result; + } + + private string ReadStonecutterRecipeDisplayResultLabel(Queue packetData) + { + _ = ReadSlotDisplayLabel(packetData); // input + string result = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // crafting station + return result; + } + + private string ReadSmithingRecipeDisplayResultLabel(Queue packetData) + { + _ = ReadSlotDisplayLabel(packetData); // template + _ = ReadSlotDisplayLabel(packetData); // base + _ = ReadSlotDisplayLabel(packetData); // addition + string result = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // crafting station + return result; + } + + private string ReadSlotDisplayLabel(Queue packetData) + { + int slotDisplayType = dataTypes.ReadNextVarInt(packetData); + return slotDisplayType switch + { + 0 => "Empty", + 1 => "Any Fuel", + 2 => Item.GetTypeString(itemPalette.FromId(dataTypes.ReadNextVarInt(packetData))), + 3 => dataTypes.ReadNextItemSlot(packetData, itemPalette)?.GetTypeString() ?? "Empty", + 4 => "#" + dataTypes.ReadNextString(packetData), + 5 => ReadSmithingTrimSlotDisplayLabel(packetData), + 6 => ReadWithRemainderSlotDisplayLabel(packetData), + 7 => ReadCompositeSlotDisplayLabel(packetData), + _ => $"slot_display_{slotDisplayType}", + }; + } + + private string ReadSmithingTrimSlotDisplayLabel(Queue packetData) + { + string baseLabel = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // material + _ = dataTypes.ReadNextVarInt(packetData); // trim pattern registry id + return baseLabel; + } + + private string ReadWithRemainderSlotDisplayLabel(Queue packetData) + { + string inputLabel = ReadSlotDisplayLabel(packetData); + _ = ReadSlotDisplayLabel(packetData); // remainder + return inputLabel; + } + + private string ReadCompositeSlotDisplayLabel(Queue packetData) + { + int optionCount = dataTypes.ReadNextVarInt(packetData); + string label = "Composite"; + + for (int i = 0; i < optionCount; i++) + { + string optionLabel = ReadSlotDisplayLabel(packetData); + if (label == "Composite" && optionLabel is not "Empty" and not "Composite") + label = optionLabel; + } + + return label; + } + + private void SkipOptionalCraftingRequirements(Queue packetData) + { + if (!dataTypes.ReadNextBool(packetData)) + return; + + int ingredientCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < ingredientCount; i++) + SkipItemHolderSet(packetData); + } + + private void SkipItemHolderSet(Queue packetData) + { + int entryCount = dataTypes.ReadNextVarInt(packetData) - 1; + if (entryCount == -1) + { + _ = dataTypes.ReadNextString(packetData); + return; + } + + for (int i = 0; i < entryCount; i++) + _ = dataTypes.ReadNextVarInt(packetData); + } + private bool SkipRecipeBookSettings(Queue packetData) { // MC 1.13 uses 4 booleans for the crafting/smelting recipe book states. @@ -5111,7 +5270,10 @@ namespace MinecraftClient.Protocol.Handlers return false; packet.AddRange(DataTypes.GetVarInt(windowId)); - packet.AddRange(dataTypes.GetString(recipeId)); + if (protocolVersion >= MC_1_21_2_Version) + packet.AddRange(DataTypes.GetVarInt(int.Parse(recipeId, CultureInfo.InvariantCulture))); + else + packet.AddRange(dataTypes.GetString(recipeId)); packet.AddRange(dataTypes.GetBool(makeAll)); SendPacket(PacketTypesOut.CraftRecipeRequest, packet); return true; diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index d6bd5eb7..81a4a056 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -520,9 +520,9 @@ namespace MinecraftClient.Protocol /// /// Called when recipe book recipes are added or replaced. /// - /// Recipe identifiers to add + /// Recipe entries to add /// True to replace the currently tracked recipe book entries - public void OnRecipeBookAdd(string[] recipeIds, bool replace); + public void OnRecipeBookAdd(RecipeBookRecipeEntry[] recipes, bool replace); /// /// Called when recipe book recipes are removed. diff --git a/MinecraftClient/RecipeBookRecipeEntry.cs b/MinecraftClient/RecipeBookRecipeEntry.cs new file mode 100644 index 00000000..a5648ba7 --- /dev/null +++ b/MinecraftClient/RecipeBookRecipeEntry.cs @@ -0,0 +1,4 @@ +namespace MinecraftClient +{ + public readonly record struct RecipeBookRecipeEntry(string CommandId, string DisplayText); +} From 90ea05b17dc640fdc1ac8fa70ffa702cf728ad6f Mon Sep 17 00:00:00 2001 From: BruceChen Date: Mon, 30 Mar 2026 02:45:56 +0800 Subject: [PATCH 274/484] Enhance server status display and player information handling - Updated `ServerStatusDisplay` to use `ChatBot.GetVerbatim` for version name formatting. - Modified `ServerStatusPanelBuilder` to improve player name display with color parsing. - Changed translation for online player label to "Online Players:" for clarity. - Refactored protocol version checks to streamline logic in server status handling. --- .../Protocol/ServerStatusDisplay.cs | 5 +++-- .../Resources/Translations/Translations.resx | 2 +- .../Tui/ServerStatusPanelBuilder.cs | 21 ++++++++++++------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/MinecraftClient/Protocol/ServerStatusDisplay.cs b/MinecraftClient/Protocol/ServerStatusDisplay.cs index 21e386ab..291745e5 100644 --- a/MinecraftClient/Protocol/ServerStatusDisplay.cs +++ b/MinecraftClient/Protocol/ServerStatusDisplay.cs @@ -1,6 +1,7 @@ using System; using System.Text; using MinecraftClient.Protocol.Message; +using MinecraftClient.Scripting; namespace MinecraftClient.Protocol { @@ -47,12 +48,12 @@ namespace MinecraftClient.Protocol sb.Append("§f"); sb.Append(Translations.mcc_server_info_label_version); sb.Append(" §b"); - sb.Append(info.VersionName); + sb.Append(ChatBot.GetVerbatim(info.VersionName)); sb.Append(" §7("); sb.Append(string.Format(Translations.mcc_server_info_label_protocol, "§e" + info.ProtocolVersion + "§7")); sb.AppendLine(")"); - if (info.ResolvedProtocol != 0 && info.ResolvedProtocol != info.ProtocolVersion) + if (info.ResolvedProtocol != 0) { string resolvedMcVer = ProtocolHandler.ProtocolVersion2MCVer(info.ResolvedProtocol); sb.Append("§f"); diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index c3acc0fc..fa9a3378 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -852,7 +852,7 @@ Add the ID of this chat to "Authorized_Chat_Ids" field in the configuration file Connecting as: - Online: + Online Players: ... +{0} diff --git a/MinecraftClient/Tui/ServerStatusPanelBuilder.cs b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs index 3b6e8f9f..dd859242 100644 --- a/MinecraftClient/Tui/ServerStatusPanelBuilder.cs +++ b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs @@ -19,6 +19,7 @@ namespace MinecraftClient.Tui if (info.FaviconBase64 is not null) { var iconGrid = BuildFaviconGrid(info.FaviconBase64, FaviconDisplaySize); + iconGrid.VerticalAlignment = VerticalAlignment.Center; DockPanel.SetDock(iconGrid, Dock.Left); contentPanel.Children.Add(iconGrid); } @@ -83,9 +84,10 @@ namespace MinecraftClient.Tui private static void AddVersion(StackPanel panel, Protocol.ServerStatusInfo info) { + string versionClean = Scripting.ChatBot.GetVerbatim(info.VersionName); var row = new TextBlock(); row.Inlines!.Add(Label(Translations.mcc_server_info_label_version)); - row.Inlines.Add(Value(info.VersionName, McColors.Aqua)); + row.Inlines.Add(Value(versionClean, McColors.Aqua)); row.Inlines.Add(new Run(" (") { Foreground = McColors.Gray }); row.Inlines.Add(new Run(string.Format(Translations.mcc_server_info_label_protocol, info.ProtocolVersion)) { Foreground = McColors.Gray }); @@ -95,7 +97,7 @@ namespace MinecraftClient.Tui private static void AddConnectingAs(StackPanel panel, Protocol.ServerStatusInfo info) { - if (info.ResolvedProtocol == 0 || info.ResolvedProtocol == info.ProtocolVersion) + if (info.ResolvedProtocol == 0) return; string resolvedMcVer = Protocol.ProtocolHandler.ProtocolVersion2MCVer(info.ResolvedProtocol); @@ -146,17 +148,20 @@ namespace MinecraftClient.Tui { Text = Translations.mcc_server_info_label_online, Foreground = McColors.Gray, - Margin = new Thickness(0, 1, 0, 0), }); int shown = Math.Min(info.SamplePlayers.Count, MaxSamplePlayers); for (int i = 0; i < shown; i++) { - panel.Children.Add(new TextBlock - { - Text = $" {info.SamplePlayers[i].Name}", - Foreground = McColors.Green, - }); + string name = info.SamplePlayers[i].Name; + if (name.Contains('\u00a7')) + panel.Children.Add(McColorParser.CreateColoredTextBlock($" {name}", TextWrapping.NoWrap)); + else + panel.Children.Add(new TextBlock + { + Text = $" {name}", + Foreground = McColors.Green, + }); } if (info.SamplePlayers.Count > shown) From d97861888dd831d57232018797dd0dcd646eff2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:52:32 +0000 Subject: [PATCH 275/484] docs: document recipebook command Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/1287ecfd-6d64-45ee-9aaf-96cbce9c3713 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- docs/guide/usage.md | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 833d5dd3..0a439aff 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -650,6 +650,79 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q +
+recipebook + +- **Description:** + + List unlocked recipe book entries and ask the server to place one of them into the active crafting inventory. + +

Note

+ + **You need to have [Inventory Handling](configuration.md#inventoryhandling) enabled in order for this command to work.** + +
+ +

Note

+ + **`craft` and `craftall` need an active player crafting grid, crafting table, furnace, blast furnace, smoker, or stonecutter inventory.** + +
+ +

Warning

+ + **Recipe book crafting is supported on Minecraft `1.13+`.** + +
+ + `list` shows the recipe book entries MCC is currently tracking. + + On newer versions, the list can contain numeric display ids instead of plain recipe names. If you see something like `838: Oak Planks`, use `838` with `craft` or `craftall`. + + `craft` and `craftall` send a recipe-book request to the server. They do not automatically take the result item for you. After the recipe appears in the active inventory, take the output slot the same way you would handle any other inventory action. + +- **Usage:** + + ``` + /recipebook list + ``` + + ``` + /recipebook craft + ``` + + ``` + /recipebook craftall + ``` + +- **Examples:** + + Show the currently tracked recipe book entries: + + ``` + /recipebook list + ``` + + Request one recipe placement: + + ``` + /recipebook craft minecraft:oak_planks + ``` + + On newer versions, use the numeric id shown by `/recipebook list`: + + ``` + /recipebook craftall 838 + ``` + + If the recipe is placed in the player crafting grid, take the result from slot `0`: + + ``` + /inventory player click 0 + ``` + +
+
connect From 7b415d5388511c1f556134d78f5daadc22a5a39d Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 29 Mar 2026 20:57:16 +0200 Subject: [PATCH 276/484] Added a Skill for MCP --- .skills/mcc-mcp-operator/SKILL.md | 94 +++++++ DebugTools/MccMcpStdioHarness/Program.cs | 5 +- MinecraftClient/Mcp/MccEmbeddedMcpHost.cs | 4 +- MinecraftClient/Mcp/MccMcpGuidanceProvider.cs | 236 ++++++++++++++++++ MinecraftClient/Mcp/MccMcpPromptSet.cs | 20 ++ MinecraftClient/Mcp/MccMcpToolSet.cs | 10 +- MinecraftClient/MinecraftClient.csproj | 1 + 7 files changed, 367 insertions(+), 3 deletions(-) create mode 100644 .skills/mcc-mcp-operator/SKILL.md create mode 100644 MinecraftClient/Mcp/MccMcpGuidanceProvider.cs create mode 100644 MinecraftClient/Mcp/MccMcpPromptSet.cs diff --git a/.skills/mcc-mcp-operator/SKILL.md b/.skills/mcc-mcp-operator/SKILL.md new file mode 100644 index 00000000..2e2e734a --- /dev/null +++ b/.skills/mcc-mcp-operator/SKILL.md @@ -0,0 +1,94 @@ +--- +name: mcc-mcp-operator +description: Operate Minecraft Console Client through the built-in MCP server. Use this whenever the user wants an agent to inspect MCC state, move, search the world, interact with players or entities, dig, pick up items, manage containers, or carry out Minecraft tasks through MCP tools, even if they do not explicitly say "use MCP" or "control MCC". Prefer this skill over ad hoc tool guessing for agentic MCC and Minecraft control work. +--- + +# MCC MCP Operator + +Use the MCC MCP toolset as the source of truth for game state and action results. +Do not guess what happened from intent alone. + +## Operating Loop + +1. Inspect the current situation before acting. +2. Make the shortest plan that can succeed. +3. Use the smallest set of high-signal tools needed to act. +4. Verify the outcome with fresh tool calls. +5. Report only what is verified, and clearly label anything inferred or still unknown. + +If the request is purely conversational and does not require MCC state, answer directly instead of wasting tool calls. + +## Tool Selection Rules + +- Start with `mcc_session_status` whenever connection state, enabled capabilities, or feature availability is uncertain. +- Prefer direct inspection tools such as `mcc_player_state`, `mcc_players_list`, `mcc_entities_list`, `mcc_blocks_find`, `mcc_items_list`, and `mcc_inventory_snapshot` before taking physical actions. +- Prefer purpose-built action tools over low-level escape hatches. +- Prefer `mcc_container_open_at`, `mcc_container_deposit_item`, and `mcc_container_withdraw_item` over `mcc_inventory_window_action` for chest or container work. +- Use `mcc_can_reach_position` or a locating tool before pathing when reachability is uncertain. +- Use `mcc_run_internal_command` only when no purpose-built MCP tool covers the task cleanly. +- Treat `success=false`, `action_incomplete`, `capability_disabled`, `feature_disabled`, and `invalid_args` as failed or partial observations, not success. +- After `invalid_args`, simplify the call and try at most one nearby variant. Do not spam near-duplicate guesses. + +## Verification Rules + +- Movement is not complete just because a move request was accepted. Confirm `arrived=true` or verify the new location with a fresh state read. +- Digging is not complete just because `mcc_dig_block` was invoked. Re-check the target block or nearby block search results. +- Item pickup is not complete just because the bot moved over an item. Re-check inventory state or nearby dropped-item entities. +- Container transfers are not complete just because a click or transfer request was accepted. Verify the resulting counts after the transfer. +- Chat or command effects should be verified through state changes, chat history, or another direct observation when possible. +- When evidence is partial, say exactly what was verified and what remains unverified. + +## Best Practices + +- Query first, act second, verify third. +- Keep plans short and concrete. Long speculative tool chains usually make the result worse. +- Prefer high-signal tools that answer the real question directly. +- Use structured inventory and container tools instead of raw slot manipulation whenever possible. +- Do not claim success from acceptance alone. Always pair actions with a follow-up observation. +- Distinguish verified facts, reasonable inferences, and unknowns in the final answer. +- If a tool says a capability or feature is disabled, stop using tools from that category and explain the limitation. +- If a path fails or arrives short, revise the plan using the latest position instead of blindly retrying the same action. +- Use `mcc_quit_client` to stop MCC. Do not send bare `quit` or `exit` through chat. +- Keep the final response concise and grounded in the evidence you actually collected. + +## Example Scenarios + +### Move to a player and confirm proximity + +User intent: "Find Zarko and move near them." + +Good flow: +- call `mcc_player_locate` or `mcc_players_list` to confirm the player is known +- if needed, call `mcc_can_reach_position` for the target area +- call `mcc_move_to_player` +- verify `arrived=true` or confirm the new position with `mcc_player_state` +- report whether proximity was verified or only partially achieved + +### Open a chest, move an exact item count, and verify the result + +User intent: "Put 5 diamonds in the chest at 11000 64 11021." + +Good flow: +- call `mcc_container_open_at` +- inspect current state with `mcc_inventory_snapshot` if item availability is unclear +- call `mcc_container_deposit_item` or `mcc_container_withdraw_item` +- verify the resulting counts from the transfer result and, when useful, a fresh inventory snapshot +- report the exact verified delta, not just that the action was attempted + +### Collect nearby dropped items or dig target blocks and verify the outcome + +User intent: "Pick up nearby apples" or "Break those logs and collect them." + +Good flow: +- call `mcc_items_list` or `mcc_blocks_find` to locate the target +- move only if the target is not already reachable from the current position +- call `mcc_items_pickup` for dropped items, or `mcc_dig_block` in a sensible order for blocks +- verify the result with `mcc_items_list`, `mcc_inventory_snapshot`, or a fresh block query +- if the result is partial, say what changed and what still remains + +## Output Style + +- Lead with the outcome the user cares about. +- Include the small set of observations that justify the answer. +- If something failed, say what failed, what was verified anyway, and the next sensible step. +- Do not embellish uncertain results. diff --git a/DebugTools/MccMcpStdioHarness/Program.cs b/DebugTools/MccMcpStdioHarness/Program.cs index 69f2488a..441f7dac 100644 --- a/DebugTools/MccMcpStdioHarness/Program.cs +++ b/DebugTools/MccMcpStdioHarness/Program.cs @@ -10,10 +10,13 @@ builder.Logging.AddConsole(options => options.LogToStandardErrorThreshold = LogLevel.Trace; }); +builder.Services.AddSingleton(new MccMcpConfig()); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddMcpServer() .WithStdioServerTransport() - .WithTools(); + .WithTools() + .WithPrompts(); await builder.Build().RunAsync(); diff --git a/MinecraftClient/Mcp/MccEmbeddedMcpHost.cs b/MinecraftClient/Mcp/MccEmbeddedMcpHost.cs index cf481d97..a40b7183 100644 --- a/MinecraftClient/Mcp/MccEmbeddedMcpHost.cs +++ b/MinecraftClient/Mcp/MccEmbeddedMcpHost.cs @@ -66,9 +66,11 @@ public sealed class MccEmbeddedMcpHost builder.Logging.AddFilter(_ => false); builder.Services.AddSingleton(capabilities); builder.Services.AddSingleton(config); + builder.Services.AddSingleton(); builder.Services.AddMcpServer() .WithHttpTransport() - .WithTools(); + .WithTools() + .WithPrompts(); builder.WebHost.UseUrls($"http://{bindHost}:{config.Transport.Port}"); WebApplication builtApp = builder.Build(); diff --git a/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs b/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs new file mode 100644 index 00000000..285a6d31 --- /dev/null +++ b/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.Json.Serialization; + +namespace MinecraftClient.Mcp; + +public sealed class MccMcpGuidanceProvider +{ + private const string EmbeddedSkillResourceSuffix = "MccMcpOperatorSkill.md"; + private const string BestPracticesHeading = "## Best Practices"; + private const string ExampleScenariosHeading = "## Example Scenarios"; + + private readonly MccMcpConfig config; + private readonly Lazy guidanceDocument; + + public MccMcpGuidanceProvider(MccMcpConfig config) + { + this.config = config; + guidanceDocument = new Lazy(LoadGuidanceDocument); + } + + public string SkillName => "mcc-mcp-operator"; + + public string GetSystemPrompt() + { + GuidanceDocument document = guidanceDocument.Value; + MccMcpAgentCapabilityStatus capabilityStatus = BuildCapabilityStatus(); + StringBuilder builder = new(); + builder.AppendLine("You are an external agent controlling Minecraft Console Client (MCC) through its built-in MCP server."); + builder.AppendLine("Use the following operator guide as your system prompt. Treat the capability snapshot as authoritative and do not invent unsupported actions."); + builder.AppendLine(); + builder.AppendLine(document.BodyMarkdown); + builder.AppendLine(); + builder.AppendLine("Current capability snapshot"); + builder.AppendLine($"- sessionStatus: {FormatCapability(capabilityStatus.SessionStatus)}"); + builder.AppendLine($"- chatAndCommands: {FormatCapability(capabilityStatus.ChatAndCommands)}"); + builder.AppendLine($"- movement: {FormatCapability(capabilityStatus.Movement)}"); + builder.AppendLine($"- inventory: {FormatCapability(capabilityStatus.Inventory)}"); + builder.AppendLine($"- entityWorld: {FormatCapability(capabilityStatus.EntityWorld)}"); + return builder.ToString().Trim(); + } + + public MccMcpAgentGuidancePayload GetToolPayload() + { + GuidanceDocument document = guidanceDocument.Value; + return new MccMcpAgentGuidancePayload + { + SkillName = SkillName, + SkillMarkdown = document.SkillMarkdown, + SystemPrompt = GetSystemPrompt(), + BestPractices = document.BestPractices, + ExampleScenarios = document.ExampleScenarios, + CapabilityStatus = BuildCapabilityStatus() + }; + } + + private GuidanceDocument LoadGuidanceDocument() + { + Assembly assembly = typeof(MccMcpGuidanceProvider).Assembly; + string resourceName = assembly.GetManifestResourceNames() + .FirstOrDefault(name => name.EndsWith(EmbeddedSkillResourceSuffix, StringComparison.Ordinal)) + ?? throw new InvalidOperationException($"Embedded MCP skill resource '{EmbeddedSkillResourceSuffix}' was not found."); + + using Stream? stream = assembly.GetManifestResourceStream(resourceName); + if (stream is null) + throw new InvalidOperationException($"Embedded MCP skill resource '{resourceName}' could not be opened."); + + using StreamReader reader = new(stream, Encoding.UTF8); + string skillMarkdown = reader.ReadToEnd(); + string bodyMarkdown = StripFrontmatter(skillMarkdown); + string bestPracticesSection = ExtractSection(bodyMarkdown, BestPracticesHeading); + string exampleScenariosSection = ExtractSection(bodyMarkdown, ExampleScenariosHeading); + + return new GuidanceDocument( + skillMarkdown.Replace("\r\n", "\n").Trim(), + bodyMarkdown, + ExtractBulletList(bestPracticesSection), + ExtractExampleScenarios(exampleScenariosSection)); + } + + private MccMcpAgentCapabilityStatus BuildCapabilityStatus() + { + return new MccMcpAgentCapabilityStatus + { + SessionStatus = config.Capabilities.SessionStatus, + ChatAndCommands = config.Capabilities.ChatAndCommands, + Movement = config.Capabilities.Movement, + Inventory = config.Capabilities.Inventory, + EntityWorld = config.Capabilities.EntityWorld + }; + } + + private static string StripFrontmatter(string markdown) + { + string normalized = markdown.Replace("\r\n", "\n"); + if (!normalized.StartsWith("---\n", StringComparison.Ordinal)) + return normalized.Trim(); + + int endOfFrontmatter = normalized.IndexOf("\n---\n", 4, StringComparison.Ordinal); + if (endOfFrontmatter < 0) + return normalized.Trim(); + + return normalized[(endOfFrontmatter + 5)..].Trim(); + } + + private static string ExtractSection(string markdownBody, string heading) + { + int headingIndex = markdownBody.IndexOf(heading, StringComparison.Ordinal); + if (headingIndex < 0) + return string.Empty; + + int sectionStart = headingIndex + heading.Length; + int nextHeading = markdownBody.IndexOf("\n## ", sectionStart, StringComparison.Ordinal); + string section = nextHeading >= 0 + ? markdownBody[sectionStart..nextHeading] + : markdownBody[sectionStart..]; + + return section.Trim(); + } + + private static string[] ExtractBulletList(string section) + { + return section + .Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Where(line => line.StartsWith("- ", StringComparison.Ordinal)) + .Select(line => line[2..].Trim()) + .Where(line => line.Length > 0) + .ToArray(); + } + + private static MccMcpAgentScenario[] ExtractExampleScenarios(string section) + { + if (string.IsNullOrWhiteSpace(section)) + return []; + + List scenarios = []; + string? currentTitle = null; + List currentBodyLines = []; + + foreach (string rawLine in section.Split('\n')) + { + string line = rawLine.TrimEnd(); + if (line.StartsWith("### ", StringComparison.Ordinal)) + { + AddScenario(scenarios, currentTitle, currentBodyLines); + currentTitle = line[4..].Trim(); + currentBodyLines = []; + continue; + } + + if (currentTitle is not null) + currentBodyLines.Add(line); + } + + AddScenario(scenarios, currentTitle, currentBodyLines); + return scenarios.ToArray(); + } + + private static void AddScenario(List scenarios, string? title, List bodyLines) + { + if (string.IsNullOrWhiteSpace(title)) + return; + + string guidance = string.Join('\n', bodyLines) + .Trim(); + + scenarios.Add(new MccMcpAgentScenario + { + Title = title, + Guidance = guidance + }); + } + + private static string FormatCapability(bool enabled) + { + return enabled ? "enabled" : "disabled"; + } + + private sealed record GuidanceDocument( + string SkillMarkdown, + string BodyMarkdown, + string[] BestPractices, + MccMcpAgentScenario[] ExampleScenarios); +} + +public sealed class MccMcpAgentGuidancePayload +{ + [JsonPropertyName("skillName")] + public string SkillName { get; init; } = string.Empty; + + [JsonPropertyName("skillMarkdown")] + public string SkillMarkdown { get; init; } = string.Empty; + + [JsonPropertyName("systemPrompt")] + public string SystemPrompt { get; init; } = string.Empty; + + [JsonPropertyName("bestPractices")] + public string[] BestPractices { get; init; } = []; + + [JsonPropertyName("exampleScenarios")] + public MccMcpAgentScenario[] ExampleScenarios { get; init; } = []; + + [JsonPropertyName("capabilityStatus")] + public MccMcpAgentCapabilityStatus CapabilityStatus { get; init; } = new(); +} + +public sealed class MccMcpAgentScenario +{ + [JsonPropertyName("title")] + public string Title { get; init; } = string.Empty; + + [JsonPropertyName("guidance")] + public string Guidance { get; init; } = string.Empty; +} + +public sealed class MccMcpAgentCapabilityStatus +{ + [JsonPropertyName("sessionStatus")] + public bool SessionStatus { get; init; } + + [JsonPropertyName("chatAndCommands")] + public bool ChatAndCommands { get; init; } + + [JsonPropertyName("movement")] + public bool Movement { get; init; } + + [JsonPropertyName("inventory")] + public bool Inventory { get; init; } + + [JsonPropertyName("entityWorld")] + public bool EntityWorld { get; init; } +} diff --git a/MinecraftClient/Mcp/MccMcpPromptSet.cs b/MinecraftClient/Mcp/MccMcpPromptSet.cs new file mode 100644 index 00000000..564e6f7f --- /dev/null +++ b/MinecraftClient/Mcp/MccMcpPromptSet.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; +using ModelContextProtocol.Server; + +namespace MinecraftClient.Mcp; + +public sealed class MccMcpPromptSet +{ + private readonly MccMcpGuidanceProvider guidanceProvider; + + public MccMcpPromptSet(MccMcpGuidanceProvider guidanceProvider) + { + this.guidanceProvider = guidanceProvider; + } + + [McpServerPrompt(Name = "mcc_operator_guide"), Description("Get the canonical MCC operator guidance prompt for external agents using this MCP server.")] + public string OperatorGuide() + { + return guidanceProvider.GetSystemPrompt(); + } +} diff --git a/MinecraftClient/Mcp/MccMcpToolSet.cs b/MinecraftClient/Mcp/MccMcpToolSet.cs index 38c01973..64dc2789 100644 --- a/MinecraftClient/Mcp/MccMcpToolSet.cs +++ b/MinecraftClient/Mcp/MccMcpToolSet.cs @@ -7,10 +7,12 @@ namespace MinecraftClient.Mcp; public sealed class MccMcpToolSet { private readonly IMccMcpCapabilities capabilities; + private readonly MccMcpGuidanceProvider guidanceProvider; - public MccMcpToolSet(IMccMcpCapabilities capabilities) + public MccMcpToolSet(IMccMcpCapabilities capabilities, MccMcpGuidanceProvider guidanceProvider) { this.capabilities = capabilities; + this.guidanceProvider = guidanceProvider; } [McpServerTool(Name = "mcc_session_status"), Description("Get current MCC session and feature status.")] @@ -49,6 +51,12 @@ public sealed class MccMcpToolSet return capabilities.GetInternalCommands(); } + [McpServerTool(Name = "mcc_agent_guidance"), Description("Get the canonical MCC operator guidance bundle for external agents using this MCP server.")] + public object AgentGuidance() + { + return guidanceProvider.GetToolPayload(); + } + [McpServerTool(Name = "mcc_materials_list"), Description("List known MCC material names with optional filtering.")] public object MaterialsList(string? filter = null, int maxCount = 500) { diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index dd843035..68b31912 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -20,6 +20,7 @@ + From 301ea6b9db3e3d614331b3c92d2a7aef988d2bd4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:25:17 +0000 Subject: [PATCH 277/484] Initial plan From d08cf803b8f603cd57388024d3bf6e7a164da37c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:30:05 +0000 Subject: [PATCH 278/484] feat: add install.sh and install.ps1 download scripts with docs update Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/bfeecfa8-81d9-45da-b1a7-b2dd6804b34f Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- .../.installation | 1 + docs/.vuepress/public/install.ps1 | 48 +++++++++ docs/.vuepress/public/install.sh | 100 ++++++++++++++++++ docs/guide/installation.md | 37 +++++++ 4 files changed, 186 insertions(+) create mode 100644 Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation create mode 100644 docs/.vuepress/public/install.ps1 create mode 100644 docs/.vuepress/public/install.sh diff --git a/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation b/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation new file mode 100644 index 00000000..17b48a06 --- /dev/null +++ b/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation @@ -0,0 +1 @@ +2c16f5a2-7133-410c-80fb-d99a09cc7988 \ No newline at end of file diff --git a/docs/.vuepress/public/install.ps1 b/docs/.vuepress/public/install.ps1 new file mode 100644 index 00000000..4d998b01 --- /dev/null +++ b/docs/.vuepress/public/install.ps1 @@ -0,0 +1,48 @@ +# Minecraft Console Client - Installer for Windows +# Downloads the latest MinecraftClient binary for your Windows architecture. +# Usage (PowerShell): iwr -useb https://mccteam.github.io/install.ps1 | iex + +$ErrorActionPreference = 'Stop' + +$REPO = "MCCTeam/Minecraft-Console-Client" +$OUTPUT = "MinecraftClient.exe" + +# --- Detect CPU architecture --- +$arch = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture +$archId = switch ($arch) { + 'X64' { 'x64' } + 'X86' { 'x86' } + 'Arm64' { 'arm64' } + default { + Write-Error "Unsupported CPU architecture: $arch" + exit 1 + } +} + +$suffix = "win-$archId" + +# --- Fetch latest release metadata from GitHub API --- +$apiUrl = "https://api.github.com/repos/$REPO/releases/latest" +Write-Host "Fetching latest release information..." +$release = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing + +# --- Locate the correct asset --- +$asset = $release.assets | Where-Object { $_.name -like "*-$suffix.exe" } | Select-Object -First 1 + +if (-not $asset) { + Write-Error "Could not find a release asset for '$suffix'." + exit 1 +} + +$downloadUrl = $asset.browser_download_url +$tag = $release.tag_name + +Write-Host "Downloading MinecraftClient $tag ($suffix)..." + +# Suppress the progress bar to avoid cluttering the terminal and speed up the download +$ProgressPreference = 'SilentlyContinue' +Invoke-WebRequest -Uri $downloadUrl -OutFile $OUTPUT -UseBasicParsing + +Write-Host "" +Write-Host "Downloaded: .\$OUTPUT" +Write-Host "Run with: .\$OUTPUT --help" diff --git a/docs/.vuepress/public/install.sh b/docs/.vuepress/public/install.sh new file mode 100644 index 00000000..f1cf57d0 --- /dev/null +++ b/docs/.vuepress/public/install.sh @@ -0,0 +1,100 @@ +#!/bin/sh +# Minecraft Console Client - Installer +# Downloads the latest MinecraftClient binary for your Linux or macOS platform. +# Usage: curl -fsSL https://mccteam.github.io/install.sh | sh +# or: wget -qO- https://mccteam.github.io/install.sh | sh + +set -e + +REPO="MCCTeam/Minecraft-Console-Client" +OUTPUT="MinecraftClient" + +# --- Detect OS --- +OS=$(uname -s) +case "$OS" in + Linux) PLATFORM="linux" ;; + Darwin) PLATFORM="osx" ;; + *) + echo "Error: Unsupported OS '$OS'. This script supports Linux and macOS." >&2 + exit 1 + ;; +esac + +# --- Detect CPU architecture --- +ARCH=$(uname -m) +case "$ARCH" in + x86_64|amd64) ARCH_ID="x64" ;; + aarch64|arm64) ARCH_ID="arm64" ;; + armv7l|armv8l|armhf) ARCH_ID="arm" ;; + arm*) ARCH_ID="arm" ;; + *) + echo "Error: Unsupported CPU architecture '$ARCH'." >&2 + exit 1 + ;; +esac + +# macOS does not have an arm (32-bit) build +if [ "$PLATFORM" = "osx" ] && [ "$ARCH_ID" = "arm" ]; then + echo "Error: 32-bit ARM is not supported on macOS." >&2 + exit 1 +fi + +SUFFIX="${PLATFORM}-${ARCH_ID}" + +# --- Download helpers: prefer curl, fall back to wget --- +_download_stdout() { + if command -v curl >/dev/null 2>&1; then + curl -fsSL "$1" + elif command -v wget >/dev/null 2>&1; then + wget -qO- "$1" + else + echo "Error: Neither 'curl' nor 'wget' is available. Please install one and retry." >&2 + exit 1 + fi +} + +_download_file() { + if command -v curl >/dev/null 2>&1; then + curl -fL --progress-bar -o "$2" "$1" + elif command -v wget >/dev/null 2>&1; then + wget -O "$2" "$1" + else + echo "Error: Neither 'curl' nor 'wget' is available. Please install one and retry." >&2 + exit 1 + fi +} + +# --- Fetch latest release metadata from GitHub API --- +API_URL="https://api.github.com/repos/${REPO}/releases/latest" +echo "Fetching latest release information..." +RELEASE_JSON=$(_download_stdout "$API_URL") + +# --- Parse asset download URL (no external tools required) --- +# The JSON key "browser_download_url" appears once per asset. +# We match the key followed by the URL, anchoring on the platform-arch suffix +# and the closing quote so that e.g. "linux-arm" does not match "linux-arm64". +# The ' *: *' pattern handles optional spaces around the colon (GitHub API adds spaces). +ASSET_URL=$(printf '%s' "$RELEASE_JSON" \ + | grep -o '"browser_download_url" *: *"[^"]*-'"${SUFFIX}"'"' \ + | grep -o 'https://[^"]*' \ + | head -1) + +if [ -z "$ASSET_URL" ]; then + echo "Error: Could not find a release asset for platform '${SUFFIX}'." >&2 + exit 1 +fi + +# --- Extract tag name for display --- +TAG=$(printf '%s' "$RELEASE_JSON" \ + | grep -o '"tag_name" *: *"[^"]*"' \ + | head -1 \ + | grep -o '"[^"]*"$' \ + | tr -d '"') + +echo "Downloading MinecraftClient ${TAG} (${SUFFIX})..." +_download_file "$ASSET_URL" "$OUTPUT" +chmod +x "$OUTPUT" + +echo "" +echo "Downloaded: ./${OUTPUT}" +echo "Run with: ./${OUTPUT} --help" diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 612cf37c..1ba686ed 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -4,6 +4,7 @@ title: Installation # Installation +- [Quick Install (one-liner)](#quick-install) - [YouTube Tutorials](#youtube-tutorials) - [Download a compiled binary](#download-a-compiled-binary) - [Building from the source code](#building-from-the-source-code) @@ -11,6 +12,42 @@ title: Installation - [Run on Android](#run-on-android) - [Run MCC 24/7 on a VPS](#run-on-a-vps) +## Quick Install + +The quickest way to get MCC is to run the installer script for your platform. It auto-detects your OS and CPU architecture, fetches the latest release from GitHub, and saves the binary to your current directory. + +### Linux / macOS + +Open a terminal in the folder where you want MCC and run: + +```bash +curl -fsSL https://mccteam.github.io/install.sh | sh +``` + +If you prefer `wget`: + +```bash +wget -qO- https://mccteam.github.io/install.sh | sh +``` + +The script downloads `MinecraftClient` and marks it executable. Supported architectures: `x64`, `arm64`, `arm` (Linux only). + +### Windows + +Open **PowerShell** in the folder where you want MCC and run: + +```powershell +iwr -useb https://mccteam.github.io/install.ps1 | iex +``` + +The script downloads `MinecraftClient.exe`. Supported architectures: `x64`, `x86`, `arm64`. + +::: tip +You can also download the scripts directly and inspect them before running: +- Linux/macOS: [install.sh](https://mccteam.github.io/install.sh) +- Windows: [install.ps1](https://mccteam.github.io/install.ps1) +::: + ## YouTube Tutorials If you're not the kind of person that likes textual tutorials, our community has made video tutorials available on YouTube. From 8c4acb0ad556bae9285010ef259688067f7f3988 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:30:24 +0000 Subject: [PATCH 279/484] chore: remove Sentry cache dir and add to .gitignore Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/bfeecfa8-81d9-45da-b1a7-b2dd6804b34f Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- .gitignore | 1 + Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation diff --git a/.gitignore b/.gitignore index fe783fa4..91c3a8b6 100644 --- a/.gitignore +++ b/.gitignore @@ -436,3 +436,4 @@ FodyWeavers.xsd # SpecStory files /.specstory/ /.vscode/settings.json +/Sentry/ diff --git a/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation b/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation deleted file mode 100644 index 17b48a06..00000000 --- a/Sentry/E84A17A5B8C1640BCE4BE9BA61BAF7487EDC56C0/.installation +++ /dev/null @@ -1 +0,0 @@ -2c16f5a2-7133-410c-80fb-d99a09cc7988 \ No newline at end of file From 53afc252ea629fa410c25042e07d06c9ea63369a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:31:26 +0000 Subject: [PATCH 280/484] fix: use precise regex in install.ps1 asset matching Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/bfeecfa8-81d9-45da-b1a7-b2dd6804b34f Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- docs/.vuepress/public/install.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.vuepress/public/install.ps1 b/docs/.vuepress/public/install.ps1 index 4d998b01..7255738d 100644 --- a/docs/.vuepress/public/install.ps1 +++ b/docs/.vuepress/public/install.ps1 @@ -27,7 +27,7 @@ Write-Host "Fetching latest release information..." $release = Invoke-RestMethod -Uri $apiUrl -UseBasicParsing # --- Locate the correct asset --- -$asset = $release.assets | Where-Object { $_.name -like "*-$suffix.exe" } | Select-Object -First 1 +$asset = $release.assets | Where-Object { $_.name -match "^MinecraftClient-.*-$([regex]::Escape($suffix))\.exe$" } | Select-Object -First 1 if (-not $asset) { Write-Error "Could not find a release asset for '$suffix'." From 46fdd687c763322f55a6ec5bf51e98d3841a48eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:39:58 +0000 Subject: [PATCH 281/484] feat: add ASCII progress bars to both install scripts Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/00d3b725-2246-40c5-93e4-d9813d95c333 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- docs/.vuepress/public/install.ps1 | 38 ++++++++++++++++++++++++++++--- docs/.vuepress/public/install.sh | 6 +++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/docs/.vuepress/public/install.ps1 b/docs/.vuepress/public/install.ps1 index 7255738d..8a14a86c 100644 --- a/docs/.vuepress/public/install.ps1 +++ b/docs/.vuepress/public/install.ps1 @@ -39,9 +39,41 @@ $tag = $release.tag_name Write-Host "Downloading MinecraftClient $tag ($suffix)..." -# Suppress the progress bar to avoid cluttering the terminal and speed up the download -$ProgressPreference = 'SilentlyContinue' -Invoke-WebRequest -Uri $downloadUrl -OutFile $OUTPUT -UseBasicParsing +# Download with a built-in ASCII progress bar (no external tools required). +# HttpWebRequest streams the body on the main thread so we can update the +# progress bar inline without any Runspace or thread-safety concerns. +$outPath = Join-Path (Get-Location).Path $OUTPUT +$request = [System.Net.HttpWebRequest]::Create($downloadUrl) +$response = $request.GetResponse() +$totalBytes = $response.ContentLength + +$responseStream = $response.GetResponseStream() +$fileStream = [System.IO.File]::Create($outPath) +$buffer = New-Object byte[] 32768 +$totalRead = 0 + +try { + while ($true) { + $read = $responseStream.Read($buffer, 0, $buffer.Length) + if ($read -le 0) { break } + $fileStream.Write($buffer, 0, $read) + $totalRead += $read + if ($totalBytes -gt 0) { + $pct = [int]($totalRead * 100 / $totalBytes) + $filled = '=' * [int]($pct / 2) + $bar = $filled.PadRight(50) + $recv = [math]::Round($totalRead / 1MB, 1) + $total = [math]::Round($totalBytes / 1MB, 1) + Write-Host -NoNewline ("`r[{0}] {1,3}% {2,6:N1} / {3,6:N1} MB" -f $bar, $pct, $recv, $total) + } + } +} finally { + $fileStream.Close() + $responseStream.Close() + $response.Close() +} + +Write-Host "" # end the progress line Write-Host "" Write-Host "Downloaded: .\$OUTPUT" diff --git a/docs/.vuepress/public/install.sh b/docs/.vuepress/public/install.sh index f1cf57d0..d3e74d3d 100644 --- a/docs/.vuepress/public/install.sh +++ b/docs/.vuepress/public/install.sh @@ -57,6 +57,12 @@ _download_file() { if command -v curl >/dev/null 2>&1; then curl -fL --progress-bar -o "$2" "$1" elif command -v wget >/dev/null 2>&1; then + # --show-progress forces the progress bar even when stdout is not a TTY. + # Fall back silently to default output if the flag is not supported + # (older wget versions, e.g. BusyBox wget). + if wget --show-progress -O "$2" "$1" 2>/dev/null; then + return 0 + fi wget -O "$2" "$1" else echo "Error: Neither 'curl' nor 'wget' is available. Please install one and retry." >&2 From f10556a162ccbd8098f8725b0fa66e11a1bb03c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:45:40 +0000 Subject: [PATCH 282/484] fix: use Console::Write for progress bar to avoid duplicate bars when piped via iex Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/2c598307-7028-46d4-ac37-045f5ce125ed Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- docs/.vuepress/public/install.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/.vuepress/public/install.ps1 b/docs/.vuepress/public/install.ps1 index 8a14a86c..31f2e324 100644 --- a/docs/.vuepress/public/install.ps1 +++ b/docs/.vuepress/public/install.ps1 @@ -64,7 +64,12 @@ try { $bar = $filled.PadRight(50) $recv = [math]::Round($totalRead / 1MB, 1) $total = [math]::Round($totalBytes / 1MB, 1) - Write-Host -NoNewline ("`r[{0}] {1,3}% {2,6:N1} / {3,6:N1} MB" -f $bar, $pct, $recv, $total) + # Use [Console]::Write with an explicit \r so the cursor returns to + # column 0 and overwrites the previous bar. Write-Host -NoNewline + # does not reliably reposition the cursor when the script is run + # via iex (pipe mode), producing multiple bars on one line. + $line = "`r[{0}] {1,3}% {2,6:N1} / {3,6:N1} MB" -f $bar, $pct, $recv, $total + [Console]::Write($line) } } } finally { @@ -73,7 +78,7 @@ try { $response.Close() } -Write-Host "" # end the progress line +[Console]::WriteLine() # end the progress line Write-Host "" Write-Host "Downloaded: .\$OUTPUT" From 031dbb16d461da7d75ee68ce90036f824ea942c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:03:11 +0000 Subject: [PATCH 283/484] Initial plan From 534e337f107a4cb99d052a3e1ad6453d72efac74 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:05:16 +0000 Subject: [PATCH 284/484] Add Quick Install section to README with one-liner install commands Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/0a622d0a-bb4e-4cba-96f6-df2afa3bf4b7 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fb690dd9..76228060 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,25 @@ ## Download -Get development builds from the [Releases section](https://github.com/MCCTeam/Minecraft-Console-Client/releases/latest) +Get the latest release from the [Releases section](https://github.com/MCCTeam/Minecraft-Console-Client/releases/latest). + +## Quick Install ⚡ + +Open a terminal in the folder where you want MCC and run: + +Linux / macOS: + +```bash +curl -fsSL https://mccteam.github.io/install.sh | sh +``` + +Windows (PowerShell): + +```powershell +iwr -useb https://mccteam.github.io/install.ps1 | iex +``` + +The script detects your architecture and downloads the right binary. For more options (including `wget` and manual downloads), see the [installation guide](https://mccteam.github.io/guide/installation.html). ## How to use 📚 From 6dc42d9bd1f077a4f9523722ed5437864964dbaf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:10:15 +0000 Subject: [PATCH 285/484] Initial plan From 65ef3dde6b07d97aab65226e70665585a76f6c97 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:22:31 +0000 Subject: [PATCH 286/484] Implement unified achievements feature: data model, protocol handling, state management, ChatBot API, and /achievement command Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/9db483a8-4a5f-47b1-a6f4-30b6e39075bd Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Achievement.cs | 36 ++++ .../Commands/AchievementCommand.cs | 106 ++++++++++ MinecraftClient/McClient.cs | 100 +++++++++ .../Protocol/Handlers/Protocol18.cs | 191 ++++++++++++++++++ .../Protocol/IMinecraftComHandler.cs | 14 ++ .../Translations/Translations.Designer.cs | 99 +++++++++ .../Resources/Translations/Translations.resx | 33 +++ MinecraftClient/Scripting/ChatBot.cs | 35 ++++ 8 files changed, 614 insertions(+) create mode 100644 MinecraftClient/Achievement.cs create mode 100644 MinecraftClient/Commands/AchievementCommand.cs diff --git a/MinecraftClient/Achievement.cs b/MinecraftClient/Achievement.cs new file mode 100644 index 00000000..760e4054 --- /dev/null +++ b/MinecraftClient/Achievement.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace MinecraftClient +{ + /// + /// The type of an achievement or advancement. + /// + public enum AchievementType + { + Task, + Challenge, + Goal, + Legacy + } + + /// + /// Represents a Minecraft achievement (pre-1.12) or advancement (1.12+). + /// + /// Resource identifier, e.g. "minecraft:story/root" or "achievement.openInventory" + /// Display title (null for legacy achievements without display info) + /// Display description (null for legacy achievements without display info) + /// The frame type / achievement category + /// Whether this advancement is hidden in the UI + /// Whether all requirements have been met + /// OR-groups of criterion names; all groups must be satisfied + /// Per-criterion completion status + public record Achievement( + string Id, + string? Title, + string? Description, + AchievementType Type, + bool IsHidden, + bool IsCompleted, + IReadOnlyList> Requirements, + IReadOnlyDictionary CriteriaProgress); +} diff --git a/MinecraftClient/Commands/AchievementCommand.cs b/MinecraftClient/Commands/AchievementCommand.cs new file mode 100644 index 00000000..ee99c4d7 --- /dev/null +++ b/MinecraftClient/Commands/AchievementCommand.cs @@ -0,0 +1,106 @@ +using System.Linq; +using System.Text; +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; + +namespace MinecraftClient.Commands +{ + public class AchievementCommand : Command + { + public override string CmdName => "achievement"; + public override string CmdUsage => "achievement "; + public override string CmdDesc => Translations.cmd_achievement_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source, string.Empty)) + .Then(l => l.Literal("list") + .Executes(r => GetUsage(r.Source, "list"))) + .Then(l => l.Literal("locked") + .Executes(r => GetUsage(r.Source, "locked"))) + .Then(l => l.Literal("unlocked") + .Executes(r => GetUsage(r.Source, "unlocked"))) + ) + ); + + dispatcher.Register(l => l.Literal(CmdName) + .Executes(r => ListAchievements(r.Source, null)) + .Then(l => l.Literal("list") + .Executes(r => ListAchievements(r.Source, null))) + .Then(l => l.Literal("locked") + .Executes(r => ListAchievements(r.Source, false))) + .Then(l => l.Literal("unlocked") + .Executes(r => ListAchievements(r.Source, true))) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source, string.Empty)) + .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) + ); + } + + private int GetUsage(CmdResult r, string? cmd) + { + return r.SetAndReturn(cmd switch + { +#pragma warning disable format + "list" => GetCmdDescTranslated(), + "locked" => GetCmdDescTranslated(), + "unlocked" => GetCmdDescTranslated(), + _ => GetCmdDescTranslated(), +#pragma warning restore format + }); + } + + /// null = all, true = unlocked only, false = locked only + private static int ListAchievements(CmdResult r, bool? completed) + { + McClient handler = CmdResult.currentHandler!; + + Achievement[] items = completed switch + { + true => handler.GetUnlockedAchievements(), + false => handler.GetLockedAchievements(), + null => handler.GetAchievements() + }; + + if (items.Length == 0) + { + string msg = completed switch + { + true => Translations.cmd_achievement_none_unlocked, + false => Translations.cmd_achievement_none_locked, + _ => Translations.cmd_achievement_none + }; + return r.SetAndReturn(CmdResult.Status.Done, msg); + } + + string header = completed switch + { + true => Translations.cmd_achievement_header_unlocked, + false => Translations.cmd_achievement_header_locked, + _ => Translations.cmd_achievement_header + }; + + StringBuilder sb = new(); + sb.AppendLine(header); + + foreach (Achievement a in items.OrderBy(static a => a.Id)) + { + string status = a.IsCompleted + ? Translations.cmd_achievement_done + : Translations.cmd_achievement_todo; + + string display = a.Title is not null + ? string.Format(Translations.cmd_achievement_entry_titled, status, a.Title, a.Id, a.Type) + : string.Format(Translations.cmd_achievement_entry, status, a.Id, a.Type); + + sb.AppendLine(display); + } + + handler.Log.Info(sb.ToString().TrimEnd()); + return r.SetAndReturn(CmdResult.Status.Done); + } + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 24069342..3eabfbd8 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -45,11 +45,14 @@ namespace MinecraftClient private readonly Queue threadTasks = new(); private readonly Lock threadTasksLock = new(); private readonly Lock recipeBookLock = new(); + private readonly Lock achievementsLock = new(); private readonly List bots = new(); private static readonly List botsOnHold = new(); private static readonly Dictionary inventories = new(); private readonly Dictionary unlockedRecipes = new(StringComparer.Ordinal); + private readonly Dictionary achievements = new(StringComparer.Ordinal); + private string? activeAdvancementTab; private readonly Dictionary> registeredBotPluginChannels = new(); private readonly List registeredServerPluginChannels = new(); @@ -1353,6 +1356,42 @@ namespace MinecraftClient } } + /// + /// Get all achievements/advancements known to the client. + /// + /// Snapshot of all achievements + public Achievement[] GetAchievements() + { + lock (achievementsLock) + { + return [.. achievements.Values]; + } + } + + /// + /// Get only completed achievements/advancements. + /// + /// Snapshot of completed achievements + public Achievement[] GetUnlockedAchievements() + { + lock (achievementsLock) + { + return achievements.Values.Where(static a => a.IsCompleted).ToArray(); + } + } + + /// + /// Get only incomplete achievements/advancements. + /// + /// Snapshot of locked achievements + public Achievement[] GetLockedAchievements() + { + lock (achievementsLock) + { + return achievements.Values.Where(static a => !a.IsCompleted).ToArray(); + } + } + /// /// Get all Entities /// @@ -4139,6 +4178,67 @@ namespace MinecraftClient } } + public void OnAchievementsUpdate(IReadOnlyList added, IReadOnlyList removedIds, bool reset) + { + lock (achievementsLock) + { + if (reset) + achievements.Clear(); + + // Remove entries + foreach (string id in removedIds) + achievements.Remove(id); + + // Add/update entries. For progress-only updates (no definition), + // merge with existing definition if available. + foreach (Achievement entry in added) + { + if (entry.Title is null && achievements.TryGetValue(entry.Id, out Achievement? existing)) + { + // Progress-only update - merge with existing definition + bool isCompleted = ComputeAchievementCompleted(existing.Requirements, entry.CriteriaProgress); + achievements[entry.Id] = existing with { IsCompleted = isCompleted, CriteriaProgress = entry.CriteriaProgress }; + } + else + { + achievements[entry.Id] = entry; + } + } + } + + DispatchBotEvent(bot => bot.OnAchievementUpdate(added, removedIds, reset)); + } + + public void OnSelectAdvancementTab(string? tabId) + { + activeAdvancementTab = tabId; + } + + /// + /// Compute whether an achievement is completed based on AND-of-ORs requirements. + /// + private static bool ComputeAchievementCompleted(IReadOnlyList> requirements, IReadOnlyDictionary criteria) + { + if (requirements.Count == 0) + return true; + + foreach (IReadOnlyList group in requirements) + { + bool groupSatisfied = false; + foreach (string criterion in group) + { + if (criteria.TryGetValue(criterion, out bool done) && done) + { + groupSatisfied = true; + break; + } + } + if (!groupSatisfied) + return false; + } + return true; + } + /// /// Send a click container button packet to the server. /// Used for Enchanting table, Lectern, stone cutter and loom diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index bc9537cd..2d934561 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3132,6 +3132,14 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.RecipeBookSettings: break; + case PacketTypesIn.Advancements: + HandleAdvancements(packetData); + break; + + case PacketTypesIn.SelectAdvancementTab: + HandleSelectAdvancementTab(packetData); + break; + default: return false; //Ignored packet } @@ -3139,6 +3147,189 @@ namespace MinecraftClient.Protocol.Handlers return true; //Packet processed } + /// + /// Handle the Advancements packet (1.12+). + /// Also handles the Statistics packet for pre-1.12 legacy achievements. + /// + private void HandleAdvancements(Queue packetData) + { + bool reset = dataTypes.ReadNextBool(packetData); + + // --- Added advancements --- + int addedCount = dataTypes.ReadNextVarInt(packetData); + var added = new List(addedCount); + var addedDefinitions = new Dictionary> requirements)>(addedCount); + + for (int i = 0; i < addedCount; i++) + { + string id = dataTypes.ReadNextString(packetData); + + // Parent + bool hasParent = dataTypes.ReadNextBool(packetData); + if (hasParent) + dataTypes.ReadNextString(packetData); // parentId - read and discard + + // Display + string? title = null; + string? description = null; + var type = AchievementType.Task; + bool isHidden = false; + + bool hasDisplay = dataTypes.ReadNextBool(packetData); + if (hasDisplay) + { + title = dataTypes.ReadNextChat(packetData); + description = dataTypes.ReadNextChat(packetData); + dataTypes.ReadNextItemSlot(packetData, itemPalette); // icon - read and discard + + int frameType = dataTypes.ReadNextVarInt(packetData); + type = frameType switch + { + 1 => AchievementType.Challenge, + 2 => AchievementType.Goal, + _ => AchievementType.Task + }; + + int flags = dataTypes.ReadNextInt(packetData); + isHidden = (flags & 0x04) != 0; + if ((flags & 0x01) != 0) + dataTypes.ReadNextString(packetData); // background texture - read and discard + + dataTypes.ReadNextFloat(packetData); // x + dataTypes.ReadNextFloat(packetData); // y + } + + // Criteria and requirements differ by version + var requirements = new List>(); + + if (protocolVersion < MC_1_20_6_Version) + { + // Builder-based: criteria names list, then requirements + int criteriaCount = dataTypes.ReadNextVarInt(packetData); + for (int c = 0; c < criteriaCount; c++) + dataTypes.ReadNextString(packetData); // criterion name only, no trigger data + + int reqGroupCount = dataTypes.ReadNextVarInt(packetData); + for (int g = 0; g < reqGroupCount; g++) + { + int groupSize = dataTypes.ReadNextVarInt(packetData); + var group = new List(groupSize); + for (int s = 0; s < groupSize; s++) + group.Add(dataTypes.ReadNextString(packetData)); + requirements.Add(group); + } + } + else + { + // AdvancementHolder-based (1.20.6+): requirements only, then sendsTelemetryEvent + int reqGroupCount = dataTypes.ReadNextVarInt(packetData); + for (int g = 0; g < reqGroupCount; g++) + { + int groupSize = dataTypes.ReadNextVarInt(packetData); + var group = new List(groupSize); + for (int s = 0; s < groupSize; s++) + group.Add(dataTypes.ReadNextString(packetData)); + requirements.Add(group); + } + + dataTypes.ReadNextBool(packetData); // sendsTelemetryEvent + } + + addedDefinitions[id] = (title, description, type, isHidden, requirements); + } + + // --- Removed advancement IDs --- + int removedCount = dataTypes.ReadNextVarInt(packetData); + var removedIds = new List(removedCount); + for (int i = 0; i < removedCount; i++) + removedIds.Add(dataTypes.ReadNextString(packetData)); + + // --- Progress updates --- + int progressCount = dataTypes.ReadNextVarInt(packetData); + var progressMap = new Dictionary>(progressCount); + + for (int i = 0; i < progressCount; i++) + { + string id = dataTypes.ReadNextString(packetData); + int criteriaEntries = dataTypes.ReadNextVarInt(packetData); + var criteria = new Dictionary(criteriaEntries); + + for (int c = 0; c < criteriaEntries; c++) + { + string criterionName = dataTypes.ReadNextString(packetData); + bool isDone = dataTypes.ReadNextBool(packetData); + if (isDone) + dataTypes.ReadNextLong(packetData); // epochMs - read and discard + criteria[criterionName] = isDone; + } + + progressMap[id] = criteria; + } + + // showAdvancements boolean added in 1.21.11+ + if (protocolVersion >= MC_1_21_11_Version) + dataTypes.ReadNextBool(packetData); // showAdvancements - read and discard + + // Build Achievement records from definitions + progress + foreach (var (id, def) in addedDefinitions) + { + progressMap.TryGetValue(id, out var criteria); + criteria ??= new Dictionary(); + + bool isCompleted = ComputeAdvancementCompleted(def.requirements, criteria); + + var readOnlyReqs = def.requirements.ConvertAll>(static g => g.AsReadOnly()); + added.Add(new Achievement(id, def.title, def.description, def.type, def.isHidden, isCompleted, readOnlyReqs.AsReadOnly(), criteria)); + } + + // Also build Achievement records for progress-only updates (no definition change) + var progressOnly = new List(); + foreach (var (id, criteria) in progressMap) + { + if (!addedDefinitions.ContainsKey(id)) + progressOnly.Add(new Achievement(id, null, null, AchievementType.Task, false, false, [], criteria)); + } + + handler.OnAchievementsUpdate([.. added, .. progressOnly], removedIds, reset); + } + + /// + /// Compute whether an advancement is completed based on AND-of-ORs requirements. + /// + private static bool ComputeAdvancementCompleted(List> requirements, Dictionary criteria) + { + // Zero requirements = automatically done + if (requirements.Count == 0) + return true; + + // Each OR-group must have at least one satisfied criterion + foreach (var group in requirements) + { + bool groupSatisfied = false; + foreach (string criterion in group) + { + if (criteria.TryGetValue(criterion, out bool done) && done) + { + groupSatisfied = true; + break; + } + } + if (!groupSatisfied) + return false; + } + return true; + } + + /// + /// Handle the SelectAdvancementTab packet. + /// + private void HandleSelectAdvancementTab(Queue packetData) + { + bool hasTab = dataTypes.ReadNextBool(packetData); + string? tabId = hasTab ? dataTypes.ReadNextString(packetData) : null; + handler.OnSelectAdvancementTab(tabId); + } + private void HandleUnlockRecipes(Queue packetData) { int action = dataTypes.ReadNextVarInt(packetData); diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 81a4a056..9bfa44e8 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -530,6 +530,20 @@ namespace MinecraftClient.Protocol /// Recipe identifiers to remove public void OnRecipeBookRemove(string[] recipeIds); + /// + /// Called when achievement/advancement data is received from the server. + /// + /// Achievements that were added or updated + /// IDs of achievements that were removed + /// True if all existing state should be cleared before applying + public void OnAchievementsUpdate(IReadOnlyList added, IReadOnlyList removedIds, bool reset); + + /// + /// Called when the server selects an advancement tab. + /// + /// The tab identifier, or null if no tab is selected + public void OnSelectAdvancementTab(string? tabId); + /// /// Send a click container button packet to the server. /// Used for Enchanting table, Lectern, stone cutter and loom diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 022e9cad..b77b0f39 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -7174,5 +7174,104 @@ namespace MinecraftClient { return ResourceManager.GetString("cmd.minimap.position_set", resourceCulture); } } + + /// + /// Looks up a localized string similar to list achievements/advancements from the server.. + /// + internal static string cmd_achievement_desc { + get { + return ResourceManager.GetString("cmd.achievement.desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No achievements/advancements received yet.. + /// + internal static string cmd_achievement_none { + get { + return ResourceManager.GetString("cmd.achievement.none", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No completed achievements/advancements.. + /// + internal static string cmd_achievement_none_unlocked { + get { + return ResourceManager.GetString("cmd.achievement.none_unlocked", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No incomplete achievements/advancements.. + /// + internal static string cmd_achievement_none_locked { + get { + return ResourceManager.GetString("cmd.achievement.none_locked", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Achievements/Advancements:. + /// + internal static string cmd_achievement_header { + get { + return ResourceManager.GetString("cmd.achievement.header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Completed achievements/advancements:. + /// + internal static string cmd_achievement_header_unlocked { + get { + return ResourceManager.GetString("cmd.achievement.header_unlocked", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incomplete achievements/advancements:. + /// + internal static string cmd_achievement_header_locked { + get { + return ResourceManager.GetString("cmd.achievement.header_locked", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [DONE]. + /// + internal static string cmd_achievement_done { + get { + return ResourceManager.GetString("cmd.achievement.done", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [TODO]. + /// + internal static string cmd_achievement_todo { + get { + return ResourceManager.GetString("cmd.achievement.todo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} {1} ({2}) [{3}]. + /// + internal static string cmd_achievement_entry_titled { + get { + return ResourceManager.GetString("cmd.achievement.entry_titled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} {1} [{2}]. + /// + internal static string cmd_achievement_entry { + get { + return ResourceManager.GetString("cmd.achievement.entry", resourceCulture); + } + } } } diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 7c883622..48a07470 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2527,4 +2527,37 @@ see item details. Minimap position set to: {0} + + list achievements/advancements from the server. + + + No achievements/advancements received yet. + + + No completed achievements/advancements. + + + No incomplete achievements/advancements. + + + Achievements/Advancements: + + + Completed achievements/advancements: + + + Incomplete achievements/advancements: + + + [DONE] + + + [TODO] + + + {0} {1} ({2}) [{3}] + + + {0} {1} [{2}] + diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index f62e1377..422fc1a4 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -514,6 +514,14 @@ namespace MinecraftClient.Scripting /// The block public virtual void OnBlockChange(Location location, Block block) { } + /// + /// Called when achievement/advancement data is updated. + /// + /// Achievements that were added or updated + /// IDs of achievements that were removed + /// Whether the achievement state was fully reset before this update + public virtual void OnAchievementUpdate(IReadOnlyList updated, IReadOnlyList removedIds, bool reset) { } + /* =================================================================== */ /* ToolBox - Methods below might be useful while creating your bot. */ /* You should not need to interact with other classes of the program. */ @@ -1120,6 +1128,33 @@ namespace MinecraftClient.Scripting return Handler.GetEntities(); } + /// + /// Get all achievements/advancements. + /// + /// Snapshot of all achievements + protected Achievement[] GetAchievements() + { + return Handler.GetAchievements(); + } + + /// + /// Get only completed achievements/advancements. + /// + /// Snapshot of unlocked achievements + protected Achievement[] GetUnlockedAchievements() + { + return Handler.GetUnlockedAchievements(); + } + + /// + /// Get only incomplete achievements/advancements. + /// + /// Snapshot of locked achievements + protected Achievement[] GetLockedAchievements() + { + return Handler.GetLockedAchievements(); + } + /// /// Get all players Latency /// From 7b3e5ee49215ddc76b5addf7db599e43267f8852 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:27:12 +0000 Subject: [PATCH 287/484] Address code review: eliminate unnecessary allocation in progress-only updates Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/9db483a8-4a5f-47b1-a6f4-30b6e39075bd Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 2d934561..bb603f9b 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3283,14 +3283,13 @@ namespace MinecraftClient.Protocol.Handlers } // Also build Achievement records for progress-only updates (no definition change) - var progressOnly = new List(); foreach (var (id, criteria) in progressMap) { if (!addedDefinitions.ContainsKey(id)) - progressOnly.Add(new Achievement(id, null, null, AchievementType.Task, false, false, [], criteria)); + added.Add(new Achievement(id, null, null, AchievementType.Task, false, false, [], criteria)); } - handler.OnAchievementsUpdate([.. added, .. progressOnly], removedIds, reset); + handler.OnAchievementsUpdate(added, removedIds, reset); } /// From 5705df43bdb8f91daa29256eeb0821ee11fc5e6c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:07:17 +0000 Subject: [PATCH 288/484] Fix Advancements packet parsing: sendsTelemetryEvent added in 1.20, deduplicate requirements reading Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/5da0ec37-35e2-4aae-b165-66ddd82df985 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- .../Protocol/Handlers/Protocol18.cs | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index bb603f9b..73c47a59 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3204,37 +3204,27 @@ namespace MinecraftClient.Protocol.Handlers if (protocolVersion < MC_1_20_6_Version) { - // Builder-based: criteria names list, then requirements + // Builder-based (pre-1.20.6): criteria names list, then requirements int criteriaCount = dataTypes.ReadNextVarInt(packetData); for (int c = 0; c < criteriaCount; c++) dataTypes.ReadNextString(packetData); // criterion name only, no trigger data - - int reqGroupCount = dataTypes.ReadNextVarInt(packetData); - for (int g = 0; g < reqGroupCount; g++) - { - int groupSize = dataTypes.ReadNextVarInt(packetData); - var group = new List(groupSize); - for (int s = 0; s < groupSize; s++) - group.Add(dataTypes.ReadNextString(packetData)); - requirements.Add(group); - } } - else + + // Requirements (all versions) + int reqGroupCount = dataTypes.ReadNextVarInt(packetData); + for (int g = 0; g < reqGroupCount; g++) { - // AdvancementHolder-based (1.20.6+): requirements only, then sendsTelemetryEvent - int reqGroupCount = dataTypes.ReadNextVarInt(packetData); - for (int g = 0; g < reqGroupCount; g++) - { - int groupSize = dataTypes.ReadNextVarInt(packetData); - var group = new List(groupSize); - for (int s = 0; s < groupSize; s++) - group.Add(dataTypes.ReadNextString(packetData)); - requirements.Add(group); - } - - dataTypes.ReadNextBool(packetData); // sendsTelemetryEvent + int groupSize = dataTypes.ReadNextVarInt(packetData); + var group = new List(groupSize); + for (int s = 0; s < groupSize; s++) + group.Add(dataTypes.ReadNextString(packetData)); + requirements.Add(group); } + // sendsTelemetryEvent (added in 1.20, present in all versions since) + if (protocolVersion >= MC_1_20_Version) + dataTypes.ReadNextBool(packetData); + addedDefinitions[id] = (title, description, type, isHidden, requirements); } From 0f3289dfdffa8156ae4a1508d52041dd2f2d3984 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:16:45 +0000 Subject: [PATCH 289/484] Fix criteria version boundary: criteria list removed from wire format in MC 1.20.2, not 1.20.6 Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/5da0ec37-35e2-4aae-b165-66ddd82df985 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 73c47a59..ac6b3b4f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3202,9 +3202,9 @@ namespace MinecraftClient.Protocol.Handlers // Criteria and requirements differ by version var requirements = new List>(); - if (protocolVersion < MC_1_20_6_Version) + if (protocolVersion < MC_1_20_2_Version) { - // Builder-based (pre-1.20.6): criteria names list, then requirements + // Builder-based (pre-1.20.2): criteria names list, then requirements int criteriaCount = dataTypes.ReadNextVarInt(packetData); for (int c = 0; c < criteriaCount; c++) dataTypes.ReadNextString(packetData); // criterion name only, no trigger data From c95fe131e31ad63142619bab0122352131d6c46d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 07:40:08 +0000 Subject: [PATCH 290/484] Initial plan From c55d32bb7009156723f36f9d77901ac54612c8f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:03:56 +0000 Subject: [PATCH 291/484] Diagnose root cause of 26.1 RecipeBookAdd crash Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/47b0c937-1491-4216-8ee0-1aca866e99ab Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- server.pid | 1 + 1 file changed, 1 insertion(+) create mode 100644 server.pid diff --git a/server.pid b/server.pid new file mode 100644 index 00000000..7b6ceee2 --- /dev/null +++ b/server.pid @@ -0,0 +1 @@ +5586 From 962c8b1ab24776773a28b10eb5eadeeea8fae580 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:09:33 +0000 Subject: [PATCH 292/484] Fix 26.1 RecipeBookAdd crash: update SlotDisplay registry IDs for 26.1 MC 26.1 changed the minecraft:slot_display registry, inserting 3 new types (with_any_potion, only_with_component, dyed) and shifting all existing IDs. This caused MCC to misparse recipe display data, leading to a Queue empty crash in SkipItemHolderSet. Add version-gated ReadSlotDisplayLabel with correct 26.1 type mapping and reader methods for the 3 new slot display types. Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/47b0c937-1491-4216-8ee0-1aca866e99ab Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- .gitignore | 1 + .../Protocol/Handlers/Protocol18.cs | 51 +++++++++++++++++++ server.pid | 1 - 3 files changed, 52 insertions(+), 1 deletion(-) delete mode 100644 server.pid diff --git a/.gitignore b/.gitignore index 91c3a8b6..d0f86370 100644 --- a/.gitignore +++ b/.gitignore @@ -437,3 +437,4 @@ FodyWeavers.xsd /.specstory/ /.vscode/settings.json /Sentry/ +server.pid diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ac6b3b4f..7032bcbd 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3470,6 +3470,29 @@ namespace MinecraftClient.Protocol.Handlers private string ReadSlotDisplayLabel(Queue packetData) { int slotDisplayType = dataTypes.ReadNextVarInt(packetData); + + // 26.1 changed the slot display registry order, inserting 3 new types: + // Pre-26.1: 0=empty, 1=any_fuel, 2=item, 3=item_stack, 4=tag, 5=smithing_trim, 6=with_remainder, 7=composite + // 26.1+: 0=empty, 1=any_fuel, 2=with_any_potion, 3=only_with_component, 4=item, 5=item_stack, 6=tag, 7=dyed, 8=smithing_trim, 9=with_remainder, 10=composite + if (protocolVersion >= MC_26_1_Version) + { + return slotDisplayType switch + { + 0 => "Empty", + 1 => "Any Fuel", + 2 => ReadWithAnyPotionSlotDisplayLabel(packetData), + 3 => ReadOnlyWithComponentSlotDisplayLabel(packetData), + 4 => Item.GetTypeString(itemPalette.FromId(dataTypes.ReadNextVarInt(packetData))), + 5 => dataTypes.ReadNextItemSlot(packetData, itemPalette)?.GetTypeString() ?? "Empty", + 6 => "#" + dataTypes.ReadNextString(packetData), + 7 => ReadDyedSlotDisplayLabel(packetData), + 8 => ReadSmithingTrimSlotDisplayLabel(packetData), + 9 => ReadWithRemainderSlotDisplayLabel(packetData), + 10 => ReadCompositeSlotDisplayLabel(packetData), + _ => $"slot_display_{slotDisplayType}", + }; + } + return slotDisplayType switch { 0 => "Empty", @@ -3484,6 +3507,34 @@ namespace MinecraftClient.Protocol.Handlers }; } + /// + /// Reads a with_any_potion slot display (26.1+): contains a nested SlotDisplay. + /// + private string ReadWithAnyPotionSlotDisplayLabel(Queue packetData) + { + return ReadSlotDisplayLabel(packetData); + } + + /// + /// Reads an only_with_component slot display (26.1+): contains a nested SlotDisplay and a DataComponentType VarInt ID. + /// + private string ReadOnlyWithComponentSlotDisplayLabel(Queue packetData) + { + string sourceLabel = ReadSlotDisplayLabel(packetData); + _ = dataTypes.ReadNextVarInt(packetData); // DataComponentType registry id + return sourceLabel; + } + + /// + /// Reads a dyed slot display (26.1+): contains two nested SlotDisplays (dye + target). + /// + private string ReadDyedSlotDisplayLabel(Queue packetData) + { + _ = ReadSlotDisplayLabel(packetData); // dye + string targetLabel = ReadSlotDisplayLabel(packetData); // target + return targetLabel; + } + private string ReadSmithingTrimSlotDisplayLabel(Queue packetData) { string baseLabel = ReadSlotDisplayLabel(packetData); diff --git a/server.pid b/server.pid deleted file mode 100644 index 7b6ceee2..00000000 --- a/server.pid +++ /dev/null @@ -1 +0,0 @@ -5586 From 22455905a7952a706024f852ac21c25ca01ca1b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:24:00 +0000 Subject: [PATCH 293/484] Add automatic mining-speed and dig-duration handling - Add BlockHardness.cs with hardness data for all 1053 blocks from MC 1.21.11 - Add MiningCalculator.cs with version-aware dig duration computation - Tool speed from ToolComponent (1.20.6+) or legacy hardcoded tables - Efficiency enchantment (legacy: level^2+1, 1.21.11+: mining_efficiency attribute) - Haste/Conduit Power/Mining Fatigue effects - BLOCK_BREAK_SPEED attribute (1.20.6+) - MINING_EFFICIENCY and SUBMERGED_MINING_SPEED attributes (1.21.11+) - Underwater penalty with Aqua Affinity support (legacy) or attribute (modern) - Airborne penalty - Correct tool for drops check (30 vs 100 divisor) - Modify McClient.DigBlock to auto-compute duration for survival/adventure mode - Cache player attributes from OnEntityProperties in McClient - Expose duration parameter in ChatBot.cs scripting wrapper - Add /downloads/ to .gitignore Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/579df446-a335-4174-9a8b-4d66173c82b1 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- .gitignore | 1 + MinecraftClient/Mapping/BlockHardness.cs | 1326 +++++++++++++++++++ MinecraftClient/Mapping/MiningCalculator.cs | 493 +++++++ MinecraftClient/McClient.cs | 59 + MinecraftClient/Scripting/ChatBot.cs | 5 +- 5 files changed, 1882 insertions(+), 2 deletions(-) create mode 100644 MinecraftClient/Mapping/BlockHardness.cs create mode 100644 MinecraftClient/Mapping/MiningCalculator.cs diff --git a/.gitignore b/.gitignore index 91c3a8b6..cf6e90b9 100644 --- a/.gitignore +++ b/.gitignore @@ -437,3 +437,4 @@ FodyWeavers.xsd /.specstory/ /.vscode/settings.json /Sentry/ +/downloads/ diff --git a/MinecraftClient/Mapping/BlockHardness.cs b/MinecraftClient/Mapping/BlockHardness.cs new file mode 100644 index 00000000..311507b0 --- /dev/null +++ b/MinecraftClient/Mapping/BlockHardness.cs @@ -0,0 +1,1326 @@ +using System.Collections.Frozen; +using System.Collections.Generic; + +namespace MinecraftClient.Mapping +{ + /// + /// Provides block hardness values and tool requirement data for mining calculations. + /// Data extracted from Minecraft 1.21.11 decompiled source (Blocks.java). + /// + public static class BlockHardness + { + /// + /// Default hardness for blocks not in the table (assumes stone-like). + /// + public const float DefaultHardness = 1.5f; + + /// + /// Get the hardness value for a block material. + /// Returns -1 for unbreakable blocks, 0 for instant-break blocks. + /// + public static float GetHardness(Material material) + { + if (HardnessTable.TryGetValue(material, out float hardness)) + return hardness; + return DefaultHardness; + } + + /// + /// Check whether a block requires the correct tool to get drops + /// (and uses the 100 divisor instead of 30 when mined without the correct tool). + /// + public static bool RequiresCorrectTool(Material material) + { + return RequiresCorrectToolSet.Contains(material); + } + + private static readonly FrozenDictionary HardnessTable = new Dictionary + { + // Hardness -1.0: 15 blocks + { Material.Barrier, -1.0f }, + { Material.Bedrock, -1.0f }, + { Material.ChainCommandBlock, -1.0f }, + { Material.CommandBlock, -1.0f }, + { Material.EndGateway, -1.0f }, + { Material.EndPortal, -1.0f }, + { Material.EndPortalFrame, -1.0f }, + { Material.Jigsaw, -1.0f }, + { Material.Light, -1.0f }, + { Material.MovingPiston, -1.0f }, + { Material.NetherPortal, -1.0f }, + { Material.RepeatingCommandBlock, -1.0f }, + { Material.StructureBlock, -1.0f }, + { Material.TestBlock, -1.0f }, + { Material.TestInstanceBlock, -1.0f }, + // Hardness 0.0: 443 blocks + { Material.AcaciaButton, 0.0f }, + { Material.AcaciaLeaves, 0.0f }, + { Material.AcaciaLog, 0.0f }, + { Material.AcaciaSapling, 0.0f }, + { Material.Air, 0.0f }, + { Material.Allium, 0.0f }, + { Material.AndesiteSlab, 0.0f }, + { Material.AndesiteWall, 0.0f }, + { Material.Azalea, 0.0f }, + { Material.AzaleaLeaves, 0.0f }, + { Material.AzureBluet, 0.0f }, + { Material.Bamboo, 0.0f }, + { Material.BambooBlock, 0.0f }, + { Material.BambooButton, 0.0f }, + { Material.BambooSapling, 0.0f }, + { Material.Beetroots, 0.0f }, + { Material.BirchButton, 0.0f }, + { Material.BirchLeaves, 0.0f }, + { Material.BirchLog, 0.0f }, + { Material.BirchSapling, 0.0f }, + { Material.BlackCandle, 0.0f }, + { Material.BlackCandleCake, 0.0f }, + { Material.BlackShulkerBox, 0.0f }, + { Material.BlackstoneWall, 0.0f }, + { Material.BlueCandle, 0.0f }, + { Material.BlueCandleCake, 0.0f }, + { Material.BlueOrchid, 0.0f }, + { Material.BlueShulkerBox, 0.0f }, + { Material.BrainCoral, 0.0f }, + { Material.BrainCoralFan, 0.0f }, + { Material.BrainCoralWallFan, 0.0f }, + { Material.BrickWall, 0.0f }, + { Material.BrownCandle, 0.0f }, + { Material.BrownCandleCake, 0.0f }, + { Material.BrownMushroom, 0.0f }, + { Material.BrownShulkerBox, 0.0f }, + { Material.BubbleColumn, 0.0f }, + { Material.BubbleCoral, 0.0f }, + { Material.BubbleCoralFan, 0.0f }, + { Material.BubbleCoralWallFan, 0.0f }, + { Material.Bush, 0.0f }, + { Material.CactusFlower, 0.0f }, + { Material.CalibratedSculkSensor, 0.0f }, + { Material.Candle, 0.0f }, + { Material.CandleCake, 0.0f }, + { Material.Carrots, 0.0f }, + { Material.CaveAir, 0.0f }, + { Material.CaveVines, 0.0f }, + { Material.CaveVinesPlant, 0.0f }, + { Material.CherryButton, 0.0f }, + { Material.CherryLog, 0.0f }, + { Material.CherrySapling, 0.0f }, + { Material.ChiseledCopper, 0.0f }, + { Material.ChiseledDeepslate, 0.0f }, + { Material.ChiseledTuff, 0.0f }, + { Material.ChiseledTuffBricks, 0.0f }, + { Material.ClosedEyeblossom, 0.0f }, + { Material.CobbledDeepslateSlab, 0.0f }, + { Material.CobbledDeepslateWall, 0.0f }, + { Material.CobblestoneWall, 0.0f }, + { Material.Comparator, 0.0f }, + { Material.CopperOre, 0.0f }, + { Material.CopperTorch, 0.0f }, + { Material.CopperWallTorch, 0.0f }, + { Material.Cornflower, 0.0f }, + { Material.CrackedDeepslateBricks, 0.0f }, + { Material.CrackedDeepslateTiles, 0.0f }, + { Material.CrackedPolishedBlackstoneBricks, 0.0f }, + { Material.CrimsonButton, 0.0f }, + { Material.CrimsonFungus, 0.0f }, + { Material.CrimsonRoots, 0.0f }, + { Material.CrimsonStem, 0.0f }, + { Material.CutCopper, 0.0f }, + { Material.CutCopperSlab, 0.0f }, + { Material.CutCopperStairs, 0.0f }, + { Material.CyanCandle, 0.0f }, + { Material.CyanCandleCake, 0.0f }, + { Material.CyanShulkerBox, 0.0f }, + { Material.Dandelion, 0.0f }, + { Material.DarkOakButton, 0.0f }, + { Material.DarkOakLeaves, 0.0f }, + { Material.DarkOakLog, 0.0f }, + { Material.DarkOakSapling, 0.0f }, + { Material.DeadBrainCoral, 0.0f }, + { Material.DeadBrainCoralFan, 0.0f }, + { Material.DeadBrainCoralWallFan, 0.0f }, + { Material.DeadBubbleCoral, 0.0f }, + { Material.DeadBubbleCoralFan, 0.0f }, + { Material.DeadBubbleCoralWallFan, 0.0f }, + { Material.DeadBush, 0.0f }, + { Material.DeadFireCoral, 0.0f }, + { Material.DeadFireCoralFan, 0.0f }, + { Material.DeadFireCoralWallFan, 0.0f }, + { Material.DeadHornCoral, 0.0f }, + { Material.DeadHornCoralFan, 0.0f }, + { Material.DeadHornCoralWallFan, 0.0f }, + { Material.DeadTubeCoral, 0.0f }, + { Material.DeadTubeCoralFan, 0.0f }, + { Material.DeadTubeCoralWallFan, 0.0f }, + { Material.DecoratedPot, 0.0f }, + { Material.DeepslateBrickSlab, 0.0f }, + { Material.DeepslateBrickWall, 0.0f }, + { Material.DeepslateBricks, 0.0f }, + { Material.DeepslateTileSlab, 0.0f }, + { Material.DeepslateTileWall, 0.0f }, + { Material.DeepslateTiles, 0.0f }, + { Material.DioriteSlab, 0.0f }, + { Material.DioriteWall, 0.0f }, + { Material.DriedGhast, 0.0f }, + { Material.EndRod, 0.0f }, + { Material.EndStoneBrickSlab, 0.0f }, + { Material.EndStoneBrickWall, 0.0f }, + { Material.ExposedChiseledCopper, 0.0f }, + { Material.ExposedCopper, 0.0f }, + { Material.ExposedCopperBulb, 0.0f }, + { Material.ExposedCopperChest, 0.0f }, + { Material.ExposedCopperDoor, 0.0f }, + { Material.ExposedCopperGolemStatue, 0.0f }, + { Material.ExposedCopperGrate, 0.0f }, + { Material.ExposedCopperTrapdoor, 0.0f }, + { Material.ExposedCutCopper, 0.0f }, + { Material.ExposedCutCopperSlab, 0.0f }, + { Material.ExposedCutCopperStairs, 0.0f }, + { Material.ExposedLightningRod, 0.0f }, + { Material.Fern, 0.0f }, + { Material.Fire, 0.0f }, + { Material.FireCoral, 0.0f }, + { Material.FireCoralFan, 0.0f }, + { Material.FireCoralWallFan, 0.0f }, + { Material.FireflyBush, 0.0f }, + { Material.FlowerPot, 0.0f }, + { Material.FloweringAzalea, 0.0f }, + { Material.FloweringAzaleaLeaves, 0.0f }, + { Material.Frogspawn, 0.0f }, + { Material.GildedBlackstone, 0.0f }, + { Material.GlassPane, 0.0f }, + { Material.GraniteSlab, 0.0f }, + { Material.GraniteWall, 0.0f }, + { Material.GrayCandle, 0.0f }, + { Material.GrayCandleCake, 0.0f }, + { Material.GrayShulkerBox, 0.0f }, + { Material.GreenCandle, 0.0f }, + { Material.GreenCandleCake, 0.0f }, + { Material.GreenShulkerBox, 0.0f }, + { Material.HangingRoots, 0.0f }, + { Material.HoneyBlock, 0.0f }, + { Material.HornCoral, 0.0f }, + { Material.HornCoralFan, 0.0f }, + { Material.HornCoralWallFan, 0.0f }, + { Material.InfestedChiseledStoneBricks, 0.0f }, + { Material.InfestedCobblestone, 0.0f }, + { Material.InfestedCrackedStoneBricks, 0.0f }, + { Material.InfestedDeepslate, 0.0f }, + { Material.InfestedMossyStoneBricks, 0.0f }, + { Material.InfestedStone, 0.0f }, + { Material.InfestedStoneBricks, 0.0f }, + { Material.JungleButton, 0.0f }, + { Material.JungleLeaves, 0.0f }, + { Material.JungleLog, 0.0f }, + { Material.JungleSapling, 0.0f }, + { Material.Kelp, 0.0f }, + { Material.KelpPlant, 0.0f }, + { Material.LargeAmethystBud, 0.0f }, + { Material.LargeFern, 0.0f }, + { Material.LavaCauldron, 0.0f }, + { Material.LeafLitter, 0.0f }, + { Material.LightBlueCandle, 0.0f }, + { Material.LightBlueCandleCake, 0.0f }, + { Material.LightBlueShulkerBox, 0.0f }, + { Material.LightGrayCandle, 0.0f }, + { Material.LightGrayCandleCake, 0.0f }, + { Material.LightGrayShulkerBox, 0.0f }, + { Material.Lilac, 0.0f }, + { Material.LilyOfTheValley, 0.0f }, + { Material.LilyPad, 0.0f }, + { Material.LimeCandle, 0.0f }, + { Material.LimeCandleCake, 0.0f }, + { Material.LimeShulkerBox, 0.0f }, + { Material.MagentaCandle, 0.0f }, + { Material.MagentaCandleCake, 0.0f }, + { Material.MagentaShulkerBox, 0.0f }, + { Material.MangroveButton, 0.0f }, + { Material.MangroveLeaves, 0.0f }, + { Material.MangroveLog, 0.0f }, + { Material.MangrovePropagule, 0.0f }, + { Material.MediumAmethystBud, 0.0f }, + { Material.MossyCobblestoneSlab, 0.0f }, + { Material.MossyCobblestoneWall, 0.0f }, + { Material.MossyStoneBrickSlab, 0.0f }, + { Material.MossyStoneBrickWall, 0.0f }, + { Material.Mud, 0.0f }, + { Material.MudBrickWall, 0.0f }, + { Material.NetherBrickWall, 0.0f }, + { Material.NetherSprouts, 0.0f }, + { Material.NetherWart, 0.0f }, + { Material.OakButton, 0.0f }, + { Material.OakLeaves, 0.0f }, + { Material.OakLog, 0.0f }, + { Material.OakSapling, 0.0f }, + { Material.OpenEyeblossom, 0.0f }, + { Material.OrangeCandle, 0.0f }, + { Material.OrangeCandleCake, 0.0f }, + { Material.OrangeShulkerBox, 0.0f }, + { Material.OrangeTulip, 0.0f }, + { Material.OxeyeDaisy, 0.0f }, + { Material.OxidizedChiseledCopper, 0.0f }, + { Material.OxidizedCopper, 0.0f }, + { Material.OxidizedCopperBulb, 0.0f }, + { Material.OxidizedCopperChest, 0.0f }, + { Material.OxidizedCopperDoor, 0.0f }, + { Material.OxidizedCopperGolemStatue, 0.0f }, + { Material.OxidizedCopperGrate, 0.0f }, + { Material.OxidizedCopperTrapdoor, 0.0f }, + { Material.OxidizedCutCopper, 0.0f }, + { Material.OxidizedCutCopperSlab, 0.0f }, + { Material.OxidizedCutCopperStairs, 0.0f }, + { Material.OxidizedLightningRod, 0.0f }, + { Material.PaleHangingMoss, 0.0f }, + { Material.PaleOakButton, 0.0f }, + { Material.PaleOakLog, 0.0f }, + { Material.PaleOakSapling, 0.0f }, + { Material.Peony, 0.0f }, + { Material.PinkCandle, 0.0f }, + { Material.PinkCandleCake, 0.0f }, + { Material.PinkPetals, 0.0f }, + { Material.PinkShulkerBox, 0.0f }, + { Material.PinkTulip, 0.0f }, + { Material.Piston, 0.0f }, + { Material.PitcherCrop, 0.0f }, + { Material.PitcherPlant, 0.0f }, + { Material.PolishedAndesiteSlab, 0.0f }, + { Material.PolishedBlackstoneBrickWall, 0.0f }, + { Material.PolishedBlackstoneButton, 0.0f }, + { Material.PolishedBlackstoneSlab, 0.0f }, + { Material.PolishedBlackstoneWall, 0.0f }, + { Material.PolishedDeepslate, 0.0f }, + { Material.PolishedDeepslateSlab, 0.0f }, + { Material.PolishedDeepslateWall, 0.0f }, + { Material.PolishedDioriteSlab, 0.0f }, + { Material.PolishedGraniteSlab, 0.0f }, + { Material.PolishedTuff, 0.0f }, + { Material.PolishedTuffSlab, 0.0f }, + { Material.PolishedTuffStairs, 0.0f }, + { Material.PolishedTuffWall, 0.0f }, + { Material.Poppy, 0.0f }, + { Material.Potatoes, 0.0f }, + { Material.PottedAcaciaSapling, 0.0f }, + { Material.PottedAllium, 0.0f }, + { Material.PottedAzaleaBush, 0.0f }, + { Material.PottedAzureBluet, 0.0f }, + { Material.PottedBamboo, 0.0f }, + { Material.PottedBirchSapling, 0.0f }, + { Material.PottedBlueOrchid, 0.0f }, + { Material.PottedBrownMushroom, 0.0f }, + { Material.PottedCactus, 0.0f }, + { Material.PottedCherrySapling, 0.0f }, + { Material.PottedClosedEyeblossom, 0.0f }, + { Material.PottedCornflower, 0.0f }, + { Material.PottedCrimsonFungus, 0.0f }, + { Material.PottedCrimsonRoots, 0.0f }, + { Material.PottedDandelion, 0.0f }, + { Material.PottedDarkOakSapling, 0.0f }, + { Material.PottedDeadBush, 0.0f }, + { Material.PottedFern, 0.0f }, + { Material.PottedFloweringAzaleaBush, 0.0f }, + { Material.PottedJungleSapling, 0.0f }, + { Material.PottedLilyOfTheValley, 0.0f }, + { Material.PottedMangrovePropagule, 0.0f }, + { Material.PottedOakSapling, 0.0f }, + { Material.PottedOpenEyeblossom, 0.0f }, + { Material.PottedOrangeTulip, 0.0f }, + { Material.PottedOxeyeDaisy, 0.0f }, + { Material.PottedPaleOakSapling, 0.0f }, + { Material.PottedPinkTulip, 0.0f }, + { Material.PottedPoppy, 0.0f }, + { Material.PottedRedMushroom, 0.0f }, + { Material.PottedRedTulip, 0.0f }, + { Material.PottedSpruceSapling, 0.0f }, + { Material.PottedTorchflower, 0.0f }, + { Material.PottedWarpedFungus, 0.0f }, + { Material.PottedWarpedRoots, 0.0f }, + { Material.PottedWhiteTulip, 0.0f }, + { Material.PottedWitherRose, 0.0f }, + { Material.PowderSnowCauldron, 0.0f }, + { Material.PrismarineWall, 0.0f }, + { Material.PurpleCandle, 0.0f }, + { Material.PurpleCandleCake, 0.0f }, + { Material.PurpleShulkerBox, 0.0f }, + { Material.QuartzBricks, 0.0f }, + { Material.RedCandle, 0.0f }, + { Material.RedCandleCake, 0.0f }, + { Material.RedMushroom, 0.0f }, + { Material.RedNetherBrickSlab, 0.0f }, + { Material.RedNetherBrickWall, 0.0f }, + { Material.RedSandstoneWall, 0.0f }, + { Material.RedShulkerBox, 0.0f }, + { Material.RedTulip, 0.0f }, + { Material.RedstoneTorch, 0.0f }, + { Material.RedstoneWallTorch, 0.0f }, + { Material.RedstoneWire, 0.0f }, + { Material.Repeater, 0.0f }, + { Material.ResinBlock, 0.0f }, + { Material.ResinClump, 0.0f }, + { Material.RoseBush, 0.0f }, + { Material.SandstoneWall, 0.0f }, + { Material.Scaffolding, 0.0f }, + { Material.SeaPickle, 0.0f }, + { Material.Seagrass, 0.0f }, + { Material.ShortDryGrass, 0.0f }, + { Material.ShortGrass, 0.0f }, + { Material.ShulkerBox, 0.0f }, + { Material.SlimeBlock, 0.0f }, + { Material.SmallAmethystBud, 0.0f }, + { Material.SmallDripleaf, 0.0f }, + { Material.SmoothBasalt, 0.0f }, + { Material.SmoothQuartzSlab, 0.0f }, + { Material.SmoothRedSandstoneSlab, 0.0f }, + { Material.SmoothSandstoneSlab, 0.0f }, + { Material.SoulFire, 0.0f }, + { Material.SoulTorch, 0.0f }, + { Material.SoulWallTorch, 0.0f }, + { Material.SporeBlossom, 0.0f }, + { Material.SpruceButton, 0.0f }, + { Material.SpruceLeaves, 0.0f }, + { Material.SpruceLog, 0.0f }, + { Material.SpruceSapling, 0.0f }, + { Material.StickyPiston, 0.0f }, + { Material.StoneBrickWall, 0.0f }, + { Material.StoneButton, 0.0f }, + { Material.StrippedAcaciaLog, 0.0f }, + { Material.StrippedBambooBlock, 0.0f }, + { Material.StrippedBirchLog, 0.0f }, + { Material.StrippedCherryLog, 0.0f }, + { Material.StrippedCrimsonStem, 0.0f }, + { Material.StrippedDarkOakLog, 0.0f }, + { Material.StrippedJungleLog, 0.0f }, + { Material.StrippedMangroveLog, 0.0f }, + { Material.StrippedMangroveWood, 0.0f }, + { Material.StrippedOakLog, 0.0f }, + { Material.StrippedPaleOakLog, 0.0f }, + { Material.StrippedSpruceLog, 0.0f }, + { Material.StrippedWarpedStem, 0.0f }, + { Material.StructureVoid, 0.0f }, + { Material.SugarCane, 0.0f }, + { Material.Sunflower, 0.0f }, + { Material.SweetBerryBush, 0.0f }, + { Material.TallDryGrass, 0.0f }, + { Material.TallGrass, 0.0f }, + { Material.TallSeagrass, 0.0f }, + { Material.TintedGlass, 0.0f }, + { Material.Tnt, 0.0f }, + { Material.Torch, 0.0f }, + { Material.Torchflower, 0.0f }, + { Material.TorchflowerCrop, 0.0f }, + { Material.Tripwire, 0.0f }, + { Material.TripwireHook, 0.0f }, + { Material.TubeCoral, 0.0f }, + { Material.TubeCoralFan, 0.0f }, + { Material.TubeCoralWallFan, 0.0f }, + { Material.TuffBrickSlab, 0.0f }, + { Material.TuffBrickStairs, 0.0f }, + { Material.TuffBrickWall, 0.0f }, + { Material.TuffBricks, 0.0f }, + { Material.TuffSlab, 0.0f }, + { Material.TuffStairs, 0.0f }, + { Material.TuffWall, 0.0f }, + { Material.TwistingVines, 0.0f }, + { Material.TwistingVinesPlant, 0.0f }, + { Material.VoidAir, 0.0f }, + { Material.WallTorch, 0.0f }, + { Material.WarpedButton, 0.0f }, + { Material.WarpedFungus, 0.0f }, + { Material.WarpedRoots, 0.0f }, + { Material.WarpedStem, 0.0f }, + { Material.WaterCauldron, 0.0f }, + { Material.WaxedChiseledCopper, 0.0f }, + { Material.WaxedCopperBlock, 0.0f }, + { Material.WaxedCopperBulb, 0.0f }, + { Material.WaxedCopperChest, 0.0f }, + { Material.WaxedCopperDoor, 0.0f }, + { Material.WaxedCopperGolemStatue, 0.0f }, + { Material.WaxedCopperGrate, 0.0f }, + { Material.WaxedCopperTrapdoor, 0.0f }, + { Material.WaxedCutCopper, 0.0f }, + { Material.WaxedCutCopperSlab, 0.0f }, + { Material.WaxedExposedChiseledCopper, 0.0f }, + { Material.WaxedExposedCopper, 0.0f }, + { Material.WaxedExposedCopperBulb, 0.0f }, + { Material.WaxedExposedCopperChest, 0.0f }, + { Material.WaxedExposedCopperDoor, 0.0f }, + { Material.WaxedExposedCopperGolemStatue, 0.0f }, + { Material.WaxedExposedCopperGrate, 0.0f }, + { Material.WaxedExposedCopperTrapdoor, 0.0f }, + { Material.WaxedExposedCutCopper, 0.0f }, + { Material.WaxedExposedCutCopperSlab, 0.0f }, + { Material.WaxedExposedLightningRod, 0.0f }, + { Material.WaxedLightningRod, 0.0f }, + { Material.WaxedOxidizedChiseledCopper, 0.0f }, + { Material.WaxedOxidizedCopper, 0.0f }, + { Material.WaxedOxidizedCopperBulb, 0.0f }, + { Material.WaxedOxidizedCopperChest, 0.0f }, + { Material.WaxedOxidizedCopperDoor, 0.0f }, + { Material.WaxedOxidizedCopperGolemStatue, 0.0f }, + { Material.WaxedOxidizedCopperGrate, 0.0f }, + { Material.WaxedOxidizedCopperTrapdoor, 0.0f }, + { Material.WaxedOxidizedCutCopper, 0.0f }, + { Material.WaxedOxidizedCutCopperSlab, 0.0f }, + { Material.WaxedOxidizedLightningRod, 0.0f }, + { Material.WaxedWeatheredChiseledCopper, 0.0f }, + { Material.WaxedWeatheredCopper, 0.0f }, + { Material.WaxedWeatheredCopperBulb, 0.0f }, + { Material.WaxedWeatheredCopperChest, 0.0f }, + { Material.WaxedWeatheredCopperDoor, 0.0f }, + { Material.WaxedWeatheredCopperGolemStatue, 0.0f }, + { Material.WaxedWeatheredCopperGrate, 0.0f }, + { Material.WaxedWeatheredCopperTrapdoor, 0.0f }, + { Material.WaxedWeatheredCutCopper, 0.0f }, + { Material.WaxedWeatheredCutCopperSlab, 0.0f }, + { Material.WaxedWeatheredLightningRod, 0.0f }, + { Material.WeatheredChiseledCopper, 0.0f }, + { Material.WeatheredCopper, 0.0f }, + { Material.WeatheredCopperBulb, 0.0f }, + { Material.WeatheredCopperChest, 0.0f }, + { Material.WeatheredCopperDoor, 0.0f }, + { Material.WeatheredCopperGolemStatue, 0.0f }, + { Material.WeatheredCopperGrate, 0.0f }, + { Material.WeatheredCopperTrapdoor, 0.0f }, + { Material.WeatheredCutCopper, 0.0f }, + { Material.WeatheredCutCopperSlab, 0.0f }, + { Material.WeatheredCutCopperStairs, 0.0f }, + { Material.WeatheredLightningRod, 0.0f }, + { Material.WeepingVines, 0.0f }, + { Material.WeepingVinesPlant, 0.0f }, + { Material.Wheat, 0.0f }, + { Material.WhiteCandle, 0.0f }, + { Material.WhiteCandleCake, 0.0f }, + { Material.WhiteShulkerBox, 0.0f }, + { Material.WhiteTulip, 0.0f }, + { Material.Wildflowers, 0.0f }, + { Material.WitherRose, 0.0f }, + { Material.YellowCandle, 0.0f }, + { Material.YellowCandleCake, 0.0f }, + { Material.YellowShulkerBox, 0.0f }, + // Hardness 0.1: 23 blocks + { Material.BigDripleaf, 0.1f }, + { Material.BigDripleafStem, 0.1f }, + { Material.BlackCarpet, 0.1f }, + { Material.BlueCarpet, 0.1f }, + { Material.BrownCarpet, 0.1f }, + { Material.CyanCarpet, 0.1f }, + { Material.GrayCarpet, 0.1f }, + { Material.GreenCarpet, 0.1f }, + { Material.LightBlueCarpet, 0.1f }, + { Material.LightGrayCarpet, 0.1f }, + { Material.LimeCarpet, 0.1f }, + { Material.MagentaCarpet, 0.1f }, + { Material.MossBlock, 0.1f }, + { Material.MossCarpet, 0.1f }, + { Material.OrangeCarpet, 0.1f }, + { Material.PaleMossBlock, 0.1f }, + { Material.PaleMossCarpet, 0.1f }, + { Material.PinkCarpet, 0.1f }, + { Material.PurpleCarpet, 0.1f }, + { Material.RedCarpet, 0.1f }, + { Material.Snow, 0.1f }, + { Material.WhiteCarpet, 0.1f }, + { Material.YellowCarpet, 0.1f }, + // Hardness 0.2: 12 blocks + { Material.BrownMushroomBlock, 0.2f }, + { Material.CherryLeaves, 0.2f }, + { Material.Cocoa, 0.2f }, + { Material.DaylightDetector, 0.2f }, + { Material.GlowLichen, 0.2f }, + { Material.MushroomStem, 0.2f }, + { Material.PaleOakLeaves, 0.2f }, + { Material.RedMushroomBlock, 0.2f }, + { Material.Sculk, 0.2f }, + { Material.SculkVein, 0.2f }, + { Material.SnowBlock, 0.2f }, + { Material.Vine, 0.2f }, + { Material.PowderSnow, 0.25f }, + { Material.SuspiciousGravel, 0.25f }, + { Material.SuspiciousSand, 0.25f }, + // Hardness 0.3: 24 blocks + { Material.BeeNest, 0.3f }, + { Material.BlackStainedGlassPane, 0.3f }, + { Material.BlueStainedGlassPane, 0.3f }, + { Material.BrownStainedGlassPane, 0.3f }, + { Material.CyanStainedGlassPane, 0.3f }, + { Material.Glass, 0.3f }, + { Material.Glowstone, 0.3f }, + { Material.GrayStainedGlassPane, 0.3f }, + { Material.GreenStainedGlassPane, 0.3f }, + { Material.LightBlueStainedGlassPane, 0.3f }, + { Material.LightGrayStainedGlassPane, 0.3f }, + { Material.LimeStainedGlassPane, 0.3f }, + { Material.MagentaStainedGlassPane, 0.3f }, + { Material.OchreFroglight, 0.3f }, + { Material.OrangeStainedGlassPane, 0.3f }, + { Material.PearlescentFroglight, 0.3f }, + { Material.PinkStainedGlassPane, 0.3f }, + { Material.PurpleStainedGlassPane, 0.3f }, + { Material.RedStainedGlassPane, 0.3f }, + { Material.RedstoneLamp, 0.3f }, + { Material.SeaLantern, 0.3f }, + { Material.VerdantFroglight, 0.3f }, + { Material.WhiteStainedGlassPane, 0.3f }, + { Material.YellowStainedGlassPane, 0.3f }, + { Material.Cactus, 0.4f }, + { Material.ChorusFlower, 0.4f }, + { Material.ChorusPlant, 0.4f }, + { Material.CrimsonNylium, 0.4f }, + { Material.Ladder, 0.4f }, + { Material.Netherrack, 0.4f }, + { Material.WarpedNylium, 0.4f }, + // Hardness 0.5: 52 blocks + { Material.AcaciaPressurePlate, 0.5f }, + { Material.BambooPressurePlate, 0.5f }, + { Material.BirchPressurePlate, 0.5f }, + { Material.BlackConcretePowder, 0.5f }, + { Material.BlueConcretePowder, 0.5f }, + { Material.BrewingStand, 0.5f }, + { Material.BrownConcretePowder, 0.5f }, + { Material.Cake, 0.5f }, + { Material.CherryPressurePlate, 0.5f }, + { Material.CoarseDirt, 0.5f }, + { Material.CrimsonPressurePlate, 0.5f }, + { Material.CyanConcretePowder, 0.5f }, + { Material.DarkOakPressurePlate, 0.5f }, + { Material.Dirt, 0.5f }, + { Material.DriedKelpBlock, 0.5f }, + { Material.FrostedIce, 0.5f }, + { Material.GrayConcretePowder, 0.5f }, + { Material.GreenConcretePowder, 0.5f }, + { Material.HayBlock, 0.5f }, + { Material.HeavyWeightedPressurePlate, 0.5f }, + { Material.Ice, 0.5f }, + { Material.JunglePressurePlate, 0.5f }, + { Material.Lever, 0.5f }, + { Material.LightBlueConcretePowder, 0.5f }, + { Material.LightGrayConcretePowder, 0.5f }, + { Material.LightWeightedPressurePlate, 0.5f }, + { Material.LimeConcretePowder, 0.5f }, + { Material.MagentaConcretePowder, 0.5f }, + { Material.MagmaBlock, 0.5f }, + { Material.MangrovePressurePlate, 0.5f }, + { Material.OakPressurePlate, 0.5f }, + { Material.OrangeConcretePowder, 0.5f }, + { Material.PackedIce, 0.5f }, + { Material.PaleOakPressurePlate, 0.5f }, + { Material.PinkConcretePowder, 0.5f }, + { Material.Podzol, 0.5f }, + { Material.PolishedBlackstonePressurePlate, 0.5f }, + { Material.PurpleConcretePowder, 0.5f }, + { Material.RedConcretePowder, 0.5f }, + { Material.RedSand, 0.5f }, + { Material.RootedDirt, 0.5f }, + { Material.Sand, 0.5f }, + { Material.SnifferEgg, 0.5f }, + { Material.SoulSand, 0.5f }, + { Material.SoulSoil, 0.5f }, + { Material.SprucePressurePlate, 0.5f }, + { Material.StonePressurePlate, 0.5f }, + { Material.Target, 0.5f }, + { Material.TurtleEgg, 0.5f }, + { Material.WarpedPressurePlate, 0.5f }, + { Material.WhiteConcretePowder, 0.5f }, + { Material.YellowConcretePowder, 0.5f }, + // Hardness 0.6: 10 blocks + { Material.Beehive, 0.6f }, + { Material.Clay, 0.6f }, + { Material.Composter, 0.6f }, + { Material.Farmland, 0.6f }, + { Material.GrassBlock, 0.6f }, + { Material.Gravel, 0.6f }, + { Material.HoneycombBlock, 0.6f }, + { Material.Mycelium, 0.6f }, + { Material.Sponge, 0.6f }, + { Material.WetSponge, 0.6f }, + { Material.DirtPath, 0.65f }, + { Material.ActivatorRail, 0.7f }, + { Material.DetectorRail, 0.7f }, + { Material.MangroveRoots, 0.7f }, + { Material.MuddyMangroveRoots, 0.7f }, + { Material.PoweredRail, 0.7f }, + { Material.Rail, 0.7f }, + { Material.Calcite, 0.75f }, + // Hardness 0.8: 26 blocks + { Material.BlackWool, 0.8f }, + { Material.BlueWool, 0.8f }, + { Material.BrownWool, 0.8f }, + { Material.ChiseledQuartzBlock, 0.8f }, + { Material.ChiseledRedSandstone, 0.8f }, + { Material.ChiseledSandstone, 0.8f }, + { Material.CutRedSandstone, 0.8f }, + { Material.CutSandstone, 0.8f }, + { Material.CyanWool, 0.8f }, + { Material.GrayWool, 0.8f }, + { Material.GreenWool, 0.8f }, + { Material.LightBlueWool, 0.8f }, + { Material.LightGrayWool, 0.8f }, + { Material.LimeWool, 0.8f }, + { Material.MagentaWool, 0.8f }, + { Material.NoteBlock, 0.8f }, + { Material.OrangeWool, 0.8f }, + { Material.PinkWool, 0.8f }, + { Material.PurpleWool, 0.8f }, + { Material.QuartzBlock, 0.8f }, + { Material.QuartzPillar, 0.8f }, + { Material.RedSandstone, 0.8f }, + { Material.RedWool, 0.8f }, + { Material.Sandstone, 0.8f }, + { Material.WhiteWool, 0.8f }, + { Material.YellowWool, 0.8f }, + // Hardness 1.0: 100 blocks + { Material.AcaciaHangingSign, 1.0f }, + { Material.AcaciaSign, 1.0f }, + { Material.AcaciaWallHangingSign, 1.0f }, + { Material.AcaciaWallSign, 1.0f }, + { Material.BambooHangingSign, 1.0f }, + { Material.BambooSign, 1.0f }, + { Material.BambooWallHangingSign, 1.0f }, + { Material.BambooWallSign, 1.0f }, + { Material.BirchHangingSign, 1.0f }, + { Material.BirchSign, 1.0f }, + { Material.BirchWallHangingSign, 1.0f }, + { Material.BirchWallSign, 1.0f }, + { Material.BlackBanner, 1.0f }, + { Material.BlackWallBanner, 1.0f }, + { Material.BlueBanner, 1.0f }, + { Material.BlueWallBanner, 1.0f }, + { Material.BrownBanner, 1.0f }, + { Material.BrownWallBanner, 1.0f }, + { Material.CarvedPumpkin, 1.0f }, + { Material.CherryHangingSign, 1.0f }, + { Material.CherrySign, 1.0f }, + { Material.CherryWallHangingSign, 1.0f }, + { Material.CherryWallSign, 1.0f }, + { Material.CreeperHead, 1.0f }, + { Material.CreeperWallHead, 1.0f }, + { Material.CrimsonHangingSign, 1.0f }, + { Material.CrimsonSign, 1.0f }, + { Material.CrimsonWallHangingSign, 1.0f }, + { Material.CrimsonWallSign, 1.0f }, + { Material.CyanBanner, 1.0f }, + { Material.CyanWallBanner, 1.0f }, + { Material.DarkOakHangingSign, 1.0f }, + { Material.DarkOakSign, 1.0f }, + { Material.DarkOakWallHangingSign, 1.0f }, + { Material.DarkOakWallSign, 1.0f }, + { Material.DragonHead, 1.0f }, + { Material.DragonWallHead, 1.0f }, + { Material.GrayBanner, 1.0f }, + { Material.GrayWallBanner, 1.0f }, + { Material.GreenBanner, 1.0f }, + { Material.GreenWallBanner, 1.0f }, + { Material.JackOLantern, 1.0f }, + { Material.JungleHangingSign, 1.0f }, + { Material.JungleSign, 1.0f }, + { Material.JungleWallHangingSign, 1.0f }, + { Material.JungleWallSign, 1.0f }, + { Material.LightBlueBanner, 1.0f }, + { Material.LightBlueWallBanner, 1.0f }, + { Material.LightGrayBanner, 1.0f }, + { Material.LightGrayWallBanner, 1.0f }, + { Material.LimeBanner, 1.0f }, + { Material.LimeWallBanner, 1.0f }, + { Material.MagentaBanner, 1.0f }, + { Material.MagentaWallBanner, 1.0f }, + { Material.MangroveHangingSign, 1.0f }, + { Material.MangroveSign, 1.0f }, + { Material.MangroveWallHangingSign, 1.0f }, + { Material.MangroveWallSign, 1.0f }, + { Material.NetherWartBlock, 1.0f }, + { Material.OakHangingSign, 1.0f }, + { Material.OakSign, 1.0f }, + { Material.OakWallHangingSign, 1.0f }, + { Material.OakWallSign, 1.0f }, + { Material.OrangeBanner, 1.0f }, + { Material.OrangeWallBanner, 1.0f }, + { Material.PackedMud, 1.0f }, + { Material.PaleOakHangingSign, 1.0f }, + { Material.PaleOakSign, 1.0f }, + { Material.PaleOakWallHangingSign, 1.0f }, + { Material.PaleOakWallSign, 1.0f }, + { Material.PiglinHead, 1.0f }, + { Material.PiglinWallHead, 1.0f }, + { Material.PinkBanner, 1.0f }, + { Material.PinkWallBanner, 1.0f }, + { Material.PlayerHead, 1.0f }, + { Material.PlayerWallHead, 1.0f }, + { Material.PurpleBanner, 1.0f }, + { Material.PurpleWallBanner, 1.0f }, + { Material.RedBanner, 1.0f }, + { Material.RedWallBanner, 1.0f }, + { Material.Shroomlight, 1.0f }, + { Material.SkeletonSkull, 1.0f }, + { Material.SkeletonWallSkull, 1.0f }, + { Material.SpruceHangingSign, 1.0f }, + { Material.SpruceSign, 1.0f }, + { Material.SpruceWallHangingSign, 1.0f }, + { Material.SpruceWallSign, 1.0f }, + { Material.WarpedHangingSign, 1.0f }, + { Material.WarpedSign, 1.0f }, + { Material.WarpedWallHangingSign, 1.0f }, + { Material.WarpedWallSign, 1.0f }, + { Material.WarpedWartBlock, 1.0f }, + { Material.WhiteBanner, 1.0f }, + { Material.WhiteWallBanner, 1.0f }, + { Material.WitherSkeletonSkull, 1.0f }, + { Material.WitherSkeletonWallSkull, 1.0f }, + { Material.YellowBanner, 1.0f }, + { Material.YellowWallBanner, 1.0f }, + { Material.ZombieHead, 1.0f }, + { Material.ZombieWallHead, 1.0f }, + // Hardness 1.25: 19 blocks + { Material.Basalt, 1.25f }, + { Material.BlackTerracotta, 1.25f }, + { Material.BlueTerracotta, 1.25f }, + { Material.BrownTerracotta, 1.25f }, + { Material.CyanTerracotta, 1.25f }, + { Material.GrayTerracotta, 1.25f }, + { Material.GreenTerracotta, 1.25f }, + { Material.LightBlueTerracotta, 1.25f }, + { Material.LightGrayTerracotta, 1.25f }, + { Material.LimeTerracotta, 1.25f }, + { Material.MagentaTerracotta, 1.25f }, + { Material.OrangeTerracotta, 1.25f }, + { Material.PinkTerracotta, 1.25f }, + { Material.PolishedBasalt, 1.25f }, + { Material.PurpleTerracotta, 1.25f }, + { Material.RedTerracotta, 1.25f }, + { Material.Terracotta, 1.25f }, + { Material.WhiteTerracotta, 1.25f }, + { Material.YellowTerracotta, 1.25f }, + // Hardness 1.4: 16 blocks + { Material.BlackGlazedTerracotta, 1.4f }, + { Material.BlueGlazedTerracotta, 1.4f }, + { Material.BrownGlazedTerracotta, 1.4f }, + { Material.CyanGlazedTerracotta, 1.4f }, + { Material.GrayGlazedTerracotta, 1.4f }, + { Material.GreenGlazedTerracotta, 1.4f }, + { Material.LightBlueGlazedTerracotta, 1.4f }, + { Material.LightGrayGlazedTerracotta, 1.4f }, + { Material.LimeGlazedTerracotta, 1.4f }, + { Material.MagentaGlazedTerracotta, 1.4f }, + { Material.OrangeGlazedTerracotta, 1.4f }, + { Material.PinkGlazedTerracotta, 1.4f }, + { Material.PurpleGlazedTerracotta, 1.4f }, + { Material.RedGlazedTerracotta, 1.4f }, + { Material.WhiteGlazedTerracotta, 1.4f }, + { Material.YellowGlazedTerracotta, 1.4f }, + // Hardness 1.5: 49 blocks + { Material.AmethystBlock, 1.5f }, + { Material.AmethystCluster, 1.5f }, + { Material.Andesite, 1.5f }, + { Material.Blackstone, 1.5f }, + { Material.Bookshelf, 1.5f }, + { Material.BrainCoralBlock, 1.5f }, + { Material.BubbleCoralBlock, 1.5f }, + { Material.BuddingAmethyst, 1.5f }, + { Material.ChiseledBookshelf, 1.5f }, + { Material.ChiseledPolishedBlackstone, 1.5f }, + { Material.ChiseledResinBricks, 1.5f }, + { Material.ChiseledStoneBricks, 1.5f }, + { Material.CrackedStoneBricks, 1.5f }, + { Material.Crafter, 1.5f }, + { Material.DarkPrismarine, 1.5f }, + { Material.DarkPrismarineSlab, 1.5f }, + { Material.DeadBrainCoralBlock, 1.5f }, + { Material.DeadBubbleCoralBlock, 1.5f }, + { Material.DeadFireCoralBlock, 1.5f }, + { Material.DeadHornCoralBlock, 1.5f }, + { Material.DeadTubeCoralBlock, 1.5f }, + { Material.Diorite, 1.5f }, + { Material.DripstoneBlock, 1.5f }, + { Material.FireCoralBlock, 1.5f }, + { Material.Granite, 1.5f }, + { Material.HornCoralBlock, 1.5f }, + { Material.MossyStoneBricks, 1.5f }, + { Material.MudBrickSlab, 1.5f }, + { Material.MudBricks, 1.5f }, + { Material.PistonHead, 1.5f }, + { Material.PointedDripstone, 1.5f }, + { Material.PolishedAndesite, 1.5f }, + { Material.PolishedBlackstoneBricks, 1.5f }, + { Material.PolishedDiorite, 1.5f }, + { Material.PolishedGranite, 1.5f }, + { Material.Prismarine, 1.5f }, + { Material.PrismarineBrickSlab, 1.5f }, + { Material.PrismarineBricks, 1.5f }, + { Material.PrismarineSlab, 1.5f }, + { Material.PurpurBlock, 1.5f }, + { Material.PurpurPillar, 1.5f }, + { Material.ResinBrickSlab, 1.5f }, + { Material.ResinBrickWall, 1.5f }, + { Material.ResinBricks, 1.5f }, + { Material.SculkSensor, 1.5f }, + { Material.Stone, 1.5f }, + { Material.StoneBricks, 1.5f }, + { Material.TubeCoralBlock, 1.5f }, + { Material.Tuff, 1.5f }, + // Hardness 1.8: 16 blocks + { Material.BlackConcrete, 1.8f }, + { Material.BlueConcrete, 1.8f }, + { Material.BrownConcrete, 1.8f }, + { Material.CyanConcrete, 1.8f }, + { Material.GrayConcrete, 1.8f }, + { Material.GreenConcrete, 1.8f }, + { Material.LightBlueConcrete, 1.8f }, + { Material.LightGrayConcrete, 1.8f }, + { Material.LimeConcrete, 1.8f }, + { Material.MagentaConcrete, 1.8f }, + { Material.OrangeConcrete, 1.8f }, + { Material.PinkConcrete, 1.8f }, + { Material.PurpleConcrete, 1.8f }, + { Material.RedConcrete, 1.8f }, + { Material.WhiteConcrete, 1.8f }, + { Material.YellowConcrete, 1.8f }, + // Hardness 2.0: 117 blocks + { Material.AcaciaFence, 2.0f }, + { Material.AcaciaFenceGate, 2.0f }, + { Material.AcaciaPlanks, 2.0f }, + { Material.AcaciaShelf, 2.0f }, + { Material.AcaciaSlab, 2.0f }, + { Material.AcaciaWood, 2.0f }, + { Material.BambooFence, 2.0f }, + { Material.BambooFenceGate, 2.0f }, + { Material.BambooMosaic, 2.0f }, + { Material.BambooMosaicSlab, 2.0f }, + { Material.BambooPlanks, 2.0f }, + { Material.BambooShelf, 2.0f }, + { Material.BambooSlab, 2.0f }, + { Material.BirchFence, 2.0f }, + { Material.BirchFenceGate, 2.0f }, + { Material.BirchPlanks, 2.0f }, + { Material.BirchShelf, 2.0f }, + { Material.BirchSlab, 2.0f }, + { Material.BirchWood, 2.0f }, + { Material.BlackstoneSlab, 2.0f }, + { Material.BoneBlock, 2.0f }, + { Material.BrickSlab, 2.0f }, + { Material.Bricks, 2.0f }, + { Material.Campfire, 2.0f }, + { Material.Cauldron, 2.0f }, + { Material.CherryFence, 2.0f }, + { Material.CherryFenceGate, 2.0f }, + { Material.CherryPlanks, 2.0f }, + { Material.CherryShelf, 2.0f }, + { Material.CherrySlab, 2.0f }, + { Material.CherryWood, 2.0f }, + { Material.ChiseledNetherBricks, 2.0f }, + { Material.Cobblestone, 2.0f }, + { Material.CobblestoneSlab, 2.0f }, + { Material.CrackedNetherBricks, 2.0f }, + { Material.CrimsonFence, 2.0f }, + { Material.CrimsonFenceGate, 2.0f }, + { Material.CrimsonHyphae, 2.0f }, + { Material.CrimsonPlanks, 2.0f }, + { Material.CrimsonShelf, 2.0f }, + { Material.CrimsonSlab, 2.0f }, + { Material.CutRedSandstoneSlab, 2.0f }, + { Material.CutSandstoneSlab, 2.0f }, + { Material.DarkOakFence, 2.0f }, + { Material.DarkOakFenceGate, 2.0f }, + { Material.DarkOakPlanks, 2.0f }, + { Material.DarkOakShelf, 2.0f }, + { Material.DarkOakSlab, 2.0f }, + { Material.DarkOakWood, 2.0f }, + { Material.Grindstone, 2.0f }, + { Material.Jukebox, 2.0f }, + { Material.JungleFence, 2.0f }, + { Material.JungleFenceGate, 2.0f }, + { Material.JunglePlanks, 2.0f }, + { Material.JungleShelf, 2.0f }, + { Material.JungleSlab, 2.0f }, + { Material.JungleWood, 2.0f }, + { Material.MangroveFence, 2.0f }, + { Material.MangroveFenceGate, 2.0f }, + { Material.MangrovePlanks, 2.0f }, + { Material.MangroveShelf, 2.0f }, + { Material.MangroveSlab, 2.0f }, + { Material.MangroveWood, 2.0f }, + { Material.MossyCobblestone, 2.0f }, + { Material.NetherBrickFence, 2.0f }, + { Material.NetherBrickSlab, 2.0f }, + { Material.NetherBricks, 2.0f }, + { Material.OakFence, 2.0f }, + { Material.OakFenceGate, 2.0f }, + { Material.OakPlanks, 2.0f }, + { Material.OakShelf, 2.0f }, + { Material.OakSlab, 2.0f }, + { Material.OakWood, 2.0f }, + { Material.PaleOakFence, 2.0f }, + { Material.PaleOakFenceGate, 2.0f }, + { Material.PaleOakPlanks, 2.0f }, + { Material.PaleOakShelf, 2.0f }, + { Material.PaleOakSlab, 2.0f }, + { Material.PaleOakWood, 2.0f }, + { Material.PetrifiedOakSlab, 2.0f }, + { Material.PolishedBlackstone, 2.0f }, + { Material.PolishedBlackstoneBrickSlab, 2.0f }, + { Material.PurpurSlab, 2.0f }, + { Material.QuartzSlab, 2.0f }, + { Material.RedNetherBricks, 2.0f }, + { Material.RedSandstoneSlab, 2.0f }, + { Material.SandstoneSlab, 2.0f }, + { Material.SmoothQuartz, 2.0f }, + { Material.SmoothRedSandstone, 2.0f }, + { Material.SmoothSandstone, 2.0f }, + { Material.SmoothStone, 2.0f }, + { Material.SmoothStoneSlab, 2.0f }, + { Material.SoulCampfire, 2.0f }, + { Material.SpruceFence, 2.0f }, + { Material.SpruceFenceGate, 2.0f }, + { Material.SprucePlanks, 2.0f }, + { Material.SpruceShelf, 2.0f }, + { Material.SpruceSlab, 2.0f }, + { Material.SpruceWood, 2.0f }, + { Material.StoneBrickSlab, 2.0f }, + { Material.StoneSlab, 2.0f }, + { Material.StrippedAcaciaWood, 2.0f }, + { Material.StrippedBirchWood, 2.0f }, + { Material.StrippedCherryWood, 2.0f }, + { Material.StrippedCrimsonHyphae, 2.0f }, + { Material.StrippedDarkOakWood, 2.0f }, + { Material.StrippedJungleWood, 2.0f }, + { Material.StrippedOakWood, 2.0f }, + { Material.StrippedPaleOakWood, 2.0f }, + { Material.StrippedSpruceWood, 2.0f }, + { Material.StrippedWarpedHyphae, 2.0f }, + { Material.WarpedFence, 2.0f }, + { Material.WarpedFenceGate, 2.0f }, + { Material.WarpedHyphae, 2.0f }, + { Material.WarpedPlanks, 2.0f }, + { Material.WarpedShelf, 2.0f }, + { Material.WarpedSlab, 2.0f }, + // Hardness 2.5: 9 blocks + { Material.Barrel, 2.5f }, + { Material.CartographyTable, 2.5f }, + { Material.Chest, 2.5f }, + { Material.CraftingTable, 2.5f }, + { Material.FletchingTable, 2.5f }, + { Material.Lectern, 2.5f }, + { Material.Loom, 2.5f }, + { Material.SmithingTable, 2.5f }, + { Material.TrappedChest, 2.5f }, + { Material.BlueIce, 2.8f }, + // Hardness 3.0: 53 blocks + { Material.AcaciaDoor, 3.0f }, + { Material.AcaciaTrapdoor, 3.0f }, + { Material.BambooDoor, 3.0f }, + { Material.BambooTrapdoor, 3.0f }, + { Material.Beacon, 3.0f }, + { Material.BirchDoor, 3.0f }, + { Material.BirchTrapdoor, 3.0f }, + { Material.CherryDoor, 3.0f }, + { Material.CherryTrapdoor, 3.0f }, + { Material.CoalOre, 3.0f }, + { Material.Conduit, 3.0f }, + { Material.CopperBlock, 3.0f }, + { Material.CopperBulb, 3.0f }, + { Material.CopperChest, 3.0f }, + { Material.CopperDoor, 3.0f }, + { Material.CopperGolemStatue, 3.0f }, + { Material.CopperGrate, 3.0f }, + { Material.CopperTrapdoor, 3.0f }, + { Material.CrimsonDoor, 3.0f }, + { Material.CrimsonTrapdoor, 3.0f }, + { Material.DarkOakDoor, 3.0f }, + { Material.DarkOakTrapdoor, 3.0f }, + { Material.Deepslate, 3.0f }, + { Material.DiamondOre, 3.0f }, + { Material.DragonEgg, 3.0f }, + { Material.EmeraldOre, 3.0f }, + { Material.EndStone, 3.0f }, + { Material.EndStoneBricks, 3.0f }, + { Material.GoldBlock, 3.0f }, + { Material.GoldOre, 3.0f }, + { Material.Hopper, 3.0f }, + { Material.IronOre, 3.0f }, + { Material.JungleDoor, 3.0f }, + { Material.JungleTrapdoor, 3.0f }, + { Material.LapisBlock, 3.0f }, + { Material.LapisOre, 3.0f }, + { Material.LightningRod, 3.0f }, + { Material.MangroveDoor, 3.0f }, + { Material.MangroveTrapdoor, 3.0f }, + { Material.NetherGoldOre, 3.0f }, + { Material.NetherQuartzOre, 3.0f }, + { Material.OakDoor, 3.0f }, + { Material.OakTrapdoor, 3.0f }, + { Material.Observer, 3.0f }, + { Material.PaleOakDoor, 3.0f }, + { Material.PaleOakTrapdoor, 3.0f }, + { Material.RedstoneOre, 3.0f }, + { Material.SculkCatalyst, 3.0f }, + { Material.SculkShrieker, 3.0f }, + { Material.SpruceDoor, 3.0f }, + { Material.SpruceTrapdoor, 3.0f }, + { Material.WarpedDoor, 3.0f }, + { Material.WarpedTrapdoor, 3.0f }, + // Hardness 3.5: 10 blocks + { Material.BlastFurnace, 3.5f }, + { Material.CobbledDeepslate, 3.5f }, + { Material.Dispenser, 3.5f }, + { Material.Dropper, 3.5f }, + { Material.Furnace, 3.5f }, + { Material.Lantern, 3.5f }, + { Material.Lodestone, 3.5f }, + { Material.Smoker, 3.5f }, + { Material.SoulLantern, 3.5f }, + { Material.Stonecutter, 3.5f }, + { Material.Cobweb, 4.0f }, + { Material.DeepslateCoalOre, 4.5f }, + { Material.DeepslateCopperOre, 4.5f }, + { Material.DeepslateDiamondOre, 4.5f }, + { Material.DeepslateEmeraldOre, 4.5f }, + { Material.DeepslateGoldOre, 4.5f }, + { Material.DeepslateIronOre, 4.5f }, + { Material.DeepslateLapisOre, 4.5f }, + { Material.DeepslateRedstoneOre, 4.5f }, + // Hardness 5.0: 18 blocks + { Material.Anvil, 5.0f }, + { Material.Bell, 5.0f }, + { Material.ChippedAnvil, 5.0f }, + { Material.CoalBlock, 5.0f }, + { Material.DamagedAnvil, 5.0f }, + { Material.DiamondBlock, 5.0f }, + { Material.EmeraldBlock, 5.0f }, + { Material.EnchantingTable, 5.0f }, + { Material.IronBars, 5.0f }, + { Material.IronBlock, 5.0f }, + { Material.IronChain, 5.0f }, + { Material.IronDoor, 5.0f }, + { Material.IronTrapdoor, 5.0f }, + { Material.RawCopperBlock, 5.0f }, + { Material.RawGoldBlock, 5.0f }, + { Material.RawIronBlock, 5.0f }, + { Material.RedstoneBlock, 5.0f }, + { Material.Spawner, 5.0f }, + { Material.CreakingHeart, 10.0f }, + { Material.HeavyCore, 10.0f }, + { Material.EnderChest, 22.5f }, + { Material.AncientDebris, 30.0f }, + { Material.CryingObsidian, 50.0f }, + { Material.NetheriteBlock, 50.0f }, + { Material.Obsidian, 50.0f }, + { Material.RespawnAnchor, 50.0f }, + { Material.TrialSpawner, 50.0f }, + { Material.Vault, 50.0f }, + { Material.ReinforcedDeepslate, 55.0f }, + { Material.Lava, 100.0f }, + { Material.Water, 100.0f }, + }.ToFrozenDictionary(); + + private static readonly FrozenSet RequiresCorrectToolSet = new HashSet + { + Material.AmethystBlock, + Material.AncientDebris, + Material.Andesite, + Material.Anvil, + Material.Basalt, + Material.BlackConcrete, + Material.BlackGlazedTerracotta, + Material.BlackTerracotta, + Material.Blackstone, + Material.BlastFurnace, + Material.BlueConcrete, + Material.BlueGlazedTerracotta, + Material.BlueTerracotta, + Material.BoneBlock, + Material.BrainCoralBlock, + Material.BrickSlab, + Material.Bricks, + Material.BrownConcrete, + Material.BrownGlazedTerracotta, + Material.BrownTerracotta, + Material.BubbleCoralBlock, + Material.BuddingAmethyst, + Material.Calcite, + Material.Cauldron, + Material.ChainCommandBlock, + Material.ChippedAnvil, + Material.ChiseledNetherBricks, + Material.ChiseledQuartzBlock, + Material.ChiseledRedSandstone, + Material.ChiseledResinBricks, + Material.ChiseledSandstone, + Material.ChiseledStoneBricks, + Material.CoalBlock, + Material.CoalOre, + Material.Cobblestone, + Material.CobblestoneSlab, + Material.Cobweb, + Material.CommandBlock, + Material.CopperBlock, + Material.CopperBulb, + Material.CopperChest, + Material.CopperGrate, + Material.CopperTrapdoor, + Material.CrackedNetherBricks, + Material.CrackedStoneBricks, + Material.CrimsonNylium, + Material.CryingObsidian, + Material.CutRedSandstone, + Material.CutRedSandstoneSlab, + Material.CutSandstone, + Material.CutSandstoneSlab, + Material.CyanConcrete, + Material.CyanGlazedTerracotta, + Material.CyanTerracotta, + Material.DamagedAnvil, + Material.DarkPrismarine, + Material.DarkPrismarineSlab, + Material.DeadBrainCoral, + Material.DeadBrainCoralBlock, + Material.DeadBrainCoralFan, + Material.DeadBrainCoralWallFan, + Material.DeadBubbleCoral, + Material.DeadBubbleCoralBlock, + Material.DeadBubbleCoralFan, + Material.DeadBubbleCoralWallFan, + Material.DeadFireCoral, + Material.DeadFireCoralBlock, + Material.DeadFireCoralFan, + Material.DeadFireCoralWallFan, + Material.DeadHornCoral, + Material.DeadHornCoralBlock, + Material.DeadHornCoralFan, + Material.DeadHornCoralWallFan, + Material.DeadTubeCoral, + Material.DeadTubeCoralBlock, + Material.DeadTubeCoralFan, + Material.DeadTubeCoralWallFan, + Material.Deepslate, + Material.DiamondBlock, + Material.DiamondOre, + Material.Diorite, + Material.Dispenser, + Material.DripstoneBlock, + Material.Dropper, + Material.EmeraldBlock, + Material.EmeraldOre, + Material.EnchantingTable, + Material.EndStone, + Material.EndStoneBricks, + Material.FireCoralBlock, + Material.Furnace, + Material.GoldBlock, + Material.GoldOre, + Material.Granite, + Material.GrayConcrete, + Material.GrayGlazedTerracotta, + Material.GrayTerracotta, + Material.GreenConcrete, + Material.GreenGlazedTerracotta, + Material.GreenTerracotta, + Material.Grindstone, + Material.Hopper, + Material.HornCoralBlock, + Material.IronBars, + Material.IronBlock, + Material.IronChain, + Material.IronOre, + Material.IronTrapdoor, + Material.Jigsaw, + Material.LapisBlock, + Material.LapisOre, + Material.LightBlueConcrete, + Material.LightBlueGlazedTerracotta, + Material.LightBlueTerracotta, + Material.LightGrayConcrete, + Material.LightGrayGlazedTerracotta, + Material.LightGrayTerracotta, + Material.LightningRod, + Material.LimeConcrete, + Material.LimeGlazedTerracotta, + Material.LimeTerracotta, + Material.Lodestone, + Material.MagentaConcrete, + Material.MagentaGlazedTerracotta, + Material.MagentaTerracotta, + Material.MagmaBlock, + Material.MossyCobblestone, + Material.MossyStoneBricks, + Material.MudBrickSlab, + Material.MudBricks, + Material.NetherBrickFence, + Material.NetherBrickSlab, + Material.NetherBricks, + Material.NetherGoldOre, + Material.NetherQuartzOre, + Material.NetheriteBlock, + Material.Netherrack, + Material.Observer, + Material.Obsidian, + Material.OrangeConcrete, + Material.OrangeGlazedTerracotta, + Material.OrangeTerracotta, + Material.PetrifiedOakSlab, + Material.PinkConcrete, + Material.PinkGlazedTerracotta, + Material.PinkTerracotta, + Material.PolishedAndesite, + Material.PolishedBasalt, + Material.PolishedDiorite, + Material.PolishedGranite, + Material.Prismarine, + Material.PrismarineBrickSlab, + Material.PrismarineBricks, + Material.PrismarineSlab, + Material.PurpleConcrete, + Material.PurpleGlazedTerracotta, + Material.PurpleTerracotta, + Material.PurpurBlock, + Material.PurpurPillar, + Material.PurpurSlab, + Material.QuartzBlock, + Material.QuartzPillar, + Material.QuartzSlab, + Material.RawCopperBlock, + Material.RawGoldBlock, + Material.RawIronBlock, + Material.RedConcrete, + Material.RedGlazedTerracotta, + Material.RedNetherBricks, + Material.RedSandstone, + Material.RedSandstoneSlab, + Material.RedTerracotta, + Material.RedstoneBlock, + Material.RedstoneOre, + Material.RepeatingCommandBlock, + Material.ResinBrickSlab, + Material.ResinBrickWall, + Material.ResinBricks, + Material.RespawnAnchor, + Material.Sandstone, + Material.SandstoneSlab, + Material.Smoker, + Material.SmoothQuartz, + Material.SmoothRedSandstone, + Material.SmoothSandstone, + Material.SmoothStone, + Material.SmoothStoneSlab, + Material.Snow, + Material.SnowBlock, + Material.Spawner, + Material.Stone, + Material.StoneBrickSlab, + Material.StoneBricks, + Material.StoneSlab, + Material.Stonecutter, + Material.StructureBlock, + Material.Terracotta, + Material.TubeCoralBlock, + Material.Tuff, + Material.WarpedNylium, + Material.WaxedCutCopperSlab, + Material.WaxedExposedCutCopperSlab, + Material.WaxedOxidizedCutCopperSlab, + Material.WaxedWeatheredCutCopperSlab, + Material.WhiteConcrete, + Material.WhiteGlazedTerracotta, + Material.WhiteTerracotta, + Material.YellowConcrete, + Material.YellowGlazedTerracotta, + Material.YellowTerracotta, + }.ToFrozenSet(); + } +} diff --git a/MinecraftClient/Mapping/MiningCalculator.cs b/MinecraftClient/Mapping/MiningCalculator.cs new file mode 100644 index 00000000..38cf6d18 --- /dev/null +++ b/MinecraftClient/Mapping/MiningCalculator.cs @@ -0,0 +1,493 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MinecraftClient.Inventory; +using MinecraftClient.Protocol.Handlers; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; + +namespace MinecraftClient.Mapping +{ + /// + /// Computes dig duration in ticks for survival-style block breaking. + /// Version-aware across 1.8-1.21.11+, using tool speed, enchantments, effects, and attributes. + /// + public static class MiningCalculator + { + /// + /// Compute the number of ticks required to break a block in survival mode. + /// Returns 0 for instant-break blocks, -1 for unbreakable blocks. + /// + /// The block material to break + /// The item in the player's main hand (null for empty hand) + /// The item in the player's helmet slot (null if empty, used for Aqua Affinity) + /// Currently active player effects + /// Cached player attribute values (from OnEntityProperties) + /// Whether the player's eyes are submerged in water + /// Whether the player is on the ground + /// The Minecraft protocol version + /// Ticks to break the block, 0 for instant, -1 for unbreakable + public static int ComputeDigTicks( + Material blockMaterial, + Item? heldItem, + Item? helmetItem, + Dictionary effects, + Dictionary playerAttributes, + bool isUnderwater, + bool isOnGround, + int protocolVersion) + { + float hardness = BlockHardness.GetHardness(blockMaterial); + + if (hardness < 0) + return -1; // Unbreakable + + if (hardness == 0) + return 0; // Instant break + + float destroySpeed = GetDestroySpeed( + blockMaterial, heldItem, helmetItem, effects, playerAttributes, + isUnderwater, isOnGround, protocolVersion); + + bool correctTool = HasCorrectToolForDrops(blockMaterial, heldItem, protocolVersion); + int divisor = correctTool ? 30 : 100; + + float destroyProgress = destroySpeed / hardness / divisor; + + if (destroyProgress >= 1.0f) + return 0; // Instant break + + return (int)MathF.Ceiling(1.0f / destroyProgress); + } + + /// + /// Compute the player's destroy speed for a given block, following vanilla formulas. + /// + private static float GetDestroySpeed( + Material blockMaterial, + Item? heldItem, + Item? helmetItem, + Dictionary effects, + Dictionary playerAttributes, + bool isUnderwater, + bool isOnGround, + int protocolVersion) + { + float speed = GetToolSpeed(blockMaterial, heldItem, protocolVersion); + + if (protocolVersion >= Protocol18Handler.MC_1_21_11_Version) + { + // 1.21.11+: Efficiency is delivered via the MINING_EFFICIENCY attribute + if (speed > 1.0f && playerAttributes.TryGetValue("player.mining_efficiency", out double miningEff)) + speed += (float)miningEff; + } + else + { + // Pre-1.21.11: Efficiency enchantment adds level^2 + 1 + int effLevel = GetEnchantmentLevel(heldItem, Enchantments.Efficiency, protocolVersion); + if (speed > 1.0f && effLevel > 0) + speed += effLevel * effLevel + 1; + } + + // Haste effect: multiply by 1 + 0.2 * (amplifier + 1) + if (effects.TryGetValue(Effects.Haste, out var hasteData)) + speed *= 1.0f + (hasteData.Amplifier + 1) * 0.2f; + + // Conduit Power also grants dig speed equivalent when in water + if (effects.TryGetValue(Effects.ConduitPower, out var conduitData)) + speed *= 1.0f + (conduitData.Amplifier + 1) * 0.2f; + + // Mining Fatigue + if (effects.TryGetValue(Effects.MiningFatigue, out var fatigueData)) + { + float multiplier = fatigueData.Amplifier switch + { + 0 => 0.3f, + 1 => 0.09f, + 2 => 0.0027f, + _ => 8.1E-4f + }; + speed *= multiplier; + } + + // Attribute multipliers for modern versions + if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version) + { + // BLOCK_BREAK_SPEED attribute (default 1.0) + if (playerAttributes.TryGetValue("player.block_break_speed", out double bbs)) + speed *= (float)bbs; + } + + // Underwater penalty + if (isUnderwater) + { + if (protocolVersion >= Protocol18Handler.MC_1_21_11_Version) + { + // 1.21.11+: Uses SUBMERGED_MINING_SPEED attribute (default 0.2) + double submergedSpeed = 0.2; + if (playerAttributes.TryGetValue("player.submerged_mining_speed", out double sms)) + submergedSpeed = sms; + speed *= (float)submergedSpeed; + } + else + { + // Pre-1.21.11: /5 unless Aqua Affinity + bool hasAquaAffinity = GetEnchantmentLevel(helmetItem, Enchantments.AquaAffinity, protocolVersion) > 0; + if (!hasAquaAffinity) + speed /= 5.0f; + } + } + + // Airborne penalty + if (!isOnGround) + speed /= 5.0f; + + return speed; + } + + /// + /// Get the base tool mining speed for a block. + /// For 1.20.6+ with ToolComponent, uses structured component data. + /// For older versions, uses hardcoded tool speed tables. + /// + private static float GetToolSpeed(Material blockMaterial, Item? heldItem, int protocolVersion) + { + if (heldItem is null) + return 1.0f; + + // Modern path: use ToolComponent from structured components + if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version) + { + var toolComp = heldItem.Components?.OfType().FirstOrDefault(); + if (toolComp is not null) + { + // Check rules for matching blocks + foreach (var rule in toolComp.Rules) + { + if (rule.HasSpeed && MatchesBlockSet(rule.Blocks, blockMaterial)) + return rule.Speed; + } + return toolComp.DefaultMiningSpeed; + } + } + + // Legacy path: hardcoded tool speed tables + return GetLegacyToolSpeed(heldItem.Type, blockMaterial); + } + + /// + /// Check whether the tool provides correct drops for a block. + /// + private static bool HasCorrectToolForDrops(Material blockMaterial, Item? heldItem, int protocolVersion) + { + if (!BlockHardness.RequiresCorrectTool(blockMaterial)) + return true; + + if (heldItem is null) + return false; + + // Modern path: check ToolComponent rules + if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version) + { + var toolComp = heldItem.Components?.OfType().FirstOrDefault(); + if (toolComp is not null) + { + foreach (var rule in toolComp.Rules) + { + if (rule.HasCorrectDropForBlocks && rule.CorrectDropForBlocks + && MatchesBlockSet(rule.Blocks, blockMaterial)) + return true; + } + } + return false; + } + + // Legacy path: check if Material2Tool recommends this tool type + return IsCorrectToolLegacy(heldItem.Type, blockMaterial); + } + + /// + /// Match a block material against a ToolComponent BlockSetSubcomponent. + /// + private static bool MatchesBlockSet( + Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6.BlockSetSubcomponent blockSet, + Material blockMaterial) + { + if (blockSet.BlockIds is not null) + { + // Check against explicit block state IDs + foreach (int blockId in blockSet.BlockIds) + { + if (Block.Palette.FromId(blockId) == blockMaterial) + return true; + } + } + + if (blockSet.TagName is not null) + { + // Match against tag name (e.g., "minecraft:mineable/pickaxe") + return MatchesBlockTag(blockSet.TagName, blockMaterial); + } + + return false; + } + + /// + /// Approximate block tag matching using Material2Tool categories. + /// Tags like "minecraft:mineable/pickaxe" map to the appropriate tool categories. + /// + private static bool MatchesBlockTag(string tagName, Material blockMaterial) + { + // Normalize tag name + string tag = tagName.Replace("minecraft:", ""); + + ItemType[] tools = Material2Tool.GetCorrectToolForBlock(blockMaterial); + if (tools.Length == 0) + return false; + + ItemType firstTool = tools[0]; + return tag switch + { + "mineable/pickaxe" => IsPickaxe(firstTool), + "mineable/axe" => IsAxe(firstTool), + "mineable/shovel" => IsShovel(firstTool), + "mineable/hoe" => IsHoe(firstTool), + _ => false + }; + } + + /// + /// Get the enchantment level from an item, supporting both legacy NBT and modern structured components. + /// + public static int GetEnchantmentLevel(Item? item, Enchantments enchantment, int protocolVersion) + { + if (item is null) + return 0; + + // Modern path: structured components (1.20.6+) + var enchList = item.EnchantmentList; + if (enchList is not null) + { + var ench = enchList.FirstOrDefault(e => e.Type == enchantment); + if (ench is not null) + return ench.Level; + } + + // Legacy path: NBT data + if (item.NBT is not null && + item.NBT.TryGetValue("Enchantments", out object? enchantments)) + { + try + { + string enchNameLower = GetEnchantmentResourceName(enchantment); + foreach (Dictionary enchEntry in (object[])enchantments) + { + string id = ((string)enchEntry["id"]).ToLowerInvariant(); + if (id == enchNameLower || id == "minecraft:" + enchNameLower) + return (short)enchEntry["lvl"]; + } + } + catch + { + // NBT parsing failure - return 0 + } + } + + return 0; + } + + /// + /// Map Enchantments enum to Minecraft resource name (e.g., "efficiency"). + /// + private static string GetEnchantmentResourceName(Enchantments enchantment) + { + return enchantment switch + { + Enchantments.AquaAffinity => "aqua_affinity", + Enchantments.BaneOfArthropods => "bane_of_arthropods", + Enchantments.BlastProtection => "blast_protection", + Enchantments.Efficiency => "efficiency", + Enchantments.FeatherFalling => "feather_falling", + Enchantments.FireAspect => "fire_aspect", + Enchantments.FireProtection => "fire_protection", + Enchantments.FrostWalker => "frost_walker", + Enchantments.LuckOfTheSea => "luck_of_the_sea", + Enchantments.ProjectileProtection => "projectile_protection", + Enchantments.QuickCharge => "quick_charge", + Enchantments.SilkTouch => "silk_touch", + Enchantments.SoulSpeed => "soul_speed", + Enchantments.SwiftSneak => "swift_sneak", + Enchantments.VanishingCurse => "vanishing_curse", + Enchantments.BindingCurse => "binding_curse", + Enchantments.WindBurst => "wind_burst", + _ => enchantment.ToString().ToUnderscoreCase() + }; + } + + #region Legacy Tool Speed Tables + + /// + /// Legacy tool speed for pre-1.20.6 versions using hardcoded values. + /// + private static float GetLegacyToolSpeed(ItemType toolType, Material blockMaterial) + { + ItemType[] recommended = Material2Tool.GetCorrectToolForBlock(blockMaterial); + if (recommended.Length == 0) + return 1.0f; + + // Check if the held tool matches the recommended tool category + ToolCategory heldCategory = GetToolCategory(toolType); + ToolCategory neededCategory = GetToolCategory(recommended[0]); + + if (heldCategory == ToolCategory.None || heldCategory != neededCategory) + { + // Special cases: sword on cobweb, shears on specific blocks + if (toolType is ItemType.Shears && IsShearable(blockMaterial)) + return 1.5f; + if (IsSword(toolType) && blockMaterial == Material.Cobweb) + return 15.0f; + return 1.0f; + } + + return GetBaseToolSpeed(toolType); + } + + private static float GetBaseToolSpeed(ItemType toolType) + { + return toolType switch + { + // Wooden tools + ItemType.WoodenPickaxe or ItemType.WoodenAxe or ItemType.WoodenShovel or + ItemType.WoodenSword or ItemType.WoodenHoe => 2.0f, + + // Stone tools + ItemType.StonePickaxe or ItemType.StoneAxe or ItemType.StoneShovel or + ItemType.StoneSword or ItemType.StoneHoe => 4.0f, + + // Iron tools + ItemType.IronPickaxe or ItemType.IronAxe or ItemType.IronShovel or + ItemType.IronSword or ItemType.IronHoe => 6.0f, + + // Diamond tools + ItemType.DiamondPickaxe or ItemType.DiamondAxe or ItemType.DiamondShovel or + ItemType.DiamondSword or ItemType.DiamondHoe => 8.0f, + + // Netherite tools + ItemType.NetheritePickaxe or ItemType.NetheriteAxe or ItemType.NetheriteShovel or + ItemType.NetheriteSword or ItemType.NetheriteHoe => 9.0f, + + // Golden tools + ItemType.GoldenPickaxe or ItemType.GoldenAxe or ItemType.GoldenShovel or + ItemType.GoldenSword or ItemType.GoldenHoe => 12.0f, + + // Shears + ItemType.Shears => 2.0f, + + _ => 1.0f + }; + } + + /// + /// Check if the held tool is the correct tool for drops in legacy versions. + /// Uses Material2Tool's recommendations to determine correctness. + /// + private static bool IsCorrectToolLegacy(ItemType toolType, Material blockMaterial) + { + ItemType[] recommended = Material2Tool.GetCorrectToolForBlock(blockMaterial); + if (recommended.Length == 0) + return false; + + ToolCategory heldCategory = GetToolCategory(toolType); + ToolCategory neededCategory = GetToolCategory(recommended[0]); + + if (heldCategory == ToolCategory.None || heldCategory != neededCategory) + return false; + + // Check tool tier requirement + int heldTier = GetToolTier(toolType); + int requiredTier = GetRequiredTier(blockMaterial, recommended); + + return heldTier >= requiredTier; + } + + /// + /// Get the minimum tool tier required for a block based on Material2Tool's recommendation ordering. + /// + private static int GetRequiredTier(Material blockMaterial, ItemType[] recommended) + { + if (recommended.Length == 0) + return 0; + + // Material2Tool lists tools from highest to lowest tier. + // The last tool in the array is the minimum required tier. + return GetToolTier(recommended[^1]); + } + + private enum ToolCategory + { + None, + Pickaxe, + Axe, + Shovel, + Hoe, + Sword, + Shears + } + + private static ToolCategory GetToolCategory(ItemType item) + { + if (IsPickaxe(item)) return ToolCategory.Pickaxe; + if (IsAxe(item)) return ToolCategory.Axe; + if (IsShovel(item)) return ToolCategory.Shovel; + if (IsHoe(item)) return ToolCategory.Hoe; + if (IsSword(item)) return ToolCategory.Sword; + if (item == ItemType.Shears) return ToolCategory.Shears; + return ToolCategory.None; + } + + private static int GetToolTier(ItemType item) + { + string name = item.ToString(); + if (name.StartsWith("Wooden")) return 0; + if (name.StartsWith("Golden")) return 0; + if (name.StartsWith("Stone")) return 1; + if (name.StartsWith("Iron")) return 2; + if (name.StartsWith("Diamond")) return 3; + if (name.StartsWith("Netherite")) return 4; + return 0; + } + + private static bool IsPickaxe(ItemType item) => + item is ItemType.WoodenPickaxe or ItemType.StonePickaxe or ItemType.IronPickaxe + or ItemType.GoldenPickaxe or ItemType.DiamondPickaxe or ItemType.NetheritePickaxe; + + private static bool IsAxe(ItemType item) => + item is ItemType.WoodenAxe or ItemType.StoneAxe or ItemType.IronAxe + or ItemType.GoldenAxe or ItemType.DiamondAxe or ItemType.NetheriteAxe; + + private static bool IsShovel(ItemType item) => + item is ItemType.WoodenShovel or ItemType.StoneShovel or ItemType.IronShovel + or ItemType.GoldenShovel or ItemType.DiamondShovel or ItemType.NetheriteShovel; + + private static bool IsHoe(ItemType item) => + item is ItemType.WoodenHoe or ItemType.StoneHoe or ItemType.IronHoe + or ItemType.GoldenHoe or ItemType.DiamondHoe or ItemType.NetheriteHoe; + + private static bool IsSword(ItemType item) => + item is ItemType.WoodenSword or ItemType.StoneSword or ItemType.IronSword + or ItemType.GoldenSword or ItemType.DiamondSword or ItemType.NetheriteSword; + + private static bool IsShearable(Material block) => + block is Material.Cobweb or Material.OakLeaves or Material.SpruceLeaves + or Material.BirchLeaves or Material.JungleLeaves or Material.AcaciaLeaves + or Material.DarkOakLeaves or Material.CherryLeaves or Material.MangroveLeaves + or Material.AzaleaLeaves or Material.FloweringAzaleaLeaves + or Material.WhiteWool or Material.OrangeWool or Material.MagentaWool + or Material.LightBlueWool or Material.YellowWool or Material.LimeWool + or Material.PinkWool or Material.GrayWool or Material.LightGrayWool + or Material.CyanWool or Material.PurpleWool or Material.BlueWool + or Material.BrownWool or Material.GreenWool or Material.RedWool + or Material.BlackWool or Material.Vine; + + #endregion + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 24069342..edfa9cec 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -107,6 +107,9 @@ namespace MinecraftClient // player effects private readonly Dictionary playerEffects = new(); + + // player attributes (e.g., block_break_speed, mining_efficiency, submerged_mining_speed) + private readonly Dictionary playerAttributes = new(); // Sneaking public bool IsSneaking { get; set; } = false; @@ -2591,6 +2594,13 @@ namespace MinecraftClient if (lookAtBlock) UpdateLocation(GetCurrentLocation(), location); + // Auto-compute dig duration for survival/adventure mode when not explicitly supplied + if (duration <= 0 && protocolversion >= Protocol18Handler.MC_1_8_Version + && gamemode is 0 or 2) // Survival or Adventure + { + duration = ComputeAutoDigDuration(location); + } + // Send dig start and dig end, will need to wait for server response to know dig result // See https://wiki.vg/How_to_Write_a_Client#Digging for more details bool result = handler.SendPlayerDigging(0, location, blockFace, sequenceId++) @@ -2608,6 +2618,52 @@ namespace MinecraftClient } } + /// + /// Compute the automatic dig duration in seconds for a block, based on held tool, + /// enchantments, effects, attributes, and player state. + /// Returns 0 for instant-break blocks. + /// + private double ComputeAutoDigDuration(Location location) + { + try + { + Block block = world.GetBlock(location); + Material blockMaterial = block.Type; + + if (blockMaterial == Material.Air) + return 0; + + // Get held item from player inventory + Item? heldItem = null; + Item? helmetItem = null; + if (inventories.TryGetValue(0, out var playerInv)) + { + int hotbarSlot = 36 + CurrentSlot; // Hotbar slots are 36-44 + playerInv.Items.TryGetValue(hotbarSlot, out heldItem); + playerInv.Items.TryGetValue(5, out helmetItem); // Slot 5 = helmet + } + + int ticks = MiningCalculator.ComputeDigTicks( + blockMaterial, + heldItem, + helmetItem, + playerEffects, + playerAttributes, + playerPhysics.InWater, + playerPhysics.OnGround, + protocolversion); + + if (ticks <= 0) + return 0; + + return (double)ticks / Settings.ClientTicksPerSecond; + } + catch + { + return 0; + } + } + /// /// Change active slot in the player inventory /// @@ -3712,6 +3768,9 @@ namespace MinecraftClient { if (EntityID == playerEntityID) { + foreach (var kvp in prop) + playerAttributes[kvp.Key] = kvp.Value; + DispatchBotEvent(bot => bot.OnPlayerProperty(prop)); } } diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index f62e1377..912b1c49 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -1089,9 +1089,10 @@ namespace MinecraftClient.Scripting /// Example: if your player is under a block that is being destroyed, use Down /// Also perform the "arm swing" animation /// Also look at the block before digging - protected bool DigBlock(Location location, Direction direction, bool swingArms = true, bool lookAtBlock = true) + /// Dig duration in seconds. 0 = auto-compute for survival, or instant for creative + protected bool DigBlock(Location location, Direction direction, bool swingArms = true, bool lookAtBlock = true, double duration = 0) { - return Handler.DigBlock(location, direction, swingArms, lookAtBlock); + return Handler.DigBlock(location, direction, swingArms, lookAtBlock, duration); } /// From 0881cbaa1ca0af7a4d4876cc3fad03a1c4eb1cc2 Mon Sep 17 00:00:00 2001 From: milutinke Date: Mon, 30 Mar 2026 17:25:08 +0200 Subject: [PATCH 294/484] Fix legacy achievements and add test harness --- .../scripts/ensure_offline_server.sh | 19 +- .../scripts/prepare_offline_mcc_config.sh | 10 +- .../scripts/run_achievements_matrix.sh | 157 +++++++ .../scripts/run_achievements_test.sh | 443 ++++++++++++++++++ .../scripts/summarize_achievements_matrix.sh | 57 +++ MinecraftClient/LegacyAchievementCatalog.cs | 53 +++ .../Protocol/Handlers/Protocol18.cs | 49 +- 7 files changed, 785 insertions(+), 3 deletions(-) create mode 100755 .skills/mcc-integration-testing/scripts/run_achievements_matrix.sh create mode 100755 .skills/mcc-integration-testing/scripts/run_achievements_test.sh create mode 100755 .skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh create mode 100644 MinecraftClient/LegacyAchievementCatalog.cs diff --git a/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh index 5e67687d..1e348445 100755 --- a/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh +++ b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh @@ -6,6 +6,14 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # shellcheck source=tools/mcc-env.sh source "$REPO_ROOT/tools/mcc-env.sh" +sed_in_place() { + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + VERSION="${1:-1.21.11-Vanilla}" SERVER_DIR="${MCC_SERVERS:?}/$VERSION" PROPS_FILE="$SERVER_DIR/server.properties" @@ -49,6 +57,15 @@ wait_for_server_stop() { sleep 1 ((elapsed += 1)) done + + # Legacy servers can leave the tmux session around after stdin stop. + # Fall back to force-killing the session so the harness can continue. + mc-kill "$VERSION" >/dev/null 2>&1 || true + + if ! server_running; then + return 0 + fi + echo "Timed out waiting for $VERSION to stop" >&2 return 1 } @@ -58,7 +75,7 @@ upsert_property() { local value="$2" if grep -Eq "^${key}=" "$PROPS_FILE"; then - sed -i "s#^${key}=.*#${key}=${value}#" "$PROPS_FILE" + sed_in_place "s#^${key}=.*#${key}=${value}#" "$PROPS_FILE" else printf '%s=%s\n' "$key" "$value" >> "$PROPS_FILE" fi diff --git a/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh b/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh index f36129fa..9eae53b3 100644 --- a/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh +++ b/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh @@ -1,6 +1,14 @@ #!/usr/bin/env bash set -euo pipefail +sed_in_place() { + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + if [[ $# -lt 3 || $# -gt 4 ]]; then echo "Usage: $0 [login]" >&2 exit 1 @@ -28,7 +36,7 @@ fi cp "$TEMPLATE_INI" "$OUTPUT_INI" -sed -i \ +sed_in_place \ -e "s#^Account = .*#Account = { Login = \"$LOGIN_NAME\", Password = \"$PASSWORD_VALUE\" }#" \ -e "s#^AccountType = .*#AccountType = \"$ACCOUNT_TYPE\"#" \ -e "s#^MinecraftVersion = \"[^\"]*\"\\(.*\\)\$#MinecraftVersion = \"$MC_VERSION\"\\1#" \ diff --git a/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh b/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh new file mode 100755 index 00000000..45629525 --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# shellcheck source=tools/mcc-env.sh +source "$REPO_ROOT/tools/mcc-env.sh" + +RUN_ROOT="${TMPDIR:-/tmp}/mcc-achievements/matrix" +RUN_ID="$(date +%Y%m%d-%H%M%S)" +MATRIX_DIR="$RUN_ROOT/$RUN_ID" +RESULTS_TSV="$MATRIX_DIR/results.tsv" +BUILD_LOG="$MATRIX_DIR/build.log" +REPORT_MD="$MATRIX_DIR/report.md" +PRECHECK_TXT="$MATRIX_DIR/preflight.txt" + +mkdir -p "$MATRIX_DIR" + +write_row() { + local fields=("$@") + + while (( ${#fields[@]} < 14 )); do + fields+=("") + done + + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "${fields[0]}" "${fields[1]}" "${fields[2]}" "${fields[3]}" "${fields[4]}" "${fields[5]}" "${fields[6]}" \ + "${fields[7]}" "${fields[8]}" "${fields[9]}" "${fields[10]}" "${fields[11]}" "${fields[12]}" \ + "${fields[13]}" >> "$RESULTS_TSV" +} + +resolve_server_dir() { + local version="$1" + local candidate + + for candidate in "$version" "$version-Vanilla"; do + if [[ -d "$MCC_SERVERS/$candidate" ]]; then + printf '%s\n' "$candidate" + return 0 + fi + done + + return 1 +} + +run_version() { + local version="$1" + local profile="$2" + local family="$3" + local server_dir="$4" + local summary_env + + if bash "$SCRIPT_DIR/run_achievements_test.sh" --no-build "$server_dir" "$version" "$profile"; then + : + fi + + summary_env="${TMPDIR:-/tmp}/mcc-achievements/$server_dir/latest/summary.env" + if [[ ! -f "$summary_env" ]]; then + write_row "$version" "$server_dir" "unknown" "$family" "❌" "❌" "❌" "❌" "❌ Fail" \ + "Summary file was not produced." "" "" "" + return + fi + + # shellcheck disable=SC1090 + source "$summary_env" + + write_row "$VERSION" "$SERVER_DIR" "$PORT" "$FAMILY" "$INITIAL_STATUS" "$GRANT_STATUS" "$REVOKE_STATUS" \ + "$API_STATUS" "$VERDICT" "$NOTE" "$RUN_DIR" "$MCC_LOG" "$COPIED_SERVER_LOG" "$COMMAND_LOG" +} + +{ + printf 'MCC_SERVERS=%s\n' "$MCC_SERVERS" + printf 'RUN_DIR=%s\n' "$MATRIX_DIR" + printf 'DATE=%s\n' "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" +} > "$PRECHECK_TXT" + +printf 'Version\tServerDir\tPort\tFamily\tInitial\tGrant\tRevoke\tAPI\tVerdict\tNote\tRunDir\tMccLog\tServerLog\tCommandLog\n' > "$RESULTS_TSV" + +JAVA_OK="yes" +TMUX_OK="yes" +DOTNET_OK="yes" +BUILD_OK="yes" + +if ! command -v dotnet >/dev/null 2>&1; then + DOTNET_OK="no" +fi + +if ! command -v java >/dev/null 2>&1 || ! java -version >/dev/null 2>&1; then + JAVA_OK="no" +fi + +if ! command -v tmux >/dev/null 2>&1; then + TMUX_OK="no" +fi + +if [[ "$DOTNET_OK" == "yes" ]]; then + if ! dotnet build "$REPO_ROOT/MinecraftClient.sln" -c Release > "$BUILD_LOG" 2>&1; then + BUILD_OK="no" + fi +else + : > "$BUILD_LOG" +fi + +{ + printf 'MCC_SERVERS=%s\n' "$MCC_SERVERS" + printf 'RUN_DIR=%s\n' "$MATRIX_DIR" + printf 'DATE=%s\n' "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" + printf 'dotnet=%s\n' "$DOTNET_OK" + printf 'java=%s\n' "$JAVA_OK" + printf 'tmux=%s\n' "$TMUX_OK" + printf 'build=%s\n' "$BUILD_OK" +} > "$PRECHECK_TXT" + +while IFS='|' read -r version profile family; do + [[ -z "$version" ]] && continue + + if [[ "$DOTNET_OK" != "yes" ]]; then + write_row "$version" "" "" "$family" "❌" "❌" "❌" "❌" "❌ Fail" \ + "dotnet is not available on PATH." + continue + fi + + if [[ "$BUILD_OK" != "yes" ]]; then + write_row "$version" "" "" "$family" "❌" "❌" "❌" "❌" "❌ Fail" \ + "dotnet build failed. See $BUILD_LOG." + continue + fi + + if [[ "$JAVA_OK" != "yes" || "$TMUX_OK" != "yes" ]]; then + write_row "$version" "" "" "$family" "❌" "❌" "❌" "❌" "❌ Fail" \ + "java or tmux is not available, so live server execution was blocked." + continue + fi + + if ! server_dir="$(resolve_server_dir "$version")"; then + write_row "$version" "" "" "$family" "❌" "❌" "❌" "❌" "⚠️ Partial" \ + "Server directory for $version was not found under $MCC_SERVERS." + continue + fi + + run_version "$version" "$profile" "$family" "$server_dir" +done <<'EOF' +1.8|legacy|Legacy 🧱 +1.11.2|legacy|Legacy 🧱 +1.12.2|modern|First advancements 🌱 +1.19.4|modern|Stable modern ✅ +1.20|modern|Telemetry edge 1 ⚠️ +1.20.2|modern|Telemetry edge 2 ⚠️ +1.20.4|modern|End of 1.20.x ⚠️ +1.20.6|modern|Post-1.20.6 🔧 +1.21.2|modern|1.21.2 family 🔧 +1.21.11|modern|showAdvancements 🆕 +26.1|modern|Latest supported 🚀 +EOF + +bash "$SCRIPT_DIR/summarize_achievements_matrix.sh" "$MATRIX_DIR" > "$REPORT_MD" +printf '%s\n' "$MATRIX_DIR" diff --git a/.skills/mcc-integration-testing/scripts/run_achievements_test.sh b/.skills/mcc-integration-testing/scripts/run_achievements_test.sh new file mode 100755 index 00000000..88c2b027 --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/run_achievements_test.sh @@ -0,0 +1,443 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# shellcheck source=tools/mcc-env.sh +source "$REPO_ROOT/tools/mcc-env.sh" + +sed_in_place() { + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +usage() { + cat <<'EOF' +Usage: run_achievements_test.sh [--no-build] + +Examples: + .skills/mcc-integration-testing/scripts/run_achievements_test.sh --no-build 1.8 1.8 legacy + .skills/mcc-integration-testing/scripts/run_achievements_test.sh --no-build 1.21.11-Vanilla 1.21.11 modern +EOF +} + +DO_BUILD=true + +while [[ $# -gt 0 ]]; do + case "$1" in + --no-build) DO_BUILD=false; shift ;; + --build) DO_BUILD=true; shift ;; + -h|--help) usage; exit 0 ;; + *) break ;; + esac +done + +if [[ $# -ne 3 ]]; then + usage >&2 + exit 1 +fi + +SERVER_DIR="$1" +MC_VERSION="$2" +PROFILE="$3" + +if [[ "$PROFILE" != "legacy" && "$PROFILE" != "modern" ]]; then + echo "Unsupported profile: $PROFILE" >&2 + exit 1 +fi + +RUN_ROOT="${TMPDIR:-/tmp}/mcc-achievements" +RUN_ID="$(date +%Y%m%d-%H%M%S)" +RUN_DIR="$RUN_ROOT/$SERVER_DIR/$RUN_ID" +LATEST_LINK="$RUN_ROOT/$SERVER_DIR/latest" +MCC_LOG="$RUN_DIR/mcc.log" +BUILD_LOG="$RUN_DIR/build.log" +SERVER_TMUX_LOG="$RUN_DIR/server-tmux.log" +SERVER_FILE_LOG="$RUN_DIR/server-latest.log" +COMMAND_LOG="$RUN_DIR/commands.log" +SUMMARY_ENV="$RUN_DIR/summary.env" +PROBE_SCRIPT="$RUN_DIR/achievement_probe.cs" +CFG="$RUN_DIR/MinecraftClient.$MC_VERSION.ini" +INPUT_FILE="$REPO_ROOT/mcc_input.txt" +SERVER_LOG_FILE="$MCC_SERVERS/$SERVER_DIR/logs/latest.log" +TARGET_ID="minecraft:story/root" +TARGET_COMMAND_GRANT="advancement grant CursorBot only minecraft:story/root" +TARGET_COMMAND_REVOKE="advancement revoke CursorBot only minecraft:story/root" +TARGET_TYPE="Modern 🌱" +PORT="unknown" +MCC_PID="" + +INITIAL_STATUS="❌" +GRANT_STATUS="❌" +REVOKE_STATUS="❌" +API_STATUS="❌" +VERDICT="❌ Fail" +NOTE="Run did not complete." +EXECUTED="yes" + +if [[ "$PROFILE" == "legacy" ]]; then + TARGET_ID="achievement.openInventory" + TARGET_COMMAND_GRANT="achievement give achievement.openInventory CursorBot" + TARGET_COMMAND_REVOKE="achievement take achievement.openInventory CursorBot" + TARGET_TYPE="Legacy 🧱" +fi + +mkdir -p "$RUN_DIR" + +write_summary() { + { + printf 'VERSION=%q\n' "$MC_VERSION" + printf 'SERVER_DIR=%q\n' "$SERVER_DIR" + printf 'PROFILE=%q\n' "$PROFILE" + printf 'FAMILY=%q\n' "$TARGET_TYPE" + printf 'PORT=%q\n' "$PORT" + printf 'RUN_DIR=%q\n' "$RUN_DIR" + printf 'MCC_LOG=%q\n' "$MCC_LOG" + printf 'SERVER_LOG=%q\n' "$RUN_DIR/server-latest.log" + printf 'SERVER_FILE_LOG=%q\n' "$SERVER_LOG_FILE" + printf 'SERVER_TMUX_LOG=%q\n' "$SERVER_TMUX_LOG" + printf 'COPIED_SERVER_LOG=%q\n' "$RUN_DIR/server-latest.log" + printf 'COMMAND_LOG=%q\n' "$COMMAND_LOG" + printf 'SUMMARY_ENV=%q\n' "$SUMMARY_ENV" + printf 'TARGET_ID=%q\n' "$TARGET_ID" + printf 'INITIAL_STATUS=%q\n' "$INITIAL_STATUS" + printf 'GRANT_STATUS=%q\n' "$GRANT_STATUS" + printf 'REVOKE_STATUS=%q\n' "$REVOKE_STATUS" + printf 'API_STATUS=%q\n' "$API_STATUS" + printf 'VERDICT=%q\n' "$VERDICT" + printf 'NOTE=%q\n' "$NOTE" + printf 'EXECUTED=%q\n' "$EXECUTED" + } > "$SUMMARY_ENV" +} + +capture_server_logs() { + mc-log "$SERVER_DIR" 400 > "$SERVER_TMUX_LOG" 2>/dev/null || true + if [[ -f "$SERVER_LOG_FILE" ]]; then + cp "$SERVER_LOG_FILE" "$RUN_DIR/server-latest.log" 2>/dev/null || true + fi +} + +cleanup() { + capture_server_logs + + if [[ -n "${MCC_PID:-}" ]] && kill -0 "$MCC_PID" 2>/dev/null; then + echo "quit" >> "$INPUT_FILE" 2>/dev/null || true + sleep 2 + kill "$MCC_PID" 2>/dev/null || true + wait "$MCC_PID" 2>/dev/null || true + fi + + mc-stop "$SERVER_DIR" >/dev/null 2>&1 || true + ln -sfn "$RUN_DIR" "$LATEST_LINK" + write_summary +} +trap cleanup EXIT + +log_step() { + printf '[%s] %s\n' "$(date '+%H:%M:%S')" "$1" | tee -a "$COMMAND_LOG" +} + +fail() { + NOTE="$1" + VERDICT="❌ Fail" + exit 1 +} + +wait_for_file_pattern() { + local file="$1" + local pattern="$2" + local description="$3" + local timeout="${4:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if [[ -f "$file" ]] && grep -Fq "$pattern" "$file"; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for: $description" >&2 + return 1 +} + +wait_for_server_ready() { + local timeout="${1:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if mc-log "$SERVER_DIR" 250 2>/dev/null | grep -Fq "Done ("; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for server readiness" >&2 + return 1 +} + +disable_noisy_bots() { + sed_in_place '/^\[ChatBot.ScriptScheduler\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.DiscordRpc\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.AntiAFK\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.AutoDig\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.AutoAttack\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.PlayerListLogger\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" + sed_in_place '/^\[ChatBot.ReplayCapture\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" +} + +ensure_root_config() { + if [[ -f "$REPO_ROOT/MinecraftClient.ini" ]]; then + return + fi + + ( + cd "$REPO_ROOT" + dotnet run --project MinecraftClient -c Release --no-build -- --help >/dev/null 2>&1 + ) +} + +write_probe_script() { + cat > "$PROBE_SCRIPT" < updated, IReadOnlyList removedIds, bool reset) + { + LogToConsole($"[ACH_TEST] event reset={reset} updated={updated.Count} removed={removedIds.Count}"); + DumpState("event"); + } + + private void DumpState(string origin) + { + Achievement[] all = GetAchievements(); + Achievement[] unlocked = GetUnlockedAchievements(); + Achievement[] locked = GetLockedAchievements(); + Achievement? target = null; + + foreach (Achievement entry in all) + { + if (entry.Id == TargetId) + { + target = entry; + break; + } + } + + string titleState = "missing"; + string completionState = "missing"; + + if (target is not null) + { + titleState = target.Title is null ? "null" : "present"; + completionState = target.IsCompleted ? "done" : "todo"; + } + + LogToConsole($"[ACH_TEST] snapshot origin={origin} all={all.Length} unlocked={unlocked.Length} locked={locked.Length}"); + LogToConsole($"[ACH_TEST] target_state origin={origin} id={TargetId} title={titleState} completed={completionState}"); + } +} +EOF +} + +run_server_command() { + local cmd="$1" + local attempt + + log_step "SERVER> $cmd" + for attempt in 1 2 3 4 5; do + if mc-rcon "$cmd" >/dev/null 2>&1; then + sleep 1 + return 0 + fi + sleep 1 + done + + fail "Server command failed: $cmd" +} + +run_mcc_command() { + local name="$1" + local cmd="$2" + local delay="${3:-2}" + local start_line=0 + local end_line=0 + + if [[ -f "$MCC_LOG" ]]; then + start_line="$(wc -l < "$MCC_LOG")" + fi + + log_step "MCC> $cmd" + echo "$cmd" >> "$INPUT_FILE" + sleep "$delay" + + if [[ -f "$MCC_LOG" ]]; then + end_line="$(wc -l < "$MCC_LOG")" + fi + + if (( end_line > start_line )); then + sed -n "$((start_line + 1)),$((end_line))p" "$MCC_LOG" > "$RUN_DIR/$name.mcc.log" + else + : > "$RUN_DIR/$name.mcc.log" + fi +} + +assert_pattern() { + local file="$1" + local pattern="$2" + local description="$3" + + grep -Fq "$pattern" "$file" || fail "$description" +} + +if ! command -v java >/dev/null 2>&1 || ! java -version >/dev/null 2>&1; then + fail "java was not found on PATH." +fi + +if ! command -v tmux >/dev/null 2>&1; then + fail "tmux was not found on PATH." +fi + +if [[ ! -d "$MCC_SERVERS/$SERVER_DIR" ]]; then + fail "Server directory not found: $MCC_SERVERS/$SERVER_DIR" +fi + +PORT="$(bash "$SCRIPT_DIR/get_server_port.sh" "$SERVER_DIR")" + +ensure_root_config +"$SCRIPT_DIR/ensure_offline_server.sh" "$SERVER_DIR" +disable_noisy_bots +write_probe_script + +if [[ "$PROFILE" == "legacy" && -f "$MCC_SERVERS/$SERVER_DIR/server.properties" ]]; then + sed_in_place 's/^use-native-transport=.*/use-native-transport=false/' "$MCC_SERVERS/$SERVER_DIR/server.properties" +fi + +if $DO_BUILD; then + log_step "BUILD> dotnet build MinecraftClient.sln -c Release" + mcc-build > "$BUILD_LOG" 2>&1 || fail "dotnet build failed." +else + : > "$BUILD_LOG" +fi + +: > "$INPUT_FILE" +rm -f "$MCC_LOG" + +log_step "Starting server $SERVER_DIR on port $PORT" +mc-start "$SERVER_DIR" >/dev/null +wait_for_server_ready || fail "Server did not become ready." + +log_step "Starting MCC for $MC_VERSION" +( + cd "$REPO_ROOT" + MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release --no-build -- \ + CursorBot \ + - \ + "localhost:$PORT" \ + "--accounttype=mojang" \ + "--minecraftversion=$MC_VERSION" \ + "--terrainandmovements=true" \ + "--inventoryhandling=true" \ + "--entityhandling=true" \ + "--autorespawn=true" \ + "--debugmessages=true" \ + > "$MCC_LOG" 2>&1 +) & +MCC_PID=$! + +wait_for_file_pattern "$MCC_LOG" "Server was successfully joined." "MCC join success" 90 || fail "MCC failed to join." +wait_for_file_pattern "$SERVER_LOG_FILE" "CursorBot joined the game" "server join entry" 30 || fail "Server never logged the join." + +run_server_command "op CursorBot" +run_server_command "gamerule sendCommandFeedback true" +if [[ "$PROFILE" == "modern" ]]; then + run_server_command "gamerule logAdminCommands true" +fi +run_server_command "time set day" +run_server_command "weather clear" + +run_mcc_command "load_probe" "script $PROBE_SCRIPT" 3 +wait_for_file_pattern "$MCC_LOG" "[ACH_TEST] probe initialized" "probe startup" 30 || fail "Probe script did not initialize." + +run_mcc_command "baseline_debug" "debug state" 2 +run_mcc_command "baseline_all" "achievement" 2 +run_mcc_command "baseline_locked" "achievement locked" 2 +run_mcc_command "baseline_unlocked" "achievement unlocked" 2 + +run_server_command "$TARGET_COMMAND_GRANT" +sleep 3 +run_mcc_command "after_grant_all" "achievement" 2 +run_mcc_command "after_grant_unlocked" "achievement unlocked" 2 + +run_server_command "$TARGET_COMMAND_REVOKE" +sleep 3 +run_mcc_command "after_revoke_all" "achievement" 2 +run_mcc_command "after_revoke_locked" "achievement locked" 2 + +assert_pattern "$MCC_LOG" "Achievements/Advancements:" "Achievement command header never appeared." + +if ! grep -Fq "No achievements/advancements received yet." "$RUN_DIR/baseline_all.mcc.log"; then + INITIAL_STATUS="✅" +fi + +if grep -Fq "$TARGET_ID" "$RUN_DIR/after_grant_unlocked.mcc.log" && grep -Fq "[DONE]" "$RUN_DIR/after_grant_unlocked.mcc.log"; then + GRANT_STATUS="✅" +fi + +if [[ "$PROFILE" == "legacy" ]]; then + if grep -Fq "$TARGET_ID" "$RUN_DIR/after_revoke_locked.mcc.log" && grep -Fq "[TODO]" "$RUN_DIR/after_revoke_locked.mcc.log"; then + REVOKE_STATUS="✅" + fi +else + if grep -Fq "$TARGET_ID" "$RUN_DIR/after_revoke_locked.mcc.log" && grep -Fq "[TODO]" "$RUN_DIR/after_revoke_locked.mcc.log"; then + REVOKE_STATUS="✅" + elif [[ "$GRANT_STATUS" == "✅" ]] && ! grep -Fq "$TARGET_ID" "$RUN_DIR/after_revoke_all.mcc.log"; then + REVOKE_STATUS="✅" + fi +fi + +if grep -Fq "[ACH_TEST] event" "$MCC_LOG" && grep -Fq "target_state origin=event id=$TARGET_ID title=" "$MCC_LOG"; then + API_STATUS="✅" +fi + +case "$INITIAL_STATUS|$GRANT_STATUS|$REVOKE_STATUS|$API_STATUS" in + "✅|✅|✅|✅") + VERDICT="✅ Pass" + NOTE="All planned achievement checks passed." + ;; + *"✅"*) + VERDICT="⚠️ Partial" + NOTE="At least one achievement phase passed, but the matrix did not fully clear." + ;; + *) + VERDICT="❌ Fail" + NOTE="Achievement checks did not produce the expected evidence." + ;; +esac + +run_mcc_command "quit" "quit" 2 +NOTE="$NOTE Artifacts saved in $RUN_DIR." diff --git a/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh b/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh new file mode 100755 index 00000000..9dbeb78c --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "Usage: summarize_achievements_matrix.sh " >&2 + exit 1 +fi + +MATRIX_DIR="$1" +RESULTS_TSV="$MATRIX_DIR/results.tsv" +PRECHECK_TXT="$MATRIX_DIR/preflight.txt" +BUILD_LOG="$MATRIX_DIR/build.log" + +if [[ ! -f "$RESULTS_TSV" ]]; then + echo "Missing results file: $RESULTS_TSV" >&2 + exit 1 +fi + +echo "# Achievements Matrix Report" +echo +echo "## Executed" +echo +if [[ -f "$PRECHECK_TXT" ]]; then + echo '```text' + cat "$PRECHECK_TXT" + echo '```' +fi +echo +echo "- Matrix artifacts: \`$MATRIX_DIR\`" +echo "- Results TSV: \`$RESULTS_TSV\`" +echo "- Build log: \`$BUILD_LOG\`" +echo "- Execution mode: sequential" +echo "- Auth mode: offline" +echo +echo "## Observed" +echo +echo "| Version | Port | Family | Initial snapshot | Grant | Revoke | API callback | Verdict |" +echo "|---|---:|---|---|---|---|---|---|" +awk -F '\t' 'NR > 1 { + printf("| `%s` | `%s` | %s | %s | %s | %s | %s | %s |\n", + $1, $3, $4, $5, $6, $7, $8, $9); +}' "$RESULTS_TSV" + +echo +echo "## Artifact Links" +echo +awk -F '\t' 'NR > 1 { + printf("- `%s`: run=`%s`, mcc=`%s`, server=`%s`, commands=`%s`\n", $1, $11, $12, $13, $14); + printf(" note: %s\n", $10); +}' "$RESULTS_TSV" + +echo +echo "## Inferred" +echo +echo "- Only rows with real MCC and server-log artifacts count as executed proof." +echo "- Rows blocked by missing Java, tmux, or server directories are environment-limited, not product pass results." +echo "- Legacy rows remain the highest-risk bucket because static inspection suggests pre-1.12 \`Statistics\` packets may not currently reach the achievements handler." diff --git a/MinecraftClient/LegacyAchievementCatalog.cs b/MinecraftClient/LegacyAchievementCatalog.cs new file mode 100644 index 00000000..bce17f8d --- /dev/null +++ b/MinecraftClient/LegacyAchievementCatalog.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace MinecraftClient +{ + internal static class LegacyAchievementCatalog + { + public static IReadOnlyList Ids { get; } = + [ + "achievement.openInventory", + "achievement.mineWood", + "achievement.buildWorkBench", + "achievement.buildPickaxe", + "achievement.buildFurnace", + "achievement.acquireIron", + "achievement.buildHoe", + "achievement.makeBread", + "achievement.bakeCake", + "achievement.buildBetterPickaxe", + "achievement.cookFish", + "achievement.onARail", + "achievement.buildSword", + "achievement.killEnemy", + "achievement.killCow", + "achievement.flyPig", + "achievement.snipeSkeleton", + "achievement.diamonds", + "achievement.diamondsToYou", + "achievement.portal", + "achievement.ghast", + "achievement.blazeRod", + "achievement.potion", + "achievement.theEnd", + "achievement.theEnd2", + "achievement.enchantments", + "achievement.overkill", + "achievement.bookcase", + "achievement.breedCow", + "achievement.spawnWither", + "achievement.killWither", + "achievement.fullBeacon", + "achievement.exploreAllBiomes", + "achievement.overpowered" + ]; + + private static readonly HashSet s_idSet = new(Ids, StringComparer.Ordinal); + + public static bool Contains(string id) + { + return s_idSet.Contains(id); + } + } +} diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 7032bcbd..eeabc8e0 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -91,6 +91,7 @@ namespace MinecraftClient.Protocol.Handlers private int currentDimension; private bool isOnlineMode = false; private readonly BlockingCollection>> packetQueue = new(); + private readonly Dictionary legacyAchievementProgress = new(StringComparer.Ordinal); private float LastYaw, LastPitch; private double lastSentX, lastSentY, lastSentZ; private float lastSentYaw, lastSentPitch; @@ -120,6 +121,7 @@ namespace MinecraftClient.Protocol.Handlers Tuple? netReader = null; // reader thread readonly ILogger log; readonly RandomNumberGenerator randomGen; + private bool legacyAchievementsInitialized; public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHandler handler, ForgeInfo? forgeInfo, int rawProtocolVersion = 0) @@ -3132,6 +3134,11 @@ namespace MinecraftClient.Protocol.Handlers case PacketTypesIn.RecipeBookSettings: break; + case PacketTypesIn.Statistics: + if (protocolVersion < MC_1_12_Version) + HandleLegacyStatistics(packetData); + break; + case PacketTypesIn.Advancements: HandleAdvancements(packetData); break; @@ -3147,9 +3154,39 @@ namespace MinecraftClient.Protocol.Handlers return true; //Packet processed } + /// + /// Handle the Statistics packet for pre-1.12 legacy achievements. + /// + private void HandleLegacyStatistics(Queue packetData) + { + int statCount = dataTypes.ReadNextVarInt(packetData); + + for (int i = 0; i < statCount; i++) + { + string statId = dataTypes.ReadNextString(packetData); + int value = dataTypes.ReadNextVarInt(packetData); + + if (statId.StartsWith("achievement.", StringComparison.Ordinal)) + legacyAchievementProgress[statId] = value > 0; + } + + List added = new(LegacyAchievementCatalog.Ids.Count + legacyAchievementProgress.Count); + + foreach (string achievementId in LegacyAchievementCatalog.Ids) + added.Add(CreateLegacyAchievement(achievementId, legacyAchievementProgress.TryGetValue(achievementId, out bool completed) && completed)); + + foreach (var (achievementId, completed) in legacyAchievementProgress) + { + if (!LegacyAchievementCatalog.Contains(achievementId)) + added.Add(CreateLegacyAchievement(achievementId, completed)); + } + + handler.OnAchievementsUpdate(added, [], reset: !legacyAchievementsInitialized); + legacyAchievementsInitialized = true; + } + /// /// Handle the Advancements packet (1.12+). - /// Also handles the Statistics packet for pre-1.12 legacy achievements. /// private void HandleAdvancements(Queue packetData) { @@ -3282,6 +3319,16 @@ namespace MinecraftClient.Protocol.Handlers handler.OnAchievementsUpdate(added, removedIds, reset); } + private static Achievement CreateLegacyAchievement(string id, bool isCompleted) + { + Dictionary criteria = new(StringComparer.Ordinal) + { + [id] = isCompleted + }; + IReadOnlyList[] requirements = [[id]]; + return new Achievement(id, null, null, AchievementType.Legacy, false, isCompleted, requirements, criteria); + } + /// /// Compute whether an advancement is completed based on AND-of-ORs requirements. /// From 62740ee94e50e1a7eb5e2bfc762e0667e8ce00f8 Mon Sep 17 00:00:00 2001 From: milutinke Date: Mon, 30 Mar 2026 17:28:15 +0200 Subject: [PATCH 295/484] Document achievements feature --- docs/guide/creating-bots.md | 52 +++++++++++++++++++++++++++++++++++++ docs/guide/usage.md | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/docs/guide/creating-bots.md b/docs/guide/creating-bots.md index e374f273..ed35d549 100644 --- a/docs/guide/creating-bots.md +++ b/docs/guide/creating-bots.md @@ -229,6 +229,58 @@ Make a built-in MCC chat bot named AutoTorch and wire it fully into the repo con Create a standalone MCC /script bot that follows private messages, uses GetVerbatim(text), and replies only to bot owners. Use the mcc-chatbot-authoring skill. ``` +## Achievements And Advancements + +Chat bots and C# scripts can read the current achievement state and react to updates. + +Useful methods: + +- `GetAchievements()` +- `GetUnlockedAchievements()` +- `GetLockedAchievements()` +- `OnAchievementUpdate(IReadOnlyList updated, IReadOnlyList removedIds, bool reset)` + +Things worth knowing: + +- On `1.8` to `1.11.2`, ids use the legacy `achievement.*` format. +- On `1.12+`, ids use advancement resource ids such as `minecraft:story/root`. +- Legacy achievements usually have `Title = null` and `Description = null` because the server does not send display metadata in the statistics packet. +- On newer versions, revoking an advancement may remove it from the current set instead of turning it into a locked entry, so `removedIds` matters. + +Example: + +```csharp +//MCCScript 1.0 + +MCC.LoadBot(new AchievementWatcher()); + +//MCCScript Extensions + +public class AchievementWatcher : ChatBot +{ + public override void AfterGameJoined() + { + Achievement[] known = GetAchievements(); + LogToConsole($"Known achievements: {known.Length}"); + } + + public override void OnAchievementUpdate(IReadOnlyList updated, IReadOnlyList removedIds, bool reset) + { + LogToConsole($"Achievement update: reset={reset}, updated={updated.Count}, removed={removedIds.Count}"); + + foreach (Achievement achievement in updated) + { + string title = achievement.Title ?? achievement.Id; + string state = achievement.IsCompleted ? "done" : "todo"; + LogToConsole($" - {title}: {state}"); + } + + foreach (string removedId in removedIds) + LogToConsole($" - removed: {removedId}"); + } +} +``` + ## C# API The authoritative reference for the C# API is [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs). diff --git a/docs/guide/usage.md b/docs/guide/usage.md index 0a439aff..e0e4a0ea 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -219,6 +219,54 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
+
+achievement + +- **Description:** + + Show the achievements or advancements currently known to MCC. + + On Minecraft `1.8` to `1.11.2`, MCC tracks legacy achievements such as `achievement.openInventory`. + + On Minecraft `1.12+`, MCC tracks advancements such as `minecraft:story/root`. + +- **Usage:** + + ``` + /achievement + /achievement list + /achievement locked + /achievement unlocked + ``` + +- **Examples:** + + List everything MCC currently knows: + + ``` + /achievement + ``` + + Show only incomplete entries: + + ``` + /achievement locked + ``` + + Show only completed entries: + + ``` + /achievement unlocked + ``` + +- **Notes:** + + The command only shows data the server has already sent to MCC. + + Legacy achievements do not include titles or descriptions in the protocol, so older servers usually show the raw id instead. + +
+
bed From 76e5cab248f946fec6ff94de73bf6910fdc2dabe Mon Sep 17 00:00:00 2001 From: milutinke Date: Mon, 30 Mar 2026 18:02:10 +0200 Subject: [PATCH 296/484] Improve MCC testing workflow resilience --- .skills/mcc-dev-workflow/SKILL.md | 38 ++++-- .skills/mcc-integration-testing/SKILL.md | 23 +++- .../mcc-integration-testing/scripts/common.sh | 110 ++++++++++++++++++ .../scripts/ensure_offline_server.sh | 53 +-------- .../scripts/preflight_test_env.sh | 48 ++++++++ .../scripts/prepare_offline_mcc_config.sh | 69 +++++++++-- .../scripts/reset_shared_test_state.sh | 50 ++++++++ .../scripts/run_achievements_matrix.sh | 11 ++ .../scripts/run_achievements_test.sh | 91 ++++----------- .../scripts/run_full_spectrum_test.sh | 68 +++++------ .../scripts/summarize_achievements_matrix.sh | 2 +- .skills/mcc-version-adaptation/SKILL.md | 1 + tools/mcc-debug.sh | 43 ++++--- tools/mcc-env.sh | 4 + tools/run-creative-e2e.sh | 66 +++-------- tools/start-server.sh | 42 ++++++- 16 files changed, 464 insertions(+), 255 deletions(-) create mode 100755 .skills/mcc-integration-testing/scripts/common.sh create mode 100755 .skills/mcc-integration-testing/scripts/preflight_test_env.sh create mode 100755 .skills/mcc-integration-testing/scripts/reset_shared_test_state.sh diff --git a/.skills/mcc-dev-workflow/SKILL.md b/.skills/mcc-dev-workflow/SKILL.md index f1a3c8fe..b1a9ef01 100644 --- a/.skills/mcc-dev-workflow/SKILL.md +++ b/.skills/mcc-dev-workflow/SKILL.md @@ -1,6 +1,6 @@ --- name: mcc-dev-workflow -description: Build, run, and debug Minecraft Console Client (MCC) against a real local Minecraft Java server in WSL. Use this whenever the user wants to compile MCC, start or inspect a local test server, connect MCC to a server, debug protocol or login issues, validate a code change end-to-end, or run MCC commands on a real server instead of guessing from static code. +description: Build, run, and debug Minecraft Console Client (MCC) against a real local Minecraft Java server on Linux, macOS, or WSL. Use this whenever the user wants to compile MCC, start or inspect a local test server, connect MCC to a server, debug protocol or login issues, validate a code change end-to-end, or run MCC commands on a real server instead of guessing from static code. --- # MCC Development Workflow @@ -11,7 +11,7 @@ Use this skill when the task needs a real local server loop, not just code readi - Solution: `MinecraftClient.sln` - Runtime target: `.NET 10` / `net10.0` -- Environment: WSL Ubuntu, Java 21, tmux, python3 +- Environment: Linux, macOS, or WSL with Java, tmux, python3, and dotnet available - Default server root: `${MCC_SERVERS:-$MCC_REPO/MinecraftOfficial/downloads}` - Default validation target when the user does not specify a version: `1.21.11` @@ -30,10 +30,22 @@ Both modes support the same commands and input/output through `ConsoleIO.Backend - Prefer a real local server over static reasoning for protocol, login, movement, inventory, entity, or command-path work. - Treat tmux `mc-*` sessions as shared state. Do not run multi-version server workflows in parallel unless the harness explicitly isolates them. -- For scripted or repeatable runs, prefer a temporary config copied from `MinecraftClient.ini`. Use the repo-root config only for ad hoc manual work. +- For scripted or repeatable runs, use a generated temporary config. Do not edit the repo-root `MinecraftClient.ini` as part of the test loop. - A server log line containing `Done (` means startup finished. It does not guarantee that RCON is ready on the first attempt. Retry early `mc-rcon` commands. - When instructions, docs, and code disagree, trust current code and current tool behavior first. +## Preflight and reset + +Before scripted runs, especially on macOS or in a reused tmux environment: + +```bash +source tools/mcc-env.sh +mcc-preflight 1.21.11 +mc-reset-test-env 1.21.11 +``` + +`mcc-preflight` checks Java, tmux, dotnet, python3, and server directories. It also resolves common Homebrew Java paths on macOS. `mc-reset-test-env` clears stale tmux sessions and stale `stdin.pipe` files before they turn into misleading startup failures. + ## Build ```bash @@ -92,7 +104,7 @@ mcc-debug -v 1.21.11 --file-input --no-build ### What mcc-debug.sh does 1. Builds MCC (unless `--no-build`) -2. Creates a temp config at `/tmp/mcc-debug/MinecraftClient.debug.ini` with CursorBot account, Terrain/Inventory/Entity enabled +2. Creates a clean temp config at `/tmp/mcc-debug/MinecraftClient.debug.ini` with CursorBot account, Terrain/Inventory/Entity enabled and noisy bots disabled 3. Ensures server is running (starts if not, waits for `Done (`) 4. Launches MCC in the specified mode @@ -210,6 +222,9 @@ After `source tools/mcc-env.sh`: | `mc-rcon "CMD"` | Send RCON command | | `mc-kill VER` | Force-kill server tmux session | | `mc-list` | List running MC server sessions | +| `mc-wait-ready VER [SEC]` | Wait for server `Done (` | +| `mc-wait-stop VER [SEC]` | Wait for server shutdown, with force-kill fallback | +| `mc-reset-test-env [--all|VER...]` | Reset shared tmux server state and stale pipes | | `mcc-build` | Build MCC | | `mcc-run [PORT]` | Run MCC classic+FileInput on port | | `mcc-tui [PORT]` | Run MCC TUI mode in tmux | @@ -218,6 +233,7 @@ After `source tools/mcc-env.sh`: | `mcc-debug [OPTS]` | One-step debug session (see above) | | `mcc-log-mcc` | Tail MCC debug log | | `mcc-state` | Send `debug state` and print last 30 log lines | +| `mcc-preflight [VER...]` | Verify Java, tmux, dotnet, python3, and server dirs | ## Temporary config recipe @@ -226,14 +242,10 @@ source tools/mcc-env.sh TEST_ROOT="${TMPDIR:-/tmp}/mcc-dev" CFG="$TEST_ROOT/MinecraftClient.1.21.11.ini" mkdir -p "$TEST_ROOT" -cp "$MCC_REPO/MinecraftClient.ini" "$CFG" -sed -i \ - -e 's/Account = { Login = "test", Password = "-" }/Account = { Login = "CursorBot", Password = "-" }/' \ - -e 's/MinecraftVersion = "auto"/MinecraftVersion = "1.21.11"/' \ - -e 's/TerrainAndMovements = false/TerrainAndMovements = true/' \ - -e 's/InventoryHandling = false/InventoryHandling = true/' \ - -e 's/EntityHandling = false/EntityHandling = true/' \ - "$CFG" +bash "$MCC_REPO/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh" \ + "$CFG" \ + "1.21.11" \ + "CursorBot" ``` For TUI mode, also add: @@ -257,6 +269,8 @@ Basic command check: mcc-cmd "inventory player list" ``` +If a scripted run fails before MCC joins, check for a harness problem before assuming a product regression. Missing `mcc.log`, a pre-join `Connection refused`, or a server that never reached `Done (` usually means shared-state cleanup or startup failed. + ## Typical debug loop 1. `source tools/mcc-env.sh` diff --git a/.skills/mcc-integration-testing/SKILL.md b/.skills/mcc-integration-testing/SKILL.md index 50673abb..168b545f 100644 --- a/.skills/mcc-integration-testing/SKILL.md +++ b/.skills/mcc-integration-testing/SKILL.md @@ -56,7 +56,7 @@ If the environment cannot run a real server, say so and report the result as une - Use a real local server. - Launch MCC against an explicit `localhost:` target for repeatable local tests. - Keep version matrices sequential in shared local environments. The tmux server harness is shared state by default. -- Prefer temporary MCC configs for scripted runs so one test does not contaminate the next. +- Prefer generated temporary MCC configs for scripted runs so one test does not contaminate the next. - Default to offline auth in generated temp configs. Do not trust the repo-root `MinecraftClient.ini` account defaults. - If the user explicitly asks for Microsoft online login, honor that request and generate the temp config for Microsoft auth instead of offline mode. - For Microsoft auth, prefer an interactive TTY launch with `BasicIO-NoColor` so the device code is easy to read and relay to the user. @@ -65,8 +65,10 @@ If the environment cannot run a real server, say so and report the result as une - Legacy and modern command syntax differ. Do not assume one server-command profile fits every version. - Use actual MCC output and actual server logs for assertions. Do not invent success strings. - Treat server `Done` as startup progress, not RCON readiness. Retry the first RCON command before assuming the setup is broken. +- Run preflight before scripted test loops. On macOS, Java may be installed but not exported on PATH in the shell the harness uses. - If a change touches shared routing or a version range, test at least one adjacent version that shares that path, or explicitly mark adjacent versions as unexecuted and inferred. - For palette or version-content changes, probe at least one neighboring or existing item, entity, or block. Do not only check the headline addition. +- Separate product failures from harness failures. Missing logs, stale tmux state, stale `stdin.pipe`, or pre-join `Connection refused` errors are usually environment problems until proven otherwise. ## Choose the test mode @@ -117,11 +119,19 @@ Run them against a real server with a temp config and summarize counts from the Before running any scenario: +0. run preflight and clear stale shared state when the environment is reused 1. configure the target server for offline testing 2. ensure `eula=true` 3. ensure RCON is enabled 4. build MCC unless the task explicitly reuses a fresh build +Preflight and reset helpers: + +```bash +.skills/mcc-integration-testing/scripts/preflight_test_env.sh 1.21.11-Vanilla +.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh 1.21.11-Vanilla +``` + Offline configuration helper: ```bash @@ -141,8 +151,12 @@ Optionally override the login name with the fourth argument to the config helper - `.skills/mcc-integration-testing/scripts/ensure_offline_server.sh` - configures persistent offline mode and RCON +- `.skills/mcc-integration-testing/scripts/preflight_test_env.sh` + - verifies Java, tmux, dotnet, python3, server directories, and resolves common Java PATH issues +- `.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh` + - clears stale tmux sessions and stale `stdin.pipe` files before a rerun - `.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh` - - copies `MinecraftClient.ini`, prepares offline login by default, and can switch to Microsoft auth when explicitly requested + - generates a clean temporary MCC config, prepares offline login by default, disables noisy bots, and can switch to Microsoft auth when explicitly requested - `.skills/mcc-integration-testing/scripts/get_server_port.sh` - resolves the actual local server port from `server.properties` or the latest server log - `.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh` @@ -159,6 +173,7 @@ In every report, separate: - `Executed`: exact scripts, commands, versions, auth mode, and whether the run was sequential or single-version - `Observed`: exact MCC output, exact server-log evidence, and the saved log directory - `Inferred`: conclusions not directly shown by that run's runtime evidence +- `Harness issues`: setup or runner problems such as missing Java on PATH, stale tmux sessions, stale `stdin.pipe`, missing log artifacts, or failed config generation Never upgrade inferred claims to observed facts. Absence of errors is supporting evidence only; pair it with a positive assertion for the feature under test. @@ -196,6 +211,7 @@ Always summarize: ## Troubleshooting - If the first RCON command fails, retry it before assuming the setup is broken. +- If Java is installed but the harness still says it is missing, run `preflight_test_env.sh`. This resolves common Homebrew Java paths on macOS. - If MCC reaches Microsoft device-code login during an offline test, stop and inspect the generated temp config before retrying. - If the user explicitly requests Microsoft online login, set `MCC_TEST_ACCOUNT_TYPE=microsoft` before launching the harness. - If the user explicitly requests Microsoft online login, use `BasicIO-NoColor` in a real TTY, relay the device code from the TUI, and avoid pressing empty Enter at any auth prompt. @@ -203,7 +219,8 @@ Always summarize: - If `dotnet run` cannot see an existing Microsoft session, check whether `SessionCache.db` and `ProfileKeyCache.ini` need to be synced from `MinecraftClient/bin/Release/net10.0/` to the repo root. - If Microsoft auth keeps prompting even with a valid session cache, verify `Account.Login` matches the cached username exactly. - If MCC reports `Connection refused`, verify the launched target matches the server's actual `server-port`. +- If MCC reports `Connection refused` immediately after a server start, also check for stale shared state: old tmux sessions, a stale `stdin.pipe`, or a server that never actually reached `Done (`. - If multiple versions are being tested, do not start them in parallel unless the harness isolates tmux sessions and input files. - If a test assertion fails, inspect the real MCC output before changing the code or weakening the assertion. - If an older server behaves oddly on Linux, check `use-native-transport=false` in `server.properties`. -- If a test should be repeatable, avoid mutating the repo-root `MinecraftClient.ini`. +- If a matrix row fails before producing `mcc.log` or a command transcript, treat it as a harness failure, fix the environment, and rerun that row before drawing product conclusions. diff --git a/.skills/mcc-integration-testing/scripts/common.sh b/.skills/mcc-integration-testing/scripts/common.sh new file mode 100755 index 00000000..973b5da3 --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/common.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +sed_in_place() { + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +ensure_java_in_path() { + if command -v java >/dev/null 2>&1 && java -version >/dev/null 2>&1; then + return 0 + fi + + local candidate + for candidate in \ + "${JAVA_BIN:-}" \ + "/opt/homebrew/opt/openjdk/bin/java" \ + "/usr/local/opt/openjdk/bin/java" \ + "/usr/lib/jvm/default-java/bin/java" + do + [[ -z "$candidate" ]] && continue + if [[ -x "$candidate" ]]; then + export PATH="$(dirname "$candidate"):$PATH" + export JAVA_BIN="$candidate" + if java -version >/dev/null 2>&1; then + return 0 + fi + fi + done + + echo "java was not found on PATH. Install Java or set JAVA_BIN." >&2 + return 1 +} + +server_session_name() { + printf 'mc-%s\n' "${1//./_}" +} + +server_running() { + local version="$1" + mc-list | grep -Fq "$(server_session_name "$version")" +} + +wait_for_server_ready() { + local version="$1" + local timeout="${2:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if mc-log "$version" 250 2>/dev/null | grep -Fq "Done ("; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for $version to become ready" >&2 + return 1 +} + +wait_for_server_stop() { + local version="$1" + local timeout="${2:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if ! server_running "$version"; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + mc-kill "$version" >/dev/null 2>&1 || true + + if ! server_running "$version"; then + return 0 + fi + + echo "Timed out waiting for $version to stop" >&2 + return 1 +} + +disable_noisy_bots_in_ini() { + local ini_file="$1" + local section + + for section in \ + ScriptScheduler \ + DiscordRpc \ + AntiAFK \ + AutoDig \ + AutoAttack \ + PlayerListLogger \ + ReplayCapture + do + sed_in_place "/^\\[ChatBot\\.${section}\\]/,/^\\[/ { s/^Enabled = true/Enabled = false/; }" "$ini_file" + done +} + +remove_stale_stdin_pipe() { + local version="$1" + local pipe_path="$MCC_SERVERS/$version/stdin.pipe" + + if [[ -e "$pipe_path" && ! -p "$pipe_path" ]]; then + rm -f "$pipe_path" + fi +} diff --git a/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh index 1e348445..38e73978 100755 --- a/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh +++ b/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh @@ -5,14 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # shellcheck source=tools/mcc-env.sh source "$REPO_ROOT/tools/mcc-env.sh" - -sed_in_place() { - if [[ "$(uname)" == "Darwin" ]]; then - sed -i '' "$@" - else - sed -i "$@" - fi -} +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" VERSION="${1:-1.21.11-Vanilla}" SERVER_DIR="${MCC_SERVERS:?}/$VERSION" @@ -33,43 +27,6 @@ server_running() { mc-list | grep -Fq "$SESSION_NAME" } -wait_for_server_ready() { - local timeout="${1:-60}" - local elapsed=0 - while (( elapsed < timeout )); do - if mc-log "$VERSION" 200 2>/dev/null | grep -Fq "Done ("; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - echo "Timed out waiting for $VERSION to become ready" >&2 - return 1 -} - -wait_for_server_stop() { - local timeout="${1:-60}" - local elapsed=0 - while (( elapsed < timeout )); do - if ! server_running; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - - # Legacy servers can leave the tmux session around after stdin stop. - # Fall back to force-killing the session so the harness can continue. - mc-kill "$VERSION" >/dev/null 2>&1 || true - - if ! server_running; then - return 0 - fi - - echo "Timed out waiting for $VERSION to stop" >&2 - return 1 -} - upsert_property() { local key="$1" local value="$2" @@ -83,14 +40,14 @@ upsert_property() { if [[ ! -f "$PROPS_FILE" ]]; then mc-start "$VERSION" - wait_for_server_ready + wait_for_server_ready "$VERSION" mc-stop "$VERSION" - wait_for_server_stop + wait_for_server_stop "$VERSION" fi if server_running; then mc-stop "$VERSION" - wait_for_server_stop + wait_for_server_stop "$VERSION" fi upsert_property "online-mode" "false" diff --git a/.skills/mcc-integration-testing/scripts/preflight_test_env.sh b/.skills/mcc-integration-testing/scripts/preflight_test_env.sh new file mode 100755 index 00000000..22376026 --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/preflight_test_env.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# shellcheck source=tools/mcc-env.sh +source "$REPO_ROOT/tools/mcc-env.sh" +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" + +usage() { + cat <<'EOF' +Usage: preflight_test_env.sh [server-dir...] + +Checks the local MCC test environment and resolves common Java path issues. +EOF +} + +if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage + exit 0 +fi + +ensure_java_in_path +command -v tmux >/dev/null 2>&1 || { echo "tmux was not found on PATH." >&2; exit 1; } +command -v dotnet >/dev/null 2>&1 || { echo "dotnet was not found on PATH." >&2; exit 1; } +command -v python3 >/dev/null 2>&1 || { echo "python3 was not found on PATH." >&2; exit 1; } + +if [[ ! -d "$MCC_SERVERS" ]]; then + echo "Server root not found: $MCC_SERVERS" >&2 + exit 1 +fi + +for server_dir in "$@"; do + [[ -z "$server_dir" ]] && continue + if [[ ! -d "$MCC_SERVERS/$server_dir" ]]; then + echo "Server directory not found: $MCC_SERVERS/$server_dir" >&2 + exit 1 + fi + + remove_stale_stdin_pipe "$server_dir" +done + +printf 'MCC_REPO=%s\n' "$MCC_REPO" +printf 'MCC_SERVERS=%s\n' "$MCC_SERVERS" +printf 'JAVA=%s\n' "$(command -v java)" +printf 'TMUX=%s\n' "$(command -v tmux)" +printf 'DOTNET=%s\n' "$(command -v dotnet)" diff --git a/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh b/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh index 9eae53b3..64727a58 100644 --- a/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh +++ b/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh @@ -1,23 +1,40 @@ #!/usr/bin/env bash set -euo pipefail -sed_in_place() { - if [[ "$(uname)" == "Darwin" ]]; then - sed -i '' "$@" - else - sed -i "$@" - fi +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" + +usage() { + cat <<'EOF' >&2 +Usage: + prepare_offline_mcc_config.sh [login] + prepare_offline_mcc_config.sh [login] +EOF } -if [[ $# -lt 3 || $# -gt 4 ]]; then - echo "Usage: $0 [login]" >&2 +if [[ $# -lt 2 || $# -gt 4 ]]; then + usage exit 1 fi -TEMPLATE_INI="$1" -OUTPUT_INI="$2" -MC_VERSION="$3" -LOGIN_NAME="${4:-CursorBot}" +TEMPLATE_INI="" +OUTPUT_INI="" +MC_VERSION="" +LOGIN_NAME="" + +if [[ $# -ge 3 && -f "$1" ]]; then + TEMPLATE_INI="$1" + OUTPUT_INI="$2" + MC_VERSION="$3" + LOGIN_NAME="${4:-CursorBot}" +else + OUTPUT_INI="$1" + MC_VERSION="$2" + LOGIN_NAME="${3:-CursorBot}" +fi + ACCOUNT_TYPE="${MCC_TEST_ACCOUNT_TYPE:-mojang}" PASSWORD_VALUE="${MCC_TEST_PASSWORD-}" @@ -34,6 +51,32 @@ if [[ -z "${MCC_TEST_PASSWORD+x}" ]]; then fi fi +generate_template_ini() { + local template_root + template_root="$(mktemp -d "${TMPDIR:-/tmp}/mcc-config-template.XXXXXX")" + + if [[ ! -f "$REPO_ROOT/MinecraftClient/bin/Release/net10.0/MinecraftClient.dll" ]]; then + dotnet build "$REPO_ROOT/MinecraftClient.sln" -c Release -v quiet --nologo >/dev/null + fi + + ( + cd "$template_root" + dotnet run --project "$REPO_ROOT/MinecraftClient" -c Release --no-build -- --help >/dev/null 2>&1 + ) + + if [[ ! -f "$template_root/MinecraftClient.ini" ]]; then + echo "Failed to generate a temporary MCC config template." >&2 + exit 1 + fi + + TEMPLATE_INI="$template_root/MinecraftClient.ini" +} + +if [[ -z "$TEMPLATE_INI" ]]; then + generate_template_ini +fi + +mkdir -p "$(dirname "$OUTPUT_INI")" cp "$TEMPLATE_INI" "$OUTPUT_INI" sed_in_place \ @@ -46,6 +89,8 @@ sed_in_place \ -e 's#^AutoRespawn = false#AutoRespawn = true#' \ "$OUTPUT_INI" +disable_noisy_bots_in_ini "$OUTPUT_INI" + grep -Fq "AccountType = \"$ACCOUNT_TYPE\"" "$OUTPUT_INI" || { echo "Failed to enforce account type $ACCOUNT_TYPE in $OUTPUT_INI" >&2 exit 1 diff --git a/.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh b/.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh new file mode 100755 index 00000000..2d84ac1b --- /dev/null +++ b/.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +# shellcheck source=tools/mcc-env.sh +source "$REPO_ROOT/tools/mcc-env.sh" +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" + +usage() { + cat <<'EOF' +Usage: reset_shared_test_state.sh [--all | ...] + +Kills shared tmux test sessions and removes stale stdin pipes. +EOF +} + +if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage + exit 0 +fi + +kill_named_session() { + local session_name="$1" + tmux kill-session -t "$session_name" 2>/dev/null || true +} + +kill_named_session "mcc-debug" + +if [[ $# -eq 0 || "${1:-}" == "--all" ]]; then + while IFS= read -r session_name; do + [[ -z "$session_name" ]] && continue + kill_named_session "$session_name" + done < <(tmux list-sessions 2>/dev/null | awk -F: '/^mc-/{print $1}' || true) + + while IFS= read -r pipe_path; do + [[ -z "$pipe_path" ]] && continue + if [[ ! -p "$pipe_path" ]]; then + rm -f "$pipe_path" + fi + done < <(find "$MCC_SERVERS" -maxdepth 2 -name 'stdin.pipe' 2>/dev/null || true) +else + for version in "$@"; do + kill_named_session "$(server_session_name "$version")" + remove_stale_stdin_pipe "$version" + done +fi + +rm -f "$MCC_REPO/mcc_input.txt" diff --git a/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh b/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh index 45629525..65ff7d3f 100755 --- a/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh +++ b/.skills/mcc-integration-testing/scripts/run_achievements_matrix.sh @@ -64,6 +64,16 @@ run_version() { # shellcheck disable=SC1090 source "$summary_env" + if [[ -n "${MCC_LOG:-}" && ! -f "$MCC_LOG" ]]; then + NOTE="Harness failure: MCC log was not produced." + VERDICT="❌ Fail" + fi + + if [[ -n "${COMMAND_LOG:-}" && ! -f "$COMMAND_LOG" ]]; then + NOTE="Harness failure: command transcript was not produced." + VERDICT="❌ Fail" + fi + write_row "$VERSION" "$SERVER_DIR" "$PORT" "$FAMILY" "$INITIAL_STATUS" "$GRANT_STATUS" "$REVOKE_STATUS" \ "$API_STATUS" "$VERDICT" "$NOTE" "$RUN_DIR" "$MCC_LOG" "$COPIED_SERVER_LOG" "$COMMAND_LOG" } @@ -94,6 +104,7 @@ if ! command -v tmux >/dev/null 2>&1; then fi if [[ "$DOTNET_OK" == "yes" ]]; then + bash "$SCRIPT_DIR/preflight_test_env.sh" >/dev/null 2>&1 || true if ! dotnet build "$REPO_ROOT/MinecraftClient.sln" -c Release > "$BUILD_LOG" 2>&1; then BUILD_OK="no" fi diff --git a/.skills/mcc-integration-testing/scripts/run_achievements_test.sh b/.skills/mcc-integration-testing/scripts/run_achievements_test.sh index 88c2b027..df0236e0 100755 --- a/.skills/mcc-integration-testing/scripts/run_achievements_test.sh +++ b/.skills/mcc-integration-testing/scripts/run_achievements_test.sh @@ -5,14 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # shellcheck source=tools/mcc-env.sh source "$REPO_ROOT/tools/mcc-env.sh" - -sed_in_place() { - if [[ "$(uname)" == "Darwin" ]]; then - sed -i '' "$@" - else - sed -i "$@" - fi -} +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" usage() { cat <<'EOF' @@ -131,6 +125,7 @@ cleanup() { fi mc-stop "$SERVER_DIR" >/dev/null 2>&1 || true + wait_for_server_stop "$SERVER_DIR" 20 >/dev/null 2>&1 || true ln -sfn "$RUN_DIR" "$LATEST_LINK" write_summary } @@ -165,43 +160,6 @@ wait_for_file_pattern() { return 1 } -wait_for_server_ready() { - local timeout="${1:-60}" - local elapsed=0 - - while (( elapsed < timeout )); do - if mc-log "$SERVER_DIR" 250 2>/dev/null | grep -Fq "Done ("; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - - echo "Timed out waiting for server readiness" >&2 - return 1 -} - -disable_noisy_bots() { - sed_in_place '/^\[ChatBot.ScriptScheduler\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.DiscordRpc\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.AntiAFK\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.AutoDig\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.AutoAttack\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.PlayerListLogger\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" - sed_in_place '/^\[ChatBot.ReplayCapture\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$REPO_ROOT/MinecraftClient.ini" -} - -ensure_root_config() { - if [[ -f "$REPO_ROOT/MinecraftClient.ini" ]]; then - return - fi - - ( - cd "$REPO_ROOT" - dotnet run --project MinecraftClient -c Release --no-build -- --help >/dev/null 2>&1 - ) -} - write_probe_script() { cat > "$PROBE_SCRIPT" </dev/null 2>&1 || ! java -version >/dev/null 2>&1; then - fail "java was not found on PATH." -fi - -if ! command -v tmux >/dev/null 2>&1; then - fail "tmux was not found on PATH." -fi - -if [[ ! -d "$MCC_SERVERS/$SERVER_DIR" ]]; then - fail "Server directory not found: $MCC_SERVERS/$SERVER_DIR" -fi - -PORT="$(bash "$SCRIPT_DIR/get_server_port.sh" "$SERVER_DIR")" - -ensure_root_config -"$SCRIPT_DIR/ensure_offline_server.sh" "$SERVER_DIR" -disable_noisy_bots -write_probe_script - -if [[ "$PROFILE" == "legacy" && -f "$MCC_SERVERS/$SERVER_DIR/server.properties" ]]; then - sed_in_place 's/^use-native-transport=.*/use-native-transport=false/' "$MCC_SERVERS/$SERVER_DIR/server.properties" -fi - if $DO_BUILD; then log_step "BUILD> dotnet build MinecraftClient.sln -c Release" mcc-build > "$BUILD_LOG" 2>&1 || fail "dotnet build failed." @@ -344,17 +279,35 @@ else : > "$BUILD_LOG" fi +bash "$SCRIPT_DIR/preflight_test_env.sh" "$SERVER_DIR" >/dev/null || fail "Test environment preflight failed." +bash "$SCRIPT_DIR/reset_shared_test_state.sh" "$SERVER_DIR" >/dev/null || fail "Failed to reset shared test state." + +if [[ ! -d "$MCC_SERVERS/$SERVER_DIR" ]]; then + fail "Server directory not found: $MCC_SERVERS/$SERVER_DIR" +fi + +bash "$SCRIPT_DIR/prepare_offline_mcc_config.sh" "$CFG" "$MC_VERSION" CursorBot >/dev/null || fail "Failed to prepare temporary MCC config." +PORT="$(bash "$SCRIPT_DIR/get_server_port.sh" "$SERVER_DIR")" + +"$SCRIPT_DIR/ensure_offline_server.sh" "$SERVER_DIR" +write_probe_script + +if [[ "$PROFILE" == "legacy" && -f "$MCC_SERVERS/$SERVER_DIR/server.properties" ]]; then + sed_in_place 's/^use-native-transport=.*/use-native-transport=false/' "$MCC_SERVERS/$SERVER_DIR/server.properties" +fi + : > "$INPUT_FILE" rm -f "$MCC_LOG" log_step "Starting server $SERVER_DIR on port $PORT" mc-start "$SERVER_DIR" >/dev/null -wait_for_server_ready || fail "Server did not become ready." +wait_for_server_ready "$SERVER_DIR" || fail "Server did not become ready." log_step "Starting MCC for $MC_VERSION" ( cd "$REPO_ROOT" MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release --no-build -- \ + "$CFG" \ CursorBot \ - \ "localhost:$PORT" \ diff --git a/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh index 2db7d2a8..51021974 100755 --- a/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh +++ b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh @@ -5,6 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # shellcheck source=tools/mcc-env.sh source "$REPO_ROOT/tools/mcc-env.sh" +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$SCRIPT_DIR/common.sh" VERSION="${1:-1.21.11-Vanilla}" MC_VERSION="${VERSION%-Vanilla}" @@ -34,46 +36,12 @@ cleanup() { fi mc-stop "$VERSION" >/dev/null 2>&1 || true + wait_for_server_stop "$VERSION" 20 >/dev/null 2>&1 || true } trap cleanup EXIT prepare_config() { - bash "$SCRIPT_DIR/prepare_offline_mcc_config.sh" "$REPO_ROOT/MinecraftClient.ini" "$CFG" "$MC_VERSION" >/dev/null -} - -wait_for_file_pattern() { - local file="$1" - local pattern="$2" - local description="$3" - local timeout="${4:-60}" - local elapsed=0 - - while (( elapsed < timeout )); do - if [[ -f "$file" ]] && grep -Fq "$pattern" "$file"; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - - echo "Timed out waiting for: $description" >&2 - return 1 -} - -wait_for_server_ready() { - local timeout="${1:-60}" - local elapsed=0 - - while (( elapsed < timeout )); do - if mc-log "$VERSION" 250 2>/dev/null | grep -Fq "Done ("; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - - echo "Timed out waiting for server readiness" >&2 - return 1 + bash "$SCRIPT_DIR/prepare_offline_mcc_config.sh" "$CFG" "$MC_VERSION" CursorBot >/dev/null } wait_for_server_log_pattern() { @@ -101,6 +69,25 @@ capture_server_logs() { fi } +wait_for_file_pattern() { + local file="$1" + local pattern="$2" + local description="$3" + local timeout="${4:-60}" + local elapsed=0 + + while (( elapsed < timeout )); do + if [[ -f "$file" ]] && grep -Fq "$pattern" "$file"; then + return 0 + fi + sleep 1 + ((elapsed += 1)) + done + + echo "Timed out waiting for: $description" >&2 + return 1 +} + fail() { capture_server_logs echo "FAIL: $1" >&2 @@ -146,18 +133,19 @@ run_mcc_command() { sleep 2 } +bash "$SCRIPT_DIR/preflight_test_env.sh" "$VERSION" >/dev/null +bash "$SCRIPT_DIR/reset_shared_test_state.sh" "$VERSION" >/dev/null "$SCRIPT_DIR/ensure_offline_server.sh" "$VERSION" +echo "Building MCC..." +mcc-build > "$BUILD_LOG" 2>&1 || fail "mcc-build failed" prepare_config SERVER_PORT="$(bash "$SCRIPT_DIR/get_server_port.sh" "$VERSION")" : > "$INPUT_FILE" -echo "Building MCC..." -mcc-build > "$BUILD_LOG" 2>&1 || fail "mcc-build failed" - echo "Starting server..." mc-start "$VERSION" >/dev/null -wait_for_server_ready || fail "Server did not become ready" +wait_for_server_ready "$VERSION" || fail "Server did not become ready" echo "Starting MCC..." ( diff --git a/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh b/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh index 9dbeb78c..6ef72397 100755 --- a/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh +++ b/.skills/mcc-integration-testing/scripts/summarize_achievements_matrix.sh @@ -54,4 +54,4 @@ echo "## Inferred" echo echo "- Only rows with real MCC and server-log artifacts count as executed proof." echo "- Rows blocked by missing Java, tmux, or server directories are environment-limited, not product pass results." -echo "- Legacy rows remain the highest-risk bucket because static inspection suggests pre-1.12 \`Statistics\` packets may not currently reach the achievements handler." +echo "- Rows with missing MCC or command-log artifacts should be treated as harness failures until rerun confirms a product issue." diff --git a/.skills/mcc-version-adaptation/SKILL.md b/.skills/mcc-version-adaptation/SKILL.md index 195b5592..706399cb 100644 --- a/.skills/mcc-version-adaptation/SKILL.md +++ b/.skills/mcc-version-adaptation/SKILL.md @@ -15,6 +15,7 @@ Systematic workflow for updating Minecraft Console Client to support a new Minec $MCC_REPO/tools/decompile.sh --version ``` This auto-downloads `MinecraftDecompiler.jar` if needed, produces the decompiled source, and downloads `server.jar` into `$MCC_SERVERS//`. +- `tools/decompile.sh` depends on official mappings. For older versions where it refuses to decompile, fall back to a raw Java decompiler such as `cfr-decompiler` against `$MCC_SERVERS//server.jar`. That fallback is good enough for packet inspection and registration order checks even when the output is obfuscated. - A test server of the target version in `$MCC_SERVERS//` (see `mcc-dev-workflow` skill) ## Step 0: Generate Server Reports (CRITICAL since 1.21.9) diff --git a/tools/mcc-debug.sh b/tools/mcc-debug.sh index b29f4b20..c5c6205e 100644 --- a/tools/mcc-debug.sh +++ b/tools/mcc-debug.sh @@ -32,6 +32,7 @@ EOF VERSION="1.21.11-Vanilla" MODE="classic" PORT="25565" +PORT_SET_BY_USER=false DO_BUILD=true DEBUG_ON=false FILE_INPUT=false @@ -40,7 +41,7 @@ while [[ $# -gt 0 ]]; do case "$1" in -v|--version) VERSION="$2"; shift 2 ;; -m|--mode) MODE="$2"; shift 2 ;; - -p|--port) PORT="$2"; shift 2 ;; + -p|--port) PORT="$2"; PORT_SET_BY_USER=true; shift 2 ;; --no-build) DO_BUILD=false; shift ;; --debug-on) DEBUG_ON=true; shift ;; --file-input) FILE_INPUT=true; shift ;; @@ -54,6 +55,10 @@ CFG="$TEST_ROOT/MinecraftClient.debug.ini" MCC_LOG="$TEST_ROOT/mcc-debug.log" INPUT_FILE="$REPO_ROOT/mcc_input.txt" SESSION_NAME="mc-${VERSION//\./_}" +PREPARE_CFG_SCRIPT="$REPO_ROOT/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh" +ENSURE_SERVER_SCRIPT="$REPO_ROOT/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh" +PREFLIGHT_SCRIPT="$REPO_ROOT/.skills/mcc-integration-testing/scripts/preflight_test_env.sh" +GET_PORT_SCRIPT="$REPO_ROOT/.skills/mcc-integration-testing/scripts/get_server_port.sh" mkdir -p "$TEST_ROOT" @@ -64,6 +69,8 @@ echo " Config: $CFG" echo " Log: $MCC_LOG" echo "" +bash "$PREFLIGHT_SCRIPT" "$VERSION" >/dev/null + # --- Build --- if $DO_BUILD; then echo "[1/4] Building MCC..." @@ -75,21 +82,22 @@ fi # --- Prepare config --- echo "[2/4] Preparing config..." -cp "$REPO_ROOT/MinecraftClient.ini" "$CFG" - -sed -i \ - -e 's/Account = { Login = "[^"]*", Password = "[^"]*" }/Account = { Login = "CursorBot", Password = "-" }/' \ - -e 's/TerrainAndMovements = false/TerrainAndMovements = true/' \ - -e 's/InventoryHandling = false/InventoryHandling = true/' \ - -e 's/EntityHandling = false/EntityHandling = true/' \ - "$CFG" +bash "$PREPARE_CFG_SCRIPT" "$CFG" "${VERSION%-Vanilla}" CursorBot >/dev/null if [[ "$MODE" == "tui" ]]; then - sed -i 's/ConsoleMode = "classic"/ConsoleMode = "tui"/' "$CFG" + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' 's/ConsoleMode = "classic"/ConsoleMode = "tui"/' "$CFG" + else + sed -i 's/ConsoleMode = "classic"/ConsoleMode = "tui"/' "$CFG" + fi fi if $DEBUG_ON; then - sed -i 's/DebugMessages = false/DebugMessages = true/' "$CFG" + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' 's/DebugMessages = false/DebugMessages = true/' "$CFG" + else + sed -i 's/DebugMessages = false/DebugMessages = true/' "$CFG" + fi fi echo " Config ready" @@ -99,14 +107,7 @@ echo "[3/4] Starting server $VERSION..." if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then echo " Server already running" else - # Ensure offline mode - SERVER_DIR="$MCC_SERVERS/$VERSION" - if [[ -f "$SERVER_DIR/server.properties" ]]; then - sed -i 's/^online-mode=.*/online-mode=false/' "$SERVER_DIR/server.properties" - grep -q "^enable-rcon=" "$SERVER_DIR/server.properties" || echo "enable-rcon=true" >> "$SERVER_DIR/server.properties" - grep -q "^rcon.password=" "$SERVER_DIR/server.properties" || echo "rcon.password=test123" >> "$SERVER_DIR/server.properties" - grep -q "^rcon.port=" "$SERVER_DIR/server.properties" || echo "rcon.port=25575" >> "$SERVER_DIR/server.properties" - fi + bash "$ENSURE_SERVER_SCRIPT" "$VERSION" >/dev/null mc-start "$VERSION" >/dev/null echo -n " Waiting for server..." @@ -125,6 +126,10 @@ else done fi +if ! $PORT_SET_BY_USER; then + PORT="$(bash "$GET_PORT_SCRIPT" "$VERSION")" +fi + # --- Launch MCC --- echo "[4/4] Launching MCC in $MODE mode..." : > "$INPUT_FILE" diff --git a/tools/mcc-env.sh b/tools/mcc-env.sh index 6ddca998..904a8a00 100644 --- a/tools/mcc-env.sh +++ b/tools/mcc-env.sh @@ -26,6 +26,9 @@ mc-cmd() { local v="${2:-1.20.6}"; echo "$1" > "$MCC_SERVERS/$v/stdin.pipe"; } mc-log() { local s; s=$(_mc-session "${1:-1.20.6}"); tmux capture-pane -t "$s" -p -S "-${2:-50}"; } mc-kill() { local v="${1:-1.20.6}" s; s=$(_mc-session "$v"); tmux kill-session -t "$s" 2>/dev/null; rm -f "$MCC_SERVERS/$v/stdin.pipe"; echo "Killed $s"; } mc-list() { tmux list-sessions 2>/dev/null | grep "^mc-" || echo "No running MC servers"; } +mc-wait-ready() { bash "$MCC_REPO/.skills/mcc-integration-testing/scripts/preflight_test_env.sh" "${1:-1.20.6}" >/dev/null && source "$MCC_REPO/.skills/mcc-integration-testing/scripts/common.sh" && wait_for_server_ready "${1:-1.20.6}" "${2:-60}"; } +mc-wait-stop() { source "$MCC_REPO/.skills/mcc-integration-testing/scripts/common.sh" && wait_for_server_stop "${1:-1.20.6}" "${2:-60}"; } +mc-reset-test-env() { bash "$MCC_REPO/.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh" "$@"; } # --- RCON --- mc-rcon() { bash "$MCC_REPO/tools/mc-rcon.sh" "$@"; } @@ -59,3 +62,4 @@ mcc-tui() { mcc-debug() { bash "$MCC_REPO/tools/mcc-debug.sh" "$@"; } mcc-log-mcc() { tail -f "${TMPDIR:-/tmp}/mcc-debug/mcc-debug.log" 2>/dev/null || echo "No MCC log found"; } mcc-state() { echo "debug state" >> "$MCC_REPO/mcc_input.txt"; sleep 1; tail -30 "${TMPDIR:-/tmp}/mcc-debug/mcc-debug.log" 2>/dev/null; } +mcc-preflight() { bash "$MCC_REPO/.skills/mcc-integration-testing/scripts/preflight_test_env.sh" "$@"; } diff --git a/tools/run-creative-e2e.sh b/tools/run-creative-e2e.sh index 35555ad9..83fdb42a 100644 --- a/tools/run-creative-e2e.sh +++ b/tools/run-creative-e2e.sh @@ -5,6 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # shellcheck source=tools/mcc-env.sh source "$REPO_ROOT/tools/mcc-env.sh" +# shellcheck source=.skills/mcc-integration-testing/scripts/common.sh +source "$REPO_ROOT/.skills/mcc-integration-testing/scripts/common.sh" usage() { cat <<'EOF' @@ -37,6 +39,7 @@ MCC_LOG="$TEST_ROOT/mcc.log" SERVER_LOG_FILE="$MCC_SERVERS/$SERVER_DIR/logs/latest.log" INPUT_FILE="$REPO_ROOT/mcc_input.txt" MCC_PID="" +SERVER_PORT="25565" mkdir -p "$TEST_ROOT" @@ -59,33 +62,6 @@ wait_for_file_pattern() { return 1 } -wait_for_server_ready() { - local timeout="${1:-60}" - local elapsed=0 - - while (( elapsed < timeout )); do - if mc-log "$SERVER_DIR" 250 2>/dev/null | grep -Fq "Done ("; then - return 0 - fi - sleep 1 - ((elapsed += 1)) - done - - echo "Timed out waiting for server readiness" >&2 - return 1 -} - -kill_other_servers() { - local sessions - sessions="$(tmux list-sessions 2>/dev/null | awk -F: '/^mc-/{print $1}' || true)" - if [[ -n "$sessions" ]]; then - while IFS= read -r session; do - [[ -z "$session" ]] && continue - tmux kill-session -t "$session" 2>/dev/null || true - done <<< "$sessions" - fi -} - cleanup() { if [[ -n "${MCC_PID:-}" ]] && kill -0 "$MCC_PID" 2>/dev/null; then echo "quit" >> "$INPUT_FILE" 2>/dev/null || true @@ -96,7 +72,7 @@ cleanup() { if [[ -p "$MCC_SERVERS/$SERVER_DIR/stdin.pipe" ]]; then echo "stop" > "$MCC_SERVERS/$SERVER_DIR/stdin.pipe" 2>/dev/null || true - sleep 2 + wait_for_server_stop "$SERVER_DIR" 20 >/dev/null 2>&1 || true fi tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true @@ -105,24 +81,7 @@ cleanup() { trap cleanup EXIT prepare_config() { - cp "$REPO_ROOT/MinecraftClient.ini" "$CFG" - - sed -i \ - -e 's/Account = { Login = "test", Password = "-" }/Account = { Login = "CursorBot", Password = "-" }/' \ - -e "s/MinecraftVersion = \"auto\"/MinecraftVersion = \"$MC_VERSION\"/" \ - -e 's/TerrainAndMovements = false/TerrainAndMovements = true/' \ - -e 's/InventoryHandling = false/InventoryHandling = true/' \ - -e 's/EntityHandling = false/EntityHandling = true/' \ - -e 's/AutoRespawn = false/AutoRespawn = true/' \ - "$CFG" - - sed -i '/^\[ChatBot.ScriptScheduler\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.DiscordRpc\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.AntiAFK\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.AutoDig\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.AutoAttack\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.PlayerListLogger\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" - sed -i '/^\[ChatBot.ReplayCapture\]/,/^\[/ { s/^Enabled = true/Enabled = false/; }' "$CFG" + bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh" "$CFG" "$MC_VERSION" CursorBot >/dev/null } send_mcc_command() { @@ -195,23 +154,30 @@ modern_mob_and_effects() { run_server_command "effect give CursorBot minecraft:regeneration 10 1 true" } +bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/preflight_test_env.sh" "$SERVER_DIR" >/dev/null +bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/reset_shared_test_state.sh" --all >/dev/null prepare_config -kill_other_servers rm -f "$MCC_LOG" "$INPUT_FILE" bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/ensure_offline_server.sh" "$SERVER_DIR" >/dev/null +SERVER_PORT="$(bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/get_server_port.sh" "$SERVER_DIR")" if [[ -f "$MCC_SERVERS/$SERVER_DIR/server.properties" ]]; then - sed -i 's/^use-native-transport=.*/use-native-transport=false/' "$MCC_SERVERS/$SERVER_DIR/server.properties" + sed_in_place 's/^use-native-transport=.*/use-native-transport=false/' "$MCC_SERVERS/$SERVER_DIR/server.properties" fi mc-start "$SERVER_DIR" >/dev/null -wait_for_server_ready || exit 1 +wait_for_server_ready "$SERVER_DIR" || exit 1 : > "$INPUT_FILE" ( cd "$REPO_ROOT" - MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release --no-build -- "$CFG" > "$MCC_LOG" 2>&1 + MCC_FILE_INPUT=1 dotnet run --project MinecraftClient -c Release --no-build -- \ + "$CFG" \ + CursorBot \ + - \ + "localhost:$SERVER_PORT" \ + > "$MCC_LOG" 2>&1 ) & MCC_PID=$! diff --git a/tools/start-server.sh b/tools/start-server.sh index 9debbae9..63e5eed3 100644 --- a/tools/start-server.sh +++ b/tools/start-server.sh @@ -1,12 +1,38 @@ #!/bin/bash # Start a Minecraft server in a tmux session with named pipe for stdin # Servers live under $MCC_SERVERS or default to MinecraftOfficial/downloads//. +resolve_java_bin() { + if command -v java >/dev/null 2>&1 && java -version >/dev/null 2>&1; then + command -v java + return 0 + fi + + local candidate + for candidate in \ + "${JAVA_BIN:-}" \ + "/opt/homebrew/opt/openjdk/bin/java" \ + "/usr/local/opt/openjdk/bin/java" \ + "/usr/lib/jvm/default-java/bin/java" + do + [[ -z "$candidate" ]] && continue + if [[ -x "$candidate" ]]; then + if "$candidate" -version >/dev/null 2>&1; then + printf '%s\n' "$candidate" + return 0 + fi + fi + done + + return 1 +} + VERSION="${1}" REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" DOWNLOADS="${MCC_SERVERS:-$REPO_ROOT/MinecraftOfficial/downloads}" DIR="$DOWNLOADS/$VERSION" PIPE="$DIR/stdin.pipe" SESSION="mc-${VERSION//\./_}" +JAVA_BIN="$(resolve_java_bin || true)" if [ -z "$VERSION" ] || [ ! -d "$DIR" ]; then echo "Error: Server directory not found${VERSION:+: $DIR}" @@ -20,6 +46,16 @@ if [ ! -f "$DIR/server.jar" ]; then exit 1 fi +if ! command -v tmux >/dev/null 2>&1; then + echo "Error: tmux is required to start local test servers" + exit 1 +fi + +if [[ -z "$JAVA_BIN" ]]; then + echo "Error: Java was not found on PATH. Install Java or set JAVA_BIN." >&2 + exit 1 +fi + if tmux has-session -t "$SESSION" 2>/dev/null; then echo "Server $VERSION already running in tmux session '$SESSION'" echo "View output: tmux capture-pane -t '$SESSION' -p -S -50" @@ -29,10 +65,14 @@ fi rm -f "$DIR/world/session.lock" +if [[ -e "$PIPE" && ! -p "$PIPE" ]]; then + rm -f "$PIPE" +fi + [ -p "$PIPE" ] || mkfifo "$PIPE" tmux new-session -d -s "$SESSION" -c "$DIR" \ - "tail -f $PIPE | java -Xmx2G -Xms2G -jar server.jar nogui 2>&1" + "tail -f $PIPE | '$JAVA_BIN' -Xmx2G -Xms2G -jar server.jar nogui 2>&1" echo "Server $VERSION started in tmux session '$SESSION'" echo "Send commands: echo 'say hello' > $PIPE" From eaf4704473113c01f6b954bb4314e6db08dc3ef0 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 00:00:50 +0800 Subject: [PATCH 297/484] Add icon banner display option and refactor startup banner logic - Introduced a configuration option `Display_Icon_Banner` to control the visibility of the startup icon banner. - Refactored `ProcessStartupState` to utilize TUI for displaying the banner if enabled, falling back to a classic banner display otherwise. - Added new methods for building the banner panel and icon grid for improved visual representation. - Updated translations and resource comments to support the new banner features. --- MinecraftClient/Program.cs | 30 +- .../ConfigComments/ConfigComments.Designer.cs | 4384 +++++++++-------- .../ConfigComments/ConfigComments.resx | 3 + .../Translations/Translations.Designer.cs | 12 + .../Resources/Translations/Translations.resx | 6 + MinecraftClient/Settings.cs | 3 + MinecraftClient/Tui/IconGridBuilder.cs | 125 + MinecraftClient/Tui/MccBannerPanelBuilder.cs | 180 + .../Tui/ServerStatusPanelBuilder.cs | 113 +- 9 files changed, 2557 insertions(+), 2299 deletions(-) create mode 100644 MinecraftClient/Tui/IconGridBuilder.cs create mode 100644 MinecraftClient/Tui/MccBannerPanelBuilder.cs diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 8c1e7644..9e71ad8e 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -228,9 +228,26 @@ namespace MinecraftClient /// True if startup can continue; false if config load failed and user chose to exit. internal static bool ProcessStartupState(StartupState state) { - ConsoleIO.WriteLine($"Minecraft Console Client v{Version} - for MC {MCLowestVersion} to {MCHighestVersion} - Github.com/MCCTeam"); - if (BuildInfo is not null) - ConsoleIO.WriteLineFormatted("§8" + BuildInfo); + if (Config.Console.General.Display_Icon_Banner && ConsoleIO.Backend is Tui.TuiConsoleBackend tuiBanner) + { + var view = tuiBanner.GetView(); + if (view is not null) + { + Avalonia.Threading.Dispatcher.UIThread.Post(() => + { + var panel = Tui.MccBannerPanelBuilder.Build(BuildInfo); + view.AppendControlToLog(panel); + }); + } + else + { + ShowClassicBanner(); + } + } + else + { + ShowClassicBanner(); + } var cfg = state.ConfigResult; @@ -271,6 +288,13 @@ namespace MinecraftClient return true; } + private static void ShowClassicBanner() + { + ConsoleIO.WriteLine(string.Format(Translations.mcc_banner_classic, Version, MCLowestVersion, MCHighestVersion, "Github.com/MCCTeam")); + if (BuildInfo is not null) + ConsoleIO.WriteLineFormatted("§8" + BuildInfo); + } + private static void MaybePrintClassicModeTuiRecommendation() { if (ConsoleIO.BasicIO diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs b/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs index 66213cc9..d94cab66 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.Designer.cs @@ -1,1848 +1,1858 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MinecraftClient { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ConfigComments { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ConfigComments() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftClient.Resources.ConfigComments.ConfigComments", typeof(ConfigComments).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to can be used in some other fields as %yourvar% - ///%username% and %serverip% are reserved variables.. - /// - internal static string AppVars_Variables { - get { - return ResourceManager.GetString("AppVars.Variables", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to =============================== # - /// Minecraft Console Client Bots # - ///=============================== #. - /// - internal static string ChatBot { - get { - return ResourceManager.GetString("ChatBot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Get alerted when specified words are detected in chat - ///Useful for moderating your server or detecting when someone is talking to you. - /// - internal static string ChatBot_Alerts { - get { - return ResourceManager.GetString("ChatBot.Alerts", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Play a beep sound when a word is detected in addition to highlighting.. - /// - internal static string ChatBot_Alerts_Beep_Enabled { - get { - return ResourceManager.GetString("ChatBot.Alerts.Beep_Enabled", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to List of words/strings to NOT alert you on.. - /// - internal static string ChatBot_Alerts_Excludes { - get { - return ResourceManager.GetString("ChatBot.Alerts.Excludes", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The name of a file where alers logs will be written.. - /// - internal static string ChatBot_Alerts_Log_File { - get { - return ResourceManager.GetString("ChatBot.Alerts.Log_File", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Log alerts info a file.. - /// - internal static string ChatBot_Alerts_Log_To_File { - get { - return ResourceManager.GetString("ChatBot.Alerts.Log_To_File", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to List of words/strings to alert you on.. - /// - internal static string ChatBot_Alerts_Matches { - get { - return ResourceManager.GetString("ChatBot.Alerts.Matches", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Trigger alerts when it rains and when it stops.. - /// - internal static string ChatBot_Alerts_Trigger_By_Rain { - get { - return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Rain", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Triggers alerts at the beginning and end of thunderstorms.. - /// - internal static string ChatBot_Alerts_Trigger_By_Thunderstorm { - get { - return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Thunderstorm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Triggers an alert after receiving a specified keyword.. - /// - internal static string ChatBot_Alerts_Trigger_By_Words { - get { - return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Words", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Send a command on a regular or random basis or make the bot walk around randomly to avoid automatic AFK disconnection - /// /!\ Make sure your server rules do not forbid anti-AFK mechanisms! - /// /!\ Make sure you keep the bot in an enclosure to prevent it wandering off if you're using terrain handling! (Recommended size 5x5x5). - /// - internal static string ChatBot_AntiAfk { - get { - return ResourceManager.GetString("ChatBot.AntiAfk", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Command to send to the server.. - /// - internal static string ChatBot_AntiAfk_Command { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Command", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The time interval for execution. (in seconds). - /// - internal static string ChatBot_AntiAfk_Delay { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to sneak when sending the command.. - /// - internal static string ChatBot_AntiAfk_Use_Sneak { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Use_Sneak", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use terrain handling to enable the bot to move around.. - /// - internal static string ChatBot_AntiAfk_Use_Terrain_Handling { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Use_Terrain_Handling", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The range the bot can move around randomly (Note: the bigger the range, the slower the bot will be). - /// - internal static string ChatBot_AntiAfk_Walk_Range { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Walk_Range", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How many times can the bot fail trying to move before using the command method.. - /// - internal static string ChatBot_AntiAfk_Walk_Retries { - get { - return ResourceManager.GetString("ChatBot.AntiAfk.Walk_Retries", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically attack hostile mobs around you - ///You need to enable Entity Handling to use this bot - /// /!\ Make sure server rules allow your planned use of AutoAttack - /// /!\ SERVER PLUGINS may consider AutoAttack to be a CHEAT MOD and TAKE ACTION AGAINST YOUR ACCOUNT so DOUBLE CHECK WITH SERVER RULES!. - /// - internal static string ChatBot_AutoAttack { - get { - return ResourceManager.GetString("ChatBot.AutoAttack", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Allow attacking hostile mobs.. - /// - internal static string ChatBot_AutoAttack_Attack_Hostile { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Hostile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Allow attacking passive mobs.. - /// - internal static string ChatBot_AutoAttack_Attack_Passive { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Passive", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Capped between 1 to 4. - /// - internal static string ChatBot_AutoAttack_Attack_Range { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Range", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How long to wait between each attack. Set "Custom = false" to let MCC calculate it.. - /// - internal static string ChatBot_AutoAttack_Cooldown_Time { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Cooldown_Time", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to All entity types can be found here: https://mccteam.github.io/r/entity/#L15. - /// - internal static string ChatBot_AutoAttack_Entites_List { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Entites_List", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Possible values: "Interact", "Attack" (default), "InteractAt" (Interact and Attack).. - /// - internal static string ChatBot_AutoAttack_Interaction { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Interaction", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Wether to treat the entities list as a "whitelist" or as a "blacklist".. - /// - internal static string ChatBot_AutoAttack_List_Mode { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.List_Mode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "single" or "multi". single target one mob per attack. multi target all mobs in range per attack. - /// - internal static string ChatBot_AutoAttack_Mode { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Mode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "health" or "distance". Only needed when using single mode. - /// - internal static string ChatBot_AutoAttack_Priority { - get { - return ResourceManager.GetString("ChatBot.AutoAttack.Priority", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically craft items in your inventory - ///See https://mccteam.github.io/g/bots/#auto-craft for how to use - ///You need to enable Inventory Handling to use this bot - ///You should also enable Terrain and Movements if you need to use a crafting table. - /// - internal static string ChatBot_AutoCraft { - get { - return ResourceManager.GetString("ChatBot.AutoCraft", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Location of the crafting table if you intended to use it. Terrain and movements must be enabled.. - /// - internal static string ChatBot_AutoCraft_CraftingTable { - get { - return ResourceManager.GetString("ChatBot.AutoCraft.CraftingTable", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to What to do on crafting failure, "abort" or "wait".. - /// - internal static string ChatBot_AutoCraft_OnFailure { - get { - return ResourceManager.GetString("ChatBot.AutoCraft.OnFailure", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Recipes.Name: The name can be whatever you like and it is used to represent the recipe. - ///Recipes.Type: crafting table type: "player" or "table" - ///Recipes.Result: the resulting item - ///Recipes.Slots: All slots, counting from left to right, top to bottom. Please fill in "Null" for empty slots. - ///For the naming of the items, please see: https://mccteam.github.io/r/item/#L12. - /// - internal static string ChatBot_AutoCraft_Recipes { - get { - return ResourceManager.GetString("ChatBot.AutoCraft.Recipes", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Auto-digging blocks. - ///You need to enable Terrain Handling to use this bot - ///You can use "/digbot start" and "/digbot stop" to control the start and stop of AutoDig. - ///Since MCC does not yet support accurate calculation of the collision volume of blocks, all blocks are considered as complete cubes when obtaining the position of the lookahead. - ///For the naming of the block, please see https://mccteam.github.io/r/block/#L15. - /// - internal static string ChatBot_AutoDig { - get { - return ResourceManager.GetString("ChatBot.AutoDig", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How many seconds to wait after entering the game to start digging automatically, set to -1 to disable automatic start.. - /// - internal static string ChatBot_AutoDig_Auto_Start_Delay { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Auto_Start_Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically switch to the appropriate tool.. - /// - internal static string ChatBot_AutoDig_Auto_Tool_Switch { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Auto_Tool_Switch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Mining a block for more than "Dig_Timeout" seconds will be considered a timeout.. - /// - internal static string ChatBot_AutoDig_Dig_Timeout { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Dig_Timeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to drop the current tool when its durability is too low.. - /// - internal static string ChatBot_AutoDig_Drop_Low_Durability_Tools { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Drop_Low_Durability_Tools", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Will not use tools with less durability than this. Set to zero to disable this feature.. - /// - internal static string ChatBot_AutoDig_Durability_Limit { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Durability_Limit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Wether to treat the blocks list as a "whitelist" or as a "blacklist".. - /// - internal static string ChatBot_AutoDig_List_Type { - get { - return ResourceManager.GetString("ChatBot.AutoDig.List_Type", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "distance" or "index", When using the "fixedpos" mode, the blocks are determined by distance to the player, or by the order in the list.. - /// - internal static string ChatBot_AutoDig_Location_Order { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Location_Order", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The position of the blocks when using "fixedpos" or "both" mode.. - /// - internal static string ChatBot_AutoDig_Locations { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Locations", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to output logs when digging blocks.. - /// - internal static string ChatBot_AutoDig_Log_Block_Dig { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Log_Block_Dig", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "lookat", "fixedpos" or "both". Digging the block being looked at, the block in a fixed position, or the block that needs to be all met.. - /// - internal static string ChatBot_AutoDig_Mode { - get { - return ResourceManager.GetString("ChatBot.AutoDig.Mode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically drop items in inventory - ///You need to enable Inventory Handling to use this bot - ///See this file for an up-to-date list of item types you can use with this bot: https://mccteam.github.io/r/item/#L12. - /// - internal static string ChatBot_AutoDrop { - get { - return ResourceManager.GetString("ChatBot.AutoDrop", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "include", "exclude" or "everything". Include: drop item IN the list. Exclude: drop item NOT IN the list. - /// - internal static string ChatBot_AutoDrop_Mode { - get { - return ResourceManager.GetString("ChatBot.AutoDrop.Mode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically eat food when your Hunger value is low - ///You need to enable Inventory Handling to use this bot. - /// - internal static string ChatBot_AutoEat { - get { - return ResourceManager.GetString("ChatBot.AutoEat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically catch fish using a fishing rod - ///Guide: https://mccteam.github.io/g/bots/#auto-fishing - ///You can use "/fish" to control the bot manually. - /// /!\ Make sure server rules allow automated farming before using this bot. - /// - internal static string ChatBot_AutoFishing { - get { - return ResourceManager.GetString("ChatBot.AutoFishing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Keep it as false if you have not changed it before.. - /// - internal static string ChatBot_AutoFishing_Antidespawn { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Antidespawn", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Switch to a new rod from inventory after the current rod is unavailable.. - /// - internal static string ChatBot_AutoFishing_Auto_Rod_Switch { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Auto_Rod_Switch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to start fishing automatically after entering a world.. - /// - internal static string ChatBot_AutoFishing_Auto_Start { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Auto_Start", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How soon to re-cast after successful fishing.. - /// - internal static string ChatBot_AutoFishing_Cast_Delay { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Cast_Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Will not use rods with less durability than this (full durability is 64). Set to zero to disable this feature.. - /// - internal static string ChatBot_AutoFishing_Durability_Limit { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Durability_Limit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This allows the player to change position/facing after each fish caught.. - /// - internal static string ChatBot_AutoFishing_Enable_Move { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Enable_Move", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How long after entering the game to start fishing (seconds).. - /// - internal static string ChatBot_AutoFishing_Fishing_Delay { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Fishing_Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Fishing timeout (seconds). Timeout will trigger a re-cast.. - /// - internal static string ChatBot_AutoFishing_Fishing_Timeout { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Fishing_Timeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A "stationary" hook that moves above this threshold in the Y-axis will be considered to have caught a fish.. - /// - internal static string ChatBot_AutoFishing_Hook_Threshold { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Hook_Threshold", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Used to adjust the above two thresholds, which when enabled will print the change in the position of the fishhook entity upon receipt of its movement packet.. - /// - internal static string ChatBot_AutoFishing_Log_Fish_Bobber { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Log_Fish_Bobber", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use the mainhand or the offhand to hold the rod.. - /// - internal static string ChatBot_AutoFishing_Mainhand { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Mainhand", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to It will move in order "1->2->3->4->3->2->1->2->..." and can change position or facing or both each time. It is recommended to change the facing only.. - /// - internal static string ChatBot_AutoFishing_Movements { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Movements", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Hook movement in the X and Z axis less than this value will be considered stationary.. - /// - internal static string ChatBot_AutoFishing_Stationary_Threshold { - get { - return ResourceManager.GetString("ChatBot.AutoFishing.Stationary_Threshold", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically relog when disconnected by server, for example because the server is restating - /// /!\ Use Ignore_Kick_Message=true at own risk! Server staff might not appreciate if you auto-relog on manual kicks. - /// - internal static string ChatBot_AutoRelog { - get { - return ResourceManager.GetString("ChatBot.AutoRelog", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The delay time before joining the server. (in seconds). - /// - internal static string ChatBot_AutoRelog_Delay { - get { - return ResourceManager.GetString("ChatBot.AutoRelog.Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to When set to true, autorelog will reconnect regardless of kick messages.. - /// - internal static string ChatBot_AutoRelog_Ignore_Kick_Message { - get { - return ResourceManager.GetString("ChatBot.AutoRelog.Ignore_Kick_Message", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If the kickout message matches any of the strings, then autorelog will be triggered.. - /// - internal static string ChatBot_AutoRelog_Kick_Messages { - get { - return ResourceManager.GetString("ChatBot.AutoRelog.Kick_Messages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Retries when failing to relog to the server. use -1 for unlimited retries.. - /// - internal static string ChatBot_AutoRelog_Retries { - get { - return ResourceManager.GetString("ChatBot.AutoRelog.Retries", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Run commands or send messages automatically when a specified pattern is detected in chat - ///Server admins can spoof chat messages (/nick, /tellraw) so keep this in mind when implementing AutoRespond rules - /// /!\ This bot may get spammy depending on your rules, although the global messagecooldown setting can help you avoiding accidental spam. - /// - internal static string ChatBot_AutoRespond { - get { - return ResourceManager.GetString("ChatBot.AutoRespond", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Do not remove colors from text (Note: Your matches will have to include color codes (ones using the § character) in order to work). - /// - internal static string ChatBot_AutoRespond_Match_Colors { - get { - return ResourceManager.GetString("ChatBot.AutoRespond.Match_Colors", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Logs chat messages in a file on disk.. - /// - internal static string ChatBot_ChatLog { - get { - return ResourceManager.GetString("ChatBot.ChatLog", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This bot allows you to send and recieve messages and commands via a Discord channel. - ///For Setup you can either use the documentation or read here (Documentation has images). - ///Documentation: https://mccteam.github.io/g/bots/#discord-bridge - ///Setup: - ///First you need to create a Bot on the Discord Developers Portal, here is a video tutorial: https://www.youtube.com/watch?v=2FgMnZViNPA . - /// /!\ IMPORTANT /!\: When creating a bot, you MUST ENABLE "Message Content Intent", "Server Members Intent" and "Presence Intent [rest of string was truncated]";. - /// - internal static string ChatBot_DiscordBridge { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The ID of a channel where you want to interact with the MCC using the bot.. - /// - internal static string ChatBot_DiscordBridge_ChannelId { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.ChannelId", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Message formats - ///Words wrapped with { and } are going to be replaced during the code execution, do not change them! - ///For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time. - ///For Discord message formatting, check the following: https://mccteam.github.io/r/dc-fmt.html. - /// - internal static string ChatBot_DiscordBridge_Formats { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.Formats", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The ID of a server/guild where you have invited the bot to.. - /// - internal static string ChatBot_DiscordBridge_GuildId { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.GuildId", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How long to wait (in seconds) if a message can not be sent to discord before canceling the task (minimum 1 second).. - /// - internal static string ChatBot_DiscordBridge_MessageSendTimeout { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.MessageSendTimeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A list of IDs of people you want to be able to interact with the MCC using the bot.. - /// - internal static string ChatBot_DiscordBridge_OwnersIds { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.OwnersIds", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Your Discord Bot token.. - /// - internal static string ChatBot_DiscordBridge_Token { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.Token", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to When enabled, messages from other Discord bots in the channel will be relayed to Minecraft chat.. - /// - internal static string ChatBot_DiscordBridge_AllowOtherBotMessages { - get { - return ResourceManager.GetString("ChatBot.DiscordBridge.AllowOtherBotMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically farms cropsfor you (plants, breaks and bonemeals them). - ///Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat. - ///Usage: "/farmer start" command and "/farmer stop" command. - ///NOTE: This a newly added bot, it is not perfect and was only tested in 1.19.2, there are some minor issues like not being able to bonemeal carrots/potatoes sometimes. - ///or bot jumps onto the farm land and breaks it (this happens rarely but still happens). We are looking forward at improving this. [rest of string was truncated]";. - /// - internal static string ChatBot_Farmer { - get { - return ResourceManager.GetString("ChatBot.Farmer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Delay between tasks in seconds (Minimum 1 second). - /// - internal static string ChatBot_Farmer_Delay_Between_Tasks { - get { - return ResourceManager.GetString("ChatBot.Farmer.Delay_Between_Tasks", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enabled you to make the bot follow you - ///NOTE: This is an experimental feature, the bot can be slow at times, you need to walk with a normal speed and to sometimes stop for it to be able to keep up with you - ///It's similar to making animals follow you when you're holding food in your hand. - ///This is due to a slow pathfinding algorithm, we're working on getting a better one - ///You can tweak the update limit and find what works best for you. (NOTE: Do not but a very low one, because you might achieve the opposite, /// [rest of string was truncated]";. - /// - internal static string ChatBot_FollowPlayer { - get { - return ResourceManager.GetString("ChatBot.FollowPlayer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Do not follow the player if he is in the range of 3 blocks (prevents the bot from pushing a player in an infinite loop). - /// - internal static string ChatBot_FollowPlayer_Stop_At_Distance { - get { - return ResourceManager.GetString("ChatBot.FollowPlayer.Stop_At_Distance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The rate at which the bot does calculations (in seconds) (You can tweak this if you feel the bot is too slow). - /// - internal static string ChatBot_FollowPlayer_Update_Limit { - get { - return ResourceManager.GetString("ChatBot.FollowPlayer.Update_Limit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A small game to demonstrate chat interactions. Players can guess mystery words one letter at a time. - ///You need to have ChatFormat working correctly and add yourself in botowners to start the game with /tell <bot username> start - /// /!\ This bot may get a bit spammy if many players are interacting with it. - /// - internal static string ChatBot_HangmanGame { - get { - return ResourceManager.GetString("ChatBot.HangmanGame", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A Chat Bot that collects items on the ground. - /// - internal static string ChatBot_ItemsCollector { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If set to true, the bot will return to it's starting position after there are no items to collect. - /// - internal static string ChatBot_ItemsCollector_Always_Return_To_Start { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Always_Return_To_Start", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If set to true, the bot will collect all items, regardless of their type. If you want to use the whitelisted item types, disable this by setting it to false. - /// - internal static string ChatBot_ItemsCollector_Collect_All_Item_Types { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Collect_All_Item_Types", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The radius in which bot will look for items to collect (Default: 30). - /// - internal static string ChatBot_ItemsCollector_Collection_Radius { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Collection_Radius", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Delay in milliseconds between bot scanning items (Recommended: 300-500). - /// - internal static string ChatBot_ItemsCollector_Delay_Between_Tasks { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Delay_Between_Tasks", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to In this list you can specify which items the bot will collect. To enable this, set the Collect_All_Item_Types to false. (NOTE: This does not prevent the bot from accidentally picking up other items, it only goes to positions where it finds the whitelisted items)\nYou can see the list of item types here: https://raw.githubusercontent.com/MCCTeam/Minecraft-Console-Client/master/MinecraftClient/Inventory/ItemType.cs. - /// - internal static string ChatBot_ItemsCollector_Items_Whitelist { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Items_Whitelist", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If set to true, the bot will go after clustered items instead for the closest ones. - /// - internal static string ChatBot_ItemsCollector_Prioritize_Clusters { - get { - return ResourceManager.GetString("ChatBot.ItemsCollector.Prioritize_Clusters", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show a Discord Rich Presence status with your current Minecraft session info. - ///Setup: - ///1. Go to https://discord.com/developers/applications and log in with your Discord account. [rest of string was truncated]";. - /// - internal static string ChatBot_DiscordRpc { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Your Discord Application ID.. - /// - internal static string ChatBot_DiscordRpc_ApplicationId { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ApplicationId", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The top line of the Rich Presence display. Supports placeholders.. - /// - internal static string ChatBot_DiscordRpc_PresenceDetails { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.PresenceDetails", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The second line of the Rich Presence display. Supports placeholders.. - /// - internal static string ChatBot_DiscordRpc_PresenceState { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.PresenceState", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The key of the large image asset uploaded to your Discord application.. - /// - internal static string ChatBot_DiscordRpc_LargeImageKey { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.LargeImageKey", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Tooltip text for the large image. Supports placeholders.. - /// - internal static string ChatBot_DiscordRpc_LargeImageText { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.LargeImageText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The key of the small image asset uploaded to your Discord application (leave empty to hide).. - /// - internal static string ChatBot_DiscordRpc_SmallImageKey { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.SmallImageKey", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Tooltip text for the small image. Supports placeholders.. - /// - internal static string ChatBot_DiscordRpc_SmallImageText { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.SmallImageText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show the server address (host and port) in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowServerAddress { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowServerAddress", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show the player coordinates in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowCoordinates { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowCoordinates", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show health and food level in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowHealth { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowHealth", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show the current dimension in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowDimension { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowDimension", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show the current gamemode in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowGamemode { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowGamemode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show elapsed session time in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowElapsedTime { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowElapsedTime", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show the online player count as a party size in the Discord presence.. - /// - internal static string ChatBot_DiscordRpc_ShowPlayerCount { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.ShowPlayerCount", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How often (in seconds) to refresh the Discord presence. Minimum: 1. - /// - internal static string ChatBot_DiscordRpc_UpdateIntervalSeconds { - get { - return ResourceManager.GetString("ChatBot.DiscordRpc.UpdateIntervalSeconds", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Relay messages between players and servers, like a mail plugin - ///This bot can store messages when the recipients are offline, and send them when they join the server - /// /!\ Server admins can spoof PMs (/tellraw, /nick) so enable this bot only if you trust server admins. - /// - internal static string ChatBot_Mailer { - get { - return ResourceManager.GetString("ChatBot.Mailer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Allows you to render maps in the console and into images (which can be then sent to Discord using Discord Bridge Chat Bot) - ///This is useful for solving captchas which use maps - ///The maps are rendered into Rendered_Maps folder if the Save_To_File is enabled. - ///NOTE: - ///If some servers have a very short time for solving captchas, enabe Auto_Render_On_Update to see them immediatelly in the console. - /// /!\ Make sure server rules allow bots to be used on the server, or you risk being punished.. - /// - internal static string ChatBot_Map { - get { - return ResourceManager.GetString("ChatBot.Map", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Automatically render the map once it is received or updated from/by the server. - /// - internal static string ChatBot_Map_Auto_Render_On_Update { - get { - return ResourceManager.GetString("ChatBot.Map.Auto_Render_On_Update", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Delete all rendered maps on unload/reload or when you launch the MCC again.. - /// - internal static string ChatBot_Map_Delete_All_On_Unload { - get { - return ResourceManager.GetString("ChatBot.Map.Delete_All_On_Unload", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Get a notification when you have gotten a map from the server for the first time. - /// - internal static string ChatBot_Map_Notify_On_First_Update { - get { - return ResourceManager.GetString("ChatBot.Map.Notify_On_First_Update", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Resize an rendered image, this is useful when images that are rendered are small and when are being sent to Discord.. - /// - internal static string ChatBot_Map_Rasize_Rendered_Image { - get { - return ResourceManager.GetString("ChatBot.Map.Rasize_Rendered_Image", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to render the map in the console.. - /// - internal static string ChatBot_Map_Render_In_Console { - get { - return ResourceManager.GetString("ChatBot.Map.Render_In_Console", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The size that a rendered image should be resized to, in pixels (eg. 512).. - /// - internal static string ChatBot_Map_Resize_To { - get { - return ResourceManager.GetString("ChatBot.Map.Resize_To", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to store the rendered map as a file (You need this setting if you want to get a map on Discord using Discord Bridge).. - /// - internal static string ChatBot_Map_Save_To_File { - get { - return ResourceManager.GetString("ChatBot.Map.Save_To_File", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Send a rendered map (saved to a file) to a Discord or a Telegram channel via the Discord or Telegram Bride chat bot (The Discord/Telegram Bridge chat bot must be enabled and configured!) - ///You need to enable Save_To_File in order for this to work. - ///We also recommend turning on resizing.. - /// - internal static string ChatBot_Map_Send_Rendered_To_Bridges { - get { - return ResourceManager.GetString("ChatBot.Map.Send_Rendered_To_Bridges", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Log the list of players periodically into a textual file.. - /// - internal static string ChatBot_PlayerListLogger { - get { - return ResourceManager.GetString("ChatBot.PlayerListLogger", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (In seconds). - /// - internal static string ChatBot_PlayerListLogger_Delay { - get { - return ResourceManager.GetString("ChatBot.PlayerListLogger.Delay", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Send MCC console commands to your bot through server PMs (/tell) - ///You need to have ChatFormat working correctly and add yourself in botowners to use the bot - /// /!\ Server admins can spoof PMs (/tellraw, /nick) so enable RemoteControl only if you trust server admins. - /// - internal static string ChatBot_RemoteControl { - get { - return ResourceManager.GetString("ChatBot.RemoteControl", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enable recording of the game (/replay start) and replay it later using the Replay Mod (https://www.replaymod.com/) - ///Please note that due to technical limitations, the client player (you) will not be shown in the replay file - /// /!\ You SHOULD use /replay stop or exit the program gracefully with /quit OR THE REPLAY FILE MAY GET CORRUPT!. - /// - internal static string ChatBot_ReplayCapture { - get { - return ResourceManager.GetString("ChatBot.ReplayCapture", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How long should replay file be auto-saved, in seconds. Use -1 to disable.. - /// - internal static string ChatBot_ReplayCapture_Backup_Interval { - get { - return ResourceManager.GetString("ChatBot.ReplayCapture.Backup_Interval", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Schedule commands and scripts to launch on various events such as server join, date/time or time interval - ///See https://mccteam.github.io/g/bots/#script-scheduler for more info. - /// - internal static string ChatBot_ScriptScheduler { - get { - return ResourceManager.GetString("ChatBot.ScriptScheduler", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This bot allows you to send and receive messages and commands via a Telegram Bot DM or to receive messages in a Telegram channel. - /// /!\ NOTE: You can't send messages and commands from a group channel, you can only send them in the bot DM, but you can get the messages from the client in a group channel. - ///----------------------------------------------------------- - ///Setup: - ///First you need to create a Telegram bot and obtain an API key, to do so, go to Telegram and find @botfather - ///Click on "Start" button and re [rest of string was truncated]";. - /// - internal static string ChatBot_TelegramBridge { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A list of Chat IDs that are allowed to send messages and execute commands. To get an id of your chat DM with the bot use ".chatid" bot command in Telegram.. - /// - internal static string ChatBot_TelegramBridge_Authorized_Chat_Ids { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge.Authorized_Chat_Ids", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to An ID of a channel where you want to interact with the MCC using the bot.. - /// - internal static string ChatBot_TelegramBridge_ChannelId { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge.ChannelId", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Message formats - ///Words wrapped with { and } are going to be replaced during the code execution, do not change them! - ///For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time. - ///For Telegram message formatting, check the following: https://mccteam.github.io/r/tg-fmt.html. - /// - internal static string ChatBot_TelegramBridge_Formats { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge.Formats", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How long to wait (in seconds) if a message can not be sent to Telegram before canceling the task (minimum 1 second).. - /// - internal static string ChatBot_TelegramBridge_MessageSendTimeout { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge.MessageSendTimeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Your Telegram Bot token.. - /// - internal static string ChatBot_TelegramBridge_Token { - get { - return ResourceManager.GetString("ChatBot.TelegramBridge.Token", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Remotely control the client using Web Sockets.\n# This is useful if you want to implement an application that can remotely and asynchronously execute procedures in MCC.\n# Example implementation written in JavaScript: https://github.com/milutinke/MCC.js.git\n# The protocol specification will be available in the documentation soon.. - /// - internal static string ChatBot_WebSocketBot { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Allow IP aliases, such as "localhost" or if using containers then the container name can be used.... - /// - internal static string ChatBot_WebSocketBot_AllowIpAlias { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot.AllowIpAlias", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This setting is for developers who are developing a library that uses this chat bot to remotely execute procedures/commands/functions.. - /// - internal static string ChatBot_WebSocketBot_DebugMode { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot.DebugMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The IP address that Websocket server will be bound to.. - /// - internal static string ChatBot_WebSocketBot_Ip { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot.Ip", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A password that will be used to authenticate on thw Websocket server (It is recommended to change the default password and to set a strong one).. - /// - internal static string ChatBot_WebSocketBot_Password { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot.Password", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The Port that Websocket server will be bounded to.. - /// - internal static string ChatBot_WebSocketBot_Port { - get { - return ResourceManager.GetString("ChatBot.WebSocketBot.Port", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MCC does it best to detect chat messages, but some server have unusual chat formats - ///When this happens, you'll need to configure chat format below, see https://mccteam.github.io/g/conf/#chat-format-section. - /// - internal static string ChatFormat { - get { - return ResourceManager.GetString("ChatFormat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MCC support for common message formats. Set "false" to avoid conflicts with custom formats.. - /// - internal static string ChatFormat_Builtins { - get { - return ResourceManager.GetString("ChatFormat.Builtins", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to use the custom regular expressions below for detection.. - /// - internal static string ChatFormat_UserDefined { - get { - return ResourceManager.GetString("ChatFormat.UserDefined", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Console-related settings.. - /// - internal static string Console { - get { - return ResourceManager.GetString("Console", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The settings for command completion suggestions. - ///Custom colors are only available when using "vt100_24bit" color mode.. - /// - internal static string Console_CommandSuggestion { - get { - return ResourceManager.GetString("Console.CommandSuggestion", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to display command suggestions in the console.. - /// - internal static string Console_CommandSuggestion_Enable { - get { - return ResourceManager.GetString("Console.CommandSuggestion.Enable", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enable this option if the arrows in the command suggestions are not displayed properly in your terminal.. - /// - internal static string Console_CommandSuggestion_Use_Basic_Arrow { - get { - return ResourceManager.GetString("Console.CommandSuggestion.Use_Basic_Arrow", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Console mode: "classic" for the standard terminal, "tui" for a pseudo-graphical full-screen interface.. - /// - internal static string Console_General_ConsoleMode { - get { - return ResourceManager.GetString("Console.General.ConsoleMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "disable", "legacy_4bit", "vt100_4bit", "vt100_8bit" or "vt100_24bit". If a garbled code like "←[0m" appears on the terminal, you can try switching to "legacy_4bit" mode, or just disable it.. - /// - internal static string Console_General_ConsoleColorMode { - get { - return ResourceManager.GetString("Console.General.ConsoleColorMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You can use "Ctrl+P" to print out the current input and cursor position.. - /// - internal static string Console_General_Display_Input { - get { - return ResourceManager.GetString("Console.General.Display_Input", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Startup Config File - ///Please do not record extraneous data in this file as it will be overwritten by MCC. - /// - ///New to Minecraft Console Client? Check out this document: https://mccteam.github.io/g/conf.html - ///Want to upgrade to a newer version? See https://github.com/MCCTeam/Minecraft-Console-Client/#download. - /// - internal static string Head { - get { - return ResourceManager.GetString("Head", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This setting affects only the messages in the console.. - /// - internal static string Logging { - get { - return ResourceManager.GetString("Logging", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Regex for filtering chat message.. - /// - internal static string Logging_ChatFilter { - get { - return ResourceManager.GetString("Logging.ChatFilter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show server chat messages.. - /// - internal static string Logging_ChatMessages { - get { - return ResourceManager.GetString("Logging.ChatMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Regex for filtering debug message.. - /// - internal static string Logging_DebugFilter { - get { - return ResourceManager.GetString("Logging.DebugFilter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Please enable this before submitting bug reports. Thanks!. - /// - internal static string Logging_DebugMessages { - get { - return ResourceManager.GetString("Logging.DebugMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show error messages.. - /// - internal static string Logging_ErrorMessages { - get { - return ResourceManager.GetString("Logging.ErrorMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "disable" or "blacklist" OR "whitelist". Blacklist hide message match regex. Whitelist show message match regex.. - /// - internal static string Logging_FilterMode { - get { - return ResourceManager.GetString("Logging.FilterMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Informative messages. (i.e Most of the message from MCC). - /// - internal static string Logging_InfoMessages { - get { - return ResourceManager.GetString("Logging.InfoMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Log file name.. - /// - internal static string Logging_LogFile { - get { - return ResourceManager.GetString("Logging.LogFile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Write log messages to file.. - /// - internal static string Logging_LogToFile { - get { - return ResourceManager.GetString("Logging.LogToFile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Prepend timestamp to messages in log file.. - /// - internal static string Logging_PrependTimestamp { - get { - return ResourceManager.GetString("Logging.PrependTimestamp", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Keep color codes in the saved text.(look like "§b"). - /// - internal static string Logging_SaveColorCodes { - get { - return ResourceManager.GetString("Logging.SaveColorCodes", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show warning messages.. - /// - internal static string Logging_WarningMessages { - get { - return ResourceManager.GetString("Logging.WarningMessages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Make sure you understand what each setting does before changing anything!. - /// - internal static string Main_Advanced { - get { - return ResourceManager.GetString("Main.Advanced", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to AccountList: It allows a fast account switching without directly using the credentials - ///Usage examples: "/tell <mybot> reco Player2", "/connect <serverip> Player1". - /// - internal static string Main_Advanced_account_list { - get { - return ResourceManager.GetString("Main.Advanced.account_list", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Toggle auto respawn if client player was dead (make sure your spawn point is safe).. - /// - internal static string Main_Advanced_auto_respawn { - get { - return ResourceManager.GetString("Main.Advanced.auto_respawn", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Set the owner of the bot. /!\ Server admins can impersonate owners!. - /// - internal static string Main_Advanced_bot_owners { - get { - return ResourceManager.GetString("Main.Advanced.bot_owners", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "mcc", "vanilla" or "none". This is how MCC identifies itself to the server.. - /// - internal static string Main_Advanced_brand_info { - get { - return ResourceManager.GetString("Main.Advanced.brand_info", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Leave empty for no logfile.. - /// - internal static string Main_Advanced_chatbot_log_file { - get { - return ResourceManager.GetString("Main.Advanced.chatbot_log_file", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If turned off, the emoji will be replaced with a simpler character (for /chunk status).. - /// - internal static string Main_Advanced_enable_emoji { - get { - return ResourceManager.GetString("Main.Advanced.enable_emoji", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Set to false to opt-out of Sentry error logging.. - /// - internal static string Main_Advanced_enable_sentry { - get { - return ResourceManager.GetString("Main.Advanced.enable_sentry", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Toggle entity handling.. - /// - internal static string Main_Advanced_entity_handling { - get { - return ResourceManager.GetString("Main.Advanced.entity_handling", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to exit directly when an error occurs, for using MCC in non-interactive scripts.. - /// - internal static string Main_Advanced_exit_on_failure { - get { - return ResourceManager.GetString("Main.Advanced.exit_on_failure", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Ignore invalid player name. - /// - internal static string Main_Advanced_ignore_invalid_playername { - get { - return ResourceManager.GetString("Main.Advanced.ignore_invalid_playername", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "none", "slash"(/) or "backslash"(\).. - /// - internal static string Main_Advanced_internal_cmd_char { - get { - return ResourceManager.GetString("Main.Advanced.internal_cmd_char", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Toggle inventory handling.. - /// - internal static string Main_Advanced_inventory_handling { - get { - return ResourceManager.GetString("Main.Advanced.inventory_handling", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Fill in with in-game locale code, check https://mccteam.github.io/r/l-code.html. - /// - internal static string Main_Advanced_language { - get { - return ResourceManager.GetString("Main.Advanced.language", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Load translations applied to MCC when available, turn it off to use English only.. - /// - internal static string Main_Advanced_LoadMccTrans { - get { - return ResourceManager.GetString("Main.Advanced.LoadMccTrans", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "auto", "no" or "force". Force-enabling only works for MC 1.13+.. - /// - internal static string Main_Advanced_mc_forge { - get { - return ResourceManager.GetString("Main.Advanced.mc_forge", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "auto" or "1.X.X" values. Allows to skip server info retrieval.. - /// - internal static string Main_Advanced_mc_version { - get { - return ResourceManager.GetString("Main.Advanced.mc_version", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Controls the minimum interval (in seconds) between sending each message to the server.. - /// - internal static string Main_Advanced_message_cooldown { - get { - return ResourceManager.GetString("Main.Advanced.message_cooldown", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Override the maximum chat message length. Set to 0 to use the default (100 for 1.10 and below, 256 for 1.11+). WARNING: Setting this incorrectly may cause you to be kicked from the server.. - /// - internal static string Main_Advanced_max_chat_message_length { - get { - return ResourceManager.GetString("Main.Advanced.max_chat_message_length", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enable support for joining Minecraft Realms worlds.. - /// - internal static string Main_Advanced_minecraft_realms { - get { - return ResourceManager.GetString("Main.Advanced.minecraft_realms", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The minimum height to use when calculating the image size from the height of the terminal.. - /// - internal static string Main_Advanced_MinTerminalHeight { - get { - return ResourceManager.GetString("Main.Advanced.MinTerminalHeight", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The minimum width used when calculating the image size from the width of the terminal.. - /// - internal static string Main_Advanced_MinTerminalWidth { - get { - return ResourceManager.GetString("Main.Advanced.MinTerminalWidth", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enable head movement while walking to avoid anti-cheat triggers.. - /// - internal static string Main_Advanced_move_head_while_walking { - get { - return ResourceManager.GetString("Main.Advanced.move_head_while_walking", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A movement speed higher than 2 may be considered cheating.. - /// - internal static string Main_Advanced_movement_speed { - get { - return ResourceManager.GetString("Main.Advanced.movement_speed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Only works on Windows XP-8 or Windows 10 with old console.. - /// - internal static string Main_Advanced_player_head_icon { - get { - return ResourceManager.GetString("Main.Advanced.player_head_icon", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to For remote control of the bot.. - /// - internal static string Main_Advanced_private_msgs_cmd_name { - get { - return ResourceManager.GetString("Main.Advanced.private_msgs_cmd_name", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How to retain profile key. Use "none", "memory" or "disk".. - /// - internal static string Main_Advanced_profilekey_cache { - get { - return ResourceManager.GetString("Main.Advanced.profilekey_cache", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "no", "fast" (5s timeout), or "yes". Required for joining some servers.. - /// - internal static string Main_Advanced_resolve_srv_records { - get { - return ResourceManager.GetString("Main.Advanced.resolve_srv_records", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cache compiled scripts for faster load on low-end devices.. - /// - internal static string Main_Advanced_script_cache { - get { - return ResourceManager.GetString("Main.Advanced.script_cache", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ServerList: It allows an easier and faster server switching with short aliases instead of full server IP - ///Aliases cannot contain dots or spaces, and the name "localhost" cannot be used as an alias. - ///Usage examples: "/tell <mybot> connect Server1", "/connect Server2". - /// - internal static string Main_Advanced_server_list { - get { - return ResourceManager.GetString("Main.Advanced.server_list", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to How to retain session tokens. Use "none", "memory" or "disk".. - /// - internal static string Main_Advanced_session_cache { - get { - return ResourceManager.GetString("Main.Advanced.session_cache", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Decode links embedded in chat messages and show them in console.. - /// - internal static string Main_Advanced_show_chat_links { - get { - return ResourceManager.GetString("Main.Advanced.show_chat_links", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Show inventory layout as ASCII art in inventory command.. - /// +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MinecraftClient { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class ConfigComments { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal ConfigComments() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftClient.Resources.ConfigComments.ConfigComments", typeof(ConfigComments).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to can be used in some other fields as %yourvar% + ///%username% and %serverip% are reserved variables.. + /// + internal static string AppVars_Variables { + get { + return ResourceManager.GetString("AppVars.Variables", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to =============================== # + /// Minecraft Console Client Bots # + ///=============================== #. + /// + internal static string ChatBot { + get { + return ResourceManager.GetString("ChatBot", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Get alerted when specified words are detected in chat + ///Useful for moderating your server or detecting when someone is talking to you. + /// + internal static string ChatBot_Alerts { + get { + return ResourceManager.GetString("ChatBot.Alerts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Play a beep sound when a word is detected in addition to highlighting.. + /// + internal static string ChatBot_Alerts_Beep_Enabled { + get { + return ResourceManager.GetString("ChatBot.Alerts.Beep_Enabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List of words/strings to NOT alert you on.. + /// + internal static string ChatBot_Alerts_Excludes { + get { + return ResourceManager.GetString("ChatBot.Alerts.Excludes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The name of a file where alers logs will be written.. + /// + internal static string ChatBot_Alerts_Log_File { + get { + return ResourceManager.GetString("ChatBot.Alerts.Log_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Log alerts info a file.. + /// + internal static string ChatBot_Alerts_Log_To_File { + get { + return ResourceManager.GetString("ChatBot.Alerts.Log_To_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List of words/strings to alert you on.. + /// + internal static string ChatBot_Alerts_Matches { + get { + return ResourceManager.GetString("ChatBot.Alerts.Matches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trigger alerts when it rains and when it stops.. + /// + internal static string ChatBot_Alerts_Trigger_By_Rain { + get { + return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Rain", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Triggers alerts at the beginning and end of thunderstorms.. + /// + internal static string ChatBot_Alerts_Trigger_By_Thunderstorm { + get { + return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Thunderstorm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Triggers an alert after receiving a specified keyword.. + /// + internal static string ChatBot_Alerts_Trigger_By_Words { + get { + return ResourceManager.GetString("ChatBot.Alerts.Trigger_By_Words", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send a command on a regular or random basis or make the bot walk around randomly to avoid automatic AFK disconnection + /// /!\ Make sure your server rules do not forbid anti-AFK mechanisms! + /// /!\ Make sure you keep the bot in an enclosure to prevent it wandering off if you're using terrain handling! (Recommended size 5x5x5). + /// + internal static string ChatBot_AntiAfk { + get { + return ResourceManager.GetString("ChatBot.AntiAfk", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Command to send to the server.. + /// + internal static string ChatBot_AntiAfk_Command { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Command", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The time interval for execution. (in seconds). + /// + internal static string ChatBot_AntiAfk_Delay { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to sneak when sending the command.. + /// + internal static string ChatBot_AntiAfk_Use_Sneak { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Use_Sneak", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use terrain handling to enable the bot to move around.. + /// + internal static string ChatBot_AntiAfk_Use_Terrain_Handling { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Use_Terrain_Handling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The range the bot can move around randomly (Note: the bigger the range, the slower the bot will be). + /// + internal static string ChatBot_AntiAfk_Walk_Range { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Walk_Range", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How many times can the bot fail trying to move before using the command method.. + /// + internal static string ChatBot_AntiAfk_Walk_Retries { + get { + return ResourceManager.GetString("ChatBot.AntiAfk.Walk_Retries", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically attack hostile mobs around you + ///You need to enable Entity Handling to use this bot + /// /!\ Make sure server rules allow your planned use of AutoAttack + /// /!\ SERVER PLUGINS may consider AutoAttack to be a CHEAT MOD and TAKE ACTION AGAINST YOUR ACCOUNT so DOUBLE CHECK WITH SERVER RULES!. + /// + internal static string ChatBot_AutoAttack { + get { + return ResourceManager.GetString("ChatBot.AutoAttack", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow attacking hostile mobs.. + /// + internal static string ChatBot_AutoAttack_Attack_Hostile { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Hostile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow attacking passive mobs.. + /// + internal static string ChatBot_AutoAttack_Attack_Passive { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Passive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Capped between 1 to 4. + /// + internal static string ChatBot_AutoAttack_Attack_Range { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Attack_Range", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How long to wait between each attack. Set "Custom = false" to let MCC calculate it.. + /// + internal static string ChatBot_AutoAttack_Cooldown_Time { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Cooldown_Time", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All entity types can be found here: https://mccteam.github.io/r/entity/#L15. + /// + internal static string ChatBot_AutoAttack_Entites_List { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Entites_List", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Possible values: "Interact", "Attack" (default), "InteractAt" (Interact and Attack).. + /// + internal static string ChatBot_AutoAttack_Interaction { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Interaction", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wether to treat the entities list as a "whitelist" or as a "blacklist".. + /// + internal static string ChatBot_AutoAttack_List_Mode { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.List_Mode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "single" or "multi". single target one mob per attack. multi target all mobs in range per attack. + /// + internal static string ChatBot_AutoAttack_Mode { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Mode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "health" or "distance". Only needed when using single mode. + /// + internal static string ChatBot_AutoAttack_Priority { + get { + return ResourceManager.GetString("ChatBot.AutoAttack.Priority", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically craft items in your inventory + ///See https://mccteam.github.io/g/bots/#auto-craft for how to use + ///You need to enable Inventory Handling to use this bot + ///You should also enable Terrain and Movements if you need to use a crafting table. + /// + internal static string ChatBot_AutoCraft { + get { + return ResourceManager.GetString("ChatBot.AutoCraft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Location of the crafting table if you intended to use it. Terrain and movements must be enabled.. + /// + internal static string ChatBot_AutoCraft_CraftingTable { + get { + return ResourceManager.GetString("ChatBot.AutoCraft.CraftingTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to What to do on crafting failure, "abort" or "wait".. + /// + internal static string ChatBot_AutoCraft_OnFailure { + get { + return ResourceManager.GetString("ChatBot.AutoCraft.OnFailure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Recipes.Name: The name can be whatever you like and it is used to represent the recipe. + ///Recipes.Type: crafting table type: "player" or "table" + ///Recipes.Result: the resulting item + ///Recipes.Slots: All slots, counting from left to right, top to bottom. Please fill in "Null" for empty slots. + ///For the naming of the items, please see: https://mccteam.github.io/r/item/#L12. + /// + internal static string ChatBot_AutoCraft_Recipes { + get { + return ResourceManager.GetString("ChatBot.AutoCraft.Recipes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Auto-digging blocks. + ///You need to enable Terrain Handling to use this bot + ///You can use "/digbot start" and "/digbot stop" to control the start and stop of AutoDig. + ///Since MCC does not yet support accurate calculation of the collision volume of blocks, all blocks are considered as complete cubes when obtaining the position of the lookahead. + ///For the naming of the block, please see https://mccteam.github.io/r/block/#L15. + /// + internal static string ChatBot_AutoDig { + get { + return ResourceManager.GetString("ChatBot.AutoDig", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How many seconds to wait after entering the game to start digging automatically, set to -1 to disable automatic start.. + /// + internal static string ChatBot_AutoDig_Auto_Start_Delay { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Auto_Start_Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically switch to the appropriate tool.. + /// + internal static string ChatBot_AutoDig_Auto_Tool_Switch { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Auto_Tool_Switch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mining a block for more than "Dig_Timeout" seconds will be considered a timeout.. + /// + internal static string ChatBot_AutoDig_Dig_Timeout { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Dig_Timeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to drop the current tool when its durability is too low.. + /// + internal static string ChatBot_AutoDig_Drop_Low_Durability_Tools { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Drop_Low_Durability_Tools", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will not use tools with less durability than this. Set to zero to disable this feature.. + /// + internal static string ChatBot_AutoDig_Durability_Limit { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Durability_Limit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Wether to treat the blocks list as a "whitelist" or as a "blacklist".. + /// + internal static string ChatBot_AutoDig_List_Type { + get { + return ResourceManager.GetString("ChatBot.AutoDig.List_Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "distance" or "index", When using the "fixedpos" mode, the blocks are determined by distance to the player, or by the order in the list.. + /// + internal static string ChatBot_AutoDig_Location_Order { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Location_Order", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The position of the blocks when using "fixedpos" or "both" mode.. + /// + internal static string ChatBot_AutoDig_Locations { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Locations", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to output logs when digging blocks.. + /// + internal static string ChatBot_AutoDig_Log_Block_Dig { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Log_Block_Dig", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "lookat", "fixedpos" or "both". Digging the block being looked at, the block in a fixed position, or the block that needs to be all met.. + /// + internal static string ChatBot_AutoDig_Mode { + get { + return ResourceManager.GetString("ChatBot.AutoDig.Mode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically drop items in inventory + ///You need to enable Inventory Handling to use this bot + ///See this file for an up-to-date list of item types you can use with this bot: https://mccteam.github.io/r/item/#L12. + /// + internal static string ChatBot_AutoDrop { + get { + return ResourceManager.GetString("ChatBot.AutoDrop", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "include", "exclude" or "everything". Include: drop item IN the list. Exclude: drop item NOT IN the list. + /// + internal static string ChatBot_AutoDrop_Mode { + get { + return ResourceManager.GetString("ChatBot.AutoDrop.Mode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically eat food when your Hunger value is low + ///You need to enable Inventory Handling to use this bot. + /// + internal static string ChatBot_AutoEat { + get { + return ResourceManager.GetString("ChatBot.AutoEat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically catch fish using a fishing rod + ///Guide: https://mccteam.github.io/g/bots/#auto-fishing + ///You can use "/fish" to control the bot manually. + /// /!\ Make sure server rules allow automated farming before using this bot. + /// + internal static string ChatBot_AutoFishing { + get { + return ResourceManager.GetString("ChatBot.AutoFishing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keep it as false if you have not changed it before.. + /// + internal static string ChatBot_AutoFishing_Antidespawn { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Antidespawn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Switch to a new rod from inventory after the current rod is unavailable.. + /// + internal static string ChatBot_AutoFishing_Auto_Rod_Switch { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Auto_Rod_Switch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to start fishing automatically after entering a world.. + /// + internal static string ChatBot_AutoFishing_Auto_Start { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Auto_Start", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How soon to re-cast after successful fishing.. + /// + internal static string ChatBot_AutoFishing_Cast_Delay { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Cast_Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will not use rods with less durability than this (full durability is 64). Set to zero to disable this feature.. + /// + internal static string ChatBot_AutoFishing_Durability_Limit { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Durability_Limit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This allows the player to change position/facing after each fish caught.. + /// + internal static string ChatBot_AutoFishing_Enable_Move { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Enable_Move", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How long after entering the game to start fishing (seconds).. + /// + internal static string ChatBot_AutoFishing_Fishing_Delay { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Fishing_Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fishing timeout (seconds). Timeout will trigger a re-cast.. + /// + internal static string ChatBot_AutoFishing_Fishing_Timeout { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Fishing_Timeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A "stationary" hook that moves above this threshold in the Y-axis will be considered to have caught a fish.. + /// + internal static string ChatBot_AutoFishing_Hook_Threshold { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Hook_Threshold", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Used to adjust the above two thresholds, which when enabled will print the change in the position of the fishhook entity upon receipt of its movement packet.. + /// + internal static string ChatBot_AutoFishing_Log_Fish_Bobber { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Log_Fish_Bobber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use the mainhand or the offhand to hold the rod.. + /// + internal static string ChatBot_AutoFishing_Mainhand { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Mainhand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to It will move in order "1->2->3->4->3->2->1->2->..." and can change position or facing or both each time. It is recommended to change the facing only.. + /// + internal static string ChatBot_AutoFishing_Movements { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Movements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hook movement in the X and Z axis less than this value will be considered stationary.. + /// + internal static string ChatBot_AutoFishing_Stationary_Threshold { + get { + return ResourceManager.GetString("ChatBot.AutoFishing.Stationary_Threshold", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically relog when disconnected by server, for example because the server is restating + /// /!\ Use Ignore_Kick_Message=true at own risk! Server staff might not appreciate if you auto-relog on manual kicks. + /// + internal static string ChatBot_AutoRelog { + get { + return ResourceManager.GetString("ChatBot.AutoRelog", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The delay time before joining the server. (in seconds). + /// + internal static string ChatBot_AutoRelog_Delay { + get { + return ResourceManager.GetString("ChatBot.AutoRelog.Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to When set to true, autorelog will reconnect regardless of kick messages.. + /// + internal static string ChatBot_AutoRelog_Ignore_Kick_Message { + get { + return ResourceManager.GetString("ChatBot.AutoRelog.Ignore_Kick_Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If the kickout message matches any of the strings, then autorelog will be triggered.. + /// + internal static string ChatBot_AutoRelog_Kick_Messages { + get { + return ResourceManager.GetString("ChatBot.AutoRelog.Kick_Messages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retries when failing to relog to the server. use -1 for unlimited retries.. + /// + internal static string ChatBot_AutoRelog_Retries { + get { + return ResourceManager.GetString("ChatBot.AutoRelog.Retries", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Run commands or send messages automatically when a specified pattern is detected in chat + ///Server admins can spoof chat messages (/nick, /tellraw) so keep this in mind when implementing AutoRespond rules + /// /!\ This bot may get spammy depending on your rules, although the global messagecooldown setting can help you avoiding accidental spam. + /// + internal static string ChatBot_AutoRespond { + get { + return ResourceManager.GetString("ChatBot.AutoRespond", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do not remove colors from text (Note: Your matches will have to include color codes (ones using the § character) in order to work). + /// + internal static string ChatBot_AutoRespond_Match_Colors { + get { + return ResourceManager.GetString("ChatBot.AutoRespond.Match_Colors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Logs chat messages in a file on disk.. + /// + internal static string ChatBot_ChatLog { + get { + return ResourceManager.GetString("ChatBot.ChatLog", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This bot allows you to send and recieve messages and commands via a Discord channel. + ///For Setup you can either use the documentation or read here (Documentation has images). + ///Documentation: https://mccteam.github.io/g/bots/#discord-bridge + ///Setup: + ///First you need to create a Bot on the Discord Developers Portal, here is a video tutorial: https://www.youtube.com/watch?v=2FgMnZViNPA . + /// /!\ IMPORTANT /!\: When creating a bot, you MUST ENABLE "Message Content Intent", "Server Members Intent" and "Presence Intent [rest of string was truncated]";. + /// + internal static string ChatBot_DiscordBridge { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The ID of a channel where you want to interact with the MCC using the bot.. + /// + internal static string ChatBot_DiscordBridge_ChannelId { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.ChannelId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Message formats + ///Words wrapped with { and } are going to be replaced during the code execution, do not change them! + ///For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time. + ///For Discord message formatting, check the following: https://mccteam.github.io/r/dc-fmt.html. + /// + internal static string ChatBot_DiscordBridge_Formats { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.Formats", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The ID of a server/guild where you have invited the bot to.. + /// + internal static string ChatBot_DiscordBridge_GuildId { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.GuildId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How long to wait (in seconds) if a message can not be sent to discord before canceling the task (minimum 1 second).. + /// + internal static string ChatBot_DiscordBridge_MessageSendTimeout { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.MessageSendTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A list of IDs of people you want to be able to interact with the MCC using the bot.. + /// + internal static string ChatBot_DiscordBridge_OwnersIds { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.OwnersIds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your Discord Bot token.. + /// + internal static string ChatBot_DiscordBridge_Token { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.Token", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to When enabled, messages from other Discord bots in the channel will be relayed to Minecraft chat.. + /// + internal static string ChatBot_DiscordBridge_AllowOtherBotMessages { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.AllowOtherBotMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically farms cropsfor you (plants, breaks and bonemeals them). + ///Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat. + ///Usage: "/farmer start" command and "/farmer stop" command. + ///NOTE: This a newly added bot, it is not perfect and was only tested in 1.19.2, there are some minor issues like not being able to bonemeal carrots/potatoes sometimes. + ///or bot jumps onto the farm land and breaks it (this happens rarely but still happens). We are looking forward at improving this. [rest of string was truncated]";. + /// + internal static string ChatBot_Farmer { + get { + return ResourceManager.GetString("ChatBot.Farmer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delay between tasks in seconds (Minimum 1 second). + /// + internal static string ChatBot_Farmer_Delay_Between_Tasks { + get { + return ResourceManager.GetString("ChatBot.Farmer.Delay_Between_Tasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enabled you to make the bot follow you + ///NOTE: This is an experimental feature, the bot can be slow at times, you need to walk with a normal speed and to sometimes stop for it to be able to keep up with you + ///It's similar to making animals follow you when you're holding food in your hand. + ///This is due to a slow pathfinding algorithm, we're working on getting a better one + ///You can tweak the update limit and find what works best for you. (NOTE: Do not but a very low one, because you might achieve the opposite, + /// [rest of string was truncated]";. + /// + internal static string ChatBot_FollowPlayer { + get { + return ResourceManager.GetString("ChatBot.FollowPlayer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do not follow the player if he is in the range of 3 blocks (prevents the bot from pushing a player in an infinite loop). + /// + internal static string ChatBot_FollowPlayer_Stop_At_Distance { + get { + return ResourceManager.GetString("ChatBot.FollowPlayer.Stop_At_Distance", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The rate at which the bot does calculations (in seconds) (You can tweak this if you feel the bot is too slow). + /// + internal static string ChatBot_FollowPlayer_Update_Limit { + get { + return ResourceManager.GetString("ChatBot.FollowPlayer.Update_Limit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A small game to demonstrate chat interactions. Players can guess mystery words one letter at a time. + ///You need to have ChatFormat working correctly and add yourself in botowners to start the game with /tell <bot username> start + /// /!\ This bot may get a bit spammy if many players are interacting with it. + /// + internal static string ChatBot_HangmanGame { + get { + return ResourceManager.GetString("ChatBot.HangmanGame", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A Chat Bot that collects items on the ground. + /// + internal static string ChatBot_ItemsCollector { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If set to true, the bot will return to it's starting position after there are no items to collect. + /// + internal static string ChatBot_ItemsCollector_Always_Return_To_Start { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Always_Return_To_Start", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If set to true, the bot will collect all items, regardless of their type. If you want to use the whitelisted item types, disable this by setting it to false. + /// + internal static string ChatBot_ItemsCollector_Collect_All_Item_Types { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Collect_All_Item_Types", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The radius in which bot will look for items to collect (Default: 30). + /// + internal static string ChatBot_ItemsCollector_Collection_Radius { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Collection_Radius", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delay in milliseconds between bot scanning items (Recommended: 300-500). + /// + internal static string ChatBot_ItemsCollector_Delay_Between_Tasks { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Delay_Between_Tasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to In this list you can specify which items the bot will collect. To enable this, set the Collect_All_Item_Types to false. (NOTE: This does not prevent the bot from accidentally picking up other items, it only goes to positions where it finds the whitelisted items)\nYou can see the list of item types here: https://raw.githubusercontent.com/MCCTeam/Minecraft-Console-Client/master/MinecraftClient/Inventory/ItemType.cs. + /// + internal static string ChatBot_ItemsCollector_Items_Whitelist { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Items_Whitelist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If set to true, the bot will go after clustered items instead for the closest ones. + /// + internal static string ChatBot_ItemsCollector_Prioritize_Clusters { + get { + return ResourceManager.GetString("ChatBot.ItemsCollector.Prioritize_Clusters", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show a Discord Rich Presence status with your current Minecraft session info. + ///Setup: + ///1. Go to https://discord.com/developers/applications and log in with your Discord account. [rest of string was truncated]";. + /// + internal static string ChatBot_DiscordRpc { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your Discord Application ID.. + /// + internal static string ChatBot_DiscordRpc_ApplicationId { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ApplicationId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The top line of the Rich Presence display. Supports placeholders.. + /// + internal static string ChatBot_DiscordRpc_PresenceDetails { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.PresenceDetails", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The second line of the Rich Presence display. Supports placeholders.. + /// + internal static string ChatBot_DiscordRpc_PresenceState { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.PresenceState", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The key of the large image asset uploaded to your Discord application.. + /// + internal static string ChatBot_DiscordRpc_LargeImageKey { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.LargeImageKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tooltip text for the large image. Supports placeholders.. + /// + internal static string ChatBot_DiscordRpc_LargeImageText { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.LargeImageText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The key of the small image asset uploaded to your Discord application (leave empty to hide).. + /// + internal static string ChatBot_DiscordRpc_SmallImageKey { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.SmallImageKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tooltip text for the small image. Supports placeholders.. + /// + internal static string ChatBot_DiscordRpc_SmallImageText { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.SmallImageText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show the server address (host and port) in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowServerAddress { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowServerAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show the player coordinates in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowCoordinates { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowCoordinates", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show health and food level in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowHealth { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowHealth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show the current dimension in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowDimension { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowDimension", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show the current gamemode in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowGamemode { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowGamemode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show elapsed session time in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowElapsedTime { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowElapsedTime", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show the online player count as a party size in the Discord presence.. + /// + internal static string ChatBot_DiscordRpc_ShowPlayerCount { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.ShowPlayerCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How often (in seconds) to refresh the Discord presence. Minimum: 1. + /// + internal static string ChatBot_DiscordRpc_UpdateIntervalSeconds { + get { + return ResourceManager.GetString("ChatBot.DiscordRpc.UpdateIntervalSeconds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Relay messages between players and servers, like a mail plugin + ///This bot can store messages when the recipients are offline, and send them when they join the server + /// /!\ Server admins can spoof PMs (/tellraw, /nick) so enable this bot only if you trust server admins. + /// + internal static string ChatBot_Mailer { + get { + return ResourceManager.GetString("ChatBot.Mailer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allows you to render maps in the console and into images (which can be then sent to Discord using Discord Bridge Chat Bot) + ///This is useful for solving captchas which use maps + ///The maps are rendered into Rendered_Maps folder if the Save_To_File is enabled. + ///NOTE: + ///If some servers have a very short time for solving captchas, enabe Auto_Render_On_Update to see them immediatelly in the console. + /// /!\ Make sure server rules allow bots to be used on the server, or you risk being punished.. + /// + internal static string ChatBot_Map { + get { + return ResourceManager.GetString("ChatBot.Map", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically render the map once it is received or updated from/by the server. + /// + internal static string ChatBot_Map_Auto_Render_On_Update { + get { + return ResourceManager.GetString("ChatBot.Map.Auto_Render_On_Update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete all rendered maps on unload/reload or when you launch the MCC again.. + /// + internal static string ChatBot_Map_Delete_All_On_Unload { + get { + return ResourceManager.GetString("ChatBot.Map.Delete_All_On_Unload", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Get a notification when you have gotten a map from the server for the first time. + /// + internal static string ChatBot_Map_Notify_On_First_Update { + get { + return ResourceManager.GetString("ChatBot.Map.Notify_On_First_Update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Resize an rendered image, this is useful when images that are rendered are small and when are being sent to Discord.. + /// + internal static string ChatBot_Map_Rasize_Rendered_Image { + get { + return ResourceManager.GetString("ChatBot.Map.Rasize_Rendered_Image", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to render the map in the console.. + /// + internal static string ChatBot_Map_Render_In_Console { + get { + return ResourceManager.GetString("ChatBot.Map.Render_In_Console", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The size that a rendered image should be resized to, in pixels (eg. 512).. + /// + internal static string ChatBot_Map_Resize_To { + get { + return ResourceManager.GetString("ChatBot.Map.Resize_To", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to store the rendered map as a file (You need this setting if you want to get a map on Discord using Discord Bridge).. + /// + internal static string ChatBot_Map_Save_To_File { + get { + return ResourceManager.GetString("ChatBot.Map.Save_To_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send a rendered map (saved to a file) to a Discord or a Telegram channel via the Discord or Telegram Bride chat bot (The Discord/Telegram Bridge chat bot must be enabled and configured!) + ///You need to enable Save_To_File in order for this to work. + ///We also recommend turning on resizing.. + /// + internal static string ChatBot_Map_Send_Rendered_To_Bridges { + get { + return ResourceManager.GetString("ChatBot.Map.Send_Rendered_To_Bridges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Log the list of players periodically into a textual file.. + /// + internal static string ChatBot_PlayerListLogger { + get { + return ResourceManager.GetString("ChatBot.PlayerListLogger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to (In seconds). + /// + internal static string ChatBot_PlayerListLogger_Delay { + get { + return ResourceManager.GetString("ChatBot.PlayerListLogger.Delay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send MCC console commands to your bot through server PMs (/tell) + ///You need to have ChatFormat working correctly and add yourself in botowners to use the bot + /// /!\ Server admins can spoof PMs (/tellraw, /nick) so enable RemoteControl only if you trust server admins. + /// + internal static string ChatBot_RemoteControl { + get { + return ResourceManager.GetString("ChatBot.RemoteControl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable recording of the game (/replay start) and replay it later using the Replay Mod (https://www.replaymod.com/) + ///Please note that due to technical limitations, the client player (you) will not be shown in the replay file + /// /!\ You SHOULD use /replay stop or exit the program gracefully with /quit OR THE REPLAY FILE MAY GET CORRUPT!. + /// + internal static string ChatBot_ReplayCapture { + get { + return ResourceManager.GetString("ChatBot.ReplayCapture", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How long should replay file be auto-saved, in seconds. Use -1 to disable.. + /// + internal static string ChatBot_ReplayCapture_Backup_Interval { + get { + return ResourceManager.GetString("ChatBot.ReplayCapture.Backup_Interval", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Schedule commands and scripts to launch on various events such as server join, date/time or time interval + ///See https://mccteam.github.io/g/bots/#script-scheduler for more info. + /// + internal static string ChatBot_ScriptScheduler { + get { + return ResourceManager.GetString("ChatBot.ScriptScheduler", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This bot allows you to send and receive messages and commands via a Telegram Bot DM or to receive messages in a Telegram channel. + /// /!\ NOTE: You can't send messages and commands from a group channel, you can only send them in the bot DM, but you can get the messages from the client in a group channel. + ///----------------------------------------------------------- + ///Setup: + ///First you need to create a Telegram bot and obtain an API key, to do so, go to Telegram and find @botfather + ///Click on "Start" button and re [rest of string was truncated]";. + /// + internal static string ChatBot_TelegramBridge { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A list of Chat IDs that are allowed to send messages and execute commands. To get an id of your chat DM with the bot use ".chatid" bot command in Telegram.. + /// + internal static string ChatBot_TelegramBridge_Authorized_Chat_Ids { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge.Authorized_Chat_Ids", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An ID of a channel where you want to interact with the MCC using the bot.. + /// + internal static string ChatBot_TelegramBridge_ChannelId { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge.ChannelId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Message formats + ///Words wrapped with { and } are going to be replaced during the code execution, do not change them! + ///For example. {message} is going to be replace with an actual message, {username} will be replaced with an username, {timestamp} with the current time. + ///For Telegram message formatting, check the following: https://mccteam.github.io/r/tg-fmt.html. + /// + internal static string ChatBot_TelegramBridge_Formats { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge.Formats", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How long to wait (in seconds) if a message can not be sent to Telegram before canceling the task (minimum 1 second).. + /// + internal static string ChatBot_TelegramBridge_MessageSendTimeout { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge.MessageSendTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your Telegram Bot token.. + /// + internal static string ChatBot_TelegramBridge_Token { + get { + return ResourceManager.GetString("ChatBot.TelegramBridge.Token", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remotely control the client using Web Sockets.\n# This is useful if you want to implement an application that can remotely and asynchronously execute procedures in MCC.\n# Example implementation written in JavaScript: https://github.com/milutinke/MCC.js.git\n# The protocol specification will be available in the documentation soon.. + /// + internal static string ChatBot_WebSocketBot { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow IP aliases, such as "localhost" or if using containers then the container name can be used.... + /// + internal static string ChatBot_WebSocketBot_AllowIpAlias { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot.AllowIpAlias", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This setting is for developers who are developing a library that uses this chat bot to remotely execute procedures/commands/functions.. + /// + internal static string ChatBot_WebSocketBot_DebugMode { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot.DebugMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The IP address that Websocket server will be bound to.. + /// + internal static string ChatBot_WebSocketBot_Ip { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot.Ip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A password that will be used to authenticate on thw Websocket server (It is recommended to change the default password and to set a strong one).. + /// + internal static string ChatBot_WebSocketBot_Password { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot.Password", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Port that Websocket server will be bounded to.. + /// + internal static string ChatBot_WebSocketBot_Port { + get { + return ResourceManager.GetString("ChatBot.WebSocketBot.Port", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MCC does it best to detect chat messages, but some server have unusual chat formats + ///When this happens, you'll need to configure chat format below, see https://mccteam.github.io/g/conf/#chat-format-section. + /// + internal static string ChatFormat { + get { + return ResourceManager.GetString("ChatFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MCC support for common message formats. Set "false" to avoid conflicts with custom formats.. + /// + internal static string ChatFormat_Builtins { + get { + return ResourceManager.GetString("ChatFormat.Builtins", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to use the custom regular expressions below for detection.. + /// + internal static string ChatFormat_UserDefined { + get { + return ResourceManager.GetString("ChatFormat.UserDefined", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Console-related settings.. + /// + internal static string Console { + get { + return ResourceManager.GetString("Console", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The settings for command completion suggestions. + ///Custom colors are only available when using "vt100_24bit" color mode.. + /// + internal static string Console_CommandSuggestion { + get { + return ResourceManager.GetString("Console.CommandSuggestion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to display command suggestions in the console.. + /// + internal static string Console_CommandSuggestion_Enable { + get { + return ResourceManager.GetString("Console.CommandSuggestion.Enable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable this option if the arrows in the command suggestions are not displayed properly in your terminal.. + /// + internal static string Console_CommandSuggestion_Use_Basic_Arrow { + get { + return ResourceManager.GetString("Console.CommandSuggestion.Use_Basic_Arrow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Console mode: "classic" for the standard terminal, "tui" for a pseudo-graphical full-screen interface.. + /// + internal static string Console_General_ConsoleMode { + get { + return ResourceManager.GetString("Console.General.ConsoleMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "disable", "legacy_4bit", "vt100_4bit", "vt100_8bit" or "vt100_24bit". If a garbled code like "←[0m" appears on the terminal, you can try switching to "legacy_4bit" mode, or just disable it.. + /// + internal static string Console_General_ConsoleColorMode { + get { + return ResourceManager.GetString("Console.General.ConsoleColorMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to display the MCC startup banner with version info and icon.. + /// + internal static string Console_General_Display_Icon_Banner { + get { + return ResourceManager.GetString("Console.General.Display_Icon_Banner", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can use "Ctrl+P" to print out the current input and cursor position.. + /// + internal static string Console_General_Display_Input { + get { + return ResourceManager.GetString("Console.General.Display_Input", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Startup Config File + ///Please do not record extraneous data in this file as it will be overwritten by MCC. + /// + ///New to Minecraft Console Client? Check out this document: https://mccteam.github.io/g/conf.html + ///Want to upgrade to a newer version? See https://github.com/MCCTeam/Minecraft-Console-Client/#download. + /// + internal static string Head { + get { + return ResourceManager.GetString("Head", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This setting affects only the messages in the console.. + /// + internal static string Logging { + get { + return ResourceManager.GetString("Logging", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Regex for filtering chat message.. + /// + internal static string Logging_ChatFilter { + get { + return ResourceManager.GetString("Logging.ChatFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show server chat messages.. + /// + internal static string Logging_ChatMessages { + get { + return ResourceManager.GetString("Logging.ChatMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Regex for filtering debug message.. + /// + internal static string Logging_DebugFilter { + get { + return ResourceManager.GetString("Logging.DebugFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please enable this before submitting bug reports. Thanks!. + /// + internal static string Logging_DebugMessages { + get { + return ResourceManager.GetString("Logging.DebugMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show error messages.. + /// + internal static string Logging_ErrorMessages { + get { + return ResourceManager.GetString("Logging.ErrorMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "disable" or "blacklist" OR "whitelist". Blacklist hide message match regex. Whitelist show message match regex.. + /// + internal static string Logging_FilterMode { + get { + return ResourceManager.GetString("Logging.FilterMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Informative messages. (i.e Most of the message from MCC). + /// + internal static string Logging_InfoMessages { + get { + return ResourceManager.GetString("Logging.InfoMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Log file name.. + /// + internal static string Logging_LogFile { + get { + return ResourceManager.GetString("Logging.LogFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Write log messages to file.. + /// + internal static string Logging_LogToFile { + get { + return ResourceManager.GetString("Logging.LogToFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prepend timestamp to messages in log file.. + /// + internal static string Logging_PrependTimestamp { + get { + return ResourceManager.GetString("Logging.PrependTimestamp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keep color codes in the saved text.(look like "§b"). + /// + internal static string Logging_SaveColorCodes { + get { + return ResourceManager.GetString("Logging.SaveColorCodes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show warning messages.. + /// + internal static string Logging_WarningMessages { + get { + return ResourceManager.GetString("Logging.WarningMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Make sure you understand what each setting does before changing anything!. + /// + internal static string Main_Advanced { + get { + return ResourceManager.GetString("Main.Advanced", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to AccountList: It allows a fast account switching without directly using the credentials + ///Usage examples: "/tell <mybot> reco Player2", "/connect <serverip> Player1". + /// + internal static string Main_Advanced_account_list { + get { + return ResourceManager.GetString("Main.Advanced.account_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggle auto respawn if client player was dead (make sure your spawn point is safe).. + /// + internal static string Main_Advanced_auto_respawn { + get { + return ResourceManager.GetString("Main.Advanced.auto_respawn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set the owner of the bot. /!\ Server admins can impersonate owners!. + /// + internal static string Main_Advanced_bot_owners { + get { + return ResourceManager.GetString("Main.Advanced.bot_owners", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "mcc", "vanilla" or "none". This is how MCC identifies itself to the server.. + /// + internal static string Main_Advanced_brand_info { + get { + return ResourceManager.GetString("Main.Advanced.brand_info", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Leave empty for no logfile.. + /// + internal static string Main_Advanced_chatbot_log_file { + get { + return ResourceManager.GetString("Main.Advanced.chatbot_log_file", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If turned off, the emoji will be replaced with a simpler character (for /chunk status).. + /// + internal static string Main_Advanced_enable_emoji { + get { + return ResourceManager.GetString("Main.Advanced.enable_emoji", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set to false to opt-out of Sentry error logging.. + /// + internal static string Main_Advanced_enable_sentry { + get { + return ResourceManager.GetString("Main.Advanced.enable_sentry", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggle entity handling.. + /// + internal static string Main_Advanced_entity_handling { + get { + return ResourceManager.GetString("Main.Advanced.entity_handling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to exit directly when an error occurs, for using MCC in non-interactive scripts.. + /// + internal static string Main_Advanced_exit_on_failure { + get { + return ResourceManager.GetString("Main.Advanced.exit_on_failure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ignore invalid player name. + /// + internal static string Main_Advanced_ignore_invalid_playername { + get { + return ResourceManager.GetString("Main.Advanced.ignore_invalid_playername", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "none", "slash"(/) or "backslash"(\).. + /// + internal static string Main_Advanced_internal_cmd_char { + get { + return ResourceManager.GetString("Main.Advanced.internal_cmd_char", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Toggle inventory handling.. + /// + internal static string Main_Advanced_inventory_handling { + get { + return ResourceManager.GetString("Main.Advanced.inventory_handling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fill in with in-game locale code, check https://mccteam.github.io/r/l-code.html. + /// + internal static string Main_Advanced_language { + get { + return ResourceManager.GetString("Main.Advanced.language", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Load translations applied to MCC when available, turn it off to use English only.. + /// + internal static string Main_Advanced_LoadMccTrans { + get { + return ResourceManager.GetString("Main.Advanced.LoadMccTrans", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "auto", "no" or "force". Force-enabling only works for MC 1.13+.. + /// + internal static string Main_Advanced_mc_forge { + get { + return ResourceManager.GetString("Main.Advanced.mc_forge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "auto" or "1.X.X" values. Allows to skip server info retrieval.. + /// + internal static string Main_Advanced_mc_version { + get { + return ResourceManager.GetString("Main.Advanced.mc_version", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Controls the minimum interval (in seconds) between sending each message to the server.. + /// + internal static string Main_Advanced_message_cooldown { + get { + return ResourceManager.GetString("Main.Advanced.message_cooldown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Override the maximum chat message length. Set to 0 to use the default (100 for 1.10 and below, 256 for 1.11+). WARNING: Setting this incorrectly may cause you to be kicked from the server.. + /// + internal static string Main_Advanced_max_chat_message_length { + get { + return ResourceManager.GetString("Main.Advanced.max_chat_message_length", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable support for joining Minecraft Realms worlds.. + /// + internal static string Main_Advanced_minecraft_realms { + get { + return ResourceManager.GetString("Main.Advanced.minecraft_realms", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The minimum height to use when calculating the image size from the height of the terminal.. + /// + internal static string Main_Advanced_MinTerminalHeight { + get { + return ResourceManager.GetString("Main.Advanced.MinTerminalHeight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The minimum width used when calculating the image size from the width of the terminal.. + /// + internal static string Main_Advanced_MinTerminalWidth { + get { + return ResourceManager.GetString("Main.Advanced.MinTerminalWidth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable head movement while walking to avoid anti-cheat triggers.. + /// + internal static string Main_Advanced_move_head_while_walking { + get { + return ResourceManager.GetString("Main.Advanced.move_head_while_walking", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A movement speed higher than 2 may be considered cheating.. + /// + internal static string Main_Advanced_movement_speed { + get { + return ResourceManager.GetString("Main.Advanced.movement_speed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only works on Windows XP-8 or Windows 10 with old console.. + /// + internal static string Main_Advanced_player_head_icon { + get { + return ResourceManager.GetString("Main.Advanced.player_head_icon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to For remote control of the bot.. + /// + internal static string Main_Advanced_private_msgs_cmd_name { + get { + return ResourceManager.GetString("Main.Advanced.private_msgs_cmd_name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How to retain profile key. Use "none", "memory" or "disk".. + /// + internal static string Main_Advanced_profilekey_cache { + get { + return ResourceManager.GetString("Main.Advanced.profilekey_cache", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "no", "fast" (5s timeout), or "yes". Required for joining some servers.. + /// + internal static string Main_Advanced_resolve_srv_records { + get { + return ResourceManager.GetString("Main.Advanced.resolve_srv_records", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cache compiled scripts for faster load on low-end devices.. + /// + internal static string Main_Advanced_script_cache { + get { + return ResourceManager.GetString("Main.Advanced.script_cache", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ServerList: It allows an easier and faster server switching with short aliases instead of full server IP + ///Aliases cannot contain dots or spaces, and the name "localhost" cannot be used as an alias. + ///Usage examples: "/tell <mybot> connect Server1", "/connect Server2". + /// + internal static string Main_Advanced_server_list { + get { + return ResourceManager.GetString("Main.Advanced.server_list", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to How to retain session tokens. Use "none", "memory" or "disk".. + /// + internal static string Main_Advanced_session_cache { + get { + return ResourceManager.GetString("Main.Advanced.session_cache", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Decode links embedded in chat messages and show them in console.. + /// + internal static string Main_Advanced_show_chat_links { + get { + return ResourceManager.GetString("Main.Advanced.show_chat_links", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show inventory layout as ASCII art in inventory command.. + /// internal static string Main_Advanced_show_inventory_layout { get { return ResourceManager.GetString("Main.Advanced.show_inventory_layout", resourceCulture); @@ -1862,345 +1872,345 @@ namespace MinecraftClient { /// Looks up a localized string similar to System messages for server ops.. ///
internal static string Main_Advanced_show_system_messages { - get { - return ResourceManager.GetString("Main.Advanced.show_system_messages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Messages displayed above xp bar, set this to false in case of xp bar spam.. - /// - internal static string Main_Advanced_show_xpbar_messages { - get { - return ResourceManager.GetString("Main.Advanced.show_xpbar_messages", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Temporary fix for Badpacket issue on some servers. Need to enable "TerrainAndMovements" first.. - /// - internal static string Main_Advanced_temporary_fix_badpacket { - get { - return ResourceManager.GetString("Main.Advanced.temporary_fix_badpacket", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Uses more ram, cpu, bandwidth but allows you to move around.. - /// - internal static string Main_Advanced_terrain_and_movements { - get { - return ResourceManager.GetString("Main.Advanced.terrain_and_movements", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Customize the TCP connection timeout with the server. (in seconds). - /// - internal static string Main_Advanced_timeout { - get { - return ResourceManager.GetString("Main.Advanced.timeout", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Prepend timestamps to chat messages.. - /// - internal static string Main_Advanced_timestamps { - get { - return ResourceManager.GetString("Main.Advanced.timestamps", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Login=Email or Name. Use "-" as password for offline mode. Leave blank to prompt user on startup.. - /// - internal static string Main_General_account { - get { - return ResourceManager.GetString("Main.General.account", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Yggdrasil authlib server domain name and port.. - /// - internal static string Main_General_AuthlibServer { - get { - return ResourceManager.GetString("Main.General.AuthlibServer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Yggdrasil authlib multi-user selection.. - /// - internal static string Main_General_AuthlibUser { - get { - return ResourceManager.GetString("Main.General.AuthlibUser", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The address of the game server, "Host" can be filled in with domain name or IP address. (The "Port" field can be deleted, it will be resolved automatically). - /// - internal static string Main_General_login { - get { - return ResourceManager.GetString("Main.General.login", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Microsoft Account sign-in method: "mcc" (device code, supports 2FA) OR "browser" (manual browser login).. - /// - internal static string Main_General_method { - get { - return ResourceManager.GetString("Main.General.method", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Account type: "mojang" OR "microsoft" OR "yggdrasil". Also affects interactive login in console.. - /// - internal static string Main_General_server_info { - get { - return ResourceManager.GetString("Main.General.server_info", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Settings below are sent to the server and only affect server-side things like your skin.. - /// - internal static string MCSettings { - get { - return ResourceManager.GetString("MCSettings", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Allows disabling chat colors server-side.. - /// - internal static string MCSettings_ChatColors { - get { - return ResourceManager.GetString("MCSettings.ChatColors", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use "enabled", "commands", or "disabled". Allows to mute yourself.... - /// - internal static string MCSettings_ChatMode { - get { - return ResourceManager.GetString("MCSettings.ChatMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MC 1.7- difficulty. "peaceful", "easy", "normal", "difficult".. - /// - internal static string MCSettings_Difficulty { - get { - return ResourceManager.GetString("MCSettings.Difficulty", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to If disabled, settings below are not sent to the server.. - /// - internal static string MCSettings_Enabled { - get { - return ResourceManager.GetString("MCSettings.Enabled", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use any language implemented in Minecraft.. - /// - internal static string MCSettings_Locale { - get { - return ResourceManager.GetString("MCSettings.Locale", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MC 1.9+ main hand. "left" or "right".. - /// - internal static string MCSettings_MainHand { - get { - return ResourceManager.GetString("MCSettings.MainHand", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Value range: [0 - 255].. - /// - internal static string MCSettings_RenderDistance { - get { - return ResourceManager.GetString("MCSettings.RenderDistance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Connect to a server via a proxy instead of connecting directly - ///If Mojang session services are blocked on your network, set Enabled_Login=true to login using proxy. - ///If the connection to the Minecraft game server is blocked by the firewall, set Enabled_Ingame=true to use a proxy to connect to the game server. - /// /!\ Make sure your server rules allow Proxies or VPNs before setting enabled=true, or you may face consequences!. - /// - internal static string Proxy { - get { - return ResourceManager.GetString("Proxy", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to connect to the game server through a proxy.. - /// - internal static string Proxy_Enabled_Ingame { - get { - return ResourceManager.GetString("Proxy.Enabled_Ingame", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to connect to the login server through a proxy.. - /// - internal static string Proxy_Enabled_Login { - get { - return ResourceManager.GetString("Proxy.Enabled_Login", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to download MCC updates via proxy.. - /// - internal static string Proxy_Enabled_Update { - get { - return ResourceManager.GetString("Proxy.Enabled_Update", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Only required for password-protected proxies.. - /// - internal static string Proxy_Password { - get { - return ResourceManager.GetString("Proxy.Password", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Supported types: "HTTP", "SOCKS4", "SOCKS4a", "SOCKS5".. - /// - internal static string Proxy_Proxy_Type { - get { - return ResourceManager.GetString("Proxy.Proxy_Type", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Proxy server must allow HTTPS for login, and non-443 ports for playing.. - /// - internal static string Proxy_Server { - get { - return ResourceManager.GetString("Proxy.Server", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Only required for password-protected proxies.. - /// - internal static string Proxy_Username { - get { - return ResourceManager.GetString("Proxy.Username", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Chat signature related settings (affects minecraft 1.19+). - /// - internal static string Signature { - get { - return ResourceManager.GetString("Signature", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Microsoft accounts only. If disabled, will not be able to sign chat and join servers configured with "enforce-secure-profile=true". - /// - internal static string Signature_LoginWithSecureProfile { - get { - return ResourceManager.GetString("Signature.LoginWithSecureProfile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use red    color block to mark chat without legitimate signature. - /// - internal static string Signature_MarkIllegallySignedMsg { - get { - return ResourceManager.GetString("Signature.MarkIllegallySignedMsg", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use green  color block to mark chat with legitimate signatures. - /// - internal static string Signature_MarkLegallySignedMsg { - get { - return ResourceManager.GetString("Signature.MarkLegallySignedMsg", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use yellow color block to mark chat that have been modified by the server.. - /// - internal static string Signature_MarkModifiedMsg { - get { - return ResourceManager.GetString("Signature.MarkModifiedMsg", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Use gray   color block to mark system message (always without signature). - /// - internal static string Signature_MarkSystemMessage { - get { - return ResourceManager.GetString("Signature.MarkSystemMessage", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to display chat and messages in commands without legal signatures. - /// - internal static string Signature_ShowIllegalSignedChat { - get { - return ResourceManager.GetString("Signature.ShowIllegalSignedChat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Set to true to display messages modified by the server, false to display the original signed messages. - /// - internal static string Signature_ShowModifiedChat { - get { - return ResourceManager.GetString("Signature.ShowModifiedChat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to sign the chat send from MCC. - /// - internal static string Signature_SignChat { - get { - return ResourceManager.GetString("Signature.SignChat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Whether to sign the messages contained in the commands sent by MCC. For example, the message in "/msg" and "/me". - /// - internal static string Signature_SignMessageInCommand { - get { - return ResourceManager.GetString("Signature.SignMessageInCommand", resourceCulture); - } - } - } -} + get { + return ResourceManager.GetString("Main.Advanced.show_system_messages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Messages displayed above xp bar, set this to false in case of xp bar spam.. + /// + internal static string Main_Advanced_show_xpbar_messages { + get { + return ResourceManager.GetString("Main.Advanced.show_xpbar_messages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Temporary fix for Badpacket issue on some servers. Need to enable "TerrainAndMovements" first.. + /// + internal static string Main_Advanced_temporary_fix_badpacket { + get { + return ResourceManager.GetString("Main.Advanced.temporary_fix_badpacket", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Uses more ram, cpu, bandwidth but allows you to move around.. + /// + internal static string Main_Advanced_terrain_and_movements { + get { + return ResourceManager.GetString("Main.Advanced.terrain_and_movements", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Customize the TCP connection timeout with the server. (in seconds). + /// + internal static string Main_Advanced_timeout { + get { + return ResourceManager.GetString("Main.Advanced.timeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prepend timestamps to chat messages.. + /// + internal static string Main_Advanced_timestamps { + get { + return ResourceManager.GetString("Main.Advanced.timestamps", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Login=Email or Name. Use "-" as password for offline mode. Leave blank to prompt user on startup.. + /// + internal static string Main_General_account { + get { + return ResourceManager.GetString("Main.General.account", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yggdrasil authlib server domain name and port.. + /// + internal static string Main_General_AuthlibServer { + get { + return ResourceManager.GetString("Main.General.AuthlibServer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yggdrasil authlib multi-user selection.. + /// + internal static string Main_General_AuthlibUser { + get { + return ResourceManager.GetString("Main.General.AuthlibUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The address of the game server, "Host" can be filled in with domain name or IP address. (The "Port" field can be deleted, it will be resolved automatically). + /// + internal static string Main_General_login { + get { + return ResourceManager.GetString("Main.General.login", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Microsoft Account sign-in method: "mcc" (device code, supports 2FA) OR "browser" (manual browser login).. + /// + internal static string Main_General_method { + get { + return ResourceManager.GetString("Main.General.method", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Account type: "mojang" OR "microsoft" OR "yggdrasil". Also affects interactive login in console.. + /// + internal static string Main_General_server_info { + get { + return ResourceManager.GetString("Main.General.server_info", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Settings below are sent to the server and only affect server-side things like your skin.. + /// + internal static string MCSettings { + get { + return ResourceManager.GetString("MCSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allows disabling chat colors server-side.. + /// + internal static string MCSettings_ChatColors { + get { + return ResourceManager.GetString("MCSettings.ChatColors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use "enabled", "commands", or "disabled". Allows to mute yourself.... + /// + internal static string MCSettings_ChatMode { + get { + return ResourceManager.GetString("MCSettings.ChatMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MC 1.7- difficulty. "peaceful", "easy", "normal", "difficult".. + /// + internal static string MCSettings_Difficulty { + get { + return ResourceManager.GetString("MCSettings.Difficulty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If disabled, settings below are not sent to the server.. + /// + internal static string MCSettings_Enabled { + get { + return ResourceManager.GetString("MCSettings.Enabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use any language implemented in Minecraft.. + /// + internal static string MCSettings_Locale { + get { + return ResourceManager.GetString("MCSettings.Locale", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MC 1.9+ main hand. "left" or "right".. + /// + internal static string MCSettings_MainHand { + get { + return ResourceManager.GetString("MCSettings.MainHand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Value range: [0 - 255].. + /// + internal static string MCSettings_RenderDistance { + get { + return ResourceManager.GetString("MCSettings.RenderDistance", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Connect to a server via a proxy instead of connecting directly + ///If Mojang session services are blocked on your network, set Enabled_Login=true to login using proxy. + ///If the connection to the Minecraft game server is blocked by the firewall, set Enabled_Ingame=true to use a proxy to connect to the game server. + /// /!\ Make sure your server rules allow Proxies or VPNs before setting enabled=true, or you may face consequences!. + /// + internal static string Proxy { + get { + return ResourceManager.GetString("Proxy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to connect to the game server through a proxy.. + /// + internal static string Proxy_Enabled_Ingame { + get { + return ResourceManager.GetString("Proxy.Enabled_Ingame", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to connect to the login server through a proxy.. + /// + internal static string Proxy_Enabled_Login { + get { + return ResourceManager.GetString("Proxy.Enabled_Login", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to download MCC updates via proxy.. + /// + internal static string Proxy_Enabled_Update { + get { + return ResourceManager.GetString("Proxy.Enabled_Update", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only required for password-protected proxies.. + /// + internal static string Proxy_Password { + get { + return ResourceManager.GetString("Proxy.Password", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Supported types: "HTTP", "SOCKS4", "SOCKS4a", "SOCKS5".. + /// + internal static string Proxy_Proxy_Type { + get { + return ResourceManager.GetString("Proxy.Proxy_Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Proxy server must allow HTTPS for login, and non-443 ports for playing.. + /// + internal static string Proxy_Server { + get { + return ResourceManager.GetString("Proxy.Server", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only required for password-protected proxies.. + /// + internal static string Proxy_Username { + get { + return ResourceManager.GetString("Proxy.Username", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Chat signature related settings (affects minecraft 1.19+). + /// + internal static string Signature { + get { + return ResourceManager.GetString("Signature", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Microsoft accounts only. If disabled, will not be able to sign chat and join servers configured with "enforce-secure-profile=true". + /// + internal static string Signature_LoginWithSecureProfile { + get { + return ResourceManager.GetString("Signature.LoginWithSecureProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use red    color block to mark chat without legitimate signature. + /// + internal static string Signature_MarkIllegallySignedMsg { + get { + return ResourceManager.GetString("Signature.MarkIllegallySignedMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use green  color block to mark chat with legitimate signatures. + /// + internal static string Signature_MarkLegallySignedMsg { + get { + return ResourceManager.GetString("Signature.MarkLegallySignedMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use yellow color block to mark chat that have been modified by the server.. + /// + internal static string Signature_MarkModifiedMsg { + get { + return ResourceManager.GetString("Signature.MarkModifiedMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use gray   color block to mark system message (always without signature). + /// + internal static string Signature_MarkSystemMessage { + get { + return ResourceManager.GetString("Signature.MarkSystemMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to display chat and messages in commands without legal signatures. + /// + internal static string Signature_ShowIllegalSignedChat { + get { + return ResourceManager.GetString("Signature.ShowIllegalSignedChat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set to true to display messages modified by the server, false to display the original signed messages. + /// + internal static string Signature_ShowModifiedChat { + get { + return ResourceManager.GetString("Signature.ShowModifiedChat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to sign the chat send from MCC. + /// + internal static string Signature_SignChat { + get { + return ResourceManager.GetString("Signature.SignChat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whether to sign the messages contained in the commands sent by MCC. For example, the message in "/msg" and "/me". + /// + internal static string Signature_SignMessageInCommand { + get { + return ResourceManager.GetString("Signature.SignMessageInCommand", resourceCulture); + } + } + } +} diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index 2b09765e..4816d2de 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -566,6 +566,9 @@ Custom colors are only available when using "vt100_24bit" color mode. Use "disable", "legacy_4bit", "vt100_4bit", "vt100_8bit" or "vt100_24bit". If a garbled code like "←[0m" appears on the terminal, you can try switching to "legacy_4bit" mode, or just disable it. + + Whether to display the MCC startup icon banner. + You can use "Ctrl+P" to print out the current input and cursor position. diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index b77b0f39..d2883376 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -2269,6 +2269,18 @@ namespace MinecraftClient { } } + internal static string mcc_banner_classic { + get { + return ResourceManager.GetString("mcc.banner.classic", resourceCulture); + } + } + + internal static string mcc_banner_label_mc_versions { + get { + return ResourceManager.GetString("mcc.banner.label_mc_versions", resourceCulture); + } + } + internal static string mcc_server_info_label_server { get { return ResourceManager.GetString("mcc.server_info.label_server", resourceCulture); diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 48a07470..15895ca8 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -830,6 +830,12 @@ Add the ID of this chat to "Authorized_Chat_Ids" field in the configuration file TestBot + + Minecraft Console Client v{0} - for MC {1} to {2} - {3} + + + MC Versions: + Server: diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 299fe990..8f556a5c 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -1210,6 +1210,9 @@ namespace MinecraftClient [TomlInlineComment("$Console.General.ConsoleColorMode$")] public ConsoleColorModeType ConsoleColorMode = ConsoleColorModeType.vt100_24bit; + [TomlInlineComment("$Console.General.Display_Icon_Banner$")] + public bool Display_Icon_Banner = true; + [TomlInlineComment("$Console.General.Display_Input$")] public bool Display_Input = true; diff --git a/MinecraftClient/Tui/IconGridBuilder.cs b/MinecraftClient/Tui/IconGridBuilder.cs new file mode 100644 index 00000000..3d13a8e2 --- /dev/null +++ b/MinecraftClient/Tui/IconGridBuilder.cs @@ -0,0 +1,125 @@ +using System; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Media; + +namespace MinecraftClient.Tui +{ + internal static class IconGridBuilder + { + internal static Grid BuildFromRgba(byte[] rgba, int srcWidth, int srcHeight, int displaySize) + { + int cellCols = displaySize; + int cellRows = displaySize / 2; + + var grid = new Grid(); + for (int c = 0; c < cellCols; c++) + grid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Auto)); + for (int r = 0; r < cellRows; r++) + grid.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Auto)); + + for (int row = 0; row < cellRows; row++) + { + for (int col = 0; col < cellCols; col++) + { + int topPixelY = row * 2; + int bottomPixelY = row * 2 + 1; + + var topColor = SamplePixel(rgba, srcWidth, srcHeight, col, topPixelY, cellCols, displaySize); + var bottomColor = SamplePixel(rgba, srcWidth, srcHeight, col, bottomPixelY, cellCols, displaySize); + + var cell = new TextBlock + { + Text = "\u2580", + Foreground = new SolidColorBrush(topColor), + Background = new SolidColorBrush(bottomColor), + Padding = new Thickness(0), + Margin = new Thickness(0), + }; + + Grid.SetRow(cell, row); + Grid.SetColumn(cell, col); + grid.Children.Add(cell); + } + } + + return grid; + } + + internal static Grid BuildFromBase64(string base64Data, int displaySize) + { + byte[] imageBytes; + try + { + imageBytes = Convert.FromBase64String(base64Data); + } + catch + { + return new Grid(); + } + + return BuildFromImageBytes(imageBytes, displaySize) ?? new Grid(); + } + + internal static Grid? BuildFromImageBytes(byte[] imageBytes, int displaySize) + { + int srcWidth, srcHeight; + byte[] rgba; + try + { + (srcWidth, srcHeight, rgba) = DecodeImageToRgba(imageBytes); + } + catch + { + return null; + } + + return BuildFromRgba(rgba, srcWidth, srcHeight, displaySize); + } + + internal static (int Width, int Height, byte[] Rgba) DecodeImageToRgba(byte[] imageData) + { + using var image = new ImageMagick.MagickImage(imageData); + int w = (int)image.Width; + int h = (int)image.Height; + + using var pixels = image.GetPixelsUnsafe(); + var rgba = new byte[w * h * 4]; + + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + var pixel = pixels.GetPixel(x, y)!; + int idx = (y * w + x) * 4; + var color = pixel.ToColor()!; + rgba[idx] = (byte)(color.R >> 8); + rgba[idx + 1] = (byte)(color.G >> 8); + rgba[idx + 2] = (byte)(color.B >> 8); + rgba[idx + 3] = (byte)(color.A >> 8); + } + } + + return (w, h, rgba); + } + + private static Color SamplePixel(byte[] rgba, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) + { + int srcX = dstX * srcW / dstW; + int srcY = dstY * srcH / dstH; + srcX = Math.Clamp(srcX, 0, srcW - 1); + srcY = Math.Clamp(srcY, 0, srcH - 1); + + int idx = (srcY * srcW + srcX) * 4; + if (idx + 3 >= rgba.Length) + return Color.FromRgb(0, 0, 0); + + byte r = rgba[idx]; + byte g = rgba[idx + 1]; + byte b = rgba[idx + 2]; + byte a = rgba[idx + 3]; + + return a < 128 ? Color.FromRgb(0, 0, 0) : Color.FromRgb(r, g, b); + } + } +} diff --git a/MinecraftClient/Tui/MccBannerPanelBuilder.cs b/MinecraftClient/Tui/MccBannerPanelBuilder.cs new file mode 100644 index 00000000..67d5ccaf --- /dev/null +++ b/MinecraftClient/Tui/MccBannerPanelBuilder.cs @@ -0,0 +1,180 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Documents; +using Avalonia.Layout; +using Avalonia.Media; + +namespace MinecraftClient.Tui +{ + internal static class MccBannerPanelBuilder + { + internal static Border Build(string? buildInfo) + { + var contentPanel = new DockPanel { Background = Brushes.Black }; + + var icon = BuildIcon(); + icon.VerticalAlignment = VerticalAlignment.Center; + DockPanel.SetDock(icon, Dock.Left); + contentPanel.Children.Add(icon); + + var infoPanel = new StackPanel + { + Orientation = Orientation.Vertical, + Margin = new Thickness(1, 0, 0, 0), + VerticalAlignment = VerticalAlignment.Center, + }; + + AddTitle(infoPanel); + AddVersionRange(infoPanel); + AddGithub(infoPanel); + + if (buildInfo is not null) + AddBuildInfo(infoPanel, buildInfo); + + contentPanel.Children.Add(infoPanel); + + return new Border + { + BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80)), + BorderThickness = new Thickness(1), + Background = new SolidColorBrush(Color.FromArgb(240, 20, 20, 20)), + Padding = new Thickness(1, 0), + Child = contentPanel, + Margin = new Thickness(0), + }; + } + + private static void AddTitle(StackPanel panel) + { + var row = new TextBlock(); + row.Inlines!.Add(new Run("Minecraft Console Client") + { Foreground = Pal.Gold, FontWeight = FontWeight.Bold }); + row.Inlines.Add(new Run($" v{Program.Version}") { Foreground = Pal.Aqua }); + panel.Children.Add(row); + } + + private static void AddVersionRange(StackPanel panel) + { + var row = new TextBlock(); + row.Inlines!.Add(Lbl(Translations.mcc_banner_label_mc_versions)); + row.Inlines.Add(Val(Program.MCLowestVersion, Pal.Green)); + row.Inlines.Add(new Run(" - ") { Foreground = Pal.Gray }); + row.Inlines.Add(Val(Program.MCHighestVersion, Pal.Green)); + panel.Children.Add(row); + } + + private static void AddGithub(StackPanel panel) + { + var row = new TextBlock(); + row.Inlines!.Add(Val("Github.com/MCCTeam", Pal.Gray)); + panel.Children.Add(row); + } + + private static void AddBuildInfo(StackPanel panel, string buildInfo) + { + panel.Children.Add(new TextBlock + { + Text = buildInfo, + Foreground = Pal.DarkGray, + }); + } + + #region Icon + + private static readonly Color B1 = Color.FromRgb(200, 200, 200); // bezel bright + private static readonly Color B2 = Color.FromRgb(160, 160, 160); // bezel mid + private static readonly Color B3 = Color.FromRgb(120, 120, 120); // bezel dark + private static readonly Color Sc = Color.FromRgb(32, 32, 32); // screen + private static readonly Color Sd = Color.FromRgb(26, 26, 26); // screen (dark) + private static readonly Color S = Color.FromRgb(20, 20, 20); // screen bg + private static readonly Color C = Color.FromRgb(55, 200, 55); // creeper green + + // @formatter:off + private static readonly Color[,] Pixels = + { + { B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B2 }, + { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, B3 }, + { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, B3 }, + { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, B3 }, + { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, Sd, S, S, S, B3 }, + { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, S, S, S, S, S, S, B3 }, + { B1, Sc, Sc, Sc, Sc, Sd, Sd, S, S, C, C, S, S, C, C, S, B3 }, + { B1, Sc, Sc, Sd, Sd, S, S, S, S, C, C, S, S, C, C, S, B3 }, + { B1, Sd, Sd, S, S, S, S, S, S, S, S, C, C, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, C, C, C, C, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, C, C, C, C, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, C, S, S, C, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B2, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3 }, + }; + // @formatter:on + + private static Control BuildIcon() + { + int cols = Pixels.GetLength(1); + int textRows = Pixels.GetLength(0) / 2; + + var pixelGrid = new Grid(); + for (int c = 0; c < cols; c++) + pixelGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Auto)); + for (int r = 0; r < textRows; r++) + pixelGrid.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Auto)); + + for (int row = 0; row < textRows; row++) + { + for (int col = 0; col < cols; col++) + { + var topColor = Pixels[row * 2, col]; + var bottomColor = Pixels[row * 2 + 1, col]; + + var cell = new TextBlock + { + Text = "\u2580", + Foreground = new SolidColorBrush(topColor), + Background = new SolidColorBrush(bottomColor), + Padding = new Thickness(0), + Margin = new Thickness(0), + }; + + Grid.SetRow(cell, row); + Grid.SetColumn(cell, col); + pixelGrid.Children.Add(cell); + } + } + + var prompt = new TextBlock + { + Text = " >_", + Foreground = new SolidColorBrush(Color.FromRgb(220, 220, 220)), + Background = new SolidColorBrush(Sc), + Padding = new Thickness(0), + Margin = new Thickness(0), + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + }; + Grid.SetRow(prompt, 1); + Grid.SetColumn(prompt, 1); + Grid.SetColumnSpan(prompt, 4); + pixelGrid.Children.Add(prompt); + + return pixelGrid; + } + + #endregion + + private static Run Lbl(string text) => + new(text + " ") { Foreground = Pal.Gray }; + + private static Run Val(string text, IBrush color) => + new(text) { Foreground = color }; + + private static class Pal + { + public static readonly IBrush Gray = new SolidColorBrush(Color.FromRgb(170, 170, 170)); + public static readonly IBrush DarkGray = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + public static readonly IBrush Aqua = new SolidColorBrush(Color.FromRgb(85, 255, 255)); + public static readonly IBrush Green = new SolidColorBrush(Color.FromRgb(85, 255, 85)); + public static readonly IBrush Gold = new SolidColorBrush(Color.FromRgb(255, 170, 0)); + } + } +} diff --git a/MinecraftClient/Tui/ServerStatusPanelBuilder.cs b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs index dd859242..2c8daf6f 100644 --- a/MinecraftClient/Tui/ServerStatusPanelBuilder.cs +++ b/MinecraftClient/Tui/ServerStatusPanelBuilder.cs @@ -28,6 +28,7 @@ namespace MinecraftClient.Tui { Orientation = Orientation.Vertical, Margin = new Thickness(1, 0, 0, 0), + VerticalAlignment = VerticalAlignment.Center, }; AddMotd(infoPanel, info); @@ -47,7 +48,7 @@ namespace MinecraftClient.Tui Background = new SolidColorBrush(Color.FromArgb(240, 20, 20, 20)), Padding = new Thickness(1, 0), Child = contentPanel, - Margin = new Thickness(0, 1), + Margin = new Thickness(0), }; } @@ -180,114 +181,8 @@ namespace MinecraftClient.Tui private static Run Value(string text, IBrush color) => new(text) { Foreground = color }; - #region Favicon Rendering - - private static Grid BuildFaviconGrid(string base64Png, int displaySize) - { - byte[] pngBytes; - try - { - pngBytes = Convert.FromBase64String(base64Png); - } - catch - { - return new Grid(); - } - - int srcWidth, srcHeight; - byte[] rgba; - try - { - (srcWidth, srcHeight, rgba) = DecodePngToRgba(pngBytes); - } - catch - { - return new Grid(); - } - - int cellCols = displaySize; - int cellRows = displaySize / 2; - - var grid = new Grid(); - for (int c = 0; c < cellCols; c++) - grid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Auto)); - for (int r = 0; r < cellRows; r++) - grid.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Auto)); - - for (int row = 0; row < cellRows; row++) - { - for (int col = 0; col < cellCols; col++) - { - int topPixelY = row * 2; - int bottomPixelY = row * 2 + 1; - - var topColor = SamplePixel(rgba, srcWidth, srcHeight, col, topPixelY, cellCols, displaySize); - var bottomColor = SamplePixel(rgba, srcWidth, srcHeight, col, bottomPixelY, cellCols, displaySize); - - var cell = new TextBlock - { - Text = "\u2580", - Foreground = new SolidColorBrush(topColor), - Background = new SolidColorBrush(bottomColor), - Padding = new Thickness(0), - Margin = new Thickness(0), - }; - - Grid.SetRow(cell, row); - Grid.SetColumn(cell, col); - grid.Children.Add(cell); - } - } - - return grid; - } - - private static Color SamplePixel(byte[] rgba, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) - { - int srcX = dstX * srcW / dstW; - int srcY = dstY * srcH / dstH; - srcX = Math.Clamp(srcX, 0, srcW - 1); - srcY = Math.Clamp(srcY, 0, srcH - 1); - - int idx = (srcY * srcW + srcX) * 4; - if (idx + 3 >= rgba.Length) - return Color.FromRgb(0, 0, 0); - - byte r = rgba[idx]; - byte g = rgba[idx + 1]; - byte b = rgba[idx + 2]; - byte a = rgba[idx + 3]; - - return a < 128 ? Color.FromRgb(0, 0, 0) : Color.FromRgb(r, g, b); - } - - private static (int Width, int Height, byte[] Rgba) DecodePngToRgba(byte[] png) - { - using var image = new ImageMagick.MagickImage(png); - int w = (int)image.Width; - int h = (int)image.Height; - - using var pixels = image.GetPixelsUnsafe(); - var rgba = new byte[w * h * 4]; - - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - var pixel = pixels.GetPixel(x, y)!; - int idx = (y * w + x) * 4; - var color = pixel.ToColor()!; - rgba[idx] = (byte)(color.R >> 8); - rgba[idx + 1] = (byte)(color.G >> 8); - rgba[idx + 2] = (byte)(color.B >> 8); - rgba[idx + 3] = (byte)(color.A >> 8); - } - } - - return (w, h, rgba); - } - - #endregion + private static Grid BuildFaviconGrid(string base64Png, int displaySize) => + IconGridBuilder.BuildFromBase64(base64Png, displaySize); private static class McColors { From f7bc8174083a9e571a2540fee49a2abe114998c0 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 00:02:59 +0800 Subject: [PATCH 298/484] Refactor color definitions in MccBannerPanelBuilder for improved clarity - Removed unused color definitions for screen and dark screen. - Updated pixel array to use the new screen background color consistently. - Adjusted prompt text colors for better visibility in the TUI. --- MinecraftClient/Tui/MccBannerPanelBuilder.cs | 22 +++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/MinecraftClient/Tui/MccBannerPanelBuilder.cs b/MinecraftClient/Tui/MccBannerPanelBuilder.cs index 67d5ccaf..36d35b40 100644 --- a/MinecraftClient/Tui/MccBannerPanelBuilder.cs +++ b/MinecraftClient/Tui/MccBannerPanelBuilder.cs @@ -84,8 +84,6 @@ namespace MinecraftClient.Tui private static readonly Color B1 = Color.FromRgb(200, 200, 200); // bezel bright private static readonly Color B2 = Color.FromRgb(160, 160, 160); // bezel mid private static readonly Color B3 = Color.FromRgb(120, 120, 120); // bezel dark - private static readonly Color Sc = Color.FromRgb(32, 32, 32); // screen - private static readonly Color Sd = Color.FromRgb(26, 26, 26); // screen (dark) private static readonly Color S = Color.FromRgb(20, 20, 20); // screen bg private static readonly Color C = Color.FromRgb(55, 200, 55); // creeper green @@ -93,14 +91,14 @@ namespace MinecraftClient.Tui private static readonly Color[,] Pixels = { { B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1, B2 }, - { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, B3 }, - { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, B3 }, - { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, B3 }, - { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, Sd, S, S, S, B3 }, - { B1, Sc, Sc, Sc, Sc, Sc, Sc, Sc, Sd, Sd, S, S, S, S, S, S, B3 }, - { B1, Sc, Sc, Sc, Sc, Sd, Sd, S, S, C, C, S, S, C, C, S, B3 }, - { B1, Sc, Sc, Sd, Sd, S, S, S, S, C, C, S, S, C, C, S, B3 }, - { B1, Sd, Sd, S, S, S, S, S, S, S, S, C, C, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, B3 }, + { B1, S, S, S, S, S, S, S, S, C, C, S, S, C, C, S, B3 }, + { B1, S, S, S, S, S, S, S, S, C, C, S, S, C, C, S, B3 }, + { B1, S, S, S, S, S, S, S, S, S, S, C, C, S, S, S, B3 }, { B1, S, S, S, S, S, S, S, S, S, C, C, C, C, S, S, B3 }, { B1, S, S, S, S, S, S, S, S, S, C, C, C, C, S, S, B3 }, { B1, S, S, S, S, S, S, S, S, S, C, S, S, C, S, S, B3 }, @@ -145,8 +143,8 @@ namespace MinecraftClient.Tui var prompt = new TextBlock { Text = " >_", - Foreground = new SolidColorBrush(Color.FromRgb(220, 220, 220)), - Background = new SolidColorBrush(Sc), + Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)), + Background = new SolidColorBrush(S), Padding = new Thickness(0), Margin = new Thickness(0), HorizontalAlignment = HorizontalAlignment.Left, From 435887cc045b125483fe5eb5721765a42c92aaa0 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 00:05:22 +0800 Subject: [PATCH 299/484] Update translation for banner label to clarify supported Minecraft versions --- MinecraftClient/Resources/Translations/Translations.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 15895ca8..b67f453b 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -834,7 +834,7 @@ Add the ID of this chat to "Authorized_Chat_Ids" field in the configuration file Minecraft Console Client v{0} - for MC {1} to {2} - {3} - MC Versions: + Supported MC Versions: Server: From eae96a8fbcfc7adf15de2f4cb06f3fae2a88e785 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 00:40:26 +0800 Subject: [PATCH 300/484] Cave mode for minimap --- MinecraftClient/Commands/Minimap.cs | 30 +- .../ConfigComments/ConfigComments.resx | 3 + .../Translations/Translations.Designer.cs | 18 ++ .../Resources/Translations/Translations.resx | 6 + MinecraftClient/Settings.cs | 3 + MinecraftClient/Tui/MainTuiView.cs | 9 + MinecraftClient/Tui/MinimapColorMap.cs | 27 +- MinecraftClient/Tui/MinimapControl.cs | 304 ++++++++++++++++-- 8 files changed, 379 insertions(+), 21 deletions(-) diff --git a/MinecraftClient/Commands/Minimap.cs b/MinecraftClient/Commands/Minimap.cs index 897c88ae..0b6ca00f 100644 --- a/MinecraftClient/Commands/Minimap.cs +++ b/MinecraftClient/Commands/Minimap.cs @@ -11,7 +11,7 @@ namespace MinecraftClient.Commands class Minimap : Command { public override string CmdName => "minimap"; - public override string CmdUsage => "minimap [on|off] | minimap zoom [in|out|<1-16>] | minimap names [players|hostile|neutral|passive] [on|off] | minimap names [all_on|all_off] | minimap position [top_left|top_right|center|bottom_left|bottom_right]"; + public override string CmdUsage => "minimap [on|off] | minimap zoom [in|out|<1-16>] | minimap names [players|hostile|neutral|passive] [on|off] | minimap names [all_on|all_off] | minimap position [top_left|top_right|center|bottom_left|bottom_right] | minimap cave [auto|on|off]"; public override string CmdDesc => Translations.cmd_minimap_desc; public override void RegisterCommand(CommandDispatcher dispatcher) @@ -78,6 +78,14 @@ namespace MinecraftClient.Commands .Executes(r => DoPositionSet(r.Source, MinimapPosition.bottom_left))) .Then(l => l.Literal("bottom_right") .Executes(r => DoPositionSet(r.Source, MinimapPosition.bottom_right)))) + .Then(l => l.Literal("cave") + .Executes(r => DoCaveInfo(r.Source)) + .Then(l => l.Literal("auto") + .Executes(r => DoCaveSet(r.Source, CaveModeOption.auto))) + .Then(l => l.Literal("on") + .Executes(r => DoCaveSet(r.Source, CaveModeOption.on))) + .Then(l => l.Literal("off") + .Executes(r => DoCaveSet(r.Source, CaveModeOption.off)))) .Then(l => l.Literal("_help") .Executes(r => GetUsage(r.Source, string.Empty)) .Redirect(dispatcher.GetRoot().GetChild("help")?.GetChild(CmdName))) @@ -251,6 +259,26 @@ namespace MinecraftClient.Commands string.Format(Translations.cmd_minimap_position_set, pos)); } + private static int DoCaveInfo(CmdResult r) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + var mode = view.GetMinimapCaveMode(); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_cave_current, mode)); + } + + private static int DoCaveSet(CmdResult r, CaveModeOption mode) + { + var view = GetTuiView(r); + if (view is null) return (int)r.status; + + Dispatcher.UIThread.Post(() => view.SetMinimapCaveMode(mode)); + return r.SetAndReturn(Status.Done, + string.Format(Translations.cmd_minimap_cave_set, mode)); + } + private static string BoolStr(bool v) => v ? "ON" : "OFF"; } } diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index 4816d2de..8f3e4964 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -975,6 +975,9 @@ Note: This does NOT require a Bot Token, only an Application ID. Discord must be Minimap refresh interval in milliseconds (100-5000). + + Cave rendering mode: "auto" (detect ceiling), "on" (always cave view), "off" (always surface view). + Yggdrasil authlib multi-user selection. diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index d2883376..de6784ae 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -7187,6 +7187,24 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Current cave mode: {0}. + /// + internal static string cmd_minimap_cave_current { + get { + return ResourceManager.GetString("cmd.minimap.cave_current", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cave mode set to: {0}. + /// + internal static string cmd_minimap_cave_set { + get { + return ResourceManager.GetString("cmd.minimap.cave_set", resourceCulture); + } + } + /// /// Looks up a localized string similar to list achievements/advancements from the server.. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index b67f453b..fddf6400 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -2533,6 +2533,12 @@ see item details. Minimap position set to: {0} + + Current cave mode: {0} + + + Cave mode set to: {0} + list achievements/advancements from the server. diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 8f556a5c..ededd636 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -1286,6 +1286,9 @@ namespace MinecraftClient [TomlInlineComment("$Console.Minimap.RefreshInterval$")] public int RefreshInterval = Tui.MinimapControl.DefaultRefreshMs; + [TomlInlineComment("$Console.Minimap.CaveMode$")] + public Tui.CaveModeOption CaveMode = Tui.CaveModeOption.auto; + public void OnSettingUpdate() { Zoom = Math.Clamp(Zoom, Tui.MinimapControl.MinZoom, Tui.MinimapControl.MaxZoom); diff --git a/MinecraftClient/Tui/MainTuiView.cs b/MinecraftClient/Tui/MainTuiView.cs index 1106f763..d8155d48 100644 --- a/MinecraftClient/Tui/MainTuiView.cs +++ b/MinecraftClient/Tui/MainTuiView.cs @@ -167,6 +167,7 @@ namespace MinecraftClient.Tui _minimapControl.NameConfig.Hostile = mmCfg.ShowHostileNames; _minimapControl.NameConfig.Neutral = mmCfg.ShowNeutralNames; _minimapControl.NameConfig.Passive = mmCfg.ShowPassiveNames; + _minimapControl.CaveMode = mmCfg.CaveMode; var (hAlign, vAlign, margin) = GetMinimapAlignment(mmCfg.Position); _minimapBorder = new Border @@ -1097,6 +1098,14 @@ namespace MinecraftClient.Tui public MinimapPosition GetMinimapPosition() => Settings.Config.Console.Minimap.Position; + public void SetMinimapCaveMode(CaveModeOption mode) + { + _minimapControl.CaveMode = mode; + Settings.Config.Console.Minimap.CaveMode = mode; + } + + public CaveModeOption GetMinimapCaveMode() => _minimapControl.CaveMode; + private static (HorizontalAlignment h, VerticalAlignment v, Thickness margin) GetMinimapAlignment(MinimapPosition pos) => pos switch { MinimapPosition.top_left => (HorizontalAlignment.Left, VerticalAlignment.Top, new Thickness(1, 1, 0, 0)), diff --git a/MinecraftClient/Tui/MinimapColorMap.cs b/MinecraftClient/Tui/MinimapColorMap.cs index ae1bf21c..b0b09596 100644 --- a/MinecraftClient/Tui/MinimapColorMap.cs +++ b/MinecraftClient/Tui/MinimapColorMap.cs @@ -20,6 +20,8 @@ namespace MinecraftClient.Tui public static readonly Color LavaColor = Color.FromRgb(255, 100, 0); public static readonly Color DefaultColor = Color.FromRgb(60, 60, 60); public static readonly Color VoidColor = Color.FromRgb(0, 0, 0); + public static readonly Color CaveBorderColor = Color.FromRgb(16, 16, 16); + public static readonly Color CaveSolidColor = Color.FromRgb(24, 20, 18); private static readonly FrozenDictionary ColorTable; private static readonly FrozenSet FullyTransparentMats; @@ -114,6 +116,14 @@ namespace MinecraftClient.Tui public static bool IsFullyTransparent(Material m) => FullyTransparentMats.Contains(m); + /// + /// Returns true for materials that block light propagation (solid, liquids), + /// used by cave mode to find the surface from the player's Y level. + /// Mirrors VoxelMap's lightDampening > 0 check. + /// + public static bool IsLightBlocking(Material m) + => (m == Material.Lava) || (!FullyTransparentMats.Contains(m) && m.IsSolid()); + public static bool IsWater(Material m) => WaterMats.Contains(m); public static bool IsIce(Material m) => IceMats.Contains(m); @@ -137,8 +147,8 @@ namespace MinecraftClient.Tui int multiplier = heightDelta switch { > 0 => 255, // higher than neighbor: brightest - 0 => 220, // same height: normal - _ => 180, // lower than neighbor: darker + 0 => 220, // same height: normal + _ => 180, // lower than neighbor: darker }; byte r = (byte)(baseColor.R * multiplier / 255); byte g = (byte)(baseColor.G * multiplier / 255); @@ -157,6 +167,19 @@ namespace MinecraftClient.Tui return Blend(IceColor, bottomColor, 0.35); } + /// + /// Darken a color to simulate underground lighting. Cave floors receive + /// a minimum brightness of ~32/255 for non-solid blocks (matching VoxelMap), + /// while solid/unreachable columns render as near-black. + /// + public static Color ApplyCaveDarkening(Color baseColor, double factor = 0.55) + { + byte r = (byte)(baseColor.R * factor); + byte g = (byte)(baseColor.G * factor); + byte b = (byte)(baseColor.B * factor); + return Color.FromRgb(r, g, b); + } + private static Color Blend(Color top, Color bottom, double topAlpha) { byte r = (byte)(top.R * topAlpha + bottom.R * (1.0 - topAlpha)); diff --git a/MinecraftClient/Tui/MinimapControl.cs b/MinecraftClient/Tui/MinimapControl.cs index 33f25465..616b44e5 100644 --- a/MinecraftClient/Tui/MinimapControl.cs +++ b/MinecraftClient/Tui/MinimapControl.cs @@ -13,6 +13,8 @@ using MinecraftClient.Mapping; namespace MinecraftClient.Tui { + public enum CaveModeOption { auto, on, off } + /// /// TUI minimap control rendered as a grid of TextBlocks using half-block characters. /// Zoom is expressed as blocks-per-pixel (1 = 1:1, 16 = 16 blocks per pixel). @@ -63,6 +65,8 @@ namespace MinecraftClient.Tui public MinimapPosition Position { get; set; } = MinimapPosition.top_right; + public CaveModeOption CaveMode { get; set; } = CaveModeOption.auto; + public int MapPixelWidth => _mapWidth; public int MapPixelHeight => _mapHeight; @@ -177,19 +181,21 @@ namespace MinecraftClient.Tui bool showHostile = _nameConfig.Hostile; bool showNeutral = _nameConfig.Neutral; bool showPassive = _nameConfig.Passive; + var caveOpt = CaveMode; Task.Run(() => { try { var result = SampleTerrain(client, bpp, w, h, - showPlayers, showHostile, showNeutral, showPassive, ct); + showPlayers, showHostile, showNeutral, showPassive, caveOpt, ct); if (ct.IsCancellationRequested) return; Dispatcher.UIThread.Post(() => { ApplyPixelBuffer(result, w, h); - UpdateInfoBarAndLegend(client, bpp, result.VisibleCategories, w); + UpdateInfoBarAndLegend(client, bpp, result.VisibleCategories, w, + result.CaveModeActive); }); } catch (OperationCanceledException) { } @@ -236,6 +242,7 @@ namespace MinecraftClient.Tui public int CenterX; public int CenterY; public int Bpp; + public bool CaveModeActive; } private static bool ShouldShowNameLocal(MobCategory cat, @@ -253,7 +260,7 @@ namespace MinecraftClient.Tui private static SampleResult SampleTerrain(McClient client, int bpp, int mapW, int mapH, bool showPlayers, bool showHostile, bool showNeutral, bool showPassive, - CancellationToken ct) + CaveModeOption caveOpt, CancellationToken ct) { var result = new SampleResult { @@ -281,6 +288,9 @@ namespace MinecraftClient.Tui int minY = dim.minY; int scanTop = Math.Min(playerBlockY + 32, dim.maxY - 1); + bool caveMode = ResolveCaveMode(caveOpt, world, dim, playerBlockX, playerBlockY, playerBlockZ, scanTop); + result.CaveModeActive = caveMode; + var entities = client.GetEntityHandlingEnabled() ? client.GetEntities() : null; @@ -374,6 +384,8 @@ namespace MinecraftClient.Tui ChunkColumn? cachedColumn = null; int cachedChunkX = int.MinValue, cachedChunkZ = int.MinValue; + bool[,]? caveMask = caveMode ? new bool[mapW, mapH] : null; + for (int px = 0; px < mapW; px++) { for (int py = 0; py < mapH; py++) @@ -383,23 +395,51 @@ namespace MinecraftClient.Tui int baseX = playerBlockX + (px - centerX) * bpp; int baseZ = playerBlockZ + (py - centerY) * bpp; - if (bpp == 1) + if (caveMode) { - var (color, surfY, surfMat) = SampleColumn(world, baseX, baseZ, scanTop, minY, - ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); - result.Pixels[px, py] = color; - result.Heights[px, py] = surfY; - result.BlockTypes![px, py] = surfMat; + if (bpp == 1) + { + var (color, surfY, surfMat, inCave) = SampleColumnCave( + world, baseX, baseZ, playerBlockY, minY, dim.maxY - 1, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + result.BlockTypes![px, py] = surfMat; + caveMask![px, py] = inCave; + } + else + { + var (color, surfY, matSum, inCave) = SampleAreaDominantCave( + world, baseX, baseZ, bpp, playerBlockY, minY, dim.maxY - 1, + result.BlockSummary is not null, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + if (result.BlockSummary is not null) + result.BlockSummary[px, py] = matSum; + caveMask![px, py] = inCave; + } } else { - var (color, surfY, matSum) = SampleAreaDominant(world, baseX, baseZ, bpp, - scanTop, minY, result.BlockSummary is not null, - ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); - result.Pixels[px, py] = color; - result.Heights[px, py] = surfY; - if (result.BlockSummary is not null) - result.BlockSummary[px, py] = matSum; + if (bpp == 1) + { + var (color, surfY, surfMat) = SampleColumn(world, baseX, baseZ, scanTop, minY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + result.BlockTypes![px, py] = surfMat; + } + else + { + var (color, surfY, matSum) = SampleAreaDominant(world, baseX, baseZ, bpp, + scanTop, minY, result.BlockSummary is not null, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + result.Pixels[px, py] = color; + result.Heights[px, py] = surfY; + if (result.BlockSummary is not null) + result.BlockSummary[px, py] = matSum; + } } } } @@ -416,6 +456,9 @@ namespace MinecraftClient.Tui } } + if (caveMask is not null) + ApplyCaveBorder(result, caveMask, mapW, mapH, entityPixels); + foreach (var (key, info) in entityPixels) { var (px, py) = key; @@ -640,6 +683,230 @@ namespace MinecraftClient.Tui return (best, avgY, summary); } + /// + /// Determine whether cave mode should be active for this frame. + /// Mirrors VoxelMap's detection: hasCeiling dimensions always use cave mode, + /// otherwise check whether the player's column has a solid block above. + /// + private static bool ResolveCaveMode(CaveModeOption opt, World world, Dimension dim, + int playerX, int playerY, int playerZ, int scanTop) + { + if (opt == CaveModeOption.off) return false; + if (opt == CaveModeOption.on) return true; + + if (dim.hasCeiling) return true; + + for (int y = playerY + 2; y <= scanTop; y++) + { + var mat = world.GetBlock(new Mapping.Location(playerX, y, playerZ)).Type; + if (MinimapColorMap.IsLightBlocking(mat)) + return true; + } + return false; + } + + /// + /// Cave-mode column sampler. Starting from playerY, scans down through air + /// to find the first light-blocking block (the cave floor), or scans up if + /// the player is embedded in solid. Returns the floor block color with cave + /// darkening applied, plus an inCave flag indicating the column has a reachable + /// air pocket at the player's Y level. + /// + private static (Color color, int surfaceY, Material surfaceMat, bool inCave) SampleColumnCave( + World world, int x, int z, int playerY, int minY, int maxY, + ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) + { + int chunkX = x >> 4; + int chunkZ = z >> 4; + if (chunkX != cachedChunkX || chunkZ != cachedChunkZ) + { + cachedColumn = world[chunkX, chunkZ]; + cachedChunkX = chunkX; + cachedChunkZ = chunkZ; + } + + if (cachedColumn is null) + return (MinimapColorMap.VoidColor, minY, Material.Air, false); + + int caveFloorY = FindCaveFloorY(cachedColumn, x, z, playerY, minY, maxY); + + if (caveFloorY == int.MinValue) + { + var fallback = SampleColumn(world, x, z, maxY, minY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + return (MinimapColorMap.CaveSolidColor, fallback.surfaceY, fallback.surfaceMat, false); + } + + var loc = new Mapping.Location(x, caveFloorY, z); + var chunk = cachedColumn.GetChunk(loc); + if (chunk is null) + return (MinimapColorMap.CaveSolidColor, caveFloorY, Material.Air, false); + + var block = chunk.GetBlock(loc); + var mat = block.Type; + var color = MinimapColorMap.GetBaseColor(mat); + color = MinimapColorMap.ApplyCaveDarkening(color); + + return (color, caveFloorY, mat, true); + } + + /// + /// Find the cave floor Y at (x, z) by scanning from playerY. + /// If the block at playerY is air-like, scan down for the first solid block. + /// If the block at playerY is solid, scan up (up to playerY + 10) for the + /// first air block, then return that Y (the cave ceiling opening). + /// Returns int.MinValue if no cave floor is found. + /// + private static int FindCaveFloorY(ChunkColumn column, int x, int z, int playerY, int minY, int maxY) + { + var startLoc = new Mapping.Location(x, playerY, z); + var startChunk = column.GetChunk(startLoc); + + bool startIsAir; + if (startChunk is null) + { + startIsAir = true; + } + else + { + var startMat = startChunk.GetBlock(startLoc).Type; + startIsAir = !MinimapColorMap.IsLightBlocking(startMat); + } + + if (startIsAir) + { + for (int y = playerY - 1; y >= minY; y--) + { + var loc = new Mapping.Location(x, y, z); + var chunk = column.GetChunk(loc); + if (chunk is null) continue; + + var mat = chunk.GetBlock(loc).Type; + if (MinimapColorMap.IsLightBlocking(mat)) + return y; + } + return minY; + } + else + { + int upLimit = Math.Min(playerY + 10, maxY); + for (int y = playerY + 1; y <= upLimit; y++) + { + var loc = new Mapping.Location(x, y, z); + var chunk = column.GetChunk(loc); + if (chunk is null) continue; + + var mat = chunk.GetBlock(loc).Type; + if (!MinimapColorMap.IsLightBlocking(mat)) + { + for (int y2 = y - 1; y2 >= minY; y2--) + { + var loc2 = new Mapping.Location(x, y2, z); + var chunk2 = column.GetChunk(loc2); + if (chunk2 is null) continue; + + var mat2 = chunk2.GetBlock(loc2).Type; + if (MinimapColorMap.IsLightBlocking(mat2)) + return y2; + } + return minY; + } + } + return int.MinValue; + } + } + + private static (Color color, int surfaceY, List<(Material Mat, int Count)>? matSummary, bool inCave) + SampleAreaDominantCave(World world, int baseX, int baseZ, + int size, int playerY, int minY, int maxY, bool collectMats, + ref ChunkColumn? cachedColumn, ref int cachedChunkX, ref int cachedChunkZ) + { + var colorCounts = new Dictionary(); + Dictionary? matCounts = collectMats ? [] : null; + int caveCount = 0; + + int step = Math.Max(1, size / 3); + for (int dx = 0; dx < size; dx += step) + { + for (int dz = 0; dz < size; dz += step) + { + var (c, surfY, surfMat, inCave) = SampleColumnCave( + world, baseX + dx, baseZ + dz, playerY, minY, maxY, + ref cachedColumn, ref cachedChunkX, ref cachedChunkZ); + + if (inCave) caveCount++; + + if (colorCounts.TryGetValue(c, out var existing)) + colorCounts[c] = (existing.Count + 1, existing.SumY + surfY); + else + colorCounts[c] = (1, surfY); + + if (matCounts is not null) + { + if (matCounts.TryGetValue(surfMat, out int mc)) + matCounts[surfMat] = mc + 1; + else + matCounts[surfMat] = 1; + } + } + } + + Color best = MinimapColorMap.VoidColor; + int bestCount = 0; + int avgY = minY; + foreach (var kvp in colorCounts) + { + if (kvp.Value.Count > bestCount) + { + bestCount = kvp.Value.Count; + best = kvp.Key; + avgY = kvp.Value.SumY / kvp.Value.Count; + } + } + + List<(Material, int)>? summary = null; + if (matCounts is not null && matCounts.Count > 0) + { + summary = matCounts + .OrderByDescending(kv => kv.Value) + .Select(kv => (kv.Key, kv.Value)) + .ToList(); + } + + int totalSamples = 0; + foreach (var kvp in colorCounts) + totalSamples += kvp.Value.Count; + + bool majorityInCave = caveCount * 2 >= totalSamples; + return (best, avgY, summary, majorityInCave); + } + + /// + /// Draw a 1-pixel dark border around the boundary between cave-reachable pixels + /// and non-cave (solid/surface) pixels, giving the cave region a visible edge. + /// + private static void ApplyCaveBorder(SampleResult result, bool[,] caveMask, + int mapW, int mapH, Dictionary<(int, int), (Color, int)> entityPixels) + { + for (int px = 0; px < mapW; px++) + { + for (int py = 0; py < mapH; py++) + { + if (entityPixels.ContainsKey((px, py))) continue; + if (caveMask[px, py]) continue; + + bool neighborInCave = false; + if (px > 0 && caveMask[px - 1, py]) neighborInCave = true; + if (!neighborInCave && px < mapW - 1 && caveMask[px + 1, py]) neighborInCave = true; + if (!neighborInCave && py > 0 && caveMask[px, py - 1]) neighborInCave = true; + if (!neighborInCave && py < mapH - 1 && caveMask[px, py + 1]) neighborInCave = true; + + if (neighborInCave) + result.Pixels[px, py] = MinimapColorMap.CaveBorderColor; + } + } + } + private void ApplyPixelBuffer(SampleResult result, int w, int h) { int rows = h / 2; @@ -898,7 +1165,7 @@ namespace MinecraftClient.Tui } private void UpdateInfoBarAndLegend(McClient client, int bpp, - HashSet categories, int mapW) + HashSet categories, int mapW, bool caveModeActive) { var loc = client.GetCurrentLocation(); float yaw = client.GetYaw(); @@ -908,7 +1175,8 @@ namespace MinecraftClient.Tui int y = (int)Math.Floor(loc.Y); int z = (int)Math.Floor(loc.Z); - string coordPart = $"{x}, {y}, {z} {arrow} {bpp}:1"; + string caveSuffix = caveModeActive ? " \u25bc" : ""; + string coordPart = $"{x}, {y}, {z} {arrow} {bpp}:1{caveSuffix}"; var legendParts = new List(); var legendColors = new List(); From 35dd3c4f069c64fb2583632c7c49b061f68d10e1 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 01:27:27 +0800 Subject: [PATCH 301/484] Add support for ItemStackTemplate in DataTypes and Protocol18 - Implemented ReadNextItemStackTemplate method to read ItemStackTemplate data with item-first encoding. - Updated Protocol18 to utilize ReadItemStackTemplateLabel for improved item display handling. - Enhanced item component parsing to accommodate new structured components. --- .../Protocol/Handlers/DataTypes.cs | 31 +++++++++++++++++++ .../Protocol/Handlers/Protocol18.cs | 11 ++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 669ba5b3..6a0d27aa 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -411,6 +411,37 @@ namespace MinecraftClient.Protocol.Handlers return ReadNextNbt(cache, true); } + /// + /// Read an ItemStackTemplate (26.1+) from a cache of bytes. + /// Unlike ItemStack, this uses item-first encoding: item_id, count, DataComponentPatch. + /// ItemStackTemplate is always non-empty (no count=0 sentinel). + /// + public Item ReadNextItemStackTemplate(Queue cache, ItemPalette itemPalette) + { + var itemId = ReadNextVarInt(cache); + var itemCount = ReadNextVarInt(cache); + var item = new Item(itemPalette.FromId(itemId), itemCount, null); + + var numberOfComponentsToAdd = ReadNextVarInt(cache); + var numberofComponentsToRemove = ReadNextVarInt(cache); + var structuredComponentHandler = new StructuredComponentsHandler(protocolversion, this, itemPalette); + var strcturedComponentsToAdd = new List(numberOfComponentsToAdd); + + for (var i = 0; i < numberOfComponentsToAdd; i++) + { + var componentTypeId = ReadNextVarInt(cache); + strcturedComponentsToAdd.Add(structuredComponentHandler.Parse(componentTypeId, cache)); + } + + for (var i = 0; i < numberofComponentsToRemove; i++) + ReadNextVarInt(cache); + + if (strcturedComponentsToAdd.Count > 0) + item.Components = strcturedComponentsToAdd; + + return item; + } + /// /// Read a single item slot from a cache of bytes and remove it from the cache /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index eeabc8e0..45bde28f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3530,7 +3530,7 @@ namespace MinecraftClient.Protocol.Handlers 2 => ReadWithAnyPotionSlotDisplayLabel(packetData), 3 => ReadOnlyWithComponentSlotDisplayLabel(packetData), 4 => Item.GetTypeString(itemPalette.FromId(dataTypes.ReadNextVarInt(packetData))), - 5 => dataTypes.ReadNextItemSlot(packetData, itemPalette)?.GetTypeString() ?? "Empty", + 5 => ReadItemStackTemplateLabel(packetData), 6 => "#" + dataTypes.ReadNextString(packetData), 7 => ReadDyedSlotDisplayLabel(packetData), 8 => ReadSmithingTrimSlotDisplayLabel(packetData), @@ -3612,6 +3612,15 @@ namespace MinecraftClient.Protocol.Handlers return label; } + /// + /// Read an ItemStackTemplate (26.1+) which encodes fields in a different order + /// than ItemStack: item_id (VarInt), count (VarInt), DataComponentPatch. + /// + private string ReadItemStackTemplateLabel(Queue packetData) + { + return dataTypes.ReadNextItemStackTemplate(packetData, itemPalette).GetTypeString(); + } + private void SkipOptionalCraftingRequirements(Queue packetData) { if (!dataTypes.ReadNextBool(packetData)) From b9b7160e19d1b985c6e682650b84652d1947d79d Mon Sep 17 00:00:00 2001 From: BruceChen Date: Tue, 31 Mar 2026 01:27:34 +0800 Subject: [PATCH 302/484] Enhance decompile.sh to support version metadata resolution and improved decompilation handling - Added functionality to fetch version metadata from Mojang's manifest. - Implemented checks for the presence of Proguard mappings to determine decompilation method. - Enhanced the script to handle unobfuscated versions by downloading and extracting inner jars when necessary. - Improved error handling for missing dependencies and added informative output messages during the decompilation process. --- tools/decompile.sh | 101 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 20 deletions(-) diff --git a/tools/decompile.sh b/tools/decompile.sh index cd17ab7a..791431ba 100644 --- a/tools/decompile.sh +++ b/tools/decompile.sh @@ -86,18 +86,90 @@ fi mkdir -p "$MC_OFFICIAL/remapped_jar" +# --- Resolve version metadata from Mojang manifest --- +MANIFEST_URL="https://launchermeta.mojang.com/mc/game/version_manifest_v2.json" +VERSION_URL=$(curl -sL "$MANIFEST_URL" | python3 -c " +import json, sys +data = json.load(sys.stdin) +for v in data['versions']: + if v['id'] == '$VERSION': + print(v['url']) + break +") +if [[ -z "$VERSION_URL" ]]; then + echo "Error: version $VERSION not found in Mojang launcher manifest." + exit 1 +fi + +VERSION_META=$(curl -sL "$VERSION_URL") +MAPPING_KEY="${SIDE_LOWER}_mappings" +HAS_MAPPINGS=$(echo "$VERSION_META" | python3 -c " +import json, sys +data = json.load(sys.stdin) +print('true' if '$MAPPING_KEY' in data.get('downloads', {}) else 'false') +") + echo "=== Decompiling Minecraft $VERSION ($SIDE) ===" echo " Remapped JAR: $REMAPPED_JAR" echo " Decompiled: $DECOMPILED_DIR" +echo " Obfuscated: $HAS_MAPPINGS" echo "" cd "$MC_OFFICIAL" -java -jar "$DECOMPILER_JAR" \ - --version "$VERSION" \ - --side "$SIDE" \ - --decompile \ - --output "$REMAPPED_JAR" \ - --decompiled-output "$DECOMPILED_DIR" + +if [[ "$HAS_MAPPINGS" == "true" ]]; then + # Obfuscated version: use --version/--side to auto-download jar + mappings + deobfuscate + java -jar "$DECOMPILER_JAR" \ + --version "$VERSION" \ + --side "$SIDE" \ + --decompile \ + --output "$REMAPPED_JAR" \ + --decompiled-output "$DECOMPILED_DIR" +else + # Unobfuscated version (26.1+): download jar, extract inner jar from bundle, decompile directly. + # MinecraftDecompiler requires --mapping-path with --input, but unobfuscated versions + # have no mappings. We use Vineflower directly instead. + echo "No Proguard mappings for $VERSION; decompiling without deobfuscation." + + JAR_URL=$(echo "$VERSION_META" | python3 -c " +import json, sys +data = json.load(sys.stdin) +print(data['downloads']['${SIDE_LOWER}']['url']) +") + ORIGINAL_JAR="$MC_OFFICIAL/remapped_jar/${VERSION}-${SIDE_LOWER}-original.jar" + if [[ ! -f "$ORIGINAL_JAR" ]]; then + echo "Downloading ${SIDE_LOWER}.jar ..." + curl -L -o "$ORIGINAL_JAR" "$JAR_URL" + fi + + # Since 1.18, server.jar is a bundled jar containing the actual game jar inside + # META-INF/versions//server-.jar. Extract it if present. + DECOMPILE_TARGET="$ORIGINAL_JAR" + EXTRACT_DIR=$(mktemp -d) + trap "rm -rf '$EXTRACT_DIR'" EXIT + if unzip -q -o "$ORIGINAL_JAR" "META-INF/versions.list" -d "$EXTRACT_DIR" 2>/dev/null; then + INNER_PATH=$(awk '{print $NF}' "$EXTRACT_DIR/META-INF/versions.list" | head -1) + if [[ -n "$INNER_PATH" ]]; then + unzip -q -o "$ORIGINAL_JAR" "META-INF/versions/$INNER_PATH" -d "$EXTRACT_DIR" + DECOMPILE_TARGET="$EXTRACT_DIR/META-INF/versions/$INNER_PATH" + echo "Extracted inner jar: $INNER_PATH" + fi + fi + + # Use Vineflower directly (bundled with MinecraftDecompiler, or standalone) + VINEFLOWER_JAR="$MC_OFFICIAL/downloads/decompiler/vineflower.jar" + if [[ ! -f "$VINEFLOWER_JAR" ]]; then + # Fall back to vineflower bundled inside MinecraftDecompiler's cache + VINEFLOWER_JAR=$(find "$MC_OFFICIAL" -name "vineflower*.jar" -not -name "MinecraftDecompiler.jar" 2>/dev/null | head -1) + fi + if [[ -z "$VINEFLOWER_JAR" || ! -f "$VINEFLOWER_JAR" ]]; then + echo "Error: vineflower.jar not found. Place it at $MC_OFFICIAL/downloads/decompiler/vineflower.jar" + exit 1 + fi + + echo "Decompiling with Vineflower: $VINEFLOWER_JAR" + java -jar "$VINEFLOWER_JAR" "$DECOMPILE_TARGET" "$DECOMPILED_DIR" +fi echo "" echo "=== Done ===" @@ -108,29 +180,18 @@ if [[ "$SIDE" == "SERVER" ]]; then DOWNLOADS_DIR="$MC_OFFICIAL/downloads/$VERSION" if [[ ! -f "$DOWNLOADS_DIR/server.jar" ]]; then mkdir -p "$DOWNLOADS_DIR" - # MinecraftDecompiler downloads the original jar into its cache; - # extract it from the bundled remapped jar or re-download via manifest. echo "" echo "Downloading server.jar for $VERSION into $DOWNLOADS_DIR ..." - MANIFEST_URL="https://launchermeta.mojang.com/mc/game/version_manifest_v2.json" - VERSION_URL=$(curl -sL "$MANIFEST_URL" | python3 -c " -import json, sys -data = json.load(sys.stdin) -for v in data['versions']: - if v['id'] == '$VERSION': - print(v['url']) - break -") - if [[ -n "$VERSION_URL" ]]; then - SERVER_JAR_URL=$(curl -sL "$VERSION_URL" | python3 -c " + SERVER_JAR_URL=$(echo "$VERSION_META" | python3 -c " import json, sys data = json.load(sys.stdin) print(data['downloads']['server']['url']) ") + if [[ -n "$SERVER_JAR_URL" ]]; then curl -L -o "$DOWNLOADS_DIR/server.jar" "$SERVER_JAR_URL" echo "Downloaded server.jar" else - echo "Warning: could not find version $VERSION in Mojang manifest; server.jar not downloaded." + echo "Warning: could not download server.jar for $VERSION." fi else echo "server.jar already exists: $DOWNLOADS_DIR/server.jar" From d158bfdf21a7b8b9c6df90e159c09db0c3166395 Mon Sep 17 00:00:00 2001 From: Anon Date: Mon, 30 Mar 2026 20:20:58 +0200 Subject: [PATCH 303/484] Fixed bugs --- MinecraftClient/Mapping/BlockHardness.cs | 4 +- MinecraftClient/Mapping/MiningCalculator.cs | 199 ++++++++++++++------ 2 files changed, 141 insertions(+), 62 deletions(-) diff --git a/MinecraftClient/Mapping/BlockHardness.cs b/MinecraftClient/Mapping/BlockHardness.cs index 311507b0..84cd8f92 100644 --- a/MinecraftClient/Mapping/BlockHardness.cs +++ b/MinecraftClient/Mapping/BlockHardness.cs @@ -249,8 +249,8 @@ namespace MinecraftClient.Mapping { Material.NetherSprouts, 0.0f }, { Material.NetherWart, 0.0f }, { Material.OakButton, 0.0f }, - { Material.OakLeaves, 0.0f }, - { Material.OakLog, 0.0f }, + { Material.OakLeaves, 0.2f }, + { Material.OakLog, 2.0f }, { Material.OakSapling, 0.0f }, { Material.OpenEyeblossom, 0.0f }, { Material.OrangeCandle, 0.0f }, diff --git a/MinecraftClient/Mapping/MiningCalculator.cs b/MinecraftClient/Mapping/MiningCalculator.cs index 38cf6d18..6f49fd4a 100644 --- a/MinecraftClient/Mapping/MiningCalculator.cs +++ b/MinecraftClient/Mapping/MiningCalculator.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using MinecraftClient.Inventory; using MinecraftClient.Protocol.Handlers; using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_21_5; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents._1_20_6; namespace MinecraftClient.Mapping { @@ -74,27 +77,14 @@ namespace MinecraftClient.Mapping { float speed = GetToolSpeed(blockMaterial, heldItem, protocolVersion); - if (protocolVersion >= Protocol18Handler.MC_1_21_11_Version) + if (speed > 1.0f) { - // 1.21.11+: Efficiency is delivered via the MINING_EFFICIENCY attribute - if (speed > 1.0f && playerAttributes.TryGetValue("player.mining_efficiency", out double miningEff)) - speed += (float)miningEff; - } - else - { - // Pre-1.21.11: Efficiency enchantment adds level^2 + 1 - int effLevel = GetEnchantmentLevel(heldItem, Enchantments.Efficiency, protocolVersion); - if (speed > 1.0f && effLevel > 0) - speed += effLevel * effLevel + 1; + speed += GetEfficiencyBonus(heldItem, playerAttributes, protocolVersion); } - // Haste effect: multiply by 1 + 0.2 * (amplifier + 1) - if (effects.TryGetValue(Effects.Haste, out var hasteData)) - speed *= 1.0f + (hasteData.Amplifier + 1) * 0.2f; - - // Conduit Power also grants dig speed equivalent when in water - if (effects.TryGetValue(Effects.ConduitPower, out var conduitData)) - speed *= 1.0f + (conduitData.Amplifier + 1) * 0.2f; + int digSpeedAmplifier = GetDigSpeedAmplifier(effects); + if (digSpeedAmplifier >= 0) + speed *= 1.0f + (digSpeedAmplifier + 1) * 0.2f; // Mining Fatigue if (effects.TryGetValue(Effects.MiningFatigue, out var fatigueData)) @@ -155,19 +145,19 @@ namespace MinecraftClient.Mapping return 1.0f; // Modern path: use ToolComponent from structured components - if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version) + if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version + && TryGetToolRules(heldItem, out List? rules, out float defaultMiningSpeed)) { - var toolComp = heldItem.Components?.OfType().FirstOrDefault(); - if (toolComp is not null) + foreach (var rule in rules) { - // Check rules for matching blocks - foreach (var rule in toolComp.Rules) - { - if (rule.HasSpeed && MatchesBlockSet(rule.Blocks, blockMaterial)) - return rule.Speed; - } - return toolComp.DefaultMiningSpeed; + if (rule.HasSpeed && MatchesBlockSet(rule.Blocks, blockMaterial)) + return rule.Speed; } + + // Structured tool data covers modern mining rules, but keep the legacy fallback for + // explicit block holder-sets that MCC cannot resolve yet (for example cobweb). + if (defaultMiningSpeed > 1.0f) + return defaultMiningSpeed; } // Legacy path: hardcoded tool speed tables @@ -186,25 +176,48 @@ namespace MinecraftClient.Mapping return false; // Modern path: check ToolComponent rules - if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version) + if (protocolVersion >= Protocol18Handler.MC_1_20_6_Version + && TryGetToolRules(heldItem, out List? rules, out _)) { - var toolComp = heldItem.Components?.OfType().FirstOrDefault(); - if (toolComp is not null) + foreach (var rule in rules) { - foreach (var rule in toolComp.Rules) - { - if (rule.HasCorrectDropForBlocks && rule.CorrectDropForBlocks - && MatchesBlockSet(rule.Blocks, blockMaterial)) - return true; - } + if (rule.HasCorrectDropForBlocks && MatchesBlockSet(rule.Blocks, blockMaterial)) + return rule.CorrectDropForBlocks; } - return false; } - // Legacy path: check if Material2Tool recommends this tool type + // Legacy path, plus a modern fallback for direct block holder-sets MCC cannot resolve yet. return IsCorrectToolLegacy(heldItem.Type, blockMaterial); } + private static bool TryGetToolRules( + Item heldItem, + [NotNullWhen(true)] out List? rules, + out float defaultMiningSpeed) + { + rules = null; + defaultMiningSpeed = 1.0f; + + if (heldItem.Components is null) + return false; + + if (heldItem.Components.OfType().FirstOrDefault() is ToolComponent toolComponent) + { + rules = toolComponent.Rules; + defaultMiningSpeed = toolComponent.DefaultMiningSpeed; + return true; + } + + if (heldItem.Components.OfType().FirstOrDefault() is ToolComponent1215 toolComponent1215) + { + rules = toolComponent1215.Rules; + defaultMiningSpeed = toolComponent1215.DefaultMiningSpeed; + return true; + } + + return false; + } + /// /// Match a block material against a ToolComponent BlockSetSubcomponent. /// @@ -241,20 +254,34 @@ namespace MinecraftClient.Mapping string tag = tagName.Replace("minecraft:", ""); ItemType[] tools = Material2Tool.GetCorrectToolForBlock(blockMaterial); - if (tools.Length == 0) - return false; - - ItemType firstTool = tools[0]; return tag switch { - "mineable/pickaxe" => IsPickaxe(firstTool), - "mineable/axe" => IsAxe(firstTool), - "mineable/shovel" => IsShovel(firstTool), - "mineable/hoe" => IsHoe(firstTool), + "mineable/pickaxe" => tools.Length > 0 && IsPickaxe(tools[0]), + "mineable/axe" => tools.Length > 0 && IsAxe(tools[0]), + "mineable/shovel" => tools.Length > 0 && IsShovel(tools[0]), + "mineable/hoe" => tools.Length > 0 && IsHoe(tools[0]), + "leaves" => IsLeaf(blockMaterial), + "wool" => IsWool(blockMaterial), + "incorrect_for_wooden_tool" => RequiresHigherTier(blockMaterial, 0), + "incorrect_for_gold_tool" => RequiresHigherTier(blockMaterial, 0), + "incorrect_for_stone_tool" => RequiresHigherTier(blockMaterial, 1), + "incorrect_for_copper_tool" => RequiresHigherTier(blockMaterial, 1), + "incorrect_for_iron_tool" => RequiresHigherTier(blockMaterial, 2), + "incorrect_for_diamond_tool" => RequiresHigherTier(blockMaterial, 3), + "incorrect_for_netherite_tool" => RequiresHigherTier(blockMaterial, 4), _ => false }; } + private static bool RequiresHigherTier(Material blockMaterial, int tier) + { + ItemType[] recommended = Material2Tool.GetCorrectToolForBlock(blockMaterial); + if (recommended.Length == 0) + return false; + + return GetRequiredTier(blockMaterial, recommended) > tier; + } + /// /// Get the enchantment level from an item, supporting both legacy NBT and modern structured components. /// @@ -330,6 +357,16 @@ namespace MinecraftClient.Mapping /// private static float GetLegacyToolSpeed(ItemType toolType, Material blockMaterial) { + float specialToolSpeed = toolType switch + { + ItemType.Shears => GetShearsSpeed(blockMaterial), + _ when IsSword(toolType) && blockMaterial == Material.Cobweb => 15.0f, + _ => 1.0f + }; + + if (specialToolSpeed > 1.0f) + return specialToolSpeed; + ItemType[] recommended = Material2Tool.GetCorrectToolForBlock(blockMaterial); if (recommended.Length == 0) return 1.0f; @@ -339,14 +376,7 @@ namespace MinecraftClient.Mapping ToolCategory neededCategory = GetToolCategory(recommended[0]); if (heldCategory == ToolCategory.None || heldCategory != neededCategory) - { - // Special cases: sword on cobweb, shears on specific blocks - if (toolType is ItemType.Shears && IsShearable(blockMaterial)) - return 1.5f; - if (IsSword(toolType) && blockMaterial == Material.Cobweb) - return 15.0f; return 1.0f; - } return GetBaseToolSpeed(toolType); } @@ -400,7 +430,13 @@ namespace MinecraftClient.Mapping ToolCategory neededCategory = GetToolCategory(recommended[0]); if (heldCategory == ToolCategory.None || heldCategory != neededCategory) + { + if (toolType == ItemType.Shears && blockMaterial == Material.Cobweb) + return true; + if (IsSword(toolType) && blockMaterial == Material.Cobweb) + return true; return false; + } // Check tool tier requirement int heldTier = GetToolTier(toolType); @@ -476,17 +512,60 @@ namespace MinecraftClient.Mapping item is ItemType.WoodenSword or ItemType.StoneSword or ItemType.IronSword or ItemType.GoldenSword or ItemType.DiamondSword or ItemType.NetheriteSword; + private static float GetShearsSpeed(Material block) + { + return block switch + { + Material.Cobweb => 15.0f, + Material.Vine or Material.GlowLichen => 2.0f, + _ when IsLeaf(block) => 15.0f, + _ when IsWool(block) => 5.0f, + _ => 1.0f + }; + } + private static bool IsShearable(Material block) => - block is Material.Cobweb or Material.OakLeaves or Material.SpruceLeaves - or Material.BirchLeaves or Material.JungleLeaves or Material.AcaciaLeaves - or Material.DarkOakLeaves or Material.CherryLeaves or Material.MangroveLeaves - or Material.AzaleaLeaves or Material.FloweringAzaleaLeaves - or Material.WhiteWool or Material.OrangeWool or Material.MagentaWool + block == Material.Cobweb || IsLeaf(block) || IsWool(block) || block is Material.Vine or Material.GlowLichen; + + private static bool IsLeaf(Material block) => + block is Material.OakLeaves or Material.SpruceLeaves or Material.BirchLeaves + or Material.JungleLeaves or Material.AcaciaLeaves or Material.DarkOakLeaves + or Material.CherryLeaves or Material.MangroveLeaves or Material.AzaleaLeaves + or Material.FloweringAzaleaLeaves or Material.PaleOakLeaves; + + private static bool IsWool(Material block) => + block is Material.WhiteWool or Material.OrangeWool or Material.MagentaWool or Material.LightBlueWool or Material.YellowWool or Material.LimeWool or Material.PinkWool or Material.GrayWool or Material.LightGrayWool or Material.CyanWool or Material.PurpleWool or Material.BlueWool or Material.BrownWool or Material.GreenWool or Material.RedWool - or Material.BlackWool or Material.Vine; + or Material.BlackWool; + + private static float GetEfficiencyBonus(Item? heldItem, Dictionary playerAttributes, int protocolVersion) + { + if (protocolVersion >= Protocol18Handler.MC_1_21_11_Version + && playerAttributes.TryGetValue("player.mining_efficiency", out double miningEfficiency) + && miningEfficiency > 0.0) + { + return (float)miningEfficiency; + } + + int efficiencyLevel = GetEnchantmentLevel(heldItem, Enchantments.Efficiency, protocolVersion); + return efficiencyLevel > 0 ? efficiencyLevel * efficiencyLevel + 1 : 0.0f; + } + + private static int GetDigSpeedAmplifier(Dictionary effects) + { + int amplifier = -1; + + if (effects.TryGetValue(Effects.Haste, out var hasteData)) + amplifier = Math.Max(amplifier, hasteData.Amplifier); + + if (effects.TryGetValue(Effects.ConduitPower, out var conduitData)) + amplifier = Math.Max(amplifier, conduitData.Amplifier); + + return amplifier; + } #endregion } From 5de72de234a32262398e75c19e4e4c7b3888b0c9 Mon Sep 17 00:00:00 2001 From: Anon Date: Mon, 30 Mar 2026 21:37:53 +0200 Subject: [PATCH 304/484] Fixed a wrong effect decoding on 1.20.4 --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index eeabc8e0..8fd192a7 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2514,7 +2514,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { var entityId = dataTypes.ReadNextVarInt(packetData); - var effectId = protocolVersion >= MC_1_18_2_Version + var effectId = protocolVersion >= MC_1_20_4_Version ? dataTypes.ReadNextVarInt(packetData) + 1 : dataTypes.ReadNextByte(packetData); @@ -2544,7 +2544,7 @@ namespace MinecraftClient.Protocol.Handlers if (handler.GetEntityHandlingEnabled()) { var entityId = dataTypes.ReadNextVarInt(packetData); - var effectId = protocolVersion >= MC_1_18_2_Version + var effectId = protocolVersion >= MC_1_20_4_Version ? dataTypes.ReadNextVarInt(packetData) + 1 : dataTypes.ReadNextByte(packetData); From 968800b95a5dedbff31168da8c049931bf3510ef Mon Sep 17 00:00:00 2001 From: Anon Date: Mon, 30 Mar 2026 23:14:28 +0200 Subject: [PATCH 305/484] Added a bunch of new useful MCP Tools --- DebugTools/MccMcpSampleClient/Program.cs | 828 +++++++++++++--- DebugTools/MccMcpStdioHarness/Program.cs | 467 +++++++++- MinecraftClient/ChatBots/McpServer.cs | 133 ++- MinecraftClient/Mcp/IMccMcpCapabilities.cs | 20 + MinecraftClient/Mcp/MccMcpCapabilities.cs | 882 ++++++++++++++++++ MinecraftClient/Mcp/MccMcpRecentEventStore.cs | 75 ++ .../Mcp/MccMcpRuntimeStateStore.cs | 70 ++ MinecraftClient/Mcp/MccMcpToolSet.cs | 120 +++ MinecraftClient/Program.cs | 13 +- 9 files changed, 2453 insertions(+), 155 deletions(-) create mode 100644 MinecraftClient/Mcp/MccMcpRecentEventStore.cs create mode 100644 MinecraftClient/Mcp/MccMcpRuntimeStateStore.cs diff --git a/DebugTools/MccMcpSampleClient/Program.cs b/DebugTools/MccMcpSampleClient/Program.cs index 591cc52c..0bd91fdb 100644 --- a/DebugTools/MccMcpSampleClient/Program.cs +++ b/DebugTools/MccMcpSampleClient/Program.cs @@ -1,182 +1,733 @@ -using System.Net.Http.Headers; -using System.Text; +using System.Diagnostics; using System.Text.Json; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol; string endpoint = Environment.GetEnvironmentVariable("MCC_MCP_ENDPOINT") ?? "http://127.0.0.1:33333/mcp"; -string model = "minimax/minimax-m2.7"; bool useStdio = string.Equals(Environment.GetEnvironmentVariable("MCC_MCP_USE_STDIO"), "1", StringComparison.Ordinal); -string? openRouterApiKey = Environment.GetEnvironmentVariable("OPENROUTER_API_KEY"); -string openRouterBaseUrl = Environment.GetEnvironmentVariable("OPENROUTER_BASE_URL") ?? "https://openrouter.ai/api/v1"; string? mcpAuthToken = Environment.GetEnvironmentVariable("MCC_MCP_AUTH_TOKEN"); - -await using McpClient client = useStdio - ? await McpClient.CreateAsync(new StdioClientTransport(CreateStdioOptions())) - : await McpClient.CreateAsync(new HttpClientTransport(new HttpClientTransportOptions - { - Endpoint = new Uri(endpoint), - TransportMode = HttpTransportMode.AutoDetect, - AdditionalHeaders = string.IsNullOrWhiteSpace(mcpAuthToken) - ? null - : new Dictionary { ["Authorization"] = $"Bearer {mcpAuthToken}" } - })); - +string repoRoot = FindRepoRoot(); +string rconScript = Path.Combine(repoRoot, "tools", "mc-rcon.sh"); +string rconPort = Environment.GetEnvironmentVariable("MCC_RCON_PORT") ?? "25575"; +string rconPassword = Environment.GetEnvironmentVariable("MCC_RCON_PASSWORD") ?? "test123"; +bool skipSetup = string.Equals(Environment.GetEnvironmentVariable("MCC_MCP_SKIP_SETUP"), "1", StringComparison.Ordinal); +bool runLocalSetup = !useStdio && !skipSetup && IsLocalEndpoint(endpoint) && File.Exists(rconScript); var executed = new List(); +var checks = new List(); -CallToolResult sessionStatus = await CallAndStore("mcc_session_status"); -await CallAndStore("mcc_players_list"); -await CallAndStore("mcc_send_chat", new Dictionary { ["text"] = "/say mcp_full_sweep" }); -await CallAndStore("mcc_run_internal_command", new Dictionary { ["command"] = "debug state" }); - -(double lookX, double lookY, double lookZ) = GetLookTarget(sessionStatus); -await CallAndStore("mcc_look_at", new Dictionary { ["x"] = lookX, ["y"] = lookY, ["z"] = lookZ }); -await CallAndStore("mcc_move_to", new Dictionary { ["x"] = lookX, ["y"] = lookY, ["z"] = lookZ, ["timeoutMs"] = 2000 }); - -CallToolResult inventorySnapshot = await CallAndStore("mcc_inventory_snapshot", new Dictionary { ["inventoryId"] = 0 }); -int actionSlot = GetInventoryActionSlot(inventorySnapshot); -await CallAndStore("mcc_inventory_window_action", new Dictionary { ["inventoryId"] = 0, ["slotId"] = actionSlot, ["actionType"] = "LeftClick" }); - -await CallAndStore("mcc_entities_query", new Dictionary { ["maxCount"] = 20 }); -CallToolResult entitiesList = await CallAndStore("mcc_entities_list", new Dictionary { ["maxCount"] = 20 }); -int? firstEntityId = GetFirstEntityId(entitiesList); -if (firstEntityId.HasValue) +try { - await CallAndStore("mcc_entity_info", new Dictionary - { - ["entityId"] = firstEntityId.Value, - ["includeMetadata"] = false, - ["includeEquipment"] = true, - ["includeEffects"] = true - }); -} -await CallAndStore("mcc_blocks_find", new Dictionary { ["query"] = "Grass", ["radius"] = 6, ["maxCount"] = 50 }); -await CallAndStore("mcc_player_nearby", new Dictionary { ["radius"] = 48.0, ["includeSelf"] = false }); -await CallAndStore("mcc_world_block_at", new Dictionary { ["x"] = 0, ["y"] = 80, ["z"] = 0 }); - -string evidenceJson = JsonSerializer.Serialize(executed, new JsonSerializerOptions { WriteIndented = true }); -Console.WriteLine(evidenceJson); - -if (!useStdio && !string.IsNullOrWhiteSpace(openRouterApiKey)) -{ - using HttpClient http = new(); - http.BaseAddress = new Uri(openRouterBaseUrl.TrimEnd('/') + "/"); - http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", openRouterApiKey); - http.DefaultRequestHeaders.Add("HTTP-Referer", "https://localhost/mcc-mcp-sample"); - http.DefaultRequestHeaders.Add("X-Title", "MCC MCP Sample Client"); - - var payload = new - { - model, - messages = new object[] + await using McpClient client = useStdio + ? await McpClient.CreateAsync(new StdioClientTransport(CreateStdioOptions())) + : await McpClient.CreateAsync(new HttpClientTransport(new HttpClientTransportOptions { - new { role = "system", content = "Summarize the MCP tool execution output briefly." }, - new { role = "user", content = evidenceJson } - } - }; + Endpoint = new Uri(endpoint), + TransportMode = HttpTransportMode.AutoDetect, + AdditionalHeaders = string.IsNullOrWhiteSpace(mcpAuthToken) + ? null + : new Dictionary { ["Authorization"] = $"Bearer {mcpAuthToken}" } + })); - HttpResponseMessage response = await http.PostAsync( - "chat/completions", - new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json")); + ToolEnvelope initialWorldState = await CallSuccessAsync(client, executed, "mcc_world_state"); + JsonElement initialWorldData = RequireData(initialWorldState); + string botName = ReadString(initialWorldData, "username") ?? "CursorBot"; + Coordinate initialLocation = ReadCoordinate(initialWorldData, "location"); - string body = await response.Content.ReadAsStringAsync(); - Console.WriteLine(body); + long setupBaseline = 0; + if (runLocalSetup) + { + ToolEnvelope baselineEvents = await CallSuccessAsync(client, executed, "mcc_recent_events", new Dictionary + { + ["afterId"] = 0L, + ["maxCount"] = 1 + }); + setupBaseline = ReadInt64(RequireData(baselineEvents), "latestId"); + + await PrepareWorldAsync(rconScript, rconPort, rconPassword, botName, initialLocation); + await Task.Delay(1500); + } + + ToolEnvelope worldState = await WaitForPredicateAsync( + client, + executed, + "mcc_world_state", + null, + envelope => + { + if (!envelope.Success || envelope.Data is not JsonElement data) + return false; + + return data.TryGetProperty("loadedChunkCount", out JsonElement loaded) + && loaded.TryGetInt32(out int loadedChunkCount) + && loadedChunkCount >= 0 + && HasNonNullProperty(data, "worldAge") + && HasNonNullProperty(data, "timeOfDay"); + }, + "mcc_world_state never reported chunk/time state."); + + JsonElement worldData = RequireData(worldState); + Coordinate worldLocation = ReadCoordinate(worldData, "location"); + string dimension = RequireString(worldData, "dimension"); + int loadedChunkCount = ReadInt32(worldData, "loadedChunkCount"); + int pendingChunkCount = ReadInt32(worldData, "pendingChunkCount"); + int totalChunkCount = ReadInt32(worldData, "totalChunkCount"); + double loadRatio = ReadDouble(worldData, "loadRatio"); + _ = RequireString(worldData, "host"); + _ = ReadInt32(worldData, "port"); + _ = RequireString(worldData, "username"); + _ = ReadInt32(worldData, "protocol"); + _ = ReadDouble(worldData, "tps"); + Ensure(!string.IsNullOrWhiteSpace(dimension), "mcc_world_state returned an empty dimension."); + Ensure(loadedChunkCount + pendingChunkCount == totalChunkCount, "mcc_world_state chunk counters are inconsistent."); + Ensure(loadRatio is >= 0 and <= 1, "mcc_world_state loadRatio is out of range."); + Ensure(HasNonNullProperty(worldData, "worldAge"), "mcc_world_state.worldAge is null."); + Ensure(HasNonNullProperty(worldData, "timeOfDay"), "mcc_world_state.timeOfDay is null."); + if (runLocalSetup || useStdio) + { + Ensure(HasNonNullProperty(worldData, "rainLevel"), "mcc_world_state.rainLevel is null after setup."); + Ensure(HasNonNullProperty(worldData, "thunderLevel"), "mcc_world_state.thunderLevel is null after setup."); + } + checks.Add("mcc_world_state"); + + ToolEnvelope chunkStatus = await CallSuccessAsync(client, executed, "mcc_chunk_status"); + JsonElement chunkData = RequireData(chunkStatus); + JsonElement chunk = RequireProperty(chunkData, "chunk"); + _ = ReadInt32(chunk, "x"); + _ = ReadInt32(chunk, "z"); + Ensure(ReadBoolean(chunkData, "loaded"), "mcc_chunk_status reported the current chunk as unloaded."); + Ensure(ReadInt32(chunkData, "loadedChunkCount") + ReadInt32(chunkData, "pendingChunkCount") == ReadInt32(chunkData, "totalChunkCount"), + "mcc_chunk_status chunk counters are inconsistent."); + checks.Add("mcc_chunk_status"); + + await CallSuccessAsync(client, executed, "mcc_look_direction", new Dictionary { ["direction"] = "Down" }); + ToolEnvelope raycast = await CallSuccessAsync(client, executed, "mcc_raycast_block", new Dictionary + { + ["maxDistance"] = 8.0, + ["includeNeighbors"] = true + }); + JsonElement raycastData = RequireData(raycast); + Ensure(ReadBoolean(raycastData, "hit"), "mcc_raycast_block did not report a hit after looking down."); + JsonElement raycastBlock = RequireProperty(raycastData, "block"); + Ensure(!string.Equals(RequireString(raycastBlock, "material"), "Air", StringComparison.OrdinalIgnoreCase), + "mcc_raycast_block hit Air instead of a solid block."); + Ensure(RequireProperty(raycastData, "neighbors").ValueKind == JsonValueKind.Object, + "mcc_raycast_block did not include neighbors when requested."); + checks.Add("mcc_raycast_block"); + + ToolEnvelope pathPreview = await CallSuccessAsync(client, executed, "mcc_path_preview", new Dictionary + { + ["x"] = Math.Floor(worldLocation.X) + 2, + ["y"] = worldLocation.Y, + ["z"] = Math.Floor(worldLocation.Z), + ["allowUnsafe"] = false, + ["timeoutMs"] = 2000, + ["maxWaypoints"] = 32 + }); + JsonElement pathData = RequireData(pathPreview); + Ensure(ReadBoolean(pathData, "pathFound"), "mcc_path_preview did not find a path to a nearby target."); + Ensure(RequireProperty(pathData, "waypoints").GetArrayLength() > 0, "mcc_path_preview returned no waypoints."); + checks.Add("mcc_path_preview"); + + ToolEnvelope stoneSearch = await WaitForPredicateAsync( + client, + executed, + "mcc_inventory_search", + new Dictionary + { + ["query"] = "Stone", + ["maxCount"] = 20, + ["exactMatch"] = true, + ["includeContainers"] = false + }, + envelope => envelope.Success && envelope.Data is JsonElement data && ReadInt32(data, "count") > 0, + "mcc_inventory_search never found Stone in the player inventory."); + Ensure(ContainsItemType(RequireData(stoneSearch), "Stone"), "mcc_inventory_search results did not include Stone."); + + ToolEnvelope swordSearch = await WaitForPredicateAsync( + client, + executed, + "mcc_inventory_search", + new Dictionary + { + ["query"] = "DiamondSword", + ["maxCount"] = 20, + ["exactMatch"] = true, + ["includeContainers"] = false + }, + envelope => envelope.Success && envelope.Data is JsonElement data && ReadInt32(data, "count") > 0, + "mcc_inventory_search never found DiamondSword in the player inventory."); + Ensure(ContainsItemType(RequireData(swordSearch), "DiamondSword"), "mcc_inventory_search results did not include DiamondSword."); + checks.Add("mcc_inventory_search"); + + ToolEnvelope selectItem = await CallSuccessAsync(client, executed, "mcc_select_item", new Dictionary + { + ["itemType"] = "DiamondSword", + ["preferLowestSlot"] = true + }); + JsonElement selectData = RequireData(selectItem); + int selectedSlot = ReadInt32(selectData, "selectedSlot"); + + ToolEnvelope playerStats = await CallSuccessAsync(client, executed, "mcc_player_stats"); + JsonElement playerStatsData = RequireData(playerStats); + Ensure(ReadInt32(playerStatsData, "currentSlot") == selectedSlot, "mcc_select_item did not update mcc_player_stats.currentSlot."); + _ = ReadInt32(playerStatsData, "playerEntityId"); + _ = ReadInt32(playerStatsData, "level"); + _ = ReadInt32(playerStatsData, "totalExperience"); + _ = ReadCoordinate(playerStatsData, "location"); + checks.Add("mcc_select_item"); + checks.Add("mcc_player_stats"); + + ToolEnvelope playersDetailed = await CallSuccessAsync(client, executed, "mcc_players_detailed", new Dictionary + { + ["includeSelf"] = true, + ["includeCoordinates"] = true + }); + JsonElement playersData = RequireData(playersDetailed); + JsonElement selfPlayer = FindPlayer(RequireProperty(playersData, "players"), botName); + _ = RequireString(selfPlayer, "uuid"); + _ = ReadInt32(selfPlayer, "ping"); + _ = ReadInt32(selfPlayer, "entityId"); + _ = ReadDouble(selfPlayer, "x"); + _ = ReadDouble(selfPlayer, "y"); + _ = ReadDouble(selfPlayer, "z"); + checks.Add("mcc_players_detailed"); + + ToolEnvelope statusEffects = await CallSuccessAsync(client, executed, "mcc_status_effects"); + Ensure(RequireProperty(RequireData(statusEffects), "effects").ValueKind == JsonValueKind.Array, + "mcc_status_effects.effects is not an array."); + checks.Add("mcc_status_effects"); + + ToolEnvelope animation = await CallSuccessAsync(client, executed, "mcc_animation", new Dictionary + { + ["hand"] = "MainHand" + }); + Ensure(ReadBoolean(RequireData(animation), "success"), "mcc_animation did not report success."); + + ToolEnvelope sneakOn = await CallSuccessAsync(client, executed, "mcc_toggle_sneak", new Dictionary { ["enabled"] = true }); + Ensure(ReadBoolean(RequireData(sneakOn), "enabled"), "mcc_toggle_sneak(true) did not report enabled=true."); + + ToolEnvelope sprintOn = await CallSuccessAsync(client, executed, "mcc_toggle_sprint", new Dictionary { ["enabled"] = true }); + Ensure(ReadBoolean(RequireData(sprintOn), "enabled"), "mcc_toggle_sprint(true) did not report enabled=true."); + + await CallSuccessAsync(client, executed, "mcc_look_angles", new Dictionary + { + ["yaw"] = 45.0f, + ["pitch"] = -15.0f + }); + ToolEnvelope updatedStats = await CallSuccessAsync(client, executed, "mcc_player_stats"); + JsonElement updatedStatsData = RequireData(updatedStats); + Ensure(Math.Abs(ReadDouble(updatedStatsData, "yaw") - 45.0) < 0.01, "mcc_look_angles did not update yaw."); + Ensure(Math.Abs(ReadDouble(updatedStatsData, "pitch") - (-15.0)) < 0.01, "mcc_look_angles did not update pitch."); + checks.Add("mcc_animation"); + checks.Add("mcc_toggle_sneak"); + checks.Add("mcc_toggle_sprint"); + checks.Add("mcc_look_direction"); + checks.Add("mcc_look_angles"); + + ToolEnvelope nearestEntity = await WaitForPredicateAsync( + client, + executed, + "mcc_entity_nearest", + new Dictionary + { + ["typeFilter"] = "ArmorStand", + ["radius"] = 16.0, + ["includePlayers"] = false + }, + envelope => envelope.Success, + "mcc_entity_nearest never found a nearby ArmorStand."); + JsonElement nearestData = RequireData(nearestEntity); + int entityId = ReadInt32(nearestData, "id"); + Ensure(string.Equals(RequireString(nearestData, "type"), "ArmorStand", StringComparison.OrdinalIgnoreCase), + "mcc_entity_nearest did not return an ArmorStand."); + + ToolEnvelope attackEntity = await CallSuccessAsync(client, executed, "mcc_entity_attack", new Dictionary + { + ["entityId"] = entityId + }); + Ensure(ReadBoolean(RequireData(attackEntity), "success"), "mcc_entity_attack did not report success."); + checks.Add("mcc_entity_nearest"); + checks.Add("mcc_entity_attack"); + + long recentSetupAfterId = runLocalSetup ? setupBaseline : 0; + if (runLocalSetup || useStdio) + { + ToolEnvelope setupEvents = await WaitForRecentEventTypesAsync( + client, + executed, + recentSetupAfterId, + "weather_rain", + "title", + "actionbar"); + JsonElement setupEventsData = RequireData(setupEvents); + Ensure(GetEventTypes(setupEventsData).Contains("weather_rain", StringComparer.OrdinalIgnoreCase), "mcc_recent_events did not include weather_rain."); + Ensure(GetEventTypes(setupEventsData).Contains("title", StringComparer.OrdinalIgnoreCase), "mcc_recent_events did not include title."); + Ensure(GetEventTypes(setupEventsData).Contains("actionbar", StringComparer.OrdinalIgnoreCase), "mcc_recent_events did not include actionbar."); + } + + ToolEnvelope actionbarEvents = await CallSuccessAsync(client, executed, "mcc_recent_events", new Dictionary + { + ["afterId"] = 0L, + ["maxCount"] = 20, + ["typeFilter"] = "actionbar" + }); + JsonElement actionbarData = RequireData(actionbarEvents); + Ensure(ReadInt32(actionbarData, "count") > 0, "mcc_recent_events typeFilter=actionbar returned no events."); + Ensure(AllEventsMatchType(actionbarData, "actionbar"), "mcc_recent_events typeFilter returned mixed event types."); + + long inventoryBaseline = ReadInt64(actionbarData, "latestId"); + int chestX = (int)Math.Floor(worldLocation.X) + 2; + int chestY = (int)Math.Floor(worldLocation.Y); + int chestZ = (int)Math.Floor(worldLocation.Z); + ToolEnvelope openContainer = await WaitForPredicateAsync( + client, + executed, + "mcc_container_open_at", + new Dictionary + { + ["x"] = chestX, + ["y"] = chestY, + ["z"] = chestZ, + ["timeoutMs"] = 3000, + ["closeCurrent"] = true + }, + envelope => envelope.Success, + "mcc_open_container_at never opened the nearby chest."); + JsonElement inventoryInfo = RequireProperty(RequireData(openContainer), "inventory"); + int openedInventoryId = ReadInt32(inventoryInfo, "id"); + ToolEnvelope closeContainer = await CallSuccessAsync(client, executed, "mcc_container_close", new Dictionary + { + ["inventoryId"] = openedInventoryId, + ["timeoutMs"] = 3000 + }); + Ensure(ReadBoolean(RequireData(closeContainer), "closed"), "mcc_close_container did not close the chest."); + + ToolEnvelope inventoryEvents = await WaitForRecentEventTypesAsync( + client, + executed, + inventoryBaseline, + "inventory_open", + "inventory_close"); + JsonElement inventoryEventsData = RequireData(inventoryEvents); + Ensure(GetEventTypes(inventoryEventsData).Contains("inventory_open", StringComparer.OrdinalIgnoreCase), "mcc_recent_events did not include inventory_open."); + Ensure(GetEventTypes(inventoryEventsData).Contains("inventory_close", StringComparer.OrdinalIgnoreCase), "mcc_recent_events did not include inventory_close."); + checks.Add("mcc_recent_events"); + + if (runLocalSetup) + { + long deathBaseline = ReadInt64(inventoryEventsData, "latestId"); + await RunRconCommandAsync(rconScript, rconPort, rconPassword, $"kill {botName}"); + ToolEnvelope deathEvents = await WaitForRecentEventTypesAsync(client, executed, deathBaseline, "death"); + Ensure(GetEventTypes(RequireData(deathEvents)).Contains("death", StringComparer.OrdinalIgnoreCase), + "mcc_recent_events never reported death after the RCON kill."); + + long respawnBaseline = ReadInt64(RequireData(deathEvents), "latestId"); + ToolEnvelope respawn = await CallSuccessAsync(client, executed, "mcc_respawn"); + Ensure(ReadBoolean(RequireData(respawn), "success"), "mcc_respawn did not report success."); + ToolEnvelope respawnEvents = await WaitForRecentEventTypesAsync(client, executed, respawnBaseline, "respawn"); + Ensure(GetEventTypes(RequireData(respawnEvents)).Contains("respawn", StringComparer.OrdinalIgnoreCase), + "mcc_recent_events never reported respawn after mcc_respawn."); + checks.Add("mcc_respawn"); + } + else + { + long respawnBaseline = ReadInt64(RequireData(inventoryEvents), "latestId"); + ToolEnvelope respawn = await CallSuccessAsync(client, executed, "mcc_respawn"); + Ensure(ReadBoolean(RequireData(respawn), "success"), "mcc_respawn did not report success."); + ToolEnvelope respawnEvents = await WaitForRecentEventTypesAsync(client, executed, respawnBaseline, "respawn"); + Ensure(GetEventTypes(RequireData(respawnEvents)).Contains("respawn", StringComparer.OrdinalIgnoreCase), + "mcc_recent_events never reported respawn after mcc_respawn."); + checks.Add("mcc_respawn"); + } + + ToolEnvelope loadedBots = await CallSuccessAsync(client, executed, "mcc_loaded_bots"); + JsonElement bots = RequireProperty(RequireData(loadedBots), "bots"); + Ensure(ContainsBot(bots, "McpServer"), "mcc_loaded_bots did not include McpServer."); + checks.Add("mcc_loaded_bots"); + + ToolEnvelope disconnect = await CallSuccessAsync(client, executed, "mcc_disconnect"); + Ensure(ReadBoolean(RequireData(disconnect), "disconnecting"), "mcc_disconnect did not report disconnecting=true."); + checks.Add("mcc_disconnect"); + + if (!useStdio) + { + await AssertDisconnectStopsEndpointAsync(client, executed); + } + + Console.WriteLine(JsonSerializer.Serialize(new + { + success = true, + endpoint, + useStdio, + runLocalSetup, + checks, + executed + }, new JsonSerializerOptions { WriteIndented = true })); + + Environment.ExitCode = 0; +} +catch (Exception ex) +{ + Console.WriteLine(JsonSerializer.Serialize(new + { + success = false, + endpoint, + useStdio, + runLocalSetup, + error = ex.Message, + checks, + executed + }, new JsonSerializerOptions { WriteIndented = true })); + Environment.ExitCode = 1; } -async Task CallAndStore(string toolName, IReadOnlyDictionary? args = null) +static async Task PrepareWorldAsync(string rconScript, string rconPort, string rconPassword, string botName, Coordinate location) +{ + string[] commands = + [ + $"op {botName}", + $"gamemode creative {botName}", + $"tp {botName} 0 80 0", + $"item replace entity {botName} hotbar.0 with minecraft:stone 32", + $"item replace entity {botName} hotbar.1 with minecraft:diamond_sword 1", + $"execute as {botName} at @s run setblock ~2 ~ ~ minecraft:chest", + $"execute as {botName} at @s run summon minecraft:armor_stand ~2 ~ ~1", + "weather clear", + "weather rain", + $"title {botName} title {{\"text\":\"mcp_title\"}}", + $"title {botName} actionbar {{\"text\":\"mcp_actionbar\"}}" + ]; + + foreach (string command in commands) + { + await RunRconCommandAsync(rconScript, rconPort, rconPassword, command); + } +} + +static async Task RunRconCommandAsync(string rconScript, string rconPort, string rconPassword, string command) +{ + ProcessStartInfo startInfo = new("bash") + { + RedirectStandardOutput = true, + RedirectStandardError = true + }; + startInfo.ArgumentList.Add(rconScript); + startInfo.ArgumentList.Add(command); + startInfo.ArgumentList.Add(rconPort); + startInfo.ArgumentList.Add(rconPassword); + + using Process process = Process.Start(startInfo) ?? throw new InvalidOperationException("Failed to start mc-rcon.sh."); + string stdout = await process.StandardOutput.ReadToEndAsync(); + string stderr = await process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + if (process.ExitCode != 0) + { + throw new InvalidOperationException( + $"RCON command failed ({command}): {(string.IsNullOrWhiteSpace(stderr) ? stdout : stderr).Trim()}"); + } +} + +static async Task CallSuccessAsync( + McpClient client, + List executed, + string toolName, + IReadOnlyDictionary? args = null) +{ + ToolEnvelope envelope = await CallToolAsync(client, executed, toolName, args); + if (!envelope.Success) + { + throw new InvalidOperationException( + $"{toolName} failed with errorCode={envelope.ErrorCode ?? ""} message={envelope.Message ?? ""}."); + } + + return envelope; +} + +static async Task WaitForPredicateAsync( + McpClient client, + List executed, + string toolName, + IReadOnlyDictionary? args, + Func predicate, + string failureMessage, + int maxAttempts = 12, + int delayMs = 400) +{ + ToolEnvelope? lastEnvelope = null; + for (int attempt = 0; attempt < maxAttempts; attempt++) + { + ToolEnvelope envelope = await CallToolAsync(client, executed, toolName, args); + lastEnvelope = envelope; + if (predicate(envelope)) + return envelope; + + await Task.Delay(delayMs); + } + + throw new InvalidOperationException( + $"{failureMessage} Last result: success={lastEnvelope?.Success}, errorCode={lastEnvelope?.ErrorCode ?? ""}."); +} + +static async Task WaitForRecentEventTypesAsync( + McpClient client, + List executed, + long afterId, + params string[] expectedTypes) +{ + HashSet expected = expectedTypes.ToHashSet(StringComparer.OrdinalIgnoreCase); + ToolEnvelope? lastEnvelope = null; + + for (int attempt = 0; attempt < 12; attempt++) + { + ToolEnvelope envelope = await CallSuccessAsync(client, executed, "mcc_recent_events", new Dictionary + { + ["afterId"] = afterId, + ["maxCount"] = 100 + }); + lastEnvelope = envelope; + JsonElement data = RequireData(envelope); + HashSet actual = GetEventTypes(data); + if (expected.All(actual.Contains)) + return envelope; + + await Task.Delay(400); + } + + throw new InvalidOperationException( + $"mcc_recent_events never reported: {string.Join(", ", expectedTypes)} after event id {afterId}. Last latestId={ReadInt64(RequireData(lastEnvelope!), "latestId")}."); +} + +static async Task CallToolAsync( + McpClient client, + List executed, + string toolName, + IReadOnlyDictionary? args = null) { CallToolResult result = await client.CallToolAsync(toolName, args); + string responseJson = ExtractResponseJson(result); + JsonElement root = JsonDocument.Parse(responseJson).RootElement.Clone(); + JsonElement? data = root.TryGetProperty("data", out JsonElement dataElement) ? dataElement.Clone() : null; + bool success = root.TryGetProperty("success", out JsonElement successElement) + && successElement.ValueKind == JsonValueKind.True; + string? errorCode = ReadString(root, "errorCode"); + string? message = ReadString(root, "message"); + executed.Add(new { tool = toolName, arguments = args, isError = result.IsError, - result = result + success, + errorCode, + message, + response = root }); - return result; + + return new ToolEnvelope(toolName, result.IsError ?? false, success, errorCode, message, root, data); } -static (double x, double y, double z) GetLookTarget(CallToolResult sessionStatus) +static async Task AssertDisconnectStopsEndpointAsync(McpClient client, List executed) { - JsonElement? data = TryReadData(sessionStatus); - if (data is JsonElement jsonData && - jsonData.TryGetProperty("location", out JsonElement location) && - TryReadDouble(location, "x", out double x) && - TryReadDouble(location, "y", out double y) && - TryReadDouble(location, "z", out double z)) + for (int attempt = 0; attempt < 15; attempt++) { - return (x, y, z); - } - - return (0.5, 80.0, 0.5); -} - -static int GetInventoryActionSlot(CallToolResult inventorySnapshot) -{ - JsonElement? data = TryReadData(inventorySnapshot); - if (data is JsonElement jsonData && - jsonData.TryGetProperty("slots", out JsonElement slots) && - slots.ValueKind == JsonValueKind.Array) - { - foreach (JsonElement slot in slots.EnumerateArray()) + try { - if (TryReadInt(slot, "slot", out int slotId)) - return slotId; + await CallToolAsync(client, executed, "mcc_world_state"); } + catch + { + return; + } + + await Task.Delay(300); } - return 0; + throw new InvalidOperationException("The MCP endpoint still responded after mcc_disconnect."); } -static int? GetFirstEntityId(CallToolResult entitiesList) -{ - JsonElement? data = TryReadData(entitiesList); - if (data is not JsonElement jsonData) - return null; - - if (!jsonData.TryGetProperty("entities", out JsonElement entities) - || entities.ValueKind != JsonValueKind.Array - || entities.GetArrayLength() == 0) - { - return null; - } - - JsonElement first = entities[0]; - if (TryReadInt(first, "id", out int entityId)) - return entityId; - - return null; -} - -static JsonElement? TryReadData(CallToolResult result) +static string ExtractResponseJson(CallToolResult result) { if (result.Content is null) - return null; + throw new InvalidOperationException("Tool response did not contain any content blocks."); foreach (ContentBlock content in result.Content) { - if (content is TextContentBlock text && - !string.IsNullOrWhiteSpace(text.Text)) - { - using JsonDocument doc = JsonDocument.Parse(text.Text); - if (doc.RootElement.TryGetProperty("data", out JsonElement data)) - return data.Clone(); - } + if (content is TextContentBlock text && !string.IsNullOrWhiteSpace(text.Text)) + return text.Text; } - return null; + throw new InvalidOperationException("Tool response did not contain a text payload."); } -static bool TryReadDouble(JsonElement element, string property, out double value) +static JsonElement RequireData(ToolEnvelope envelope) { - value = 0; - return element.TryGetProperty(property, out JsonElement prop) && prop.TryGetDouble(out value); + if (envelope.Data is JsonElement data) + return data; + + throw new InvalidOperationException($"{envelope.ToolName} returned no data payload."); } -static bool TryReadInt(JsonElement element, string property, out int value) +static JsonElement RequireProperty(JsonElement element, string propertyName) { - value = 0; - return element.TryGetProperty(property, out JsonElement prop) && prop.TryGetInt32(out value); + if (element.TryGetProperty(propertyName, out JsonElement property)) + return property; + + throw new InvalidOperationException($"Missing required property '{propertyName}'."); +} + +static string RequireString(JsonElement element, string propertyName) +{ + string? value = ReadString(element, propertyName); + if (!string.IsNullOrWhiteSpace(value)) + return value; + + throw new InvalidOperationException($"Property '{propertyName}' is missing or empty."); +} + +static string? ReadString(JsonElement element, string propertyName) +{ + return element.TryGetProperty(propertyName, out JsonElement property) && property.ValueKind == JsonValueKind.String + ? property.GetString() + : null; +} + +static int ReadInt32(JsonElement element, string propertyName) +{ + JsonElement property = RequireProperty(element, propertyName); + if (property.TryGetInt32(out int value)) + return value; + + throw new InvalidOperationException($"Property '{propertyName}' is not an Int32."); +} + +static long ReadInt64(JsonElement element, string propertyName) +{ + JsonElement property = RequireProperty(element, propertyName); + if (property.TryGetInt64(out long value)) + return value; + + throw new InvalidOperationException($"Property '{propertyName}' is not an Int64."); +} + +static double ReadDouble(JsonElement element, string propertyName) +{ + JsonElement property = RequireProperty(element, propertyName); + if (property.TryGetDouble(out double value)) + return value; + + throw new InvalidOperationException($"Property '{propertyName}' is not a Double."); +} + +static bool ReadBoolean(JsonElement element, string propertyName) +{ + JsonElement property = RequireProperty(element, propertyName); + return property.ValueKind switch + { + JsonValueKind.True => true, + JsonValueKind.False => false, + _ => throw new InvalidOperationException($"Property '{propertyName}' is not a Boolean.") + }; +} + +static bool HasNonNullProperty(JsonElement element, string propertyName) +{ + return element.TryGetProperty(propertyName, out JsonElement property) && property.ValueKind != JsonValueKind.Null; +} + +static Coordinate ReadCoordinate(JsonElement element, string propertyName) +{ + JsonElement coordinate = RequireProperty(element, propertyName); + return new Coordinate( + ReadDouble(coordinate, "x"), + ReadDouble(coordinate, "y"), + ReadDouble(coordinate, "z")); +} + +static JsonElement FindPlayer(JsonElement players, string playerName) +{ + foreach (JsonElement player in players.EnumerateArray()) + { + string? name = ReadString(player, "name"); + if (string.Equals(name, playerName, StringComparison.OrdinalIgnoreCase)) + return player; + } + + throw new InvalidOperationException($"Could not find player '{playerName}' in mcc_players_detailed."); +} + +static bool ContainsItemType(JsonElement searchData, string itemType) +{ + JsonElement matches = RequireProperty(searchData, "matches"); + foreach (JsonElement match in matches.EnumerateArray()) + { + if (string.Equals(ReadString(match, "itemType"), itemType, StringComparison.OrdinalIgnoreCase)) + return true; + } + + return false; +} + +static bool ContainsBot(JsonElement bots, string botName) +{ + foreach (JsonElement bot in bots.EnumerateArray()) + { + if (string.Equals(ReadString(bot, "name"), botName, StringComparison.OrdinalIgnoreCase)) + return true; + } + + return false; +} + +static HashSet GetEventTypes(JsonElement recentEventsData) +{ + JsonElement events = RequireProperty(recentEventsData, "events"); + return events.EnumerateArray() + .Select(entry => RequireString(entry, "type")) + .ToHashSet(StringComparer.OrdinalIgnoreCase); +} + +static bool AllEventsMatchType(JsonElement recentEventsData, string type) +{ + JsonElement events = RequireProperty(recentEventsData, "events"); + foreach (JsonElement entry in events.EnumerateArray()) + { + if (!string.Equals(RequireString(entry, "type"), type, StringComparison.OrdinalIgnoreCase)) + return false; + } + + return true; +} + +static void Ensure(bool condition, string message) +{ + if (!condition) + throw new InvalidOperationException(message); +} + +static bool IsLocalEndpoint(string endpoint) +{ + if (!Uri.TryCreate(endpoint, UriKind.Absolute, out Uri? uri)) + return false; + + return string.Equals(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase) + || string.Equals(uri.Host, "127.0.0.1", StringComparison.OrdinalIgnoreCase) + || string.Equals(uri.Host, "::1", StringComparison.OrdinalIgnoreCase); +} + +static string FindRepoRoot() +{ + string current = Directory.GetCurrentDirectory(); + DirectoryInfo? directory = new(current); + + while (directory is not null) + { + if (File.Exists(Path.Combine(directory.FullName, "MinecraftClient.sln"))) + return directory.FullName; + + directory = directory.Parent; + } + + return current; } static StdioClientTransportOptions CreateStdioOptions() @@ -209,3 +760,14 @@ static StdioClientTransportOptions CreateStdioOptions() ShutdownTimeout = TimeSpan.FromSeconds(5) }; } + +internal readonly record struct Coordinate(double X, double Y, double Z); + +internal sealed record ToolEnvelope( + string ToolName, + bool IsError, + bool Success, + string? ErrorCode, + string? Message, + JsonElement Root, + JsonElement? Data); diff --git a/DebugTools/MccMcpStdioHarness/Program.cs b/DebugTools/MccMcpStdioHarness/Program.cs index 441f7dac..1b90ddbb 100644 --- a/DebugTools/MccMcpStdioHarness/Program.cs +++ b/DebugTools/MccMcpStdioHarness/Program.cs @@ -24,14 +24,36 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities { private static double C(double value) => Math.Round(value, 2, MidpointRounding.AwayFromZero); + private readonly List recentEvents = []; + private long nextEventId = 1; + private double playerX = C(0.5); + private double playerY = C(80.0); + private double playerZ = C(0.5); + private float yaw; + private float pitch; + private int currentSlot = 1; + private bool sneaking; + private bool sprinting; + private float health = 20.0f; + private bool disconnecting; + + public DeterministicCapabilities() + { + AddRecentEvent("player_join", new { name = "HarnessBot" }); + AddRecentEvent("inventory_open", new { inventoryId = 1, type = "Generic_9x3", title = "Chest" }); + AddRecentEvent("weather_rain", new { level = 1.0 }); + AddRecentEvent("title", new { text = "mcp_title" }); + AddRecentEvent("actionbar", new { text = "mcp_actionbar" }); + } + public MccMcpResult GetSessionStatus() => MccMcpResult.Ok(new { - connected = true, + connected = !disconnecting, host = "deterministic.local", port = 25565, username = "HarnessBot", - location = new { x = C(0.5), y = C(80.0), z = C(0.5) } + location = new { x = playerX, y = playerY, z = playerZ } }); public MccMcpResult GetServerInfo() => @@ -47,22 +69,222 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities { nickname = "HarnessBot", username = "HarnessBot", - health = 20.0f, + health, saturation = 20, gamemode = 1, - currentSlot = 1, - yaw = 0.0f, - pitch = 0.0f, - location = new { x = C(0.5), y = C(80.0), z = C(0.5) }, + currentSlot, + yaw, + pitch, + location = new { x = playerX, y = playerY, z = playerZ }, effects = new object[0] }); + public MccMcpResult GetWorldState() => + MccMcpResult.Ok(new + { + connected = !disconnecting, + host = "deterministic.local", + port = 25565, + username = "HarnessBot", + protocol = 769, + terrainEnabled = true, + inventoryEnabled = true, + entityHandlingEnabled = true, + location = new { x = playerX, y = playerY, z = playerZ }, + tps = 20.0, + dimension = "minecraft:overworld", + loadedChunkCount = 9, + pendingChunkCount = 0, + totalChunkCount = 9, + loadRatio = 1.0, + worldAge = 12000L, + timeOfDay = 6000L, + rainLevel = 1.0, + thunderLevel = 0.0 + }); + + public MccMcpResult GetChunkStatus(double? x, double? y, double? z) + { + double resolvedX = x ?? playerX; + double resolvedY = y ?? playerY; + double resolvedZ = z ?? playerZ; + int chunkX = (int)Math.Floor(resolvedX) >> 4; + int chunkZ = (int)Math.Floor(resolvedZ) >> 4; + + return MccMcpResult.Ok(new + { + location = new { x = C(resolvedX), y = C(resolvedY), z = C(resolvedZ) }, + chunk = new { x = chunkX, z = chunkZ }, + loaded = true, + fullyLoaded = true, + loadedChunkCount = 9, + pendingChunkCount = 0, + totalChunkCount = 9, + loadRatio = 1.0 + }); + } + + public MccMcpResult RaycastBlock(double maxDistance, bool includeNeighbors) + { + object? neighbors = includeNeighbors + ? new + { + north = new { x = 0, y = 79, z = -1, material = "Air", typeLabel = "Air" }, + south = new { x = 0, y = 79, z = 1, material = "Air", typeLabel = "Air" }, + east = new { x = 1, y = 79, z = 0, material = "Air", typeLabel = "Air" }, + west = new { x = -1, y = 79, z = 0, material = "Air", typeLabel = "Air" }, + above = new { x = 0, y = 80, z = 0, material = "Air", typeLabel = "Air" }, + below = new { x = 0, y = 78, z = 0, material = "Stone", typeLabel = "Stone" } + } + : null; + + return MccMcpResult.Ok(new + { + hit = true, + maxDistance, + playerLocation = new { x = playerX, y = playerY, z = playerZ }, + eyeLocation = new { x = playerX, y = C(playerY + 1.62), z = playerZ }, + location = new { x = 0, y = 79, z = 0 }, + block = new { material = "Stone", typeLabel = "Stone", blockId = 1, blockMeta = 0 }, + distance = 1.12, + eyeDistance = 2.03, + neighbors + }); + } + + public MccMcpResult PreviewPath(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs, int maxWaypoints) + { + object[] waypoints = + [ + new { x = playerX, y = playerY, z = playerZ }, + new { x = C((playerX + x) / 2), y = C((playerY + y) / 2), z = C((playerZ + z) / 2) }, + new { x = C(x), y = C(y), z = C(z) } + ]; + + return MccMcpResult.Ok(new + { + pathFound = true, + exactReachable = true, + target = new { x = C(x), y = C(y), z = C(z) }, + startLocation = new { x = playerX, y = playerY, z = playerZ }, + finalWaypoint = new { x = C(x), y = C(y), z = C(z) }, + finalDistance = 0.0, + waypointCount = waypoints.Length, + truncated = waypoints.Length > Math.Max(1, maxWaypoints), + waypoints = waypoints.Take(Math.Max(1, maxWaypoints)).ToArray(), + allowUnsafe, + maxOffset, + minOffset, + timeoutMs = timeoutMs <= 0 ? 5000 : timeoutMs + }); + } + public MccMcpResult GetPlayersList() => MccMcpResult.Ok(new { players = new[] { "HarnessBot", "PlayerOne" } }); + public MccMcpResult GetPlayersDetailed(bool includeSelf, bool includeCoordinates) + { + List players = []; + if (includeSelf) + { + players.Add(new + { + name = "HarnessBot", + uuid = Guid.Parse("11111111-1111-1111-1111-111111111111"), + ping = 5, + gamemode = 1, + listed = true, + displayName = "HarnessBot", + entityId = 1, + x = includeCoordinates ? playerX : (double?)null, + y = includeCoordinates ? playerY : (double?)null, + z = includeCoordinates ? playerZ : (double?)null + }); + } + + players.Add(new + { + name = "PlayerOne", + uuid = Guid.Parse("22222222-2222-2222-2222-222222222222"), + ping = 12, + gamemode = 1, + listed = true, + displayName = "PlayerOne", + entityId = 2, + x = includeCoordinates ? C(3.5) : (double?)null, + y = includeCoordinates ? C(80.0) : (double?)null, + z = includeCoordinates ? C(0.5) : (double?)null + }); + + return MccMcpResult.Ok(new + { + count = players.Count, + players = players.ToArray() + }); + } + + public MccMcpResult GetPlayerStats() => + MccMcpResult.Ok(new + { + health, + saturation = 20, + level = 12, + totalExperience = 245, + gamemode = 1, + playerEntityId = 1, + currentSlot, + yaw, + pitch, + sneaking, + sprinting, + location = new { x = playerX, y = playerY, z = playerZ }, + tps = 20.0 + }); + + public MccMcpResult GetStatusEffects() => + MccMcpResult.Ok(new + { + count = 0, + effects = Array.Empty() + }); + + public MccMcpResult GetRecentEvents(long afterId, int maxCount, string? typeFilter) + { + RecentEvent[] events = recentEvents + .Where(e => e.Id > afterId) + .Where(e => string.IsNullOrWhiteSpace(typeFilter) || string.Equals(e.Type, typeFilter, StringComparison.OrdinalIgnoreCase)) + .Take(Math.Max(1, maxCount)) + .ToArray(); + + return MccMcpResult.Ok(new + { + afterId, + latestId = recentEvents.Count > 0 ? recentEvents[^1].Id : 0, + count = events.Length, + events = events.Select(e => new + { + id = e.Id, + timestampUtc = e.TimestampUtc, + type = e.Type, + data = e.Data + }).ToArray() + }); + } + + public MccMcpResult GetLoadedBots() => + MccMcpResult.Ok(new + { + count = 2, + bots = new object[] + { + new { name = "McpServer", fullTypeName = "MinecraftClient.ChatBots.McpServer", isScript = false }, + new { name = "HarnessScript", fullTypeName = "MinecraftClient.ChatBots.Script", isScript = true } + } + }); + public MccMcpResult GetChatHistory(int maxCount, bool includeJson) => MccMcpResult.Ok(new { @@ -135,14 +357,38 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities public MccMcpResult QuitClient() => MccMcpResult.Ok(new { quitting = true }); + public MccMcpResult DisconnectClient() + { + disconnecting = true; + AddRecentEvent("disconnect", new { reason = "requested", message = "Disconnect requested by test client." }); + return MccMcpResult.Ok(new { disconnecting = true }); + } + public MccMcpResult RunInternalCommand(string command) => MccMcpResult.Ok(new { command, status = "Done", output = "deterministic" }); public MccMcpResult UseItemOnHand() => MccMcpResult.Ok(new { success = true, action = "use_item_on_hand" }); - public MccMcpResult ChangeHotbarSlot(int slot) => - MccMcpResult.Ok(new { success = true, slot }); + public MccMcpResult ChangeHotbarSlot(int slot) + { + currentSlot = slot; + return MccMcpResult.Ok(new { success = true, slot }); + } + + public MccMcpResult SelectHotbarItem(string itemType, bool preferLowestSlot) + { + currentSlot = string.Equals(itemType, "DiamondSword", StringComparison.OrdinalIgnoreCase) ? 2 : 1; + return MccMcpResult.Ok(new + { + success = true, + itemType, + inventorySlot = currentSlot - 1, + selectedSlot = currentSlot, + count = string.Equals(itemType, "DiamondSword", StringComparison.OrdinalIgnoreCase) ? 1 : 32, + preferLowestSlot + }); + } public MccMcpResult UseItemOnBlock(double x, double y, double z) => MccMcpResult.Ok(new { success = true, x = C(x), y = C(y), z = C(z), action = "useitem" }); @@ -169,6 +415,58 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities public MccMcpResult InteractEntity(int entityId, string interaction, string hand) => MccMcpResult.Ok(new { success = true, entityId, interaction, hand }); + public MccMcpResult AttackEntity(int entityId) => + MccMcpResult.Ok(new { success = true, entityId, interaction = "Attack" }); + + public MccMcpResult FindNearestEntity(string? typeFilter, string? nameFilter, double radius, bool includePlayers) + { + bool wantsArmorStand = string.IsNullOrWhiteSpace(typeFilter) + || string.Equals(typeFilter, "ArmorStand", StringComparison.OrdinalIgnoreCase) + || string.Equals(typeFilter, "Armor Stand", StringComparison.OrdinalIgnoreCase); + + if (wantsArmorStand && radius >= 4.0) + { + return MccMcpResult.Ok(new + { + id = 7, + type = "ArmorStand", + typeLabel = "Armor Stand", + uuid = Guid.Parse("33333333-3333-3333-3333-333333333333"), + name = "Armor Stand", + customName = (string?)null, + x = C(2.5), + y = C(80.0), + z = C(0.5), + distance = 2.0, + health = 20.0f, + pose = "Standing", + latency = 0 + }); + } + + if (includePlayers && radius >= 3.0) + { + return MccMcpResult.Ok(new + { + id = 2, + type = "Player", + typeLabel = "Player", + uuid = Guid.Parse("22222222-2222-2222-2222-222222222222"), + name = string.IsNullOrWhiteSpace(nameFilter) ? "PlayerOne" : nameFilter, + customName = (string?)null, + x = C(3.5), + y = C(80.0), + z = C(0.5), + distance = 3.0, + health = 20.0f, + pose = "Standing", + latency = 12 + }); + } + + return MccMcpResult.Fail("invalid_state", data: new { typeFilter, nameFilter, radius, includePlayers }); + } + public MccMcpResult ScanNearbyBlocks(int radius, int maxCount, string? materialFilter) => MccMcpResult.Ok(new { @@ -298,6 +596,61 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities public MccMcpResult LookAt(double x, double y, double z) => MccMcpResult.Ok(new { looked = true, x = C(x), y = C(y), z = C(z) }); + public MccMcpResult LookDirection(string direction) + { + switch (direction.Trim().ToLowerInvariant()) + { + case "up": + yaw = 0.0f; + pitch = -90.0f; + break; + case "down": + yaw = 0.0f; + pitch = 90.0f; + break; + case "north": + yaw = 180.0f; + pitch = 0.0f; + break; + case "south": + yaw = 0.0f; + pitch = 0.0f; + break; + case "east": + yaw = -90.0f; + pitch = 0.0f; + break; + case "west": + yaw = 90.0f; + pitch = 0.0f; + break; + } + + return MccMcpResult.Ok(new { success = true, direction, yaw, pitch }); + } + + public MccMcpResult LookAngles(float yaw, float pitch) + { + this.yaw = yaw; + this.pitch = pitch; + return MccMcpResult.Ok(new { success = true, yaw, pitch }); + } + + public MccMcpResult PlayAnimation(string hand) => + MccMcpResult.Ok(new { success = true, hand }); + + public MccMcpResult ToggleSneak(bool enabled) + { + sneaking = enabled; + return MccMcpResult.Ok(new { success = true, enabled = sneaking }); + } + + public MccMcpResult ToggleSprint(bool enabled) + { + sprinting = enabled; + return MccMcpResult.Ok(new { success = true, enabled = sprinting }); + } + public MccMcpResult ListInventories() => MccMcpResult.Ok(new { @@ -322,8 +675,73 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities } }); - public MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent) => - MccMcpResult.Ok(new + public MccMcpResult SearchInventories(string query, int maxCount, bool exactMatch, bool includeContainers) + { + List matches = []; + + if (query.Contains("stone", StringComparison.OrdinalIgnoreCase)) + { + matches.Add(new + { + inventoryId = 0, + inventoryType = "PlayerInventory", + inventoryTitle = "Player Inventory", + slot = 0, + itemType = "Stone", + typeLabel = "Stone", + count = 32, + isPlayerInventory = true, + hotbarSlot = 1 + }); + } + + if (query.Contains("diamond", StringComparison.OrdinalIgnoreCase) || query.Contains("sword", StringComparison.OrdinalIgnoreCase)) + { + matches.Add(new + { + inventoryId = 0, + inventoryType = "PlayerInventory", + inventoryTitle = "Player Inventory", + slot = 1, + itemType = "DiamondSword", + typeLabel = "Diamond Sword", + count = 1, + isPlayerInventory = true, + hotbarSlot = 2 + }); + } + + if (includeContainers) + { + matches.Add(new + { + inventoryId = 1, + inventoryType = "Generic_9x3", + inventoryTitle = "Chest", + slot = 0, + itemType = "Stone", + typeLabel = "Stone", + count = 16, + isPlayerInventory = false, + hotbarSlot = (int?)null + }); + } + + object[] result = matches.Take(Math.Max(1, maxCount)).ToArray(); + return MccMcpResult.Ok(new + { + query, + exactMatch, + includeContainers, + count = result.Length, + matches = result + }); + } + + public MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent) + { + AddRecentEvent("inventory_open", new { inventoryId = 1, type = "Generic_9x3", title = "Chest", x, y, z }); + return MccMcpResult.Ok(new { success = true, openAccepted = true, @@ -335,15 +753,20 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities block = new { material = "Chest", typeLabel = "Chest", blockId = 0, blockMeta = 0 }, inventory = new { id = 1, type = "Generic_9x3", title = "Chest", slotCount = 63, nonEmptySlots = 2 } }); + } - public MccMcpResult CloseContainer(int inventoryId, int timeoutMs) => - MccMcpResult.Ok(new + public MccMcpResult CloseContainer(int inventoryId, int timeoutMs) + { + int resolvedInventoryId = inventoryId <= 0 ? 1 : inventoryId; + AddRecentEvent("inventory_close", new { inventoryId = resolvedInventoryId }); + return MccMcpResult.Ok(new { success = true, closed = true, - inventoryId = inventoryId <= 0 ? 1 : inventoryId, + inventoryId = resolvedInventoryId, timeoutMs = timeoutMs <= 0 ? 5000 : timeoutMs }); + } public MccMcpResult InventoryWindowAction(int inventoryId, int slotId, string actionType) => MccMcpResult.Ok(new { success = true, inventoryId, slotId, actionType }); @@ -540,6 +963,22 @@ internal sealed class DeterministicCapabilities : IMccMcpCapabilities } }); + public MccMcpResult Respawn() + { + health = 20.0f; + AddRecentEvent("respawn", new { location = new { x = playerX, y = playerY, z = playerZ } }); + return MccMcpResult.Ok(new { success = true, respawned = true }); + } + public MccMcpResult GetWorldBlockAt(int x, int y, int z) => MccMcpResult.Ok(new { x, y, z, material = "Air", blockId = 0, blockMeta = 0 }); + + private void AddRecentEvent(string type, object? data) + { + recentEvents.Add(new RecentEvent(nextEventId++, DateTimeOffset.UtcNow, type, data)); + if (recentEvents.Count > 100) + recentEvents.RemoveAt(0); + } + + private sealed record RecentEvent(long Id, DateTimeOffset TimestampUtc, string Type, object? Data); } diff --git a/MinecraftClient/ChatBots/McpServer.cs b/MinecraftClient/ChatBots/McpServer.cs index 7657f0bb..3d8f7308 100644 --- a/MinecraftClient/ChatBots/McpServer.cs +++ b/MinecraftClient/ChatBots/McpServer.cs @@ -1,4 +1,5 @@ using System; +using MinecraftClient.Mapping; using MinecraftClient.Mcp; using MinecraftClient.Scripting; using Tomlet.Attributes; @@ -58,7 +59,7 @@ namespace MinecraftClient.ChatBots if (!Config.Enabled) return; - MccMcpChatHistoryStore.Clear(); + ClearStores(); MccMcpConfig mcpConfig = new() { @@ -86,15 +87,20 @@ namespace MinecraftClient.ChatBots public override bool OnDisconnect(DisconnectReason reason, string message) { + MccMcpRecentEventStore.Add("disconnect", new + { + reason = reason.ToString(), + message + }); StopHost(); - MccMcpChatHistoryStore.Clear(); + ClearStores(); return false; } public override void OnUnload() { StopHost(); - MccMcpChatHistoryStore.Clear(); + ClearStores(); } public override void GetText(string text, string? json) @@ -133,6 +139,120 @@ namespace MinecraftClient.ChatBots }); } + public override void OnTimeUpdate(long WorldAge, long TimeOfDay) + { + MccMcpRuntimeStateStore.SetTime(WorldAge, TimeOfDay); + } + + public override void OnRainLevelChange(float level) + { + MccMcpRuntimeStateStore.SetRainLevel(level); + MccMcpRecentEventStore.Add("weather_rain", new { level }); + } + + public override void OnThunderLevelChange(float level) + { + MccMcpRuntimeStateStore.SetThunderLevel(level); + MccMcpRecentEventStore.Add("weather_thunder", new { level }); + } + + public override void OnDeath() + { + MccMcpRecentEventStore.Add("death"); + } + + public override void OnRespawn() + { + MccMcpRecentEventStore.Add("respawn"); + } + + public override void OnPlayerJoin(Guid uuid, string name) + { + MccMcpRecentEventStore.Add("player_join", new + { + uuid, + name + }); + } + + public override void OnPlayerLeave(Guid uuid, string? name) + { + MccMcpRecentEventStore.Add("player_leave", new + { + uuid, + name + }); + } + + public override void OnInventoryOpen(int inventoryId) + { + MccMcpRecentEventStore.Add("inventory_open", new { inventoryId }); + } + + public override void OnInventoryClose(int inventoryId) + { + MccMcpRecentEventStore.Add("inventory_close", new { inventoryId }); + } + + public override void OnTitle(int action, string titletext, string subtitletext, string actionbartext, int fadein, int stay, int fadeout, string json) + { + if (action == 2) + { + MccMcpRecentEventStore.Add("actionbar", new + { + action, + text = actionbartext, + fadein, + stay, + fadeout, + json + }); + return; + } + + if (action is 0 or 1) + { + MccMcpRecentEventStore.Add("title", new + { + action, + titleText = titletext, + subtitleText = subtitletext, + fadein, + stay, + fadeout, + json + }); + } + } + + public override void OnBlockBreakAnimation(Entity entity, Location location, byte stage) + { + MccMcpRecentEventStore.Add("block_break_animation", new + { + entityId = entity.ID, + entityType = entity.Type.ToString(), + stage, + location = new + { + x = location.X, + y = location.Y, + z = location.Z + } + }); + } + + public override void OnEntityAnimation(Entity entity, byte animation) + { + MccMcpRecentEventStore.Add("entity_animation", new + { + entityId = entity.ID, + entityType = entity.Type.ToString(), + animation, + name = entity.Name, + customName = entity.CustomName + }); + } + private void StopHost() { if (host is null || !host.IsRunning) @@ -143,5 +263,12 @@ namespace MinecraftClient.ChatBots else LogToConsole(string.Format(Translations.bot_mcpserver_stop_failed, error ?? "unknown")); } + + private static void ClearStores() + { + MccMcpChatHistoryStore.Clear(); + MccMcpRuntimeStateStore.Clear(); + MccMcpRecentEventStore.Clear(); + } } } diff --git a/MinecraftClient/Mcp/IMccMcpCapabilities.cs b/MinecraftClient/Mcp/IMccMcpCapabilities.cs index 0e460a9e..055fb561 100644 --- a/MinecraftClient/Mcp/IMccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/IMccMcpCapabilities.cs @@ -5,7 +5,16 @@ public interface IMccMcpCapabilities MccMcpResult GetSessionStatus(); MccMcpResult GetServerInfo(); MccMcpResult GetPlayerState(); + MccMcpResult GetWorldState(); + MccMcpResult GetChunkStatus(double? x, double? y, double? z); + MccMcpResult RaycastBlock(double maxDistance, bool includeNeighbors); + MccMcpResult PreviewPath(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs, int maxWaypoints); MccMcpResult GetPlayersList(); + MccMcpResult GetPlayersDetailed(bool includeSelf, bool includeCoordinates); + MccMcpResult GetPlayerStats(); + MccMcpResult GetStatusEffects(); + MccMcpResult GetRecentEvents(long afterId, int maxCount, string? typeFilter); + MccMcpResult GetLoadedBots(); MccMcpResult GetChatHistory(int maxCount, bool includeJson); MccMcpResult GetInternalCommands(); MccMcpResult GetMaterialsList(string? filter, int maxCount); @@ -13,23 +22,34 @@ public interface IMccMcpCapabilities MccMcpResult GetEntityTypesList(string? filter, int maxCount); MccMcpResult SendChat(string text); MccMcpResult QuitClient(); + MccMcpResult DisconnectClient(); + MccMcpResult Respawn(); MccMcpResult RunInternalCommand(string command); + MccMcpResult PlayAnimation(string hand); + MccMcpResult ToggleSneak(bool enabled); + MccMcpResult ToggleSprint(bool enabled); MccMcpResult UseItemOnHand(); MccMcpResult ChangeHotbarSlot(int slot); + MccMcpResult SelectHotbarItem(string itemType, bool preferLowestSlot); MccMcpResult UseItemOnBlock(double x, double y, double z); MccMcpResult DigBlock(double x, double y, double z, double durationSeconds); MccMcpResult PlaceBlock(int x, int y, int z, string face, string hand, bool lookAtBlock); MccMcpResult InteractEntity(int entityId, string interaction, string hand); + MccMcpResult AttackEntity(int entityId); MccMcpResult ScanNearbyBlocks(int radius, int maxCount, string? materialFilter); MccMcpResult FindBlocks(string? query, int radius, int maxCount, bool exactMatch); MccMcpResult IsPlayerNearby(string? playerName, double radius, bool includeSelf); MccMcpResult LocatePlayer(string playerName, bool includeSelf); + MccMcpResult FindNearestEntity(string? typeFilter, string? nameFilter, double radius, bool includePlayers); MccMcpResult CanReachPosition(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs); MccMcpResult MoveTo(double x, double y, double z, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult MoveToPlayer(string playerName, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs); MccMcpResult LookAt(double x, double y, double z); + MccMcpResult LookDirection(string direction); + MccMcpResult LookAngles(float yaw, float pitch); MccMcpResult ListInventories(); MccMcpResult GetInventorySnapshot(int inventoryId); + MccMcpResult SearchInventories(string query, int maxCount, bool exactMatch, bool includeContainers); MccMcpResult OpenContainerAt(int x, int y, int z, int timeoutMs, bool closeCurrent); MccMcpResult CloseContainer(int inventoryId, int timeoutMs); MccMcpResult InventoryWindowAction(int inventoryId, int slotId, string actionType); diff --git a/MinecraftClient/Mcp/MccMcpCapabilities.cs b/MinecraftClient/Mcp/MccMcpCapabilities.cs index 907b8b66..9b9b7e15 100644 --- a/MinecraftClient/Mcp/MccMcpCapabilities.cs +++ b/MinecraftClient/Mcp/MccMcpCapabilities.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using MinecraftClient.CommandHandler; using MinecraftClient.Inventory; using MinecraftClient.Mapping; +using MinecraftClient.Protocol; using MinecraftClient.Protocol.Message; using MinecraftClient.Scripting; @@ -20,6 +21,7 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities private const double SelfEntityDistanceThreshold = 0.2; private const int MaxBlockScanRadius = 12; private const int MaxBlockFindRadius = 32; + private const double MaxRaycastDistance = 128.0; private const double DigReachDistance = 5.0; private const double DigReachDistanceSquared = DigReachDistance * DigReachDistance; private const int DefaultPathQueryTimeoutMs = 5000; @@ -35,6 +37,7 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities private const int MinContainerWaitMs = 250; private const int MaxContainerWaitMs = 20000; private const int DefaultInventoryActionWaitMs = 3500; + private const int MaxPathPreviewWaypoints = 1000; private sealed class InternalCommandInfo { @@ -174,6 +177,226 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult GetWorldState() + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + return client.InvokeOnMainThread(() => + { + Location location = client.GetCurrentLocation(); + World world = client.GetWorld(); + Dimension dimension = World.GetDimension(); + MccMcpRuntimeStateSnapshot runtimeState = MccMcpRuntimeStateStore.GetSnapshot(); + int totalChunkCount = world.chunkCnt; + int pendingChunkCount = Math.Max(0, world.chunkLoadNotCompleted); + int loadedChunkCount = GetLoadedChunkCount(world); + + return MccMcpResult.Ok(new + { + host = client.GetServerHost(), + port = client.GetServerPort(), + username = client.GetUsername(), + protocol = client.GetProtocolVersion(), + protocolVersion = client.GetProtocolVersion(), + terrainEnabled = client.GetTerrainEnabled(), + inventoryEnabled = client.GetInventoryEnabled(), + entityEnabled = client.GetEntityHandlingEnabled(), + entityHandlingEnabled = client.GetEntityHandlingEnabled(), + location = ToCoordinate(location), + tps = client.GetServerTPS(), + dimension = dimension.Name, + dimensionDetails = new + { + name = dimension.Name, + minY = dimension.minY, + maxY = dimension.maxY, + height = dimension.height, + logicalHeight = dimension.logicalHeight, + coordinateScale = dimension.coordinateScale, + hasSkylight = dimension.hasSkylight, + hasCeiling = dimension.hasCeiling, + fixedTime = dimension.fixedTime >= 0 ? dimension.fixedTime : (long?)null + }, + loadedChunkCount, + pendingChunkCount, + totalChunkCount, + loadRatio = GetChunkLoadRatio(world), + worldAge = runtimeState.WorldAge, + timeOfDay = runtimeState.TimeOfDay, + rainLevel = runtimeState.RainLevel, + thunderLevel = runtimeState.ThunderLevel + }); + }); + } + + public MccMcpResult GetChunkStatus(double? x, double? y, double? z) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + if (!HasCompleteCoordinateTriple(x, y, z)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + Location queryLocation = x.HasValue && y.HasValue && z.HasValue + ? new Location(x.Value, y.Value, z.Value) + : client.GetCurrentLocation(); + + World world = client.GetWorld(); + ChunkColumn? chunkColumn = world.GetChunkColumn(queryLocation); + return MccMcpResult.Ok(new + { + location = ToCoordinate(queryLocation), + chunk = new + { + x = queryLocation.ChunkX, + z = queryLocation.ChunkZ + }, + chunkX = queryLocation.ChunkX, + chunkZ = queryLocation.ChunkZ, + loaded = chunkColumn is not null, + fullyLoaded = chunkColumn?.FullyLoaded ?? false, + loadedChunkCount = GetLoadedChunkCount(world), + pendingChunkCount = Math.Max(0, world.chunkLoadNotCompleted), + totalChunkCount = world.chunkCnt, + loadRatio = GetChunkLoadRatio(world) + }); + }); + } + + public MccMcpResult RaycastBlock(double maxDistance, bool includeNeighbors) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + if (maxDistance <= 0 || maxDistance > MaxRaycastDistance) + { + return MccMcpResult.Fail("invalid_args", data: new + { + parameter = "maxDistance", + minExclusive = 0, + max = MaxRaycastDistance + }); + } + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + Location playerLocation = client.GetCurrentLocation(); + Location eyeLocation = playerLocation.EyesLocation(); + Tuple raycast = RaycastHelper.RaycastBlock(client, maxDistance, includeFluids: false); + if (!raycast.Item1) + { + return MccMcpResult.Ok(new + { + hit = false, + maxDistance, + playerLocation = ToCoordinate(playerLocation), + eyeLocation = ToCoordinate(eyeLocation), + location = (object?)null, + block = (object?)null, + distance = (double?)null, + eyeDistance = (double?)null, + neighbors = (object?)null + }); + } + + Location blockLocation = raycast.Item2; + Block block = raycast.Item3; + Location targetCenter = blockLocation.ToCenter(); + object? neighbors = includeNeighbors ? GetNeighborBlockSnapshot(client.GetWorld(), blockLocation) : null; + + return MccMcpResult.Ok(new + { + hit = true, + maxDistance, + playerLocation = ToCoordinate(playerLocation), + eyeLocation = ToCoordinate(eyeLocation), + location = ToCoordinate(blockLocation), + block = ToBlockState(block), + distance = playerLocation.Distance(targetCenter), + eyeDistance = eyeLocation.Distance(targetCenter), + neighbors + }); + }); + } + + public MccMcpResult PreviewPath(double x, double y, double z, bool allowUnsafe, int maxOffset, int minOffset, int timeoutMs, int maxWaypoints) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + if (!AreValidPathOffsets(maxOffset, minOffset) || timeoutMs < 0 || maxWaypoints <= 0) + { + return MccMcpResult.Fail("invalid_args", data: new + { + maxOffset, + minOffset, + timeoutMs, + maxWaypoints + }); + } + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + Location goal = new(x, y, z); + Location startLocation = client.InvokeOnMainThread(client.GetCurrentLocation); + World world = client.InvokeOnMainThread(client.GetWorld); + int effectiveTimeoutMs = GetPathQueryTimeoutMs(timeoutMs); + int waypointLimit = Math.Clamp(maxWaypoints, 1, MaxPathPreviewWaypoints); + Queue? path = Movement.CalculatePath( + world, + startLocation, + goal, + allowUnsafe, + maxOffset, + minOffset, + TimeSpan.FromMilliseconds(effectiveTimeoutMs)); + Location[] waypoints = path?.Take(waypointLimit).ToArray() ?? []; + Location? finalWaypoint = path is not null && path.Count > 0 ? path.Last() : null; + + return MccMcpResult.Ok(new + { + pathFound = path is not null, + exactReachable = finalWaypoint is Location location && location.ToFloor() == goal.ToFloor(), + target = ToCoordinate(goal), + startLocation = ToCoordinate(startLocation), + finalWaypoint = finalWaypoint is Location waypoint ? ToCoordinate(waypoint) : (object?)null, + finalDistance = finalWaypoint is Location endWaypoint ? GetDistance(endWaypoint, goal) : (double?)null, + waypointCount = path?.Count ?? 0, + truncated = path is not null && path.Count > waypointLimit, + waypoints = waypoints.Select(ToCoordinate).ToArray(), + allowUnsafe, + maxOffset, + minOffset, + timeoutMs = effectiveTimeoutMs + }); + } + public MccMcpResult GetPlayersList() { if (!IsCategoryEnabled(t => t.SessionStatus)) @@ -189,6 +412,202 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities })); } + public MccMcpResult GetPlayersDetailed(bool includeSelf, bool includeCoordinates) + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + return client.InvokeOnMainThread(() => + { + Dictionary onlinePlayers = client.GetOnlinePlayersWithUUID(); + Dictionary? trackedPlayers = client.GetEntityHandlingEnabled() + ? BuildTrackedPlayerSnapshots(client, includeSelf: true).ToDictionary(player => player.Uuid) + : null; + Guid selfUuid = client.GetUserUuid(); + string selfName = client.GetUsername(); + + var players = onlinePlayers + .Select(pair => + { + if (!Guid.TryParse(pair.Key, out Guid uuid)) + return null; + + bool isSelf = uuid == selfUuid || NameComparer.Equals(pair.Value, selfName); + if (!includeSelf && isSelf) + return null; + + PlayerInfo? playerInfo = client.GetPlayerInfo(uuid); + NearbyPlayerSnapshot? trackedPlayer = trackedPlayers is not null + && trackedPlayers.TryGetValue(uuid, out NearbyPlayerSnapshot? resolvedTrackedPlayer) + ? resolvedTrackedPlayer + : null; + Location? selfLocation = isSelf ? client.GetCurrentLocation() : null; + int? entityId = trackedPlayer?.EntityId ?? (isSelf ? client.GetPlayerEntityID() : null); + double? x = includeCoordinates + ? trackedPlayer?.X is double trackedX ? RoundCoordinate(trackedX) + : selfLocation.HasValue ? RoundCoordinate(selfLocation.Value.X) + : (double?)null + : null; + double? y = includeCoordinates + ? trackedPlayer?.Y is double trackedY ? RoundCoordinate(trackedY) + : selfLocation.HasValue ? RoundCoordinate(selfLocation.Value.Y) + : (double?)null + : null; + double? z = includeCoordinates + ? trackedPlayer?.Z is double trackedZ ? RoundCoordinate(trackedZ) + : selfLocation.HasValue ? RoundCoordinate(selfLocation.Value.Z) + : (double?)null + : null; + + return new + { + name = playerInfo?.Name ?? pair.Value, + uuid, + ping = playerInfo?.Ping ?? trackedPlayer?.Latency ?? 0, + gamemode = playerInfo?.Gamemode ?? -1, + listed = playerInfo?.Listed ?? true, + displayName = playerInfo?.DisplayName, + entityId, + x, + y, + z + }; + }) + .Where(player => player is not null) + .OrderBy(player => player!.name, StringComparer.OrdinalIgnoreCase) + .ToArray(); + + return MccMcpResult.Ok(new + { + includeSelf, + includeCoordinates, + count = players.Length, + players + }); + }); + } + + public MccMcpResult GetPlayerStats() + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + return client.InvokeOnMainThread(() => + { + Location location = client.GetCurrentLocation(); + return MccMcpResult.Ok(new + { + username = client.GetUsername(), + health = client.GetHealth(), + saturation = client.GetSaturation(), + level = client.GetLevel(), + totalExperience = client.GetTotalExperience(), + gamemode = client.GetGamemode(), + playerEntityId = client.GetPlayerEntityID(), + currentSlot = client.GetCurrentSlot() + 1, + yaw = client.GetYaw(), + pitch = client.GetPitch(), + location = ToCoordinate(location), + tps = client.GetServerTPS() + }); + }); + } + + public MccMcpResult GetStatusEffects() + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + return client.InvokeOnMainThread(() => + { + var effects = client.GetPlayerEffects() + .Values + .Where(effect => !effect.IsExpired) + .OrderBy(effect => effect.Effect) + .Select(effect => new + { + id = effect.Effect.ToString(), + name = effect.GetDisplayName(), + amplifier = effect.Amplifier, + remainingSeconds = effect.RemainingSeconds, + isInfinite = effect.IsInfinite + }) + .ToArray(); + + return MccMcpResult.Ok(new + { + count = effects.Length, + effects + }); + }); + } + + public MccMcpResult GetRecentEvents(long afterId, int maxCount, string? typeFilter) + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + MccMcpRecentEventEntry[] events = MccMcpRecentEventStore.GetAfter(afterId, maxCount, typeFilter); + return MccMcpResult.Ok(new + { + afterId, + latestId = MccMcpRecentEventStore.GetLatestId(), + count = events.Length, + events = events.Select(entry => new + { + id = entry.Id, + timestampUtc = entry.TimestampUtc, + type = entry.Type, + data = entry.Data + }).ToArray() + }); + } + + public MccMcpResult GetLoadedBots() + { + if (!IsCategoryEnabled(t => t.SessionStatus)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + return client.InvokeOnMainThread(() => + { + var bots = client.GetLoadedChatBots() + .Select(bot => new + { + name = bot.GetType().Name, + fullTypeName = bot.GetType().FullName, + isScript = bot is MinecraftClient.ChatBots.Script + }) + .OrderBy(bot => bot.name, StringComparer.OrdinalIgnoreCase) + .ToArray(); + + return MccMcpResult.Ok(new + { + count = bots.Length, + bots + }); + }); + } + public MccMcpResult GetChatHistory(int maxCount, bool includeJson) { if (!IsCategoryEnabled(t => t.SessionStatus)) @@ -394,6 +813,48 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Ok(new { quitting = true }); } + public MccMcpResult DisconnectClient() + { + if (!IsCategoryEnabled(t => t.ChatAndCommands)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + _ = Task.Run(async () => + { + await Task.Delay(150).ConfigureAwait(false); + client.Disconnect(); + }); + + return MccMcpResult.Ok(new { disconnecting = true }); + } + + public MccMcpResult Respawn() + { + if (!IsCategoryEnabled(t => t.ChatAndCommands)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + float health = client.InvokeOnMainThread(client.GetHealth); + if (health > 0) + { + return MccMcpResult.Fail("invalid_state", data: new + { + health + }); + } + + bool ok = client.InvokeOnMainThread(client.SendRespawnPacket); + return ok + ? MccMcpResult.Ok(new { success = true }) + : MccMcpResult.Fail("action_failed", data: new { success = false }); + } + public MccMcpResult RunInternalCommand(string command) { if (!IsCategoryEnabled(t => t.ChatAndCommands)) @@ -409,6 +870,67 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return ExecuteInternalCommand(client, command.Trim()); } + public MccMcpResult PlayAnimation(string hand) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(hand) || !Enum.TryParse(hand, true, out Hand parsedHand)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + int animation = parsedHand == Hand.MainHand ? 1 : 0; + bool ok = client.DoAnimation(animation); + object resultData = new { success = ok, hand = parsedHand.ToString() }; + return ok + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_failed", data: resultData); + } + + public MccMcpResult ToggleSneak(bool enabled) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + EntityActionType action = enabled ? EntityActionType.StartSneaking : EntityActionType.StopSneaking; + bool ok = client.InvokeOnMainThread(() => + { + bool actionResult = client.SendEntityAction(action); + if (actionResult) + client.IsSneaking = enabled; + return actionResult; + }); + + object resultData = new { success = ok, enabled }; + return ok + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_failed", data: resultData); + } + + public MccMcpResult ToggleSprint(bool enabled) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + EntityActionType action = enabled ? EntityActionType.StartSprinting : EntityActionType.StopSprinting; + bool ok = client.SendEntityAction(action); + object resultData = new { success = ok, enabled }; + return ok + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_failed", data: resultData); + } + public MccMcpResult UseItemOnHand() { if (!IsCategoryEnabled(t => t.Movement)) @@ -441,6 +963,77 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Ok(new { success = ok, slot }); } + public MccMcpResult SelectHotbarItem(string itemType, bool preferLowestSlot) + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(itemType)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + if (!TryParseItemType(itemType, out ItemType parsedItemType)) + { + return MccMcpResult.Fail("invalid_args", data: new + { + itemType = itemType.Trim() + }); + } + + return client.InvokeOnMainThread(() => + { + Container? inventory = client.GetInventory(0); + if (inventory is null) + return MccMcpResult.Fail("invalid_state"); + + var matches = inventory.Items + .Where(pair => pair.Value.Type == parsedItemType && pair.Value.Count > 0) + .Select(pair => + { + bool isHotbar = inventory.IsHotbar(pair.Key, out int hotbar); + return new + { + inventorySlot = pair.Key, + hotbar, + isHotbar, + count = pair.Value.Count + }; + }) + .Where(match => match.isHotbar) + .OrderBy(match => preferLowestSlot ? match.hotbar : -match.hotbar) + .ToArray(); + + if (matches.Length == 0) + { + return MccMcpResult.Fail("invalid_state", data: new + { + itemType = parsedItemType.ToString() + }); + } + + var selected = matches[0]; + bool ok = client.ChangeSlot((short)selected.hotbar); + object resultData = new + { + success = ok, + itemType = parsedItemType.ToString(), + inventorySlot = selected.inventorySlot, + selectedSlot = selected.hotbar + 1, + count = selected.count + }; + + return ok + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_failed", data: resultData); + }); + } + public MccMcpResult UseItemOnBlock(double x, double y, double z) { if (!IsCategoryEnabled(t => t.Movement)) @@ -595,6 +1188,37 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Ok(new { success = ok, entityId, interaction = interactType.ToString(), hand = parsedHand.ToString() }); } + public MccMcpResult AttackEntity(int entityId) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetEntityHandlingEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + if (!client.GetEntities().ContainsKey(entityId)) + return MccMcpResult.Fail("invalid_state", data: new { entityId }); + + bool ok = client.InteractEntity(entityId, InteractType.Attack); + object resultData = new + { + success = ok, + entityId, + interaction = InteractType.Attack.ToString() + }; + + return ok + ? MccMcpResult.Ok(resultData) + : MccMcpResult.Fail("action_failed", data: resultData); + }); + } + public MccMcpResult ScanNearbyBlocks(int radius, int maxCount, string? materialFilter) { if (!IsCategoryEnabled(t => t.EntityWorld)) @@ -931,6 +1555,86 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult FindNearestEntity(string? typeFilter, string? nameFilter, double radius, bool includePlayers) + { + if (!IsCategoryEnabled(t => t.EntityWorld)) + return MccMcpResult.Fail("capability_disabled"); + + if (radius <= 0 || radius > 1024) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetEntityHandlingEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + string? normalizedTypeFilter = string.IsNullOrWhiteSpace(typeFilter) ? null : typeFilter.Trim(); + string? normalizedNameFilter = string.IsNullOrWhiteSpace(nameFilter) ? null : nameFilter.Trim(); + + return client.InvokeOnMainThread(() => + { + Location playerLocation = client.GetCurrentLocation(); + Dictionary playerNamesByEntityId = BuildTrackedPlayerSnapshots(client, includeSelf: true) + .ToDictionary(player => player.EntityId, player => player.Name); + + var nearest = client.GetEntities().Values + .Where(entity => includePlayers || entity.Type != EntityType.Player) + .Select(entity => + { + double dx = entity.Location.X - playerLocation.X; + double dy = entity.Location.Y - playerLocation.Y; + double dz = entity.Location.Z - playerLocation.Z; + string? resolvedName = entity.Type == EntityType.Player + && playerNamesByEntityId.TryGetValue(entity.ID, out string? mappedName) + ? mappedName + : entity.Name; + return new + { + entity, + resolvedName, + distance = Math.Sqrt(dx * dx + dy * dy + dz * dz) + }; + }) + .Where(item => item.distance <= radius) + .Where(item => normalizedTypeFilter is null + || TextMatchesFilter(item.entity.Type.ToString(), normalizedTypeFilter) + || TextMatchesFilter(item.entity.GetTypeString(), normalizedTypeFilter)) + .Where(item => normalizedNameFilter is null || EntityNameMatches(item.resolvedName, item.entity.CustomName, normalizedNameFilter)) + .OrderBy(item => item.distance) + .FirstOrDefault(); + + if (nearest is null) + { + return MccMcpResult.Fail("invalid_state", data: new + { + typeFilter = normalizedTypeFilter, + nameFilter = normalizedNameFilter, + radius, + includePlayers + }); + } + + return MccMcpResult.Ok(new + { + id = nearest.entity.ID, + type = nearest.entity.Type.ToString(), + typeLabel = nearest.entity.GetTypeString(), + uuid = nearest.entity.UUID, + name = nearest.resolvedName, + customName = nearest.entity.CustomName, + x = RoundCoordinate(nearest.entity.Location.X), + y = RoundCoordinate(nearest.entity.Location.Y), + z = RoundCoordinate(nearest.entity.Location.Z), + distance = nearest.distance, + health = nearest.entity.Health, + pose = nearest.entity.Pose.ToString(), + latency = nearest.entity.Latency + }); + }); + } + public MccMcpResult MoveTo(double x, double y, double z, bool allowUnsafe, bool allowDirectTeleport, int maxOffset, int minOffset, int timeoutMs) { if (!IsCategoryEnabled(t => t.Movement)) @@ -1096,6 +1800,60 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return MccMcpResult.Ok(); } + public MccMcpResult LookDirection(string direction) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(direction) || !Enum.TryParse(direction, true, out Direction parsedDirection) || !IsSupportedLookDirection(parsedDirection)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + Location current = client.GetCurrentLocation(); + client.UpdateLocation(current, parsedDirection); + return MccMcpResult.Ok(new + { + direction = parsedDirection.ToString(), + yaw = client.GetYaw(), + pitch = client.GetPitch(), + location = ToCoordinate(current) + }); + }); + } + + public MccMcpResult LookAngles(float yaw, float pitch) + { + if (!IsCategoryEnabled(t => t.Movement)) + return MccMcpResult.Fail("capability_disabled"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetTerrainEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + return client.InvokeOnMainThread(() => + { + Location current = client.GetCurrentLocation(); + client.UpdateLocation(current, yaw, pitch); + return MccMcpResult.Ok(new + { + yaw = client.GetYaw(), + pitch = client.GetPitch(), + location = ToCoordinate(current) + }); + }); + } + public MccMcpResult GetInventorySnapshot(int inventoryId) { if (!IsCategoryEnabled(t => t.Inventory)) @@ -1132,6 +1890,69 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities }); } + public MccMcpResult SearchInventories(string query, int maxCount, bool exactMatch, bool includeContainers) + { + if (!IsCategoryEnabled(t => t.Inventory)) + return MccMcpResult.Fail("capability_disabled"); + + if (string.IsNullOrWhiteSpace(query)) + return MccMcpResult.Fail("invalid_args"); + + McClient? client = GetClient(); + if (client is null) + return NotConnected(); + + if (!client.GetInventoryEnabled()) + return MccMcpResult.Fail("feature_disabled"); + + string normalizedQuery = query.Trim(); + ItemType? parsedItemType = exactMatch && TryParseItemType(normalizedQuery, out ItemType exactItemType) + ? exactItemType + : null; + int limit = Math.Clamp(maxCount, 1, 1000); + + return client.InvokeOnMainThread(() => + { + var matches = client.GetInventories() + .Where(entry => includeContainers || entry.Key == 0) + .OrderBy(entry => entry.Key) + .SelectMany(entry => + { + Container inventory = entry.Value; + return inventory.Items + .Where(pair => pair.Key >= 0 && pair.Value.Count > 0) + .Where(pair => ItemMatches(pair.Value, normalizedQuery, exactMatch, parsedItemType)) + .Select(pair => + { + bool isHotbar = inventory.IsHotbar(pair.Key, out int hotbar); + return new + { + inventoryId = entry.Key, + inventoryType = inventory.Type.ToString(), + inventoryTitle = inventory.Title, + slot = pair.Key, + itemType = pair.Value.Type.ToString(), + typeLabel = pair.Value.GetTypeString(), + count = pair.Value.Count, + isPlayerInventory = entry.Key == 0, + hotbarSlot = isHotbar ? hotbar + 1 : (int?)null + }; + }); + }) + .Take(limit) + .ToArray(); + + return MccMcpResult.Ok(new + { + query = normalizedQuery, + exactMatch, + includeContainers, + count = matches.Length, + matches + }); + }); + } + public MccMcpResult ListInventories() { if (!IsCategoryEnabled(t => t.Inventory)) @@ -2812,6 +3633,67 @@ public sealed class MccMcpCapabilities : IMccMcpCapabilities return maxOffset >= 0 && minOffset >= 0 && minOffset <= maxOffset; } + private static bool HasCompleteCoordinateTriple(double? x, double? y, double? z) + { + return x.HasValue == y.HasValue && y.HasValue == z.HasValue; + } + + private static int GetLoadedChunkCount(World world) + { + return Math.Max(0, world.chunkCnt - Math.Max(0, world.chunkLoadNotCompleted)); + } + + private static double GetChunkLoadRatio(World world) + { + return world.chunkCnt > 0 + ? GetLoadedChunkCount(world) / (double)world.chunkCnt + : 0.0; + } + + private static object GetNeighborBlockSnapshot(World world, Location location) + { + Location blockLocation = location.ToFloor(); + Location north = new(blockLocation.X, blockLocation.Y, blockLocation.Z - 1); + Location south = new(blockLocation.X, blockLocation.Y, blockLocation.Z + 1); + Location east = new(blockLocation.X + 1, blockLocation.Y, blockLocation.Z); + Location west = new(blockLocation.X - 1, blockLocation.Y, blockLocation.Z); + Location above = new(blockLocation.X, blockLocation.Y + 1, blockLocation.Z); + Location below = new(blockLocation.X, blockLocation.Y - 1, blockLocation.Z); + + return new + { + north = new { location = ToCoordinate(north), block = ToBlockState(world.GetBlock(north)) }, + south = new { location = ToCoordinate(south), block = ToBlockState(world.GetBlock(south)) }, + east = new { location = ToCoordinate(east), block = ToBlockState(world.GetBlock(east)) }, + west = new { location = ToCoordinate(west), block = ToBlockState(world.GetBlock(west)) }, + above = new { location = ToCoordinate(above), block = ToBlockState(world.GetBlock(above)) }, + below = new { location = ToCoordinate(below), block = ToBlockState(world.GetBlock(below)) } + }; + } + + private static bool ItemMatches(Item item, string query, bool exactMatch, ItemType? exactItemType) + { + if (exactItemType.HasValue) + return item.Type == exactItemType.Value; + + string typeName = item.Type.ToString(); + string typeLabel = item.GetTypeString(); + return exactMatch + ? TextEqualsFilter(typeName, query) || TextEqualsFilter(typeLabel, query) + : TextMatchesFilter(typeName, query) || TextMatchesFilter(typeLabel, query); + } + + private static bool EntityNameMatches(string? name, string? customName, string filter) + { + return (!string.IsNullOrWhiteSpace(name) && TextMatchesFilter(name, filter)) + || (!string.IsNullOrWhiteSpace(customName) && TextMatchesFilter(customName, filter)); + } + + private static bool IsSupportedLookDirection(Direction direction) + { + return direction is Direction.Up or Direction.Down or Direction.North or Direction.South or Direction.East or Direction.West; + } + private static NearbyItemSnapshot[] BuildNearbyItemSnapshots(McClient client, ItemType? itemType, double radius, int maxCount) { Location playerLocation = client.GetCurrentLocation(); diff --git a/MinecraftClient/Mcp/MccMcpRecentEventStore.cs b/MinecraftClient/Mcp/MccMcpRecentEventStore.cs new file mode 100644 index 00000000..49fd9b86 --- /dev/null +++ b/MinecraftClient/Mcp/MccMcpRecentEventStore.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MinecraftClient.Mcp; + +public sealed class MccMcpRecentEventEntry +{ + public required long Id { get; init; } + public required DateTimeOffset TimestampUtc { get; init; } + public required string Type { get; init; } + public object? Data { get; init; } +} + +public static class MccMcpRecentEventStore +{ + private static readonly object historyLock = new(); + private static readonly List history = new(); + private const int MaxEntries = 500; + private static long nextId = 1; + + public static long Add(string type, object? data = null) + { + ArgumentException.ThrowIfNullOrEmpty(type); + + lock (historyLock) + { + long id = nextId++; + history.Add(new MccMcpRecentEventEntry + { + Id = id, + TimestampUtc = DateTimeOffset.UtcNow, + Type = type, + Data = data + }); + + if (history.Count > MaxEntries) + history.RemoveRange(0, history.Count - MaxEntries); + + return id; + } + } + + public static long GetLatestId() + { + lock (historyLock) + { + return history.Count > 0 ? history[^1].Id : 0; + } + } + + public static MccMcpRecentEventEntry[] GetAfter(long afterId, int maxCount, string? typeFilter = null) + { + int count = Math.Clamp(maxCount, 1, MaxEntries); + string? normalizedFilter = string.IsNullOrWhiteSpace(typeFilter) ? null : typeFilter.Trim(); + + lock (historyLock) + { + return history + .Where(entry => entry.Id > afterId) + .Where(entry => normalizedFilter is null + || entry.Type.Contains(normalizedFilter, StringComparison.OrdinalIgnoreCase)) + .Take(count) + .ToArray(); + } + } + + public static void Clear() + { + lock (historyLock) + { + history.Clear(); + } + } +} diff --git a/MinecraftClient/Mcp/MccMcpRuntimeStateStore.cs b/MinecraftClient/Mcp/MccMcpRuntimeStateStore.cs new file mode 100644 index 00000000..0c602752 --- /dev/null +++ b/MinecraftClient/Mcp/MccMcpRuntimeStateStore.cs @@ -0,0 +1,70 @@ +using System; + +namespace MinecraftClient.Mcp; + +public sealed class MccMcpRuntimeStateSnapshot +{ + public long? WorldAge { get; init; } + public long? TimeOfDay { get; init; } + public float? RainLevel { get; init; } + public float? ThunderLevel { get; init; } +} + +public static class MccMcpRuntimeStateStore +{ + private static readonly object stateLock = new(); + private static long? worldAge; + private static long? timeOfDay; + private static float? rainLevel; + private static float? thunderLevel; + + public static void SetTime(long newWorldAge, long newTimeOfDay) + { + lock (stateLock) + { + worldAge = newWorldAge; + timeOfDay = newTimeOfDay; + } + } + + public static void SetRainLevel(float level) + { + lock (stateLock) + { + rainLevel = level; + } + } + + public static void SetThunderLevel(float level) + { + lock (stateLock) + { + thunderLevel = level; + } + } + + public static MccMcpRuntimeStateSnapshot GetSnapshot() + { + lock (stateLock) + { + return new MccMcpRuntimeStateSnapshot + { + WorldAge = worldAge, + TimeOfDay = timeOfDay, + RainLevel = rainLevel, + ThunderLevel = thunderLevel + }; + } + } + + public static void Clear() + { + lock (stateLock) + { + worldAge = null; + timeOfDay = null; + rainLevel = null; + thunderLevel = null; + } + } +} diff --git a/MinecraftClient/Mcp/MccMcpToolSet.cs b/MinecraftClient/Mcp/MccMcpToolSet.cs index 64dc2789..8da6b413 100644 --- a/MinecraftClient/Mcp/MccMcpToolSet.cs +++ b/MinecraftClient/Mcp/MccMcpToolSet.cs @@ -33,12 +33,66 @@ public sealed class MccMcpToolSet return capabilities.GetPlayerState(); } + [McpServerTool(Name = "mcc_world_state"), Description("Get current world state, chunk loading progress, and last observed runtime time/weather values.")] + public object WorldState() + { + return capabilities.GetWorldState(); + } + + [McpServerTool(Name = "mcc_chunk_status"), Description("Get chunk loading status for the player location or an explicit world coordinate.")] + public object ChunkStatus(double? x = null, double? y = null, double? z = null) + { + return capabilities.GetChunkStatus(x, y, z); + } + + [McpServerTool(Name = "mcc_raycast_block"), Description("Raycast from the player's current view and return the first non-air block hit.")] + public object RaycastBlock(double maxDistance = 8.0, bool includeNeighbors = false) + { + return capabilities.RaycastBlock(maxDistance, includeNeighbors); + } + + [McpServerTool(Name = "mcc_path_preview"), Description("Compute a path preview to a target world coordinate without moving there.")] + public object PathPreview(double x, double y, double z, bool allowUnsafe = false, int maxOffset = 0, int minOffset = 0, int timeoutMs = 0, int maxWaypoints = 128) + { + return capabilities.PreviewPath(x, y, z, allowUnsafe, maxOffset, minOffset, timeoutMs, maxWaypoints); + } + [McpServerTool(Name = "mcc_players_list"), Description("List currently known online players.")] public object PlayersList() { return capabilities.GetPlayersList(); } + [McpServerTool(Name = "mcc_players_detailed"), Description("List online players with UUID, latency, gamemode, and tracked coordinates when available.")] + public object PlayersDetailed(bool includeSelf = false, bool includeCoordinates = true) + { + return capabilities.GetPlayersDetailed(includeSelf, includeCoordinates); + } + + [McpServerTool(Name = "mcc_player_stats"), Description("Get current controlled player stats, orientation, and location.")] + public object PlayerStats() + { + return capabilities.GetPlayerStats(); + } + + [McpServerTool(Name = "mcc_status_effects"), Description("Get active player status effects only.")] + public object StatusEffects() + { + return capabilities.GetStatusEffects(); + } + + [McpServerTool(Name = "mcc_recent_events"), Description("Get recent high-signal MCP runtime events after a given event ID.")] + public object RecentEvents(long afterId = 0, int maxCount = 50, string? typeFilter = null) + { + return capabilities.GetRecentEvents(afterId, maxCount, typeFilter); + } + + [McpServerTool(Name = "mcc_loaded_bots"), Description("List currently loaded MCC bots and scripts.")] + public object LoadedBots() + { + return capabilities.GetLoadedBots(); + } + [McpServerTool(Name = "mcc_chat_history"), Description("Get recent chat/system lines seen by MCC.")] public object ChatHistory(int maxCount = 50, bool includeJson = false) { @@ -87,18 +141,54 @@ public sealed class MccMcpToolSet return capabilities.QuitClient(); } + [McpServerTool(Name = "mcc_disconnect"), Description("Disconnect MCC from the current server without quitting the process.")] + public object Disconnect() + { + return capabilities.DisconnectClient(); + } + + [McpServerTool(Name = "mcc_respawn"), Description("Send the respawn packet when the controlled player is dead.")] + public object Respawn() + { + return capabilities.Respawn(); + } + [McpServerTool(Name = "mcc_run_internal_command"), Description("Run an internal MCC command.")] public object RunInternalCommand([Description("MCC command line without leading slash.")] string command) { return capabilities.RunInternalCommand(command); } + [McpServerTool(Name = "mcc_animation"), Description("Play a hand-swing animation with the selected hand.")] + public object Animation(string hand = "MainHand") + { + return capabilities.PlayAnimation(hand); + } + + [McpServerTool(Name = "mcc_toggle_sneak"), Description("Explicitly enable or disable sneaking.")] + public object ToggleSneak(bool enabled) + { + return capabilities.ToggleSneak(enabled); + } + + [McpServerTool(Name = "mcc_toggle_sprint"), Description("Explicitly send start or stop sprinting entity actions.")] + public object ToggleSprint(bool enabled) + { + return capabilities.ToggleSprint(enabled); + } + [McpServerTool(Name = "mcc_change_hotbar_slot"), Description("Change active hotbar slot (1-9).")] public object ChangeHotbarSlot(int slot) { return capabilities.ChangeHotbarSlot(slot); } + [McpServerTool(Name = "mcc_select_item"), Description("Select a hotbar item by item type without rearranging inventory contents.")] + public object SelectItem(string itemType, bool preferLowestSlot = true) + { + return capabilities.SelectHotbarItem(itemType, preferLowestSlot); + } + [McpServerTool(Name = "mcc_use_item_on_hand"), Description("Use the currently held item.")] public object UseItemOnHand() { @@ -129,6 +219,12 @@ public sealed class MccMcpToolSet return capabilities.InteractEntity(entityId, interaction, hand); } + [McpServerTool(Name = "mcc_entity_attack"), Description("Attack a tracked entity explicitly.")] + public object EntityAttack(int entityId) + { + return capabilities.AttackEntity(entityId); + } + [McpServerTool(Name = "mcc_block_scan"), Description("Scan nearby blocks around player location.")] public object BlockScan(int radius = 3, int maxCount = 200, string? materialFilter = null) { @@ -153,6 +249,12 @@ public sealed class MccMcpToolSet return capabilities.LocatePlayer(playerName, includeSelf); } + [McpServerTool(Name = "mcc_entity_nearest"), Description("Return the nearest tracked entity matching the requested filters.")] + public object EntityNearest(string? typeFilter = null, string? nameFilter = null, double radius = 64.0, bool includePlayers = true) + { + return capabilities.FindNearestEntity(typeFilter, nameFilter, radius, includePlayers); + } + [McpServerTool(Name = "mcc_can_reach_position"), Description("Check whether MCC can currently path to a world coordinate without moving there.")] public object CanReachPosition(double x, double y, double z, bool allowUnsafe = false, int maxOffset = 0, int minOffset = 0, int timeoutMs = 0) { @@ -177,12 +279,30 @@ public sealed class MccMcpToolSet return capabilities.LookAt(x, y, z); } + [McpServerTool(Name = "mcc_look_direction"), Description("Rotate player view to a cardinal direction or straight up/down.")] + public object LookDirection(string direction) + { + return capabilities.LookDirection(direction); + } + + [McpServerTool(Name = "mcc_look_angles"), Description("Rotate player view to explicit yaw and pitch angles.")] + public object LookAngles(float yaw, float pitch) + { + return capabilities.LookAngles(yaw, pitch); + } + [McpServerTool(Name = "mcc_inventory_snapshot"), Description("Get a snapshot of one inventory.")] public object InventorySnapshot([Description("Inventory ID. 0 is the player inventory.")] int inventoryId = 0) { return capabilities.GetInventorySnapshot(inventoryId); } + [McpServerTool(Name = "mcc_inventory_search"), Description("Search the player inventory and optionally open containers for items matching a query.")] + public object InventorySearch(string query, int maxCount = 100, bool exactMatch = false, bool includeContainers = true) + { + return capabilities.SearchInventories(query, maxCount, exactMatch, includeContainers); + } + [McpServerTool(Name = "mcc_inventories_list"), Description("List currently open inventories and containers known to MCC.")] public object InventoriesList() { diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 759e69ed..3ce80d79 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -807,13 +807,14 @@ namespace MinecraftClient /// Optional, keep account and server settings public static void Restart(int delaySeconds = 0, bool keepAccountAndServerSettings = false) { - ConsoleIO.Backend.StopReadThread(); + ConsoleIO.Backend?.StopReadThread(); new Thread(new ThreadStart(delegate { if (client is not null) { client.Disconnect(); ConsoleIO.Reset(); } if (offlinePrompt is not null) { - ConsoleIO.Backend.OnInputChange -= ConsoleIO.OfflineAutocompleteHandler; + if (ConsoleIO.Backend is not null) + ConsoleIO.Backend.OnInputChange -= ConsoleIO.OfflineAutocompleteHandler; offlinePrompt.Item2.Cancel(); offlinePrompt.Item1.Join(); offlinePrompt = null; ConsoleIO.Reset(); } if (delaySeconds > 0) @@ -835,7 +836,8 @@ namespace MinecraftClient if (client is not null) { client.Disconnect(); ConsoleIO.Reset(); } if (offlinePrompt is not null) { - ConsoleIO.Backend.OnInputChange -= ConsoleIO.OfflineAutocompleteHandler; + if (ConsoleIO.Backend is not null) + ConsoleIO.Backend.OnInputChange -= ConsoleIO.OfflineAutocompleteHandler; offlinePrompt.Item2.Cancel(); if (Thread.CurrentThread != offlinePrompt.Item1) offlinePrompt.Item1.Join(1000); @@ -907,8 +909,9 @@ namespace MinecraftClient if (offlinePrompt is null) { - ConsoleIO.Backend.StopReadThread(); - ConsoleIO.Backend.OnInputChange += ConsoleIO.OfflineAutocompleteHandler; + ConsoleIO.Backend?.StopReadThread(); + if (ConsoleIO.Backend is not null) + ConsoleIO.Backend.OnInputChange += ConsoleIO.OfflineAutocompleteHandler; var cancellationTokenSource = new CancellationTokenSource(); offlinePrompt = new(new Thread(new ThreadStart(delegate From c3c57c058a16846d737063bbe7de35405b224589 Mon Sep 17 00:00:00 2001 From: Anon Date: Mon, 30 Mar 2026 23:21:36 +0200 Subject: [PATCH 306/484] Moved the operator prompt from a skill to an embedded resourcce --- MinecraftClient/Mcp/MccMcpGuidanceProvider.cs | 32 +++++++++--------- MinecraftClient/Mcp/MccMcpPromptSet.cs | 4 +-- MinecraftClient/Mcp/MccMcpToolSet.cs | 2 +- .../Mcp/Prompts/MccMcpOperatorPrompt.md | 33 +++++++++++-------- MinecraftClient/MinecraftClient.csproj | 2 +- 5 files changed, 40 insertions(+), 33 deletions(-) rename .skills/mcc-mcp-operator/SKILL.md => MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md (62%) diff --git a/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs b/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs index 285a6d31..232c1bd1 100644 --- a/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs +++ b/MinecraftClient/Mcp/MccMcpGuidanceProvider.cs @@ -10,7 +10,7 @@ namespace MinecraftClient.Mcp; public sealed class MccMcpGuidanceProvider { - private const string EmbeddedSkillResourceSuffix = "MccMcpOperatorSkill.md"; + private const string EmbeddedPromptResourceSuffix = "MccMcpOperatorPrompt.md"; private const string BestPracticesHeading = "## Best Practices"; private const string ExampleScenariosHeading = "## Example Scenarios"; @@ -23,7 +23,7 @@ public sealed class MccMcpGuidanceProvider guidanceDocument = new Lazy(LoadGuidanceDocument); } - public string SkillName => "mcc-mcp-operator"; + public string PromptName => "mcc_operator_prompt"; public string GetSystemPrompt() { @@ -31,7 +31,7 @@ public sealed class MccMcpGuidanceProvider MccMcpAgentCapabilityStatus capabilityStatus = BuildCapabilityStatus(); StringBuilder builder = new(); builder.AppendLine("You are an external agent controlling Minecraft Console Client (MCC) through its built-in MCP server."); - builder.AppendLine("Use the following operator guide as your system prompt. Treat the capability snapshot as authoritative and do not invent unsupported actions."); + builder.AppendLine("Use the following MCP Operator Prompt as your system prompt. Treat the capability snapshot as authoritative and do not invent unsupported actions."); builder.AppendLine(); builder.AppendLine(document.BodyMarkdown); builder.AppendLine(); @@ -49,8 +49,8 @@ public sealed class MccMcpGuidanceProvider GuidanceDocument document = guidanceDocument.Value; return new MccMcpAgentGuidancePayload { - SkillName = SkillName, - SkillMarkdown = document.SkillMarkdown, + PromptName = PromptName, + PromptMarkdown = document.PromptMarkdown, SystemPrompt = GetSystemPrompt(), BestPractices = document.BestPractices, ExampleScenarios = document.ExampleScenarios, @@ -62,21 +62,21 @@ public sealed class MccMcpGuidanceProvider { Assembly assembly = typeof(MccMcpGuidanceProvider).Assembly; string resourceName = assembly.GetManifestResourceNames() - .FirstOrDefault(name => name.EndsWith(EmbeddedSkillResourceSuffix, StringComparison.Ordinal)) - ?? throw new InvalidOperationException($"Embedded MCP skill resource '{EmbeddedSkillResourceSuffix}' was not found."); + .FirstOrDefault(name => name.EndsWith(EmbeddedPromptResourceSuffix, StringComparison.Ordinal)) + ?? throw new InvalidOperationException($"Embedded MCP operator prompt resource '{EmbeddedPromptResourceSuffix}' was not found."); using Stream? stream = assembly.GetManifestResourceStream(resourceName); if (stream is null) - throw new InvalidOperationException($"Embedded MCP skill resource '{resourceName}' could not be opened."); + throw new InvalidOperationException($"Embedded MCP operator prompt resource '{resourceName}' could not be opened."); using StreamReader reader = new(stream, Encoding.UTF8); - string skillMarkdown = reader.ReadToEnd(); - string bodyMarkdown = StripFrontmatter(skillMarkdown); + string promptMarkdown = reader.ReadToEnd(); + string bodyMarkdown = StripFrontmatter(promptMarkdown); string bestPracticesSection = ExtractSection(bodyMarkdown, BestPracticesHeading); string exampleScenariosSection = ExtractSection(bodyMarkdown, ExampleScenariosHeading); return new GuidanceDocument( - skillMarkdown.Replace("\r\n", "\n").Trim(), + promptMarkdown.Replace("\r\n", "\n").Trim(), bodyMarkdown, ExtractBulletList(bestPracticesSection), ExtractExampleScenarios(exampleScenariosSection)); @@ -181,7 +181,7 @@ public sealed class MccMcpGuidanceProvider } private sealed record GuidanceDocument( - string SkillMarkdown, + string PromptMarkdown, string BodyMarkdown, string[] BestPractices, MccMcpAgentScenario[] ExampleScenarios); @@ -189,11 +189,11 @@ public sealed class MccMcpGuidanceProvider public sealed class MccMcpAgentGuidancePayload { - [JsonPropertyName("skillName")] - public string SkillName { get; init; } = string.Empty; + [JsonPropertyName("promptName")] + public string PromptName { get; init; } = string.Empty; - [JsonPropertyName("skillMarkdown")] - public string SkillMarkdown { get; init; } = string.Empty; + [JsonPropertyName("promptMarkdown")] + public string PromptMarkdown { get; init; } = string.Empty; [JsonPropertyName("systemPrompt")] public string SystemPrompt { get; init; } = string.Empty; diff --git a/MinecraftClient/Mcp/MccMcpPromptSet.cs b/MinecraftClient/Mcp/MccMcpPromptSet.cs index 564e6f7f..970528a6 100644 --- a/MinecraftClient/Mcp/MccMcpPromptSet.cs +++ b/MinecraftClient/Mcp/MccMcpPromptSet.cs @@ -12,8 +12,8 @@ public sealed class MccMcpPromptSet this.guidanceProvider = guidanceProvider; } - [McpServerPrompt(Name = "mcc_operator_guide"), Description("Get the canonical MCC operator guidance prompt for external agents using this MCP server.")] - public string OperatorGuide() + [McpServerPrompt(Name = "mcc_operator_prompt"), Description("Get the canonical MCC MCP Operator Prompt for external agents using this MCP server.")] + public string OperatorPrompt() { return guidanceProvider.GetSystemPrompt(); } diff --git a/MinecraftClient/Mcp/MccMcpToolSet.cs b/MinecraftClient/Mcp/MccMcpToolSet.cs index 8da6b413..84305e34 100644 --- a/MinecraftClient/Mcp/MccMcpToolSet.cs +++ b/MinecraftClient/Mcp/MccMcpToolSet.cs @@ -105,7 +105,7 @@ public sealed class MccMcpToolSet return capabilities.GetInternalCommands(); } - [McpServerTool(Name = "mcc_agent_guidance"), Description("Get the canonical MCC operator guidance bundle for external agents using this MCP server.")] + [McpServerTool(Name = "mcc_agent_guidance"), Description("Get the canonical MCC MCP Operator Prompt bundle for external agents using this MCP server.")] public object AgentGuidance() { return guidanceProvider.GetToolPayload(); diff --git a/.skills/mcc-mcp-operator/SKILL.md b/MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md similarity index 62% rename from .skills/mcc-mcp-operator/SKILL.md rename to MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md index 2e2e734a..b2dabd79 100644 --- a/.skills/mcc-mcp-operator/SKILL.md +++ b/MinecraftClient/Mcp/Prompts/MccMcpOperatorPrompt.md @@ -1,9 +1,4 @@ ---- -name: mcc-mcp-operator -description: Operate Minecraft Console Client through the built-in MCP server. Use this whenever the user wants an agent to inspect MCC state, move, search the world, interact with players or entities, dig, pick up items, manage containers, or carry out Minecraft tasks through MCP tools, even if they do not explicitly say "use MCP" or "control MCC". Prefer this skill over ad hoc tool guessing for agentic MCC and Minecraft control work. ---- - -# MCC MCP Operator +# MCC MCP Operator Prompt Use the MCC MCP toolset as the source of truth for game state and action results. Do not guess what happened from intent alone. @@ -21,20 +16,31 @@ If the request is purely conversational and does not require MCC state, answer d ## Tool Selection Rules - Start with `mcc_session_status` whenever connection state, enabled capabilities, or feature availability is uncertain. -- Prefer direct inspection tools such as `mcc_player_state`, `mcc_players_list`, `mcc_entities_list`, `mcc_blocks_find`, `mcc_items_list`, and `mcc_inventory_snapshot` before taking physical actions. +- Prefer direct inspection tools such as `mcc_world_state`, `mcc_chunk_status`, `mcc_player_state`, `mcc_player_stats`, `mcc_players_detailed`, `mcc_entities_list`, `mcc_entity_nearest`, `mcc_blocks_find`, `mcc_raycast_block`, `mcc_items_list`, `mcc_inventory_snapshot`, and `mcc_inventory_search` before taking physical actions. - Prefer purpose-built action tools over low-level escape hatches. - Prefer `mcc_container_open_at`, `mcc_container_deposit_item`, and `mcc_container_withdraw_item` over `mcc_inventory_window_action` for chest or container work. -- Use `mcc_can_reach_position` or a locating tool before pathing when reachability is uncertain. +- Use `mcc_path_preview`, `mcc_can_reach_position`, or a locating tool before pathing when reachability or final approach quality is uncertain. +- Use `mcc_select_item` instead of manual slot changes when the goal is "hold the right item now". +- Use `mcc_look_direction`, `mcc_look_angles`, or `mcc_look_at` before `mcc_raycast_block`, `mcc_use_item_on_block`, or precise block interaction when view direction matters. +- Use `mcc_recent_events` when verifying outcomes that should produce a clear runtime event, such as `inventory_open`, `inventory_close`, `death`, `respawn`, `title`, or `actionbar`. +- Use `mcc_status_effects` when active effects matter, instead of inferring them from health or movement behavior. +- Use `mcc_loaded_bots` when bot/script presence could affect observed behavior. - Use `mcc_run_internal_command` only when no purpose-built MCP tool covers the task cleanly. - Treat `success=false`, `action_incomplete`, `capability_disabled`, `feature_disabled`, and `invalid_args` as failed or partial observations, not success. - After `invalid_args`, simplify the call and try at most one nearby variant. Do not spam near-duplicate guesses. ## Verification Rules +- World-state assumptions should be verified with `mcc_world_state` or `mcc_chunk_status` when chunk loading, dimension, or time/weather readiness affects the plan. - Movement is not complete just because a move request was accepted. Confirm `arrived=true` or verify the new location with a fresh state read. +- A path preview is not proof of arrival. Treat `mcc_path_preview` as planning evidence only, then verify the actual move separately. - Digging is not complete just because `mcc_dig_block` was invoked. Re-check the target block or nearby block search results. +- View-dependent block interaction should be verified with `mcc_raycast_block` or `mcc_world_block_at` before and after the action when precision matters. - Item pickup is not complete just because the bot moved over an item. Re-check inventory state or nearby dropped-item entities. +- Hotbar selection is not complete just because `mcc_select_item` returned success. Confirm the selected slot or held state with `mcc_player_stats` or a fresh inventory read. - Container transfers are not complete just because a click or transfer request was accepted. Verify the resulting counts after the transfer. +- Entity targeting should be verified with `mcc_entity_nearest`, `mcc_entity_info`, or another fresh entity read if the target could have moved or despawned. +- Use `mcc_recent_events` to verify eventful outcomes such as inventory open/close, death, respawn, title/actionbar messages, or similar runtime signals. - Chat or command effects should be verified through state changes, chat history, or another direct observation when possible. - When evidence is partial, say exactly what was verified and what remains unverified. @@ -43,6 +49,7 @@ If the request is purely conversational and does not require MCC state, answer d - Query first, act second, verify third. - Keep plans short and concrete. Long speculative tool chains usually make the result worse. - Prefer high-signal tools that answer the real question directly. +- Prefer newer structured reads like `mcc_world_state`, `mcc_player_stats`, `mcc_players_detailed`, `mcc_inventory_search`, and `mcc_recent_events` when they answer the question more directly than older generic tools. - Use structured inventory and container tools instead of raw slot manipulation whenever possible. - Do not claim success from acceptance alone. Always pair actions with a follow-up observation. - Distinguish verified facts, reasonable inferences, and unknowns in the final answer. @@ -59,9 +66,9 @@ User intent: "Find Zarko and move near them." Good flow: - call `mcc_player_locate` or `mcc_players_list` to confirm the player is known -- if needed, call `mcc_can_reach_position` for the target area +- if needed, call `mcc_players_detailed` for exact coordinates and `mcc_path_preview` or `mcc_can_reach_position` for the target area - call `mcc_move_to_player` -- verify `arrived=true` or confirm the new position with `mcc_player_state` +- verify `arrived=true` or confirm the new position with `mcc_player_stats` - report whether proximity was verified or only partially achieved ### Open a chest, move an exact item count, and verify the result @@ -70,9 +77,9 @@ User intent: "Put 5 diamonds in the chest at 11000 64 11021." Good flow: - call `mcc_container_open_at` -- inspect current state with `mcc_inventory_snapshot` if item availability is unclear +- inspect current state with `mcc_inventory_search` or `mcc_inventory_snapshot` if item availability is unclear - call `mcc_container_deposit_item` or `mcc_container_withdraw_item` -- verify the resulting counts from the transfer result and, when useful, a fresh inventory snapshot +- verify the resulting counts from the transfer result and, when useful, a fresh inventory snapshot or `mcc_recent_events` - report the exact verified delta, not just that the action was attempted ### Collect nearby dropped items or dig target blocks and verify the outcome @@ -80,7 +87,7 @@ Good flow: User intent: "Pick up nearby apples" or "Break those logs and collect them." Good flow: -- call `mcc_items_list` or `mcc_blocks_find` to locate the target +- call `mcc_items_list`, `mcc_blocks_find`, or `mcc_raycast_block` to locate the target - move only if the target is not already reachable from the current position - call `mcc_items_pickup` for dropped items, or `mcc_dig_block` in a sensible order for blocks - verify the result with `mcc_items_list`, `mcc_inventory_snapshot`, or a fresh block query diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index 68b31912..4fdf6c94 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -20,7 +20,7 @@ - + From c9b0913c1a7fbff36c640a78614eed1e77f26990 Mon Sep 17 00:00:00 2001 From: Anon Date: Tue, 31 Mar 2026 00:18:31 +0200 Subject: [PATCH 307/484] feat(autofishing): add velocity and sound bite detection --- MinecraftClient/ChatBots/AutoFishing.cs | 100 ++++++++++++++++-- MinecraftClient/McClient.cs | 38 +++++++ .../Protocol/Handlers/DataTypes.cs | 42 ++++++-- .../Protocol/Handlers/Protocol18.cs | 97 +++++++++++++++++ .../Protocol/IMinecraftComHandler.cs | 21 ++++ .../ConfigComments/ConfigComments.resx | 15 +++ MinecraftClient/Scripting/ChatBot.cs | 23 ++++ docs/guide/chat-bots.md | 61 +++++++++++ 8 files changed, 380 insertions(+), 17 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs index 9711b86c..cf381561 100644 --- a/MinecraftClient/ChatBots/AutoFishing.cs +++ b/MinecraftClient/ChatBots/AutoFishing.cs @@ -62,6 +62,21 @@ namespace MinecraftClient.ChatBots [TomlInlineComment("$ChatBot.AutoFishing.Hook_Threshold$")] public double Hook_Threshold = 0.2; + [TomlInlineComment("$ChatBot.AutoFishing.Enable_Velocity_Detection$")] + public bool Enable_Velocity_Detection = true; + + [TomlInlineComment("$ChatBot.AutoFishing.Velocity_Hook_Threshold$")] + public double Velocity_Hook_Threshold = -0.2; + + [TomlInlineComment("$ChatBot.AutoFishing.Enable_Sound_Detection$")] + public bool Enable_Sound_Detection = true; + + [TomlInlineComment("$ChatBot.AutoFishing.Sound_Distance$")] + public double Sound_Distance = 5.0; + + [TomlInlineComment("$ChatBot.AutoFishing.Detection_Warmup$")] + public double Detection_Warmup = 1.0; + [TomlInlineComment("$ChatBot.AutoFishing.Log_Fish_Bobber$")] public bool Log_Fish_Bobber = false; @@ -97,6 +112,15 @@ namespace MinecraftClient.ChatBots if (Hook_Threshold < 0) Hook_Threshold = -Hook_Threshold; + + if (Velocity_Hook_Threshold > 0) + Velocity_Hook_Threshold = -Velocity_Hook_Threshold; + + if (Sound_Distance < 0) + Sound_Distance = -Sound_Distance; + + if (Detection_Warmup < 0) + Detection_Warmup = 0; } public struct LocationConfig @@ -171,6 +195,7 @@ namespace MinecraftClient.ChatBots private Entity? fishingBobber; private Location LastPos = Location.Zero; private DateTime CaughtTime = DateTime.Now; + private DateTime BobberSpawnTime = DateTime.MinValue; private int fishItemCounter = 15; private Dictionary fishItemCnt = new(); private Entity fishItem = new(-1, EntityType.Item, Location.Zero); @@ -464,6 +489,7 @@ namespace MinecraftClient.ChatBots fishingBobber = entity; LastPos = entity.Location; isFishing = true; + BobberSpawnTime = DateTime.Now; castTimeout = 24; counter = 0; @@ -500,7 +526,7 @@ namespace MinecraftClient.ChatBots public override void OnEntityMove(Entity entity) { if (isFishing && entity is not null && fishingBobber!.ID == entity.ID && - (state == FishingState.WaitingFishToBite || state == FishingState.WaitingFishingBobber)) + state == FishingState.WaitingFishToBite) { Location Pos = entity.Location; double Dx = LastPos.X - Pos.X; @@ -515,13 +541,7 @@ namespace MinecraftClient.ChatBots Math.Abs(Dz) < Math.Abs(Config.Stationary_Threshold) && Math.Abs(Dy) > Math.Abs(Config.Hook_Threshold)) { - // prevent triggering multiple time - if ((DateTime.Now - CaughtTime).TotalSeconds > 1) - { - isFishing = false; - CaughtTime = DateTime.Now; - OnCaughtFish(); - } + TryCatchFish(); } } } @@ -540,6 +560,38 @@ namespace MinecraftClient.ChatBots } } + public override void OnEntityVelocity(Entity entity, double velocityX, double velocityY, double velocityZ) + { + if (!Config.Enable_Velocity_Detection || !CanUseAdvancedDetection()) + return; + + if (fishingBobber is null || entity.ID != fishingBobber.ID) + return; + + if (velocityY <= Config.Velocity_Hook_Threshold) + TryCatchFish(); + } + + public override void OnSoundEffect(string? soundName, Location? location, int category, float volume, float pitch, + Entity? sourceEntity) + { + if (!Config.Enable_Sound_Detection || !CanUseAdvancedDetection()) + return; + + if (!IsFishingBobberSplashSound(soundName)) + return; + + Location? soundLocation = location; + if (soundLocation is null && sourceEntity is not null) + soundLocation = sourceEntity.Location; + + if (soundLocation is null || fishingBobber is null) + return; + + if (soundLocation.Value.Distance(fishingBobber.Location) <= Config.Sound_Distance) + TryCatchFish(); + } + public override void AfterGameJoined() { StartFishing(); @@ -562,10 +614,42 @@ namespace MinecraftClient.ChatBots fishingBobber = null; LastPos = Location.Zero; CaughtTime = DateTime.Now; + BobberSpawnTime = DateTime.MinValue; return base.OnDisconnect(reason, message); } + private bool CanUseAdvancedDetection() + { + if (!isFishing || fishingBobber is null || state != FishingState.WaitingFishToBite) + return false; + + return (DateTime.Now - BobberSpawnTime).TotalSeconds >= Config.Detection_Warmup; + } + + private void TryCatchFish() + { + if (!CanUseAdvancedDetection()) + return; + + // Prevent repeated catches from multiple packets of the same bite. + if ((DateTime.Now - CaughtTime).TotalSeconds <= 1) + return; + + isFishing = false; + CaughtTime = DateTime.Now; + OnCaughtFish(); + } + + private static bool IsFishingBobberSplashSound(string? soundName) + { + return string.Equals(soundName, "minecraft:entity.fishing_bobber.splash", + StringComparison.OrdinalIgnoreCase) + || string.Equals(soundName, "entity.fishing_bobber.splash", StringComparison.OrdinalIgnoreCase) + || string.Equals(soundName, "minecraft:entity.bobber.splash", StringComparison.OrdinalIgnoreCase) + || string.Equals(soundName, "entity.bobber.splash", StringComparison.OrdinalIgnoreCase); + } + /// /// Called when detected a fish is caught /// diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index bd84d562..e1079c3c 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -3798,6 +3798,44 @@ namespace MinecraftClient } } + /// + /// Called when an entity velocity update is received. + /// + /// Entity ID + /// Velocity on X axis (blocks/tick) + /// Velocity on Y axis (blocks/tick) + /// Velocity on Z axis (blocks/tick) + public void OnEntityVelocity(int entityID, double velocityX, double velocityY, double velocityZ) + { + if (entities.TryGetValue(entityID, out Entity? entity)) + DispatchBotEvent(bot => bot.OnEntityVelocity(entity, velocityX, velocityY, velocityZ)); + } + + /// + /// Called when a sound packet is received. + /// + /// Sound key when available, otherwise null + /// Sound location when available + /// Sound category id from packet + /// Sound volume + /// Sound pitch + /// Source entity id for entity sound packets, if any + public void OnSoundEffect(string? soundName, Location? location, int category, float volume, float pitch, + int? entityID) + { + Entity? sourceEntity = null; + Location? resolvedLocation = location; + + if (entityID is int id && entities.TryGetValue(id, out Entity? entity)) + { + sourceEntity = entity; + resolvedLocation ??= entity.Location; + } + + DispatchBotEvent(bot => bot.OnSoundEffect(soundName, resolvedLocation, category, volume, pitch, + sourceEntity)); + } + /// /// Called when received entity properties from server. /// diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 6a0d27aa..bdbdecea 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1054,20 +1054,44 @@ namespace MinecraftClient.Protocol.Handlers } } + private static bool HasLpVec3Continuation(int firstByte) => (firstByte & 4) == 4; + + private static double UnpackLpVec3(long packedAxis) + { + return Math.Min((double)(packedAxis & 32767L), 32766.0) * 2.0 / 32766.0 - 1.0; + } + /// - /// Read an LpVec3 (low-precision vec3) from the cache (1.21.9+). - /// Variable-length encoding: first byte 0 = zero vector; otherwise - /// 2 bytes + 4 bytes (6 total), plus an optional VarInt continuation. + /// Read and decode an LpVec3 (low-precision vec3) from the cache (1.21.9+). + /// Returned vector is expressed in blocks per tick. /// - public void ReadNextLpVec3(Queue cache) + public (double X, double Y, double Z) ReadNextLpVec3Values(Queue cache) { int first = ReadNextByte(cache); if (first == 0) - return; - ReadNextByte(cache); // second byte - ReadData(4, cache); // uint32 - if ((first & 4) == 4) // continuation bit set - ReadNextVarInt(cache); + return (0.0, 0.0, 0.0); + + int second = ReadNextByte(cache); + uint high = (uint)ReadNextInt(cache); + long packed = ((long)high << 16) | (long)(second << 8) | (uint)first; + + long scale = first & 3; + if (HasLpVec3Continuation(first)) + scale |= ((long)ReadNextVarInt(cache) & 0xFFFFFFFFL) << 2; + + return ( + UnpackLpVec3(packed >> 3) * scale, + UnpackLpVec3(packed >> 18) * scale, + UnpackLpVec3(packed >> 33) * scale + ); + } + + /// + /// Read an LpVec3 (low-precision vec3) from the cache (1.21.9+) and discard it. + /// + public void ReadNextLpVec3(Queue cache) + { + ReadNextLpVec3Values(cache); } /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 88c26690..a27c4b0a 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2642,6 +2642,27 @@ namespace MinecraftClient.Protocol.Handlers handler.OnEntityRotation(entityId, yaw, pitch, isOnGround); } + break; + case PacketTypesIn.EntityVelocity: + if (handler.GetEntityHandlingEnabled()) + { + var entityId = dataTypes.ReadNextVarInt(packetData); + double velocityX, velocityY, velocityZ; + + if (protocolVersion >= MC_1_21_9_Version) + { + (velocityX, velocityY, velocityZ) = dataTypes.ReadNextLpVec3Values(packetData); + } + else + { + velocityX = dataTypes.ReadNextShort(packetData) / 8000.0D; + velocityY = dataTypes.ReadNextShort(packetData) / 8000.0D; + velocityZ = dataTypes.ReadNextShort(packetData) / 8000.0D; + } + + handler.OnEntityVelocity(entityId, velocityX, velocityY, velocityZ); + } + break; case PacketTypesIn.EntityProperties: if (handler.GetEntityHandlingEnabled()) @@ -2892,6 +2913,65 @@ namespace MinecraftClient.Protocol.Handlers handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); break; + case PacketTypesIn.NamedSoundEffect: + { + string? soundName = dataTypes.ReadNextString(packetData); + int category = dataTypes.ReadNextVarInt(packetData); + double x = dataTypes.ReadNextInt(packetData) / 8.0D; + double y = dataTypes.ReadNextInt(packetData) / 8.0D; + double z = dataTypes.ReadNextInt(packetData) / 8.0D; + float volume = dataTypes.ReadNextFloat(packetData); + float pitch = dataTypes.ReadNextFloat(packetData); + + handler.OnSoundEffect(soundName, new Location(x, y, z), category, volume, pitch, null); + break; + } + case PacketTypesIn.SoundEffect: + { + string? soundName; + if (protocolVersion >= MC_1_19_Version) + soundName = ReadSoundEventHolderName(packetData); + else + { + dataTypes.ReadNextVarInt(packetData); // Sound id + soundName = null; + } + + int category = dataTypes.ReadNextVarInt(packetData); + double x = dataTypes.ReadNextInt(packetData) / 8.0D; + double y = dataTypes.ReadNextInt(packetData) / 8.0D; + double z = dataTypes.ReadNextInt(packetData) / 8.0D; + float volume = dataTypes.ReadNextFloat(packetData); + float pitch = dataTypes.ReadNextFloat(packetData); + + if (protocolVersion >= MC_1_19_Version) + dataTypes.ReadNextLong(packetData); // Seed + + handler.OnSoundEffect(soundName, new Location(x, y, z), category, volume, pitch, null); + break; + } + case PacketTypesIn.EntitySoundEffect: + { + string? soundName; + if (protocolVersion >= MC_1_19_Version) + soundName = ReadSoundEventHolderName(packetData); + else + { + dataTypes.ReadNextVarInt(packetData); // Sound id + soundName = null; + } + + int category = dataTypes.ReadNextVarInt(packetData); + int entityId = dataTypes.ReadNextVarInt(packetData); + float volume = dataTypes.ReadNextFloat(packetData); + float pitch = dataTypes.ReadNextFloat(packetData); + + if (protocolVersion >= MC_1_19_Version) + dataTypes.ReadNextLong(packetData); // Seed + + handler.OnSoundEffect(soundName, null, category, volume, pitch, entityId); + break; + } case PacketTypesIn.HeldItemChange: case PacketTypesIn.SetHeldSlot: handler.OnHeldItemChange(dataTypes.ReadNextByte(packetData)); // Slot @@ -3154,6 +3234,23 @@ namespace MinecraftClient.Protocol.Handlers return true; //Packet processed } + /// + /// Read a Holder<SoundEvent> from packet data and return its key when inline. + /// Returns null when the holder is a registry reference. + /// + private string? ReadSoundEventHolderName(Queue packetData) + { + int soundHolderId = dataTypes.ReadNextVarInt(packetData); + if (soundHolderId != 0) + return null; + + string soundName = dataTypes.ReadNextString(packetData); + bool hasFixedRange = dataTypes.ReadNextBool(packetData); + if (hasFixedRange) + dataTypes.ReadNextFloat(packetData); + return soundName; + } + /// /// Handle the Statistics packet for pre-1.12 legacy achievements. /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 9bfa44e8..13f5a628 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -295,6 +295,16 @@ namespace MinecraftClient.Protocol /// TRUE if on ground void OnEntityTeleport(int entityID, Double x, Double y, Double z, bool onGround); + /// + /// Called when an entity velocity update packet is received. + /// Velocity values are in blocks per tick. + /// + /// Entity ID + /// Velocity X + /// Velocity Y + /// Velocity Z + void OnEntityVelocity(int entityID, double velocityX, double velocityY, double velocityZ); + /// /// Called when additional properties have been received for an entity /// @@ -371,6 +381,17 @@ namespace MinecraftClient.Protocol /// Amount of affected blocks void OnExplosion(Location location, float strength, int affectedBlocks); + /// + /// Called when a sound packet is received. + /// + /// Sound key if available, otherwise null + /// Sound location for world sounds, or null if unavailable + /// Sound category id + /// Sound volume + /// Sound pitch + /// Source entity id for entity-sound packets, if any + void OnSoundEffect(string? soundName, Location? location, int category, float volume, float pitch, int? entityID); + /// /// Called when a player's game mode has changed /// diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index 8f3e4964..825c7e76 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -311,6 +311,21 @@ You can use "/fish" to control the bot manually. A "stationary" hook that moves above this threshold in the Y-axis will be considered to have caught a fish. + + Enable fish bite detection using fishing bobber velocity packets. + + + Velocity Y threshold (blocks/tick). Values below this are treated as a bite. Keep this value negative. + + + Enable fish bite detection using splash sounds near the fishing bobber. + + + Maximum distance (blocks) between splash sound and bobber to treat it as a bite. + + + Delay (seconds) after bobber spawn before bite detection starts. Helps ignore cast-entry splash/motion. + Used to adjust the above two thresholds, which when enabled will print the change in the position of the fishhook entity upon receipt of its movement packet. diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index 2776cda9..c5950334 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -199,6 +199,29 @@ namespace MinecraftClient.Scripting /// Entity with updated location public virtual void OnEntityMove(Entity entity) { } + /// + /// Called when a tracked entity receives a velocity update packet. + /// Velocity is expressed in blocks per tick. + /// + /// Entity with updated velocity + /// Velocity on X axis (blocks/tick) + /// Velocity on Y axis (blocks/tick) + /// Velocity on Z axis (blocks/tick) + public virtual void OnEntityVelocity(Entity entity, double velocityX, double velocityY, double velocityZ) { } + + /// + /// Called when a sound packet is received. + /// The sound name is null when the protocol provides only a registry id. + /// + /// Sound key when available, otherwise null + /// Sound position when available + /// Sound category id from packet + /// Sound volume + /// Sound pitch + /// Source entity for entity-sound packets when tracked + public virtual void OnSoundEffect(string? soundName, Location? location, int category, float volume, float pitch, + Entity? sourceEntity) { } + /// /// Called when an entity rotates /// diff --git a/docs/guide/chat-bots.md b/docs/guide/chat-bots.md index 512f1664..e8b6c711 100644 --- a/docs/guide/chat-bots.md +++ b/docs/guide/chat-bots.md @@ -927,6 +927,7 @@ redirectFrom: - **Description:** Automatically catch fish using a fishing rod. + Bite detection combines bobber movement, bobber velocity, and splash sounds.

Note

@@ -1103,6 +1104,66 @@ redirectFrom: - **Default:** `0.2` + #### `Enable_Velocity_Detection` + + - **Description:** + + Enables bite detection using the fishing bobber velocity packet. + + This improves reliability when bobber X/Z movement is constrained (for example by blocks near the water surface). + + - **Available values:** `true` and `false`. + + - **Type:** `boolean` + + - **Default:** `true` + + #### `Velocity_Hook_Threshold` + + - **Description:** + + Velocity Y threshold in blocks/tick for velocity-based bite detection. + + Values below this threshold are considered a bite. Keep this value negative. + + - **Type:** `float` + + - **Default:** `-0.2` + + #### `Enable_Sound_Detection` + + - **Description:** + + Enables bite detection using nearby splash sounds (`entity.fishing_bobber.splash`). + + - **Available values:** `true` and `false`. + + - **Type:** `boolean` + + - **Default:** `true` + + #### `Sound_Distance` + + - **Description:** + + Maximum distance in blocks between a splash sound and the tracked bobber to treat it as a bite. + + - **Type:** `float` + + - **Default:** `5.0` + + #### `Detection_Warmup` + + - **Description:** + + Delay in seconds after bobber spawn before bite detection starts. + + This helps ignore the initial cast-entry splash/motion. + + - **Type:** `float` + + - **Default:** `1.0` + #### `Log_Fish_Bobber` - **Description:** From cf65c6f2418662de420e2f6a824c6035812034d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 23:31:09 +0000 Subject: [PATCH 308/484] Initial plan From fdbffcc5bb4ec2d6c820e769d3136e281d9e18c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Mar 2026 23:41:11 +0000 Subject: [PATCH 309/484] feat: add Teams packet support (parsing, state tracking, /teams command, bot API) Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/72ea891e-ba62-4dfc-bbba-f197cd1d0404 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/Commands/Teams.cs | 77 ++++++++++++++ MinecraftClient/Mapping/PlayerTeam.cs | 49 +++++++++ MinecraftClient/McClient.cs | 100 +++++++++++++++++- .../Protocol/Handlers/Protocol18.cs | 78 ++++++++++++++ .../Protocol/IMinecraftComHandler.cs | 17 +++ .../Translations/Translations.Designer.cs | 45 ++++++++ .../Resources/Translations/Translations.resx | 15 +++ MinecraftClient/Scripting/ChatBot.cs | 17 +++ 8 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 MinecraftClient/Commands/Teams.cs create mode 100644 MinecraftClient/Mapping/PlayerTeam.cs diff --git a/MinecraftClient/Commands/Teams.cs b/MinecraftClient/Commands/Teams.cs new file mode 100644 index 00000000..af7a06d1 --- /dev/null +++ b/MinecraftClient/Commands/Teams.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Brigadier.NET; +using Brigadier.NET.Builder; +using MinecraftClient.CommandHandler; +using MinecraftClient.Mapping; + +namespace MinecraftClient.Commands +{ + public class Teams : Command + { + public override string CmdName => "teams"; + public override string CmdUsage => "teams"; + public override string CmdDesc => Translations.cmd_teams_desc; + + public override void RegisterCommand(CommandDispatcher dispatcher) + { + dispatcher.Register(l => l.Literal("help") + .Then(l => l.Literal(CmdName) + .Executes(r => GetUsage(r.Source, string.Empty)) + ) + ); + + dispatcher.Register(l => l.Literal(CmdName) + .Executes(r => DoListTeams(r.Source)) + .Then(l => l.Literal("_help") + .Executes(r => GetUsage(r.Source, string.Empty)) + .Redirect(dispatcher.GetRoot().GetChild("help").GetChild(CmdName))) + ); + } + + private int GetUsage(CmdResult r, string? cmd) + { + return r.SetAndReturn(cmd switch + { +#pragma warning disable format // @formatter:off + _ => GetCmdDescTranslated(), +#pragma warning restore format // @formatter:on + }); + } + + private static int DoListTeams(CmdResult r) + { + McClient handler = CmdResult.currentHandler!; + Dictionary snapshot = handler.GetTeams(); + + if (snapshot.Count == 0) + return r.SetAndReturn(CmdResult.Status.Done, Translations.cmd_teams_no_teams); + + var sb = new StringBuilder(); + foreach (var team in snapshot.Values.OrderBy(static t => t.Name, StringComparer.Ordinal)) + { + sb.AppendLine(string.Format(Translations.cmd_teams_team_header, + team.Name, + team.DisplayName, + team.Color, + team.Prefix, + team.Suffix, + team.NameTagVisibility, + team.CollisionRule, + team.AllowFriendlyFire, + team.SeeFriendlyInvisibles)); + + if (team.Members.Count == 0) + sb.AppendLine(Translations.cmd_teams_team_no_members); + else + sb.AppendLine(string.Format(Translations.cmd_teams_team_members, + team.Members.Count, + string.Join(", ", team.Members.OrderBy(static m => m, StringComparer.OrdinalIgnoreCase)))); + } + + return r.SetAndReturn(CmdResult.Status.Done, sb.ToString().TrimEnd()); + } + } +} diff --git a/MinecraftClient/Mapping/PlayerTeam.cs b/MinecraftClient/Mapping/PlayerTeam.cs new file mode 100644 index 00000000..4ad7ca64 --- /dev/null +++ b/MinecraftClient/Mapping/PlayerTeam.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Mapping +{ + /// + /// Represents a Minecraft scoreboard team and its current state. + /// + public class PlayerTeam + { + /// Team internal name (up to 16 chars) + public string Name { get; set; } = string.Empty; + + /// Display name component (formatted text) + public string DisplayName { get; set; } = string.Empty; + + /// Friendly fire is allowed between team members + public bool AllowFriendlyFire { get; set; } + + /// Team members can see invisible teammates + public bool SeeFriendlyInvisibles { get; set; } + + /// + /// Nametag visibility rule. + /// Values: "always", "hideForOtherTeams", "hideForOwnTeam", "never" + /// + public string NameTagVisibility { get; set; } = string.Empty; + + /// + /// Collision rule. + /// Values: "always", "pushOtherTeams", "pushOwnTeam", "never" + /// + public string CollisionRule { get; set; } = string.Empty; + + /// + /// Team color as ChatFormatting enum ordinal (-1 = RESET/none, + /// 0–15 = BLACK … WHITE). + /// + public int Color { get; set; } = -1; + + /// Prefix displayed before member names (formatted text) + public string Prefix { get; set; } = string.Empty; + + /// Suffix displayed after member names (formatted text) + public string Suffix { get; set; } = string.Empty; + + /// Current set of player / entity names on this team + public HashSet Members { get; } = new(System.StringComparer.OrdinalIgnoreCase); + } +} diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index e1079c3c..394d01cd 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -113,6 +113,9 @@ namespace MinecraftClient // player attributes (e.g., block_break_speed, mining_efficiency, submerged_mining_speed) private readonly Dictionary playerAttributes = new(); + + // scoreboard teams (key = team name) + private readonly Dictionary teams = new(StringComparer.Ordinal); // Sneaking public bool IsSneaking { get; set; } = false; @@ -162,6 +165,30 @@ namespace MinecraftClient return new Dictionary(playerEffects); } + /// + /// Get a snapshot of all known scoreboard teams. + /// + /// Dictionary mapping team name to + public Dictionary GetTeams() + { + lock (teams) + return new Dictionary(teams, StringComparer.Ordinal); + } + + /// + /// Get the team that contains the given player/entity name, or null if not found. + /// + public PlayerTeam? GetPlayerTeam(string playerName) + { + lock (teams) + { + foreach (var team in teams.Values) + if (team.Members.Contains(playerName)) + return team; + return null; + } + } + public int GetLevel() { return playerLevel; } public int GetTotalExperience() { return playerTotalExperience; } public byte GetCurrentSlot() { return CurrentSlot; } @@ -4053,7 +4080,78 @@ namespace MinecraftClient { DispatchBotEvent(bot => bot.OnUpdateScore(entityName, action, objectiveName, objectiveDisplayName, objectiveValue, numberFormat)); } - + + /// + /// Called when a Teams packet is received. Updates the internal team state and notifies bots. + /// + public void OnTeam(string teamName, byte method, string displayName, byte friendlyFlags, + string nameTagVisibility, string collisionRule, int color, + string prefix, string suffix, List players) + { + lock (teams) + { + switch (method) + { + case 0: // create + var newTeam = new PlayerTeam + { + Name = teamName, + DisplayName = displayName, + AllowFriendlyFire = (friendlyFlags & 0x01) != 0, + SeeFriendlyInvisibles = (friendlyFlags & 0x02) != 0, + NameTagVisibility = nameTagVisibility, + CollisionRule = collisionRule, + Color = color, + Prefix = prefix, + Suffix = suffix + }; + foreach (var p in players) + newTeam.Members.Add(p); + teams[teamName] = newTeam; + break; + + case 1: // remove + teams.Remove(teamName); + break; + + case 2: // update parameters + if (!teams.TryGetValue(teamName, out var updateTeam)) + { + updateTeam = new PlayerTeam { Name = teamName }; + teams[teamName] = updateTeam; + } + updateTeam.DisplayName = displayName; + updateTeam.AllowFriendlyFire = (friendlyFlags & 0x01) != 0; + updateTeam.SeeFriendlyInvisibles = (friendlyFlags & 0x02) != 0; + updateTeam.NameTagVisibility = nameTagVisibility; + updateTeam.CollisionRule = collisionRule; + updateTeam.Color = color; + updateTeam.Prefix = prefix; + updateTeam.Suffix = suffix; + break; + + case 3: // add players + if (!teams.TryGetValue(teamName, out var addTeam)) + { + addTeam = new PlayerTeam { Name = teamName }; + teams[teamName] = addTeam; + } + foreach (var p in players) + addTeam.Members.Add(p); + break; + + case 4: // remove players + if (teams.TryGetValue(teamName, out var removeTeam)) + foreach (var p in players) + removeTeam.Members.Remove(p); + break; + } + } + DispatchBotEvent(bot => bot.OnTeam(teamName, method, displayName, friendlyFlags, + nameTagVisibility, collisionRule, color, prefix, suffix, players)); + } + + /// /// Called when the client received the Tab Header and Footer /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index a27c4b0a..0085725b 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -3035,6 +3035,84 @@ namespace MinecraftClient.Protocol.Handlers handler.OnUpdateScore(entityName, action3, objectiveName3, objectiveDisplayName3, objectiveValue2, numberFormat2); break; + case PacketTypesIn.Teams: + // Wire format per version: + // All versions: name (string), method (byte) + // method 0/2: displayName (component), options (byte), + // nameTagVisibility, collisionRule, color (VarInt), + // prefix (component), suffix (component) + // method 0/3/4: players list (VarInt count + strings) + // 1.21.9+ (protocol 773): nameTagVisibility and collisionRule are + // VarInt-encoded enum IDs instead of UTF strings. + var teamName = dataTypes.ReadNextString(packetData); + var teamMethod = dataTypes.ReadNextByte(packetData); + + var teamDisplayName = string.Empty; + byte teamFriendlyFlags = 0; + var teamNameTagVisibility = string.Empty; + var teamCollisionRule = string.Empty; + var teamColor = -1; + var teamPrefix = string.Empty; + var teamSuffix = string.Empty; + + if (teamMethod is 0 or 2) + { + teamDisplayName = dataTypes.ReadNextChat(packetData); + teamFriendlyFlags = dataTypes.ReadNextByte(packetData); + + // nameTagVisibility + if (protocolVersion >= MC_1_21_9_Version) + { + // STREAM_CODEC: 0=always, 1=never, 2=hideForOtherTeams, 3=hideForOwnTeam + teamNameTagVisibility = dataTypes.ReadNextVarInt(packetData) switch + { + 0 => "always", + 1 => "never", + 2 => "hideForOtherTeams", + 3 => "hideForOwnTeam", + _ => "always" + }; + } + else + { + teamNameTagVisibility = dataTypes.ReadNextString(packetData); + } + + // collisionRule + if (protocolVersion >= MC_1_21_9_Version) + { + // STREAM_CODEC: 0=always, 1=never, 2=pushOtherTeams, 3=pushOwnTeam + teamCollisionRule = dataTypes.ReadNextVarInt(packetData) switch + { + 0 => "always", + 1 => "never", + 2 => "pushOtherTeams", + 3 => "pushOwnTeam", + _ => "always" + }; + } + else + { + teamCollisionRule = dataTypes.ReadNextString(packetData); + } + + teamColor = dataTypes.ReadNextVarInt(packetData); + teamPrefix = dataTypes.ReadNextChat(packetData); + teamSuffix = dataTypes.ReadNextChat(packetData); + } + + var teamPlayers = new List(); + if (teamMethod is 0 or 3 or 4) + { + int playerCount = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < playerCount; i++) + teamPlayers.Add(dataTypes.ReadNextString(packetData)); + } + + handler.OnTeam(teamName, teamMethod, teamDisplayName, teamFriendlyFlags, + teamNameTagVisibility, teamCollisionRule, teamColor, + teamPrefix, teamSuffix, teamPlayers); + break; case PacketTypesIn.BlockChangedAck: handler.OnBlockChangeAck(dataTypes.ReadNextVarInt(packetData)); break; diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 13f5a628..bfaebe1d 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -489,6 +489,23 @@ namespace MinecraftClient.Protocol /// Number format: 0 - blank, 1 - styled, 2 - fixed void OnUpdateScore(string entityName, int action, string objectiveName, string objectiveDisplayName, int objectiveValue, int numberFormat); + /// + /// Called when a Teams packet is received from the server. + /// + /// Internal team name (up to 16 chars) + /// 0=create, 1=remove, 2=update, 3=add players, 4=remove players + /// Display name (formatted). Present when method is 0 or 2. + /// Bit 0=allowFriendlyFire, bit 1=seeFriendlyInvisibles. Present when method is 0 or 2. + /// Nametag visibility rule string. Present when method is 0 or 2. + /// Collision rule string. Present when method is 0 or 2. + /// ChatFormatting color value (-1=none). Present when method is 0 or 2. + /// Member name prefix (formatted). Present when method is 0 or 2. + /// Member name suffix (formatted). Present when method is 0 or 2. + /// Player/entity names. Present when method is 0, 3, or 4. + void OnTeam(string teamName, byte method, string displayName, byte friendlyFlags, + string nameTagVisibility, string collisionRule, int color, + string prefix, string suffix, List players); + /// /// Called when the client received the Tab Header and Footer /// diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index de6784ae..96e143d3 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -4660,6 +4660,51 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to List all scoreboard teams and their members. + /// + internal static string cmd_teams_desc { + get { + return ResourceManager.GetString("cmd.teams.desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No teams are currently tracked. + /// + internal static string cmd_teams_no_teams { + get { + return ResourceManager.GetString("cmd.teams.no_teams", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Team '{0}' (display: {1}, ...). + /// + internal static string cmd_teams_team_header { + get { + return ResourceManager.GetString("cmd.teams.team_header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Members ({0}): {1}. + /// + internal static string cmd_teams_team_members { + get { + return ResourceManager.GetString("cmd.teams.team_members", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No members. + /// + internal static string cmd_teams_team_no_members { + get { + return ResourceManager.GetString("cmd.teams.team_no_members", resourceCulture); + } + } + /// /// Looks up a localized string similar to Place a block or open chest. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index fddf6400..f25a6165 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -1562,6 +1562,21 @@ You can use "/chunk status {0:0.0} {1:0.0} {2:0.0}" to check the chunk loading s Display server current tps (tick per second). May not be accurate + + List all scoreboard teams and their members. + + + No teams are currently tracked. + + + Team '{0}' (display: {1}, color: {2}, prefix: '{3}', suffix: '{4}', nameTagVisibility: {5}, collisionRule: {6}, friendlyFire: {7}, seeInvisibles: {8}) + + + Members ({0}): {1} + + + No members. + Place a block or open chest diff --git a/MinecraftClient/Scripting/ChatBot.cs b/MinecraftClient/Scripting/ChatBot.cs index c5950334..3dc27c40 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -384,6 +384,23 @@ namespace MinecraftClient.Scripting /// Number format: 0 - blank, 1 - styled, 2 - fixed public virtual void OnUpdateScore(string entityName, int action, string objectiveName, string objectiveDisplayName, int value, int numberFormat) { } + /// + /// Called when a Teams packet is received from the server. + /// + /// Internal team name (up to 16 chars) + /// 0=create, 1=remove, 2=update, 3=add players, 4=remove players + /// Display name (formatted). Present when method is 0 or 2. + /// Bit 0=allowFriendlyFire, bit 1=seeFriendlyInvisibles. Present when method is 0 or 2. + /// Nametag visibility rule. Present when method is 0 or 2. + /// Collision rule. Present when method is 0 or 2. + /// ChatFormatting color value (-1=none). Present when method is 0 or 2. + /// Member name prefix (formatted). Present when method is 0 or 2. + /// Member name suffix (formatted). Present when method is 0 or 2. + /// Player/entity names. Present when method is 0, 3, or 4. + public virtual void OnTeam(string teamName, byte method, string displayName, byte friendlyFlags, + string nameTagVisibility, string collisionRule, int color, + string prefix, string suffix, List players) { } + /// /// Called when the client received the Tab Header and Footer /// From 4c54d2bbb71bafd88442874b0a066f43d58a5997 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 00:02:38 +0000 Subject: [PATCH 310/484] docs: add /teams command entry and scoreboard teams bot API section Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/5dff6cc2-149d-431b-b0b1-2b29128a428e Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- docs/guide/creating-bots.md | 62 +++++++++++++++++++++++++++++++++++++ docs/guide/usage.md | 24 ++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/docs/guide/creating-bots.md b/docs/guide/creating-bots.md index ed35d549..076f4600 100644 --- a/docs/guide/creating-bots.md +++ b/docs/guide/creating-bots.md @@ -281,6 +281,68 @@ public class AchievementWatcher : ChatBot } ``` +## Scoreboard teams + +Chat bots and C# scripts can read the current team state and react to team changes. + +Useful methods and events: + +- `GetTeams()` - returns a snapshot of all teams the server has sent +- `GetPlayerTeam(playerName)` - returns the team a specific player is on, or `null` +- `OnTeam(teamName, method, displayName, friendlyFlags, nameTagVisibility, collisionRule, color, prefix, suffix, players)` - called whenever a team packet arrives + +The `method` byte tells you what changed: + +- `0` - team created (includes full parameters and initial member list) +- `1` - team removed +- `2` - team parameters updated (display name, colors, rules) +- `3` - players added to the team +- `4` - players removed from the team + +The `color` field is a `ChatFormatting` enum ordinal. Common values: `0`=black, `9`=blue, `10`=green, `12`=red, `14`=yellow, `-1`=none/reset. + +The `nameTagVisibility` and `collisionRule` strings take values from the Minecraft wiki: `"always"`, `"never"`, `"hideForOtherTeams"`, `"hideForOwnTeam"` (visibility) or `"pushOtherTeams"`, `"pushOwnTeam"` (collision). + +Example: + +```csharp +//MCCScript 1.0 + +MCC.LoadBot(new TeamWatcher()); + +//MCCScript Extensions + +public class TeamWatcher : ChatBot +{ + public override void AfterGameJoined() + { + foreach (var team in GetTeams().Values) + LogToConsole($"Team '{team.Name}' has {team.Members.Count} member(s)"); + } + + public override void OnTeam(string teamName, byte method, string displayName, + byte friendlyFlags, string nameTagVisibility, string collisionRule, + int color, string prefix, string suffix, List players) + { + switch (method) + { + case 0: + LogToConsole($"Team '{teamName}' created with {players.Count} member(s)"); + break; + case 1: + LogToConsole($"Team '{teamName}' removed"); + break; + case 3: + LogToConsole($"{string.Join(", ", players)} joined team '{teamName}'"); + break; + case 4: + LogToConsole($"{string.Join(", ", players)} left team '{teamName}'"); + break; + } + } +} +``` + ## C# API The authoritative reference for the C# API is [ChatBot.cs](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/Scripting/ChatBot.cs). diff --git a/docs/guide/usage.md b/docs/guide/usage.md index e0e4a0ea..24478acb 100644 --- a/docs/guide/usage.md +++ b/docs/guide/usage.md @@ -953,6 +953,30 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q +
+teams + +- **Description:** + + List all scoreboard teams the server has sent, along with their members and settings. + +- **Usage:** + + ``` + /teams + ``` + +- **Example output:** + + ``` + Team 'RedTeam' (display: RedTeam, color: 12, prefix: '', suffix: '', nameTagVisibility: always, collisionRule: always, friendlyFire: True, seeInvisibles: True) + Members (2): Steve, Alex + Team 'BlueTeam' (display: BlueTeam, color: 9, prefix: '', suffix: '', nameTagVisibility: always, collisionRule: always, friendlyFire: True, seeInvisibles: True) + No members. + ``` + +
+
useitem From 65dec596872fe32c836d417fcf1e1ef14ee2cef0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:14:25 +0000 Subject: [PATCH 311/484] Initial plan From 1a86655dfbab6ebe90cea41fd8abb9b12bbbc0d7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:44:23 +0000 Subject: [PATCH 312/484] feat: add autodig tool switching Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/e83f9c2a-a85c-4763-821b-c5b4a0db75a6 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/ChatBots/AutoDig.cs | 112 +++++++++++++++++- .../Translations/Translations.Designer.cs | 18 +++ .../Resources/Translations/Translations.resx | 6 + docs/guide/chat-bots.md | 40 +++++++ 4 files changed, 173 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index 67d0b199..4af2d90d 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -5,7 +5,9 @@ using System.Threading; using Brigadier.NET.Builder; using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler.Patch; +using MinecraftClient.Inventory; using MinecraftClient.Mapping; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; using MinecraftClient.Scripting; using Tomlet.Attributes; @@ -25,15 +27,12 @@ namespace MinecraftClient.ChatBots public bool Enabled = false; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Auto_Tool_Switch$")] public bool Auto_Tool_Switch = false; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Durability_Limit$")] public int Durability_Limit = 2; - [NonSerialized] [TomlInlineComment("$ChatBot.AutoDig.Drop_Low_Durability_Tools$")] public bool Drop_Low_Durability_Tools = false; @@ -65,6 +64,8 @@ namespace MinecraftClient.ChatBots public void OnSettingUpdate() { + Durability_Limit = Math.Max(0, Durability_Limit); + if (Auto_Start_Delay >= 0) Auto_Start_Delay = Math.Max(0.1, Auto_Start_Delay); @@ -225,6 +226,102 @@ namespace MinecraftClient.ChatBots } } + private static int GetLegacyMaxDamage(ItemType itemType) + { + return itemType switch + { + ItemType.WoodenPickaxe or ItemType.WoodenAxe or ItemType.WoodenShovel or ItemType.WoodenSword or ItemType.WoodenHoe => 59, + ItemType.StonePickaxe or ItemType.StoneAxe or ItemType.StoneShovel or ItemType.StoneSword or ItemType.StoneHoe => 131, + ItemType.IronPickaxe or ItemType.IronAxe or ItemType.IronShovel or ItemType.IronSword or ItemType.IronHoe => 250, + ItemType.GoldenPickaxe or ItemType.GoldenAxe or ItemType.GoldenShovel or ItemType.GoldenSword or ItemType.GoldenHoe => 32, + ItemType.DiamondPickaxe or ItemType.DiamondAxe or ItemType.DiamondShovel or ItemType.DiamondSword or ItemType.DiamondHoe => 1561, + ItemType.NetheritePickaxe or ItemType.NetheriteAxe or ItemType.NetheriteShovel or ItemType.NetheriteSword or ItemType.NetheriteHoe => 2031, + ItemType.Shears => 238, + _ => 0 + }; + } + + private static int GetMaxDamage(Item item) + { + if (item.Components is not null) + { + var maxDamageComponent = item.Components.OfType().FirstOrDefault(); + if (maxDamageComponent is not null) + return maxDamageComponent.MaxDamage; + } + + return GetLegacyMaxDamage(item.Type); + } + + private static int GetRemainingDurability(Item item) + { + int maxDamage = GetMaxDamage(item); + return maxDamage > 0 ? maxDamage - item.Damage : int.MaxValue; + } + + private bool HasEnoughDurability(Item item) + { + return Config.Durability_Limit <= 0 || GetRemainingDurability(item) >= Config.Durability_Limit; + } + + private bool IsBelowDurabilityLimit(Item? item) + { + return item is not null && Config.Durability_Limit > 0 && GetRemainingDurability(item) < Config.Durability_Limit; + } + + private static bool IsRecommendedTool(Item? item, ItemType[] recommendedTools) + { + return item is not null && recommendedTools.Contains(item.Type); + } + + private bool SwapToolIntoHand(int sourceSlot, int handSlot) + { + return WindowAction(0, sourceSlot, WindowActionType.LeftClick) + && WindowAction(0, handSlot, WindowActionType.LeftClick) + && WindowAction(0, sourceSlot, WindowActionType.LeftClick); + } + + private bool EnsureSuitableTool(Material blockType) + { + if (!inventoryEnabled || !Config.Auto_Tool_Switch) + return true; + + ItemType[] recommendedTools = Material2Tool.GetCorrectToolForBlock(blockType); + if (recommendedTools.Length == 0) + return true; + + Container container = GetPlayerInventory(); + int handSlot = 36 + GetCurrentSlot(); + container.Items.TryGetValue(handSlot, out Item? currentTool); + + if (IsRecommendedTool(currentTool, recommendedTools) && currentTool is not null && HasEnoughDurability(currentTool)) + return true; + + foreach (ItemType recommendedTool in recommendedTools) + { + foreach ((int slot, Item item) in container.Items) + { + if (slot == handSlot || item.Type != recommendedTool || !HasEnoughDurability(item)) + continue; + + if (!SwapToolIntoHand(slot, handSlot)) + return false; + + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, slot, item.GetTypeString())); + + if (Config.Drop_Low_Durability_Tools && IsBelowDurabilityLimit(currentTool) && + WindowAction(0, slot, WindowActionType.DropItemStack)) + { + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_drop_low_durability, currentTool!.GetTypeString(), slot)); + } + + return true; + } + } + + return !IsBelowDurabilityLimit(currentTool); + } + public override void Update() { lock (stateLock) @@ -293,6 +390,9 @@ namespace MinecraftClient.ChatBots if (Config.Mode == Configs.ModeType.lookat || (Config.Mode == Configs.ModeType.both && Config._Locations.Contains(blockLoc))) { + if (!EnsureSuitableTool(block.Type)) + return false; + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: false)) { currentDig = blockLoc; @@ -354,6 +454,9 @@ namespace MinecraftClient.ChatBots if (minDistance <= 6.0) { + if (!EnsureSuitableTool(targetBlock.Type)) + return false; + if (DigBlock(target, Direction.Down, lookAtBlock: true)) { currentDig = target; @@ -388,6 +491,9 @@ namespace MinecraftClient.ChatBots ((Config.List_Type == Configs.ListType.whitelist && Config.Blocks.Contains(block.Type)) || (Config.List_Type == Configs.ListType.blacklist && !Config.Blocks.Contains(block.Type)))) { + if (!EnsureSuitableTool(block.Type)) + return false; + if (DigBlock(blockLoc, Direction.Down, lookAtBlock: true)) { currentDig = blockLoc; diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 96e143d3..8259988c 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -437,6 +437,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Dropped low durability {0} from slot {1}.. + /// + internal static string bot_autodig_drop_low_durability { + get { + return ResourceManager.GetString("bot.autodig.drop_low_durability", resourceCulture); + } + } + /// /// Looks up a localized string similar to The block currently pointed to is not in the allowed list.. /// @@ -473,6 +482,15 @@ namespace MinecraftClient { } } + /// + /// Looks up a localized string similar to Switch to {1} from slot {0}.. + /// + internal static string bot_autodig_switch { + get { + return ResourceManager.GetString("bot.autodig.switch", resourceCulture); + } + } + /// /// Looks up a localized string similar to Added item {0}. /// diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index f25a6165..31e29fc8 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -243,6 +243,9 @@ Inventory handling is not enabled. Unable to switch tools automatically. + + Dropped low durability {0} from slot {1}. + Automatic digging has started. @@ -252,6 +255,9 @@ Auto-digging has been stopped. + + Switch to {1} from slot {0}. + Added item {0} diff --git a/docs/guide/chat-bots.md b/docs/guide/chat-bots.md index e8b6c711..3c725a7a 100644 --- a/docs/guide/chat-bots.md +++ b/docs/guide/chat-bots.md @@ -748,6 +748,46 @@ redirectFrom: - **Default:** `3.0` + #### `Auto_Tool_Switch` + + - **Description:** + + Automatically switch to a more suitable tool from your inventory before digging. + + When `Durability_Limit` is above zero, tools below that durability threshold are skipped. + + - **Available values:** `true` and `false` + + - **Type:** `boolean` + + - **Default:** `false` + + #### `Durability_Limit` + + - **Description:** + + Will not use tools with less durability than this. + + Set to `0` to disable this durability check. + + - **Type:** `integer` + + - **Default:** `2` + + #### `Drop_Low_Durability_Tools` + + - **Description:** + + Drop the replaced tool if its remaining durability is below `Durability_Limit`. + + This setting is only useful when `Auto_Tool_Switch` is enabled. + + - **Available values:** `true` and `false` + + - **Type:** `boolean` + + - **Default:** `false` + #### `Dig_Timeout` - **Description:** From 737a94475ad1613f73d031ac777f2dcaa8911b6f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:50:43 +0000 Subject: [PATCH 313/484] fix: clarify autodig switch log formatting Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/e83f9c2a-a85c-4763-821b-c5b4a0db75a6 Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> --- MinecraftClient/ChatBots/AutoDig.cs | 4 ++-- .../Resources/Translations/Translations.Designer.cs | 2 +- MinecraftClient/Resources/Translations/Translations.resx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MinecraftClient/ChatBots/AutoDig.cs b/MinecraftClient/ChatBots/AutoDig.cs index 4af2d90d..148335d5 100644 --- a/MinecraftClient/ChatBots/AutoDig.cs +++ b/MinecraftClient/ChatBots/AutoDig.cs @@ -294,7 +294,7 @@ namespace MinecraftClient.ChatBots int handSlot = 36 + GetCurrentSlot(); container.Items.TryGetValue(handSlot, out Item? currentTool); - if (IsRecommendedTool(currentTool, recommendedTools) && currentTool is not null && HasEnoughDurability(currentTool)) + if (currentTool is not null && IsRecommendedTool(currentTool, recommendedTools) && HasEnoughDurability(currentTool)) return true; foreach (ItemType recommendedTool in recommendedTools) @@ -307,7 +307,7 @@ namespace MinecraftClient.ChatBots if (!SwapToolIntoHand(slot, handSlot)) return false; - LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, slot, item.GetTypeString())); + LogToConsole(GetTimestamp() + ": " + string.Format(Translations.bot_autodig_switch, item.GetTypeString(), slot)); if (Config.Drop_Low_Durability_Tools && IsBelowDurabilityLimit(currentTool) && WindowAction(0, slot, WindowActionType.DropItemStack)) diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs index 8259988c..02447274 100644 --- a/MinecraftClient/Resources/Translations/Translations.Designer.cs +++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs @@ -483,7 +483,7 @@ namespace MinecraftClient { } /// - /// Looks up a localized string similar to Switch to {1} from slot {0}.. + /// Looks up a localized string similar to Switch to {0} from slot {1}.. /// internal static string bot_autodig_switch { get { diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx index 31e29fc8..c9c53ae6 100644 --- a/MinecraftClient/Resources/Translations/Translations.resx +++ b/MinecraftClient/Resources/Translations/Translations.resx @@ -256,7 +256,7 @@ Auto-digging has been stopped. - Switch to {1} from slot {0}. + Switch to {0} from slot {1}. Added item {0} From ee6eb84bd881b7fdfd3aaaa09fa2b68753f5c773 Mon Sep 17 00:00:00 2001 From: milutinke Date: Wed, 1 Apr 2026 12:49:07 +0200 Subject: [PATCH 314/484] Improved the Web Based Harness --- .../Api/MccPlaygroundEndpoints.cs | 36 + .../Contracts/MccContracts.cs | 94 ++ .../Harness/MccAgentRunService.cs | 852 ++++++++++++ .../Harness/MccContextCompressor.cs | 21 + .../Harness/MccFinalizer.cs | 221 ++++ .../Harness/MccGuidanceSource.cs | 63 + .../Harness/MccPromptComposer.cs | 86 ++ .../Harness/MccRunState.cs | 103 ++ .../Harness/MccToolPolicy.cs | 133 ++ .../Harness/MccWebHarnessOptions.cs | 58 + .../Mcp/MccMcpSessionFactory.cs | 200 +++ .../OpenRouter/OpenRouterChatClient.cs | 120 ++ DebugTools/MccMcpWebPlayground/Program.cs | 1149 +---------------- .../appsettings.Development.json | 6 + .../MccMcpWebPlayground/appsettings.json | 15 + DebugTools/MccMcpWebPlayground/wwwroot/app.js | 310 +++++ .../MccMcpWebPlayground/wwwroot/index.html | 1120 +--------------- .../MccMcpWebPlayground/wwwroot/site.css | 383 ++++++ MinecraftClient/Mcp/MccMcpGuidanceProvider.cs | 31 +- 19 files changed, 2799 insertions(+), 2202 deletions(-) create mode 100644 DebugTools/MccMcpWebPlayground/Api/MccPlaygroundEndpoints.cs create mode 100644 DebugTools/MccMcpWebPlayground/Contracts/MccContracts.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccAgentRunService.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccContextCompressor.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccFinalizer.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccGuidanceSource.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccPromptComposer.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccRunState.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccToolPolicy.cs create mode 100644 DebugTools/MccMcpWebPlayground/Harness/MccWebHarnessOptions.cs create mode 100644 DebugTools/MccMcpWebPlayground/Infrastructure/Mcp/MccMcpSessionFactory.cs create mode 100644 DebugTools/MccMcpWebPlayground/Infrastructure/OpenRouter/OpenRouterChatClient.cs create mode 100644 DebugTools/MccMcpWebPlayground/wwwroot/app.js create mode 100644 DebugTools/MccMcpWebPlayground/wwwroot/site.css diff --git a/DebugTools/MccMcpWebPlayground/Api/MccPlaygroundEndpoints.cs b/DebugTools/MccMcpWebPlayground/Api/MccPlaygroundEndpoints.cs new file mode 100644 index 00000000..ec3e0f83 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Api/MccPlaygroundEndpoints.cs @@ -0,0 +1,36 @@ +using DebugTools.MccMcpWebPlayground.Contracts; +using DebugTools.MccMcpWebPlayground.Harness; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; + +namespace DebugTools.MccMcpWebPlayground.Api; + +public static class MccPlaygroundEndpoints +{ + public static IEndpointRouteBuilder MapMccPlaygroundEndpoints(this IEndpointRouteBuilder endpoints) + { + RouteGroupBuilder api = endpoints.MapGroup("/api"); + + api.MapGet("/health", () => Results.Ok(new { ok = true })); + + api.MapGet("/config", (IOptions options) => + { + MccWebHarnessOptions harnessOptions = options.Value; + return Results.Ok(new MccConfigResponse( + Model: harnessOptions.ResolveModel(), + OpenRouterBaseUrl: harnessOptions.ResolveOpenRouterBaseUrl(), + McpEndpoint: harnessOptions.ResolveMcpEndpoint(), + HasApiKey: harnessOptions.HasApiKeyConfigured(), + ExposeInventoryWindowAction: harnessOptions.ExposeInventoryWindowAction, + ExposeInternalCommandTool: harnessOptions.ExposeInternalCommandTool)); + }); + + api.MapPost("/chat/stream", (ChatStreamRequest request, IMccAgentRunService runService, HttpContext httpContext, CancellationToken cancellationToken) => + { + return TypedResults.ServerSentEvents(runService.StreamAsync(request, httpContext, cancellationToken)); + }) + .WithRequestTimeout("mcc-stream"); + + return endpoints; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Contracts/MccContracts.cs b/DebugTools/MccMcpWebPlayground/Contracts/MccContracts.cs new file mode 100644 index 00000000..2257e1b1 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Contracts/MccContracts.cs @@ -0,0 +1,94 @@ +using System.Text.Json.Serialization; + +namespace DebugTools.MccMcpWebPlayground.Contracts; + +public sealed class ChatStreamRequest +{ + public List? Messages { get; set; } +} + +public sealed class ChatMessage +{ + public string Role { get; set; } = string.Empty; + public string Content { get; set; } = string.Empty; +} + +public sealed record MccConfigResponse( + string? Model, + string OpenRouterBaseUrl, + string McpEndpoint, + bool HasApiKey, + bool ExposeInventoryWindowAction, + bool ExposeInternalCommandTool); + +public sealed record MccStreamEnvelope(string RunId, long Sequence, string Kind, object Data); + +public sealed record MccRunStartedData(string Model, string McpEndpoint, DateTimeOffset StartedAtUtc); + +public sealed record MccGuidanceLoadedData( + string SourceTool, + string CanonicalPromptName, + string GuidanceVersion, + MccCapabilityStatus CapabilityStatus); + +public sealed record MccStateSummaryData( + int TurnCount, + int ToolCallCount, + bool SoftFinish, + int DirectAnswerAttempts, + IReadOnlyList OpenVerification, + IReadOnlyList RecentEvidence, + string? CompactionSummary); + +public sealed record MccToolCalledData(string CallId, string Name, string ArgumentsJson, bool Advanced, bool Sensitive); + +public sealed record MccToolResultData( + string CallId, + string Name, + bool IsError, + bool Success, + string? ErrorCode, + string Summary, + string RawText, + string EvidenceId); + +public sealed record MccVerificationEventData(string ObligationId, string ToolName, string Kind, string Description); + +public sealed record MccBudgetData( + int TurnCount, + int MaxTurns, + int ToolCallCount, + int MaxToolCalls, + double ElapsedSeconds, + int MaxWallClockSeconds); + +public sealed record MccErrorData(string Code, string Message, string? Detail = null); + +public sealed record MccFinalPayload( + string Status, + string Headline, + string AnswerMarkdown, + IReadOnlyList VerifiedFacts, + IReadOnlyList OpenIssues, + IReadOnlyList EvidenceIds, + string? NextAction); + +public sealed record MccSubmitFinalArgs( + string Status, + string Headline, + string AnswerMarkdown, + IReadOnlyList VerifiedFacts, + IReadOnlyList OpenIssues, + IReadOnlyList EvidenceIds, + string? NextAction); + +public sealed record MccCapabilityStatus( + [property: JsonPropertyName("sessionStatus")] bool SessionStatus, + [property: JsonPropertyName("chatAndCommands")] bool ChatAndCommands, + [property: JsonPropertyName("movement")] bool Movement, + [property: JsonPropertyName("inventory")] bool Inventory, + [property: JsonPropertyName("entityWorld")] bool EntityWorld); + +public sealed record MccEvidenceView(string Id, string ToolName, string Summary, bool IsError); + +public sealed record MccVerificationObligationView(string Id, string ToolName, string Kind, string Description); diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccAgentRunService.cs b/DebugTools/MccMcpWebPlayground/Harness/MccAgentRunService.cs new file mode 100644 index 00000000..33259389 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccAgentRunService.cs @@ -0,0 +1,852 @@ +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Net.ServerSentEvents; +using System.Text; +using System.Text.Json; +using DebugTools.MccMcpWebPlayground.Contracts; +using DebugTools.MccMcpWebPlayground.Infrastructure.Mcp; +using DebugTools.MccMcpWebPlayground.Infrastructure.OpenRouter; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol; + +namespace DebugTools.MccMcpWebPlayground.Harness; + +public interface IMccAgentRunService +{ + IAsyncEnumerable> StreamAsync(ChatStreamRequest request, HttpContext httpContext, CancellationToken cancellationToken); +} + +public sealed class MccAgentRunService : IMccAgentRunService +{ + private readonly MccMcpSessionFactory sessionFactory; + private readonly MccGuidanceSource guidanceSource; + private readonly MccPromptComposer promptComposer; + private readonly MccContextCompressor contextCompressor; + private readonly MccFinalizer finalizer; + private readonly OpenRouterChatClient openRouterChatClient; + private readonly MccWebHarnessOptions options; + + public MccAgentRunService( + MccMcpSessionFactory sessionFactory, + MccGuidanceSource guidanceSource, + MccPromptComposer promptComposer, + MccContextCompressor contextCompressor, + MccFinalizer finalizer, + OpenRouterChatClient openRouterChatClient, + IOptions options) + { + this.sessionFactory = sessionFactory; + this.guidanceSource = guidanceSource; + this.promptComposer = promptComposer; + this.contextCompressor = contextCompressor; + this.finalizer = finalizer; + this.openRouterChatClient = openRouterChatClient; + this.options = options.Value; + } + + public async IAsyncEnumerable> StreamAsync( + ChatStreamRequest request, + HttpContext httpContext, + [EnumeratorCancellation] CancellationToken cancellationToken) + { + using CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, httpContext.RequestAborted); + CancellationToken linkedToken = linkedCts.Token; + + string runId = Guid.NewGuid().ToString("n"); + long sequence = 0; + + string? model = options.ResolveModel(); + if (string.IsNullOrWhiteSpace(model)) + { + yield return CreateEvent(runId, ref sequence, "error", new MccErrorData("configuration_error", "OPENROUTER_MODEL or MccWebHarness:Model must be configured.")); + yield break; + } + + if (!options.HasApiKeyConfigured()) + { + yield return CreateEvent(runId, ref sequence, "error", new MccErrorData("configuration_error", "OPENROUTER_API_KEY is not set.")); + yield break; + } + + List baseConversationMessages = NormalizeConversation(request.Messages); + string userRequest = ExtractUserRequest(request.Messages); + if (string.IsNullOrWhiteSpace(userRequest)) + { + yield return CreateEvent(runId, ref sequence, "error", new MccErrorData("invalid_request", "No user message was provided.")); + yield break; + } + + await using McpClient client = await sessionFactory.CreateAsync(linkedToken); + MccGuidanceBundle guidance = await guidanceSource.LoadAsync(client, linkedToken); + + MccRunState runState = new() + { + RunId = runId, + UserRequest = userRequest, + BaseConversationMessages = baseConversationMessages, + ConfiguredModel = model, + Guidance = guidance + }; + + yield return CreateEvent(runId, ref sequence, "run_started", new MccRunStartedData(model, options.ResolveMcpEndpoint(), runState.StartedAtUtc)); + yield return CreateEvent(runId, ref sequence, "guidance_loaded", new MccGuidanceLoadedData( + guidance.SourceToolName, + guidance.CanonicalPromptName, + guidance.GuidanceVersion, + guidance.CapabilityStatus)); + + IList tools = await client.ListToolsAsync(cancellationToken: linkedToken); + MccToolCatalog catalog = MccToolPolicy.BuildCatalog(tools, options, finalizer.BuildSubmitToolSchema()); + + while (!linkedToken.IsCancellationRequested) + { + runState.TurnCount++; + contextCompressor.CompactIfNeeded(runState); + yield return CreateEvent(runId, ref sequence, "state_summary", BuildStateSummary(runState, options)); + + if (runState.IsSoftFinish(options, DateTimeOffset.UtcNow)) + { + yield return CreateEvent(runId, ref sequence, "budget", BuildBudgetData(runState)); + } + + if (runState.IsHardStop(options, DateTimeOffset.UtcNow)) + break; + + MccModelTurn? turn = null; + Exception? providerException = null; + try + { + turn = await openRouterChatClient.CreateTurnAsync( + promptComposer.Compose(runState), + catalog.ModelVisibleTools, + options, + linkedToken); + } + catch (Exception ex) + { + providerException = ex; + } + + if (providerException is not null || turn is null) + { + yield return CreateEvent(runId, ref sequence, "error", new MccErrorData("provider_error", "OpenRouter request failed.", providerException?.Message)); + yield return CreateEvent(runId, ref sequence, "final", finalizer.BuildHardStopResult(runState, options)); + yield break; + } + + runState.RoutedModel = turn.ModelId; + runState.RoutedProvider = turn.RoutedProvider; + + if (turn.ToolCalls.Count == 0) + { + runState.DirectAnswerAttempts++; + string content = string.IsNullOrWhiteSpace(turn.AssistantContent) ? "(empty assistant turn)" : turn.AssistantContent.Trim(); + runState.ToolConversationMessages.Add(new Dictionary + { + ["role"] = "assistant", + ["content"] = content + }); + + if (runState.DirectAnswerAttempts >= 4) + { + yield return CreateEvent(runId, ref sequence, "error", new MccErrorData( + "model_protocol_error", + "The model kept returning plain assistant text instead of using tools or mcc_submit_final.", + content)); + yield return CreateEvent(runId, ref sequence, "final", finalizer.BuildHardStopResult(runState, options)); + yield break; + } + + runState.ToolConversationMessages.Add(new Dictionary + { + ["role"] = "user", + ["content"] = "The previous plain assistant text was not accepted by this harness. On your next turn, you must either call the relevant MCC tools or call mcc_submit_final. Do not answer with plain assistant text again." + }); + continue; + } + + Dictionary assistantMessage = new() + { + ["role"] = "assistant", + ["content"] = turn.AssistantContent, + ["tool_calls"] = turn.ToolCalls.Select(call => new Dictionary + { + ["id"] = call.CallId, + ["type"] = "function", + ["function"] = new Dictionary + { + ["name"] = call.Name, + ["arguments"] = call.ArgumentsJson + } + }).ToArray() + }; + runState.ToolConversationMessages.Add(assistantMessage); + + foreach (MccModelToolCall toolCall in turn.ToolCalls) + { + MccToolProfile profile = MccToolPolicy.GetProfile(toolCall.Name); + yield return CreateEvent(runId, ref sequence, "tool_called", new MccToolCalledData( + toolCall.CallId, + toolCall.Name, + toolCall.ArgumentsJson, + profile.Risk == MccToolRisk.EscapeHatch, + profile.Risk == MccToolRisk.Sensitive)); + + if (toolCall.Name.Equals("mcc_submit_final", StringComparison.OrdinalIgnoreCase)) + { + MccFinalizationValidation validation = finalizer.Validate(runState, toolCall.ArgumentsJson); + if (validation.Accepted) + { + yield return CreateEvent(runId, ref sequence, "final", validation.Payload!); + yield break; + } + + string localResultText = JsonSerializer.Serialize(new + { + success = false, + errorCode = "invalid_final_submission", + message = validation.ErrorText + }); + runState.ToolConversationMessages.Add(BuildToolMessage(toolCall.CallId, localResultText)); + yield return CreateEvent(runId, ref sequence, "tool_result", new MccToolResultData( + toolCall.CallId, + toolCall.Name, + IsError: true, + Success: false, + ErrorCode: "invalid_final_submission", + Summary: validation.ErrorText ?? "Invalid final submission.", + RawText: localResultText, + EvidenceId: string.Empty)); + continue; + } + + if (MccToolPolicy.RequiresExplicitUserIntent(toolCall.Name) && !MccToolPolicy.HasExplicitUserIntent(runState.UserRequest, toolCall.Name)) + { + string localResultText = JsonSerializer.Serialize(new + { + success = false, + errorCode = "explicit_user_intent_required", + message = $"Tool '{toolCall.Name}' requires explicit user intent." + }); + runState.ToolConversationMessages.Add(BuildToolMessage(toolCall.CallId, localResultText)); + yield return CreateEvent(runId, ref sequence, "tool_result", new MccToolResultData( + toolCall.CallId, + toolCall.Name, + IsError: true, + Success: false, + ErrorCode: "explicit_user_intent_required", + Summary: $"Tool '{toolCall.Name}' requires explicit user intent.", + RawText: localResultText, + EvidenceId: string.Empty)); + continue; + } + + if (!catalog.ToolsByName.TryGetValue(toolCall.Name, out MccToolCatalogEntry? entry)) + { + string unknownToolText = JsonSerializer.Serialize(new + { + success = false, + errorCode = "unknown_tool", + message = $"Unknown tool '{toolCall.Name}'." + }); + runState.ToolConversationMessages.Add(BuildToolMessage(toolCall.CallId, unknownToolText)); + yield return CreateEvent(runId, ref sequence, "tool_result", new MccToolResultData( + toolCall.CallId, + toolCall.Name, + IsError: true, + Success: false, + ErrorCode: "unknown_tool", + Summary: $"Unknown tool '{toolCall.Name}'.", + RawText: unknownToolText, + EvidenceId: string.Empty)); + continue; + } + + CallToolResult? result = null; + Exception? toolException = null; + try + { + Dictionary arguments = MccJsonArguments.Parse(toolCall.ArgumentsJson); + result = await client.CallToolAsync(toolCall.Name, arguments, cancellationToken: linkedToken); + } + catch (Exception ex) + { + toolException = ex; + } + + if (toolException is not null || result is null) + { + string failedText = JsonSerializer.Serialize(new + { + success = false, + errorCode = "tool_call_failed", + message = toolException?.Message + }); + runState.ToolConversationMessages.Add(BuildToolMessage(toolCall.CallId, failedText)); + yield return CreateEvent(runId, ref sequence, "tool_result", new MccToolResultData( + toolCall.CallId, + toolCall.Name, + IsError: true, + Success: false, + ErrorCode: "tool_call_failed", + Summary: toolException?.Message ?? "Tool call failed.", + RawText: failedText, + EvidenceId: string.Empty)); + continue; + } + + runState.ToolCallCount++; + MccNormalizedToolResult normalized = MccMcpJson.Normalize(result); + MccEvidenceRecord evidence = CreateEvidence(runState, toolCall.Name, normalized); + runState.Evidence.Add(evidence); + runState.ToolExecutions.Add(new MccToolExecutionRecord + { + CallId = toolCall.CallId, + ToolName = toolCall.Name, + ArgumentsJson = toolCall.ArgumentsJson, + Evidence = evidence + }); + + runState.ToolConversationMessages.Add(BuildToolMessage(toolCall.CallId, normalized.Text)); + + foreach (MccVerificationObligation obligation in CreateObligations(runState, evidence, toolCall.ArgumentsJson)) + { + runState.VerificationObligations.Add(obligation); + yield return CreateEvent(runId, ref sequence, "verification_required", new MccVerificationEventData( + obligation.Id, + obligation.ToolName, + obligation.Kind, + obligation.Description)); + + if (obligation.Cleared) + { + yield return CreateEvent(runId, ref sequence, "verification_cleared", new MccVerificationEventData( + obligation.Id, + obligation.ToolName, + obligation.Kind, + obligation.Description)); + } + } + + foreach (MccVerificationObligation cleared in TryClearObligationsFromEvidence(runState, evidence)) + { + yield return CreateEvent(runId, ref sequence, "verification_cleared", new MccVerificationEventData( + cleared.Id, + cleared.ToolName, + cleared.Kind, + cleared.Description)); + } + + yield return CreateEvent(runId, ref sequence, "tool_result", new MccToolResultData( + toolCall.CallId, + toolCall.Name, + evidence.IsError, + evidence.Success, + evidence.ErrorCode, + evidence.Summary, + evidence.RawText, + evidence.Id)); + } + } + + yield return CreateEvent(runId, ref sequence, "final", finalizer.BuildHardStopResult(runState, options)); + } + + private static List NormalizeConversation(List? incoming) + { + List messages = []; + if (incoming is null) + return messages; + + foreach (ChatMessage message in incoming) + { + if (string.IsNullOrWhiteSpace(message.Role) || string.IsNullOrWhiteSpace(message.Content)) + continue; + + string role = message.Role.Trim().ToLowerInvariant(); + if (role is not ("user" or "assistant" or "system")) + continue; + + messages.Add(new Dictionary + { + ["role"] = role, + ["content"] = message.Content.Trim() + }); + } + + return messages; + } + + private static string ExtractUserRequest(List? incoming) + { + return incoming? + .LastOrDefault(message => string.Equals(message.Role, "user", StringComparison.OrdinalIgnoreCase) + && !string.IsNullOrWhiteSpace(message.Content)) + ?.Content + ?.Trim() + ?? string.Empty; + } + + private static Dictionary BuildToolMessage(string callId, string content) + { + return new Dictionary + { + ["role"] = "tool", + ["tool_call_id"] = callId, + ["content"] = content + }; + } + + private static MccStateSummaryData BuildStateSummary(MccRunState runState, MccWebHarnessOptions options) + { + return new MccStateSummaryData( + TurnCount: runState.TurnCount, + ToolCallCount: runState.ToolCallCount, + SoftFinish: runState.IsSoftFinish(options, DateTimeOffset.UtcNow), + DirectAnswerAttempts: runState.DirectAnswerAttempts, + OpenVerification: runState.OpenObligations + .Select(obligation => new MccVerificationObligationView(obligation.Id, obligation.ToolName, obligation.Kind, obligation.Description)) + .ToArray(), + RecentEvidence: runState.Evidence + .TakeLast(6) + .Select(evidence => new MccEvidenceView(evidence.Id, evidence.ToolName, evidence.Summary, evidence.IsError)) + .ToArray(), + CompactionSummary: runState.CompactionSummary); + } + + private MccBudgetData BuildBudgetData(MccRunState runState) + { + return new MccBudgetData( + TurnCount: runState.TurnCount, + MaxTurns: options.MaxTurns, + ToolCallCount: runState.ToolCallCount, + MaxToolCalls: options.MaxToolCalls, + ElapsedSeconds: (DateTimeOffset.UtcNow - runState.StartedAtUtc).TotalSeconds, + MaxWallClockSeconds: options.MaxWallClockSeconds); + } + + private static MccEvidenceRecord CreateEvidence(MccRunState runState, string toolName, MccNormalizedToolResult result) + { + string summary = SummarizeEvidence(toolName, result); + return new MccEvidenceRecord + { + Id = runState.NextEvidenceId(), + ToolName = toolName, + Summary = summary, + RawText = result.Text, + IsError = result.IsError, + Success = result.Success, + ErrorCode = result.ErrorCode, + Root = result.Root, + Data = result.Data + }; + } + + private static string SummarizeEvidence(string toolName, MccNormalizedToolResult result) + { + if (result.Data is JsonElement data) + { + if ((toolName.Equals("mcc_move_to", StringComparison.OrdinalIgnoreCase) || toolName.Equals("mcc_move_to_player", StringComparison.OrdinalIgnoreCase)) + && TryReadBool(data, "arrived", out bool arrived)) + { + return arrived + ? $"movement verified; arrived={arrived}" + : $"movement not yet verified; arrived={arrived}"; + } + + if (toolName.Equals("mcc_dig_block", StringComparison.OrdinalIgnoreCase)) + { + bool destroyed = TryReadBool(data, "destroyed", out bool destroyedValue) && destroyedValue; + bool changed = TryReadBool(data, "changed", out bool changedValue) && changedValue; + return $"dig result changed={changed} destroyed={destroyed}"; + } + + if (toolName.Equals("mcc_items_pickup", StringComparison.OrdinalIgnoreCase)) + { + int successful = TryReadInt(data, "successfulPickups", out int successfulValue) ? successfulValue : 0; + int collected = TryReadInt(data, "collectedCount", out int collectedValue) ? collectedValue : 0; + return $"pickup result successfulPickups={successful} collectedCount={collected}"; + } + + if (toolName.Equals("mcc_container_open_at", StringComparison.OrdinalIgnoreCase) + && TryReadBool(data, "opened", out bool opened)) + { + return $"container open result opened={opened}"; + } + + if (toolName is "mcc_container_deposit_item" or "mcc_container_withdraw_item" or "mcc_inventory_drop_item") + { + int moved = TryReadInt(data, "movedCount", out int movedValue) + ? movedValue + : TryReadInt(data, "droppedCount", out int droppedValue) ? droppedValue : 0; + return $"{toolName} movedCount={moved}"; + } + } + + string prefix = result.IsError ? "error" : "ok"; + return $"{prefix}: {Truncate(result.Text.Replace('\n', ' '), 180)}"; + } + + private List CreateObligations(MccRunState runState, MccEvidenceRecord evidence, string argumentsJson) + { + List obligations = []; + JsonElement metadata = ParseArgumentsToJson(argumentsJson); + + if (evidence.ToolName.Equals("mcc_move_to", StringComparison.OrdinalIgnoreCase)) + { + MccVerificationObligation obligation = new() + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "movement", + Description = "Verify final player location for the requested move target.", + SourceEvidenceId = evidence.Id, + Metadata = BuildMoveMetadata(evidence, metadata), + Cleared = IsMovementVerified(evidence) + }; + obligations.Add(obligation); + return obligations; + } + + if (evidence.ToolName.Equals("mcc_move_to_player", StringComparison.OrdinalIgnoreCase)) + { + MccVerificationObligation obligation = new() + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "movement", + Description = "Verify final proximity to the requested player target.", + SourceEvidenceId = evidence.Id, + Metadata = BuildMoveToPlayerMetadata(evidence, metadata), + Cleared = IsMovementVerified(evidence) + }; + obligations.Add(obligation); + return obligations; + } + + if (evidence.ToolName.Equals("mcc_container_open_at", StringComparison.OrdinalIgnoreCase)) + { + obligations.Add(new MccVerificationObligation + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "container", + Description = "Verify that the target container is open and active.", + SourceEvidenceId = evidence.Id, + Metadata = null, + Cleared = IsContainerOpenVerified(evidence) + }); + return obligations; + } + + if (evidence.ToolName is "mcc_container_deposit_item" or "mcc_container_withdraw_item" or "mcc_inventory_drop_item") + { + obligations.Add(new MccVerificationObligation + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "inventory", + Description = "Verify the requested inventory delta.", + SourceEvidenceId = evidence.Id, + Metadata = evidence.Data, + Cleared = IsInventoryVerified(evidence) + }); + return obligations; + } + + if (evidence.ToolName.Equals("mcc_items_pickup", StringComparison.OrdinalIgnoreCase)) + { + obligations.Add(new MccVerificationObligation + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "pickup", + Description = "Verify that the requested dropped items were picked up.", + SourceEvidenceId = evidence.Id, + Metadata = evidence.Data, + Cleared = IsPickupVerified(evidence) + }); + return obligations; + } + + if (evidence.ToolName.Equals("mcc_dig_block", StringComparison.OrdinalIgnoreCase)) + { + obligations.Add(new MccVerificationObligation + { + Id = runState.NextObligationId(), + ToolName = evidence.ToolName, + Kind = "block_change", + Description = "Verify that the target block changed state after digging.", + SourceEvidenceId = evidence.Id, + Metadata = evidence.Data, + Cleared = IsDigVerified(evidence) + }); + } + + return obligations; + } + + private List TryClearObligationsFromEvidence(MccRunState runState, MccEvidenceRecord evidence) + { + List cleared = []; + foreach (MccVerificationObligation obligation in runState.OpenObligations) + { + if (obligation.Cleared) + continue; + + if (obligation.Kind == "movement" && TryClearMovementObligation(obligation, evidence)) + { + obligation.Cleared = true; + obligation.ClearedByEvidenceId = evidence.Id; + cleared.Add(obligation); + continue; + } + + if (obligation.Kind == "block_change" && TryClearDigObligation(obligation, evidence)) + { + obligation.Cleared = true; + obligation.ClearedByEvidenceId = evidence.Id; + cleared.Add(obligation); + } + } + + return cleared; + } + + private static bool TryClearMovementObligation(MccVerificationObligation obligation, MccEvidenceRecord evidence) + { + if (evidence.ToolName.Equals("mcc_player_state", StringComparison.OrdinalIgnoreCase) + && evidence.Data is JsonElement data + && data.TryGetProperty("location", out JsonElement location) + && obligation.Metadata is JsonElement metadata) + { + if (obligation.ToolName.Equals("mcc_move_to", StringComparison.OrdinalIgnoreCase) + && metadata.TryGetProperty("x", out JsonElement targetX) + && metadata.TryGetProperty("y", out JsonElement targetY) + && metadata.TryGetProperty("z", out JsonElement targetZ)) + { + double tolerance = metadata.TryGetProperty("tolerance", out JsonElement toleranceElement) && toleranceElement.TryGetDouble(out double tol) ? tol : 1.5; + return TryReadDouble(location, "x", out double x) + && TryReadDouble(location, "y", out double y) + && TryReadDouble(location, "z", out double z) + && Distance(x, y, z, targetX.GetDouble(), targetY.GetDouble(), targetZ.GetDouble()) <= tolerance; + } + } + + if (evidence.ToolName.Equals("mcc_player_locate", StringComparison.OrdinalIgnoreCase) + && obligation.ToolName.Equals("mcc_move_to_player", StringComparison.OrdinalIgnoreCase) + && evidence.Data is JsonElement playerData + && obligation.Metadata is JsonElement playerMetadata) + { + string? expectedName = playerMetadata.TryGetProperty("playerName", out JsonElement nameElement) ? nameElement.GetString() : null; + string? matchedName = playerData.TryGetProperty("matchedName", out JsonElement matchedNameElement) ? matchedNameElement.GetString() : null; + if (!string.IsNullOrWhiteSpace(expectedName) && !string.Equals(expectedName, matchedName, StringComparison.OrdinalIgnoreCase)) + return false; + + if (TryReadDouble(playerData, "distance", out double distance)) + { + double tolerance = playerMetadata.TryGetProperty("tolerance", out JsonElement toleranceElement) && toleranceElement.TryGetDouble(out double tol) ? tol : 2.0; + return distance <= tolerance; + } + } + + return false; + } + + private static bool TryClearDigObligation(MccVerificationObligation obligation, MccEvidenceRecord evidence) + { + if (!evidence.ToolName.Equals("mcc_world_block_at", StringComparison.OrdinalIgnoreCase) + || evidence.Data is not JsonElement data + || obligation.Metadata is not JsonElement metadata) + { + return false; + } + + if (!metadata.TryGetProperty("target", out JsonElement target) + || !TryReadDouble(target, "x", out double x) + || !TryReadDouble(target, "y", out double y) + || !TryReadDouble(target, "z", out double z)) + { + return false; + } + + return TryReadInt(data, "x", out int blockX) + && TryReadInt(data, "y", out int blockY) + && TryReadInt(data, "z", out int blockZ) + && Math.Abs(blockX - x) < 0.5 + && Math.Abs(blockY - y) < 0.5 + && Math.Abs(blockZ - z) < 0.5 + && data.TryGetProperty("block", out JsonElement block) + && block.TryGetProperty("material", out JsonElement material) + && !string.Equals(material.GetString(), "Air", StringComparison.OrdinalIgnoreCase); + } + + private static bool IsMovementVerified(MccEvidenceRecord evidence) + { + if (evidence.Data is not JsonElement data) + return false; + + if (TryReadBool(data, "arrived", out bool arrived) && arrived) + return true; + + if (TryReadDouble(data, "finalDistance", out double finalDistance)) + { + double tolerance = TryReadDouble(data, "tolerance", out double tol) ? tol : 1.5; + return finalDistance <= tolerance; + } + + return false; + } + + private static bool IsContainerOpenVerified(MccEvidenceRecord evidence) + { + return evidence.Data is JsonElement data + && TryReadBool(data, "opened", out bool opened) + && opened; + } + + private static bool IsInventoryVerified(MccEvidenceRecord evidence) + { + if (evidence.Data is not JsonElement data) + return false; + + if (TryReadInt(data, "requestedCount", out int requestedCount) + && TryReadInt(data, "movedCount", out int movedCount)) + { + return movedCount == requestedCount; + } + + if (TryReadInt(data, "requestedCount", out requestedCount) + && TryReadInt(data, "droppedCount", out int droppedCount)) + { + return droppedCount == requestedCount; + } + + return evidence.Success; + } + + private static bool IsPickupVerified(MccEvidenceRecord evidence) + { + if (evidence.Data is not JsonElement data) + return false; + + return (TryReadInt(data, "successfulPickups", out int successfulPickups) && successfulPickups > 0) + || (TryReadInt(data, "collectedCount", out int collectedCount) && collectedCount > 0); + } + + private static bool IsDigVerified(MccEvidenceRecord evidence) + { + if (evidence.Data is not JsonElement data) + return false; + + return (TryReadBool(data, "destroyed", out bool destroyed) && destroyed) + || (TryReadBool(data, "changed", out bool changed) && changed); + } + + private static JsonElement? BuildMoveMetadata(MccEvidenceRecord evidence, JsonElement arguments) + { + if (evidence.Data is not JsonElement data) + return null; + + double x = TryReadDoubleFromArguments(arguments, "x", out double targetX) + ? targetX + : data.TryGetProperty("target", out JsonElement target) && TryReadDouble(target, "x", out double fromDataX) ? fromDataX : 0; + double y = TryReadDoubleFromArguments(arguments, "y", out double targetY) + ? targetY + : data.TryGetProperty("target", out target) && TryReadDouble(target, "y", out double fromDataY) ? fromDataY : 0; + double z = TryReadDoubleFromArguments(arguments, "z", out double targetZ) + ? targetZ + : data.TryGetProperty("target", out target) && TryReadDouble(target, "z", out double fromDataZ) ? fromDataZ : 0; + double tolerance = TryReadDouble(data, "tolerance", out double tol) ? tol : 1.5; + + return JsonSerializer.SerializeToElement(new + { + x, + y, + z, + tolerance + }); + } + + private static JsonElement? BuildMoveToPlayerMetadata(MccEvidenceRecord evidence, JsonElement arguments) + { + string? playerName = arguments.TryGetProperty("playerName", out JsonElement property) ? property.GetString() : null; + double tolerance = evidence.Data is JsonElement data && TryReadDouble(data, "tolerance", out double tol) ? tol : 2.0; + return JsonSerializer.SerializeToElement(new + { + playerName, + tolerance + }); + } + + private static JsonElement ParseArgumentsToJson(string argumentsJson) + { + try + { + using JsonDocument document = JsonDocument.Parse(string.IsNullOrWhiteSpace(argumentsJson) ? "{}" : argumentsJson); + return document.RootElement.Clone(); + } + catch + { + using JsonDocument document = JsonDocument.Parse("{}"); + return document.RootElement.Clone(); + } + } + + private static bool TryReadBool(JsonElement element, string propertyName, out bool value) + { + value = false; + return element.TryGetProperty(propertyName, out JsonElement property) + && property.ValueKind is JsonValueKind.True or JsonValueKind.False + && ((value = property.GetBoolean()) || !value || true); + } + + private static bool TryReadInt(JsonElement element, string propertyName, out int value) + { + value = 0; + return element.TryGetProperty(propertyName, out JsonElement property) && property.TryGetInt32(out value); + } + + private static bool TryReadDouble(JsonElement element, string propertyName, out double value) + { + value = 0; + return element.TryGetProperty(propertyName, out JsonElement property) && property.TryGetDouble(out value); + } + + private static bool TryReadDoubleFromArguments(JsonElement element, string propertyName, out double value) + { + value = 0; + if (!element.TryGetProperty(propertyName, out JsonElement property)) + return false; + + return property.ValueKind == JsonValueKind.Number + ? property.TryGetDouble(out value) + : property.ValueKind == JsonValueKind.String && double.TryParse(property.GetString(), out value); + } + + private static double Distance(double x1, double y1, double z1, double x2, double y2, double z2) + { + double dx = x1 - x2; + double dy = y1 - y2; + double dz = z1 - z2; + return Math.Sqrt(dx * dx + dy * dy + dz * dz); + } + + private static string Truncate(string text, int maxLength) + { + return string.IsNullOrEmpty(text) || text.Length <= maxLength ? text : text[..maxLength] + "..."; + } + + private static SseItem CreateEvent(string runId, ref long sequence, string kind, T data) + { + sequence++; + return new SseItem( + new MccStreamEnvelope(runId, sequence, kind, data!), + kind) + { + EventId = sequence.ToString(CultureInfo.InvariantCulture) + }; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccContextCompressor.cs b/DebugTools/MccMcpWebPlayground/Harness/MccContextCompressor.cs new file mode 100644 index 00000000..1d131bda --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccContextCompressor.cs @@ -0,0 +1,21 @@ +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccContextCompressor +{ + public void CompactIfNeeded(MccRunState runState) + { + if (runState.Evidence.Count <= 6) + return; + + IReadOnlyList olderEvidence = runState.Evidence + .Take(Math.Max(0, runState.Evidence.Count - 6)) + .ToArray(); + + if (olderEvidence.Count == 0) + return; + + runState.CompactionSummary = string.Join('\n', olderEvidence + .TakeLast(8) + .Select(record => $"- {record.Id} {record.ToolName}: {record.Summary}")); + } +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccFinalizer.cs b/DebugTools/MccMcpWebPlayground/Harness/MccFinalizer.cs new file mode 100644 index 00000000..88978bc6 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccFinalizer.cs @@ -0,0 +1,221 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using DebugTools.MccMcpWebPlayground.Contracts; + +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccFinalizer +{ + private static readonly string[] AllowedStatuses = ["completed", "partial", "blocked", "clarification_needed", "failed"]; + + public object BuildSubmitToolSchema() + { + return new Dictionary + { + ["type"] = "function", + ["function"] = new Dictionary + { + ["name"] = "mcc_submit_final", + ["description"] = "Submit the final result for this MCC run. Use completed only when no required verification obligations remain open.", + ["parameters"] = new JsonObject + { + ["type"] = "object", + ["additionalProperties"] = false, + ["properties"] = new JsonObject + { + ["status"] = new JsonObject + { + ["type"] = "string", + ["enum"] = new JsonArray(AllowedStatuses.Select(status => JsonValue.Create(status)).ToArray()) + }, + ["headline"] = new JsonObject { ["type"] = "string" }, + ["answerMarkdown"] = new JsonObject { ["type"] = "string" }, + ["verifiedFacts"] = new JsonObject + { + ["type"] = "array", + ["items"] = new JsonObject { ["type"] = "string" } + }, + ["openIssues"] = new JsonObject + { + ["type"] = "array", + ["items"] = new JsonObject { ["type"] = "string" } + }, + ["evidenceIds"] = new JsonObject + { + ["type"] = "array", + ["items"] = new JsonObject { ["type"] = "string" } + }, + ["nextAction"] = new JsonObject + { + ["type"] = new JsonArray("string", "null") + } + }, + ["required"] = new JsonArray("status", "headline", "answerMarkdown", "verifiedFacts", "openIssues", "evidenceIds", "nextAction") + } + } + }; + } + + public MccFinalizationValidation Validate(MccRunState runState, string argumentsJson) + { + try + { + using JsonDocument document = JsonDocument.Parse(string.IsNullOrWhiteSpace(argumentsJson) ? "{}" : argumentsJson); + JsonElement root = document.RootElement; + MccSubmitFinalArgs submission = new( + Status: ReadRequiredString(root, "status"), + Headline: ReadRequiredString(root, "headline"), + AnswerMarkdown: ReadRequiredString(root, "answerMarkdown"), + VerifiedFacts: ReadStringArray(root, "verifiedFacts"), + OpenIssues: ReadStringArray(root, "openIssues"), + EvidenceIds: ReadStringArray(root, "evidenceIds"), + NextAction: ReadNullableString(root, "nextAction")); + + string normalizedStatus = submission.Status.Trim().ToLowerInvariant(); + if (!AllowedStatuses.Contains(normalizedStatus, StringComparer.Ordinal)) + return MccFinalizationValidation.Reject("Invalid final status."); + + if (string.IsNullOrWhiteSpace(submission.Headline) || string.IsNullOrWhiteSpace(submission.AnswerMarkdown)) + return MccFinalizationValidation.Reject("headline and answerMarkdown are required."); + + Dictionary evidenceById = runState.Evidence.ToDictionary(record => record.Id, StringComparer.OrdinalIgnoreCase); + Dictionary evidenceAliasByCallId = new(StringComparer.OrdinalIgnoreCase); + foreach (MccToolExecutionRecord execution in runState.ToolExecutions) + { + evidenceAliasByCallId[execution.CallId] = execution.Evidence.Id; + + int suffixSeparator = execution.CallId.LastIndexOf('_'); + if (suffixSeparator >= 0 && suffixSeparator < execution.CallId.Length - 1) + evidenceAliasByCallId[execution.CallId[(suffixSeparator + 1)..]] = execution.Evidence.Id; + } + + List normalizedEvidenceIds = []; + foreach (string evidenceId in submission.EvidenceIds) + { + string normalizedEvidenceId = evidenceAliasByCallId.TryGetValue(evidenceId, out string? mappedEvidenceId) + ? mappedEvidenceId + : evidenceId; + + if (!evidenceById.ContainsKey(normalizedEvidenceId)) + return MccFinalizationValidation.Reject($"Unknown evidence id '{evidenceId}'."); + + if (!normalizedEvidenceIds.Contains(normalizedEvidenceId, StringComparer.OrdinalIgnoreCase)) + normalizedEvidenceIds.Add(normalizedEvidenceId); + } + + if (normalizedStatus == "completed" && runState.OpenObligations.Count > 0) + return MccFinalizationValidation.Reject("completed is invalid while verification obligations remain open."); + + if (!AreVerifiedFactsGrounded(submission.VerifiedFacts, normalizedEvidenceIds, evidenceById)) + return MccFinalizationValidation.Reject("verifiedFacts must be grounded in the referenced evidence."); + + return MccFinalizationValidation.Accept(new MccFinalPayload( + normalizedStatus, + submission.Headline.Trim(), + submission.AnswerMarkdown.Trim(), + submission.VerifiedFacts, + submission.OpenIssues, + normalizedEvidenceIds, + string.IsNullOrWhiteSpace(submission.NextAction) ? null : submission.NextAction.Trim())); + } + catch (Exception ex) + { + return MccFinalizationValidation.Reject($"Invalid mcc_submit_final payload: {ex.Message}"); + } + } + + public MccFinalPayload BuildHardStopResult(MccRunState runState, MccWebHarnessOptions options) + { + IReadOnlyList openIssues = runState.OpenObligations.Count > 0 + ? runState.OpenObligations.Select(obligation => obligation.Description).ToArray() + : ["The harness reached its execution budget before the run was explicitly finalized."]; + + IReadOnlyList evidenceIds = runState.Evidence.TakeLast(4).Select(record => record.Id).ToArray(); + IReadOnlyList verifiedFacts = runState.Evidence + .TakeLast(4) + .Where(record => record.Success) + .Select(record => record.Summary) + .ToArray(); + + return new MccFinalPayload( + Status: runState.OpenObligations.Count > 0 ? "partial" : "blocked", + Headline: "Run stopped before explicit completion", + AnswerMarkdown: "I could not finish the request within the current harness budget. I am returning the strongest verified state captured so far.", + VerifiedFacts: verifiedFacts, + OpenIssues: openIssues, + EvidenceIds: evidenceIds, + NextAction: "Retry with a fresh run if you want me to continue from the latest verified state."); + } + + private static bool AreVerifiedFactsGrounded( + IReadOnlyList verifiedFacts, + IReadOnlyList evidenceIds, + IReadOnlyDictionary evidenceById) + { + if (verifiedFacts.Count == 0) + return true; + + if (evidenceIds.Count == 0) + return false; + + string evidenceCorpus = string.Join(' ', evidenceIds + .Where(evidenceById.ContainsKey) + .Select(id => evidenceById[id].Summary)) + .ToLowerInvariant(); + + foreach (string fact in verifiedFacts) + { + HashSet factTokens = fact.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Select(token => token.Trim().Trim(',', '.', ':', ';', '!', '?', '"', '\'')) + .Where(token => token.Length >= 4) + .Select(token => token.ToLowerInvariant()) + .ToHashSet(StringComparer.Ordinal); + + if (factTokens.Count == 0) + continue; + + int matches = factTokens.Count(token => evidenceCorpus.Contains(token, StringComparison.Ordinal)); + if (matches < Math.Min(2, factTokens.Count)) + return false; + } + + return true; + } + + private static string ReadRequiredString(JsonElement root, string propertyName) + { + string? value = ReadNullableString(root, propertyName); + if (string.IsNullOrWhiteSpace(value)) + throw new InvalidOperationException($"{propertyName} is required."); + + return value.Trim(); + } + + private static string? ReadNullableString(JsonElement root, string propertyName) + { + if (!root.TryGetProperty(propertyName, out JsonElement property)) + return null; + + return property.ValueKind == JsonValueKind.Null ? null : property.GetString(); + } + + private static string[] ReadStringArray(JsonElement root, string propertyName) + { + if (!root.TryGetProperty(propertyName, out JsonElement property) || property.ValueKind != JsonValueKind.Array) + return []; + + return property.EnumerateArray() + .Where(item => item.ValueKind == JsonValueKind.String) + .Select(item => item.GetString()) + .Where(item => !string.IsNullOrWhiteSpace(item)) + .Cast() + .ToArray(); + } +} + +public sealed record MccFinalizationValidation(bool Accepted, string? ErrorText, MccFinalPayload? Payload) +{ + public static MccFinalizationValidation Accept(MccFinalPayload payload) => new(true, null, payload); + + public static MccFinalizationValidation Reject(string errorText) => new(false, errorText, null); +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccGuidanceSource.cs b/DebugTools/MccMcpWebPlayground/Harness/MccGuidanceSource.cs new file mode 100644 index 00000000..a302e3f0 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccGuidanceSource.cs @@ -0,0 +1,63 @@ +using System.Text.Json; +using DebugTools.MccMcpWebPlayground.Contracts; +using DebugTools.MccMcpWebPlayground.Infrastructure.Mcp; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol; + +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccGuidanceSource +{ + public const string SourceToolName = "mcc_agent_guidance"; + public const string CanonicalPromptName = "mcc_operator_guide"; + + public async Task LoadAsync(McpClient client, CancellationToken cancellationToken) + { + CallToolResult result = await client.CallToolAsync(SourceToolName, new Dictionary(), cancellationToken: cancellationToken); + MccNormalizedToolResult normalized = MccMcpJson.Normalize(result); + JsonElement data = normalized.Data ?? throw new InvalidOperationException("mcc_agent_guidance did not return data."); + + string[] bestPractices = ReadStringArray(data, "bestPractices"); + string[] exampleTitles = data.TryGetProperty("exampleScenarios", out JsonElement examples) + && examples.ValueKind == JsonValueKind.Array + ? examples.EnumerateArray() + .Select(example => example.TryGetProperty("title", out JsonElement title) ? title.GetString() : null) + .Where(title => !string.IsNullOrWhiteSpace(title)) + .Cast() + .ToArray() + : []; + + MccCapabilityStatus capabilityStatus = data.TryGetProperty("capabilityStatus", out JsonElement capabilityJson) + ? JsonSerializer.Deserialize(capabilityJson.GetRawText()) ?? new MccCapabilityStatus(false, false, false, false, false) + : new MccCapabilityStatus(false, false, false, false, false); + + return new MccGuidanceBundle( + SourceToolName, + CanonicalPromptName, + SkillName: ReadString(data, "skillName") ?? "mcc-mcp-operator", + GuidanceVersion: ReadString(data, "guidanceVersion") ?? "unknown", + SystemPrompt: ReadString(data, "systemPrompt") ?? throw new InvalidOperationException("mcc_agent_guidance did not return systemPrompt."), + BestPractices: bestPractices, + ExampleScenarioTitles: exampleTitles, + CapabilityStatus: capabilityStatus); + } + + private static string? ReadString(JsonElement element, string propertyName) + { + return element.TryGetProperty(propertyName, out JsonElement property) && property.ValueKind == JsonValueKind.String + ? property.GetString() + : null; + } + + private static string[] ReadStringArray(JsonElement element, string propertyName) + { + return element.TryGetProperty(propertyName, out JsonElement property) && property.ValueKind == JsonValueKind.Array + ? property.EnumerateArray() + .Where(item => item.ValueKind == JsonValueKind.String) + .Select(item => item.GetString()) + .Where(item => !string.IsNullOrWhiteSpace(item)) + .Cast() + .ToArray() + : []; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccPromptComposer.cs b/DebugTools/MccMcpWebPlayground/Harness/MccPromptComposer.cs new file mode 100644 index 00000000..b9cb4650 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccPromptComposer.cs @@ -0,0 +1,86 @@ +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccPromptComposer +{ + private const string HarnessContract = """ +You are operating Minecraft Console Client through MCC MCP tools. + +Rules: +- Use tool results and the run-state summary as the source of truth. +- Execute tools sequentially. +- End the run only with mcc_submit_final. +- status=completed is valid only when no required verification obligations remain open. +- If the task is blocked or partial, say exactly what is verified and what remains unverified. +- Do not repeat the same failing stateful action with the same arguments. +- mcc_quit_client requires explicit user intent. +- Prefer structured high-level tools. Avoid escape hatches unless they are explicitly exposed and necessary. +"""; + + public List Compose(MccRunState runState) + { + List messages = + [ + BuildSystemMessage(HarnessContract), + BuildSystemMessage(runState.Guidance.SystemPrompt), + BuildSystemMessage(BuildStateSummary(runState)), + .. runState.BaseConversationMessages + ]; + + if (!string.IsNullOrWhiteSpace(runState.CompactionSummary)) + { + messages.Add(BuildSystemMessage($""" +Older verified evidence summary +{runState.CompactionSummary} +""")); + } + + foreach (object message in runState.ToolConversationMessages.TakeLast(12)) + messages.Add(message); + + return messages; + } + + private static Dictionary BuildSystemMessage(string text) + { + return new Dictionary + { + ["role"] = "system", + ["content"] = text + }; + } + + private static string BuildStateSummary(MccRunState runState) + { + string evidence = runState.Evidence.Count == 0 + ? "- none yet" + : string.Join('\n', runState.Evidence.TakeLast(6).Select(record => + $"- {record.Id} {record.ToolName}: {record.Summary}")); + + string obligations = runState.OpenObligations.Count == 0 + ? "- none" + : string.Join('\n', runState.OpenObligations.Select(obligation => + $"- {obligation.Id} {obligation.ToolName}/{obligation.Kind}: {obligation.Description}")); + + string bestPractices = runState.Guidance.BestPractices.Length == 0 + ? "- use verified MCC state before claiming success" + : string.Join('\n', runState.Guidance.BestPractices.Take(4).Select(item => $"- {item}")); + + return $""" +Current run state +- turnCount: {runState.TurnCount} +- toolCallCount: {runState.ToolCallCount} +- directAnswerAttempts: {runState.DirectAnswerAttempts} +- routedModel: {runState.RoutedModel ?? runState.ConfiguredModel} +- routedProvider: {runState.RoutedProvider ?? "unknown"} + +Outstanding verification +{obligations} + +Recent evidence +{evidence} + +Guidance highlights +{bestPractices} +"""; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccRunState.cs b/DebugTools/MccMcpWebPlayground/Harness/MccRunState.cs new file mode 100644 index 00000000..f226c8b3 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccRunState.cs @@ -0,0 +1,103 @@ +using System.Text.Json; +using DebugTools.MccMcpWebPlayground.Contracts; + +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccRunState +{ + private int evidenceCounter; + private int obligationCounter; + + public required string RunId { get; init; } + public required string UserRequest { get; init; } + public required List BaseConversationMessages { get; init; } + public required string ConfiguredModel { get; init; } + public required MccGuidanceBundle Guidance { get; init; } + public DateTimeOffset StartedAtUtc { get; init; } = DateTimeOffset.UtcNow; + + public List ToolConversationMessages { get; } = []; + public List Evidence { get; } = []; + public List ToolExecutions { get; } = []; + public List VerificationObligations { get; } = []; + public string? CompactionSummary { get; set; } + public string? RoutedModel { get; set; } + public string? RoutedProvider { get; set; } + public int TurnCount { get; set; } + public int ToolCallCount { get; set; } + public int DirectAnswerAttempts { get; set; } + + public string NextEvidenceId() => $"e{++evidenceCounter:0000}"; + + public string NextObligationId() => $"v{++obligationCounter:0000}"; + + public bool IsSoftFinish(MccWebHarnessOptions options, DateTimeOffset nowUtc) + { + TimeSpan elapsed = nowUtc - StartedAtUtc; + return (options.MaxTurns - TurnCount) <= options.SoftFinishRemainingTurns + || (options.MaxToolCalls - ToolCallCount) <= options.SoftFinishRemainingToolCalls + || (options.MaxWallClockSeconds - (int)elapsed.TotalSeconds) <= options.SoftFinishRemainingSeconds; + } + + public bool IsHardStop(MccWebHarnessOptions options, DateTimeOffset nowUtc) + { + TimeSpan elapsed = nowUtc - StartedAtUtc; + return TurnCount >= options.MaxTurns + || ToolCallCount >= options.MaxToolCalls + || elapsed.TotalSeconds >= options.MaxWallClockSeconds; + } + + public IReadOnlyList OpenObligations => + VerificationObligations.Where(obligation => !obligation.Cleared).ToArray(); +} + +public sealed record MccGuidanceBundle( + string SourceToolName, + string CanonicalPromptName, + string SkillName, + string GuidanceVersion, + string SystemPrompt, + string[] BestPractices, + string[] ExampleScenarioTitles, + MccCapabilityStatus CapabilityStatus); + +public sealed class MccEvidenceRecord +{ + public required string Id { get; init; } + public required string ToolName { get; init; } + public required string Summary { get; init; } + public required string RawText { get; init; } + public required bool IsError { get; init; } + public required bool Success { get; init; } + public string? ErrorCode { get; init; } + public JsonElement? Root { get; init; } + public JsonElement? Data { get; init; } +} + +public sealed class MccToolExecutionRecord +{ + public required string CallId { get; init; } + public required string ToolName { get; init; } + public required string ArgumentsJson { get; init; } + public required MccEvidenceRecord Evidence { get; init; } +} + +public sealed class MccVerificationObligation +{ + public required string Id { get; init; } + public required string ToolName { get; init; } + public required string Kind { get; init; } + public required string Description { get; init; } + public required string SourceEvidenceId { get; init; } + public JsonElement? Metadata { get; init; } + public bool Cleared { get; set; } + public string? ClearedByEvidenceId { get; set; } +} + +public sealed record MccNormalizedToolResult( + string Text, + bool IsError, + bool Success, + string? ErrorCode, + string? Message, + JsonElement? Root, + JsonElement? Data); diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccToolPolicy.cs b/DebugTools/MccMcpWebPlayground/Harness/MccToolPolicy.cs new file mode 100644 index 00000000..e8a9bd77 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccToolPolicy.cs @@ -0,0 +1,133 @@ +using System.Collections.Frozen; +using System.Text.Json.Nodes; +using ModelContextProtocol.Client; + +namespace DebugTools.MccMcpWebPlayground.Harness; + +public enum MccToolRisk +{ + ReadOnly, + Stateful, + Sensitive, + EscapeHatch +} + +public sealed record MccToolProfile( + string Name, + MccToolRisk Risk, + bool VisibleByDefault, + bool RequiresExplicitUserIntent); + +public sealed record MccToolCatalogEntry(McpClientTool Tool, MccToolProfile Profile); + +public sealed class MccToolCatalog +{ + public required Dictionary ToolsByName { get; init; } + public required IReadOnlyList ModelVisibleTools { get; init; } +} + +public static class MccToolPolicy +{ + private static readonly FrozenDictionary Profiles = + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["mcc_agent_guidance"] = new("mcc_agent_guidance", MccToolRisk.ReadOnly, false, false), + ["mcc_inventory_window_action"] = new("mcc_inventory_window_action", MccToolRisk.EscapeHatch, false, false), + ["mcc_run_internal_command"] = new("mcc_run_internal_command", MccToolRisk.EscapeHatch, false, false), + ["mcc_quit_client"] = new("mcc_quit_client", MccToolRisk.Sensitive, true, true) + }.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase); + + public static MccToolProfile GetProfile(string toolName) + { + return Profiles.TryGetValue(toolName, out MccToolProfile? profile) + ? profile + : new MccToolProfile(toolName, MccToolRisk.Stateful, true, false); + } + + public static MccToolCatalog BuildCatalog(IList tools, MccWebHarnessOptions options, object submitFinalTool) + { + Dictionary toolsByName = tools.ToDictionary( + tool => tool.Name, + tool => new MccToolCatalogEntry(tool, GetProfile(tool.Name)), + StringComparer.OrdinalIgnoreCase); + + List visibleTools = []; + foreach (MccToolCatalogEntry entry in toolsByName.Values.OrderBy(entry => entry.Tool.Name, StringComparer.OrdinalIgnoreCase)) + { + if (!IsVisible(entry.Profile, options)) + continue; + + visibleTools.Add(ToOpenRouterTool(entry.Tool, entry.Profile)); + } + + visibleTools.Add(submitFinalTool); + + return new MccToolCatalog + { + ToolsByName = toolsByName, + ModelVisibleTools = visibleTools + }; + } + + public static bool RequiresExplicitUserIntent(string toolName) + { + return GetProfile(toolName).RequiresExplicitUserIntent; + } + + public static bool HasExplicitUserIntent(string userRequest, string toolName) + { + if (!RequiresExplicitUserIntent(toolName)) + return true; + + string request = userRequest.Trim().ToLowerInvariant(); + return toolName.Equals("mcc_quit_client", StringComparison.OrdinalIgnoreCase) + && (request.Contains("quit mcc", StringComparison.Ordinal) + || request.Contains("close mcc", StringComparison.Ordinal) + || request.Contains("stop mcc", StringComparison.Ordinal) + || request.Contains("exit mcc", StringComparison.Ordinal) + || request.Contains("quit the client", StringComparison.Ordinal) + || request.Contains("stop the client", StringComparison.Ordinal)); + } + + private static bool IsVisible(MccToolProfile profile, MccWebHarnessOptions options) + { + if (!profile.VisibleByDefault) + { + if (profile.Name.Equals("mcc_inventory_window_action", StringComparison.OrdinalIgnoreCase)) + return options.ExposeInventoryWindowAction; + + if (profile.Name.Equals("mcc_run_internal_command", StringComparison.OrdinalIgnoreCase)) + return options.ExposeInternalCommandTool; + + return false; + } + + return true; + } + + private static object ToOpenRouterTool(McpClientTool tool, MccToolProfile profile) + { + JsonNode parameters = JsonNode.Parse(tool.JsonSchema.GetRawText()) ?? new JsonObject + { + ["type"] = "object", + ["properties"] = new JsonObject() + }; + + string description = tool.Description ?? string.Empty; + if (profile.Risk == MccToolRisk.Sensitive) + description = $"{description} Requires explicit user intent."; + else if (profile.Risk == MccToolRisk.EscapeHatch) + description = $"{description} Advanced escape hatch; prefer higher-level tools first."; + + return new Dictionary + { + ["type"] = "function", + ["function"] = new Dictionary + { + ["name"] = tool.Name, + ["description"] = description, + ["parameters"] = parameters + } + }; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Harness/MccWebHarnessOptions.cs b/DebugTools/MccMcpWebPlayground/Harness/MccWebHarnessOptions.cs new file mode 100644 index 00000000..0855c471 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Harness/MccWebHarnessOptions.cs @@ -0,0 +1,58 @@ +namespace DebugTools.MccMcpWebPlayground.Harness; + +public sealed class MccWebHarnessOptions +{ + public const string SectionName = "MccWebHarness"; + + public string? Model { get; set; } + public string OpenRouterBaseUrl { get; set; } = "https://openrouter.ai/api/v1"; + public string McpEndpoint { get; set; } = "http://127.0.0.1:33333/mcp"; + public int MaxTurns { get; set; } = 48; + public int MaxToolCalls { get; set; } = 120; + public int MaxWallClockSeconds { get; set; } = 240; + public int SoftFinishRemainingTurns { get; set; } = 3; + public int SoftFinishRemainingToolCalls { get; set; } = 8; + public int SoftFinishRemainingSeconds { get; set; } = 30; + public bool RequireProviderParameters { get; set; } = true; + public bool AllowFallbacks { get; set; } + public bool DisableParallelToolCalls { get; set; } = true; + public bool ExposeInventoryWindowAction { get; set; } + public bool ExposeInternalCommandTool { get; set; } + + public string? ResolveModel() + { + return FirstNonEmpty(Environment.GetEnvironmentVariable("OPENROUTER_MODEL"), Model); + } + + public string ResolveOpenRouterBaseUrl() + { + return FirstNonEmpty(Environment.GetEnvironmentVariable("OPENROUTER_BASE_URL"), OpenRouterBaseUrl) + ?? "https://openrouter.ai/api/v1"; + } + + public string ResolveMcpEndpoint() + { + return FirstNonEmpty(Environment.GetEnvironmentVariable("MCC_MCP_ENDPOINT"), McpEndpoint) + ?? "http://127.0.0.1:33333/mcp"; + } + + public string? ResolveMcpAuthToken() + { + return Environment.GetEnvironmentVariable("MCC_MCP_AUTH_TOKEN"); + } + + public string? ResolveApiKey() + { + return Environment.GetEnvironmentVariable("OPENROUTER_API_KEY"); + } + + public bool HasApiKeyConfigured() + { + return !string.IsNullOrWhiteSpace(ResolveApiKey()); + } + + private static string? FirstNonEmpty(params string?[] candidates) + { + return candidates.FirstOrDefault(candidate => !string.IsNullOrWhiteSpace(candidate))?.Trim(); + } +} diff --git a/DebugTools/MccMcpWebPlayground/Infrastructure/Mcp/MccMcpSessionFactory.cs b/DebugTools/MccMcpWebPlayground/Infrastructure/Mcp/MccMcpSessionFactory.cs new file mode 100644 index 00000000..8775bb2c --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Infrastructure/Mcp/MccMcpSessionFactory.cs @@ -0,0 +1,200 @@ +using System.Text; +using System.Text.Json; +using System.Reflection; +using DebugTools.MccMcpWebPlayground.Harness; +using Microsoft.Extensions.Options; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol; + +namespace DebugTools.MccMcpWebPlayground.Infrastructure.Mcp; + +public sealed class MccMcpSessionFactory +{ + private readonly MccWebHarnessOptions options; + + public MccMcpSessionFactory(IOptions options) + { + this.options = options.Value; + } + + public async Task CreateAsync(CancellationToken cancellationToken) + { + string endpoint = options.ResolveMcpEndpoint(); + string? token = options.ResolveMcpAuthToken(); + + return await McpClient.CreateAsync(new HttpClientTransport(new HttpClientTransportOptions + { + Endpoint = new Uri(endpoint), + TransportMode = HttpTransportMode.AutoDetect, + AdditionalHeaders = string.IsNullOrWhiteSpace(token) + ? null + : new Dictionary + { + ["Authorization"] = $"Bearer {token}" + } + }), cancellationToken: cancellationToken); + } +} + +public static class MccMcpJson +{ + public static MccNormalizedToolResult Normalize(CallToolResult result) + { + JsonElement? structuredRoot = TryReadStructuredContent(result); + string text = ReadToolResultText(result, structuredRoot); + try + { + using JsonDocument document = JsonDocument.Parse(text); + JsonElement parsedRoot = document.RootElement.Clone(); + JsonElement root = ShouldPreferStructuredRoot(parsedRoot, structuredRoot) + ? structuredRoot!.Value + : parsedRoot; + JsonElement? data = root.TryGetProperty("data", out JsonElement dataElement) + ? dataElement.Clone() + : ShouldTreatRootAsData(root) ? root.Clone() : structuredRoot; + bool success = root.TryGetProperty("success", out JsonElement successElement) + ? successElement.ValueKind != JsonValueKind.False + : result.IsError != true; + string? errorCode = root.TryGetProperty("errorCode", out JsonElement errorCodeElement) && errorCodeElement.ValueKind == JsonValueKind.String + ? errorCodeElement.GetString() + : null; + string? message = root.TryGetProperty("message", out JsonElement messageElement) && messageElement.ValueKind == JsonValueKind.String + ? messageElement.GetString() + : null; + bool isError = result.IsError == true || !success || !string.IsNullOrWhiteSpace(errorCode); + + return new MccNormalizedToolResult(text, isError, success, errorCode, message, root, data); + } + catch + { + bool isError = result.IsError == true; + return new MccNormalizedToolResult(text, isError, !isError, null, null, structuredRoot, structuredRoot); + } + } + + private static string ReadToolResultText(CallToolResult result, JsonElement? structuredRoot) + { + if (result.Content is null) + return structuredRoot?.GetRawText() ?? (result.IsError == true ? "{\"success\":false}" : "{\"success\":true}"); + + StringBuilder builder = new(); + foreach (ContentBlock block in result.Content) + { + if (block is TextContentBlock text && !string.IsNullOrWhiteSpace(text.Text)) + { + if (builder.Length > 0) + builder.Append('\n'); + builder.Append(text.Text); + } + } + + return builder.Length > 0 + ? builder.ToString() + : structuredRoot?.GetRawText() + ?? JsonSerializer.Serialize(new { success = result.IsError != true, isError = result.IsError }); + } + + private static JsonElement? TryReadStructuredContent(CallToolResult result) + { + PropertyInfo? property = typeof(CallToolResult).GetProperty("StructuredContent", BindingFlags.Instance | BindingFlags.Public); + if (property?.GetValue(result) is not { } value) + return null; + + return value switch + { + JsonElement json when json.ValueKind != JsonValueKind.Undefined && json.ValueKind != JsonValueKind.Null => json.Clone(), + JsonDocument document => document.RootElement.Clone(), + string text when !string.IsNullOrWhiteSpace(text) => TryParseJson(text), + _ => TrySerializeToJson(value) + }; + } + + private static JsonElement? TrySerializeToJson(object value) + { + try + { + return JsonSerializer.SerializeToElement(value); + } + catch + { + return null; + } + } + + private static JsonElement? TryParseJson(string text) + { + try + { + using JsonDocument document = JsonDocument.Parse(text); + return document.RootElement.Clone(); + } + catch + { + return null; + } + } + + private static bool ShouldPreferStructuredRoot(JsonElement parsedRoot, JsonElement? structuredRoot) + { + if (structuredRoot is null) + return false; + + if (parsedRoot.ValueKind != JsonValueKind.Object) + return true; + + return !parsedRoot.EnumerateObject().Any(property => + !property.NameEquals("success") && + !property.NameEquals("isError")); + } + + private static bool ShouldTreatRootAsData(JsonElement root) + { + if (root.ValueKind != JsonValueKind.Object) + return false; + + return root.EnumerateObject().Any(property => + !property.NameEquals("success") && + !property.NameEquals("isError") && + !property.NameEquals("errorCode") && + !property.NameEquals("message")); + } +} + +public static class MccJsonArguments +{ + public static Dictionary Parse(string rawJson) + { + try + { + using JsonDocument document = JsonDocument.Parse(string.IsNullOrWhiteSpace(rawJson) ? "{}" : rawJson); + if (document.RootElement.ValueKind != JsonValueKind.Object) + return new Dictionary(); + + Dictionary values = new(StringComparer.OrdinalIgnoreCase); + foreach (JsonProperty property in document.RootElement.EnumerateObject()) + values[property.Name] = Convert(property.Value); + return values; + } + catch + { + return new Dictionary(); + } + } + + private static object? Convert(JsonElement element) + { + return element.ValueKind switch + { + JsonValueKind.Null => null, + JsonValueKind.True => true, + JsonValueKind.False => false, + JsonValueKind.Number => element.TryGetInt64(out long i64) + ? i64 + : element.TryGetDouble(out double d) ? d : element.GetRawText(), + JsonValueKind.String => element.GetString(), + JsonValueKind.Array => element.EnumerateArray().Select(Convert).ToArray(), + JsonValueKind.Object => element.EnumerateObject().ToDictionary(property => property.Name, property => Convert(property.Value)), + _ => element.GetRawText() + }; + } +} diff --git a/DebugTools/MccMcpWebPlayground/Infrastructure/OpenRouter/OpenRouterChatClient.cs b/DebugTools/MccMcpWebPlayground/Infrastructure/OpenRouter/OpenRouterChatClient.cs new file mode 100644 index 00000000..24d9a080 --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/Infrastructure/OpenRouter/OpenRouterChatClient.cs @@ -0,0 +1,120 @@ +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using DebugTools.MccMcpWebPlayground.Harness; + +namespace DebugTools.MccMcpWebPlayground.Infrastructure.OpenRouter; + +public sealed class OpenRouterChatClient +{ + private readonly IHttpClientFactory httpClientFactory; + + public OpenRouterChatClient(IHttpClientFactory httpClientFactory) + { + this.httpClientFactory = httpClientFactory; + } + + public async Task CreateTurnAsync( + List messages, + IReadOnlyList tools, + MccWebHarnessOptions options, + CancellationToken cancellationToken) + { + string apiKey = options.ResolveApiKey() ?? throw new InvalidOperationException("OPENROUTER_API_KEY is not configured."); + string model = options.ResolveModel() ?? throw new InvalidOperationException("Model is not configured."); + + using HttpClient client = httpClientFactory.CreateClient("openrouter"); + client.BaseAddress = new Uri(options.ResolveOpenRouterBaseUrl().TrimEnd('/') + "/"); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); + client.DefaultRequestHeaders.TryAddWithoutValidation("HTTP-Referer", "https://localhost/mcc-mcp-web-playground"); + client.DefaultRequestHeaders.TryAddWithoutValidation("X-Title", "MCC MCP Web Playground"); + + Dictionary payload = new() + { + ["model"] = model, + ["messages"] = messages, + ["tools"] = tools, + ["tool_choice"] = "auto", + ["provider"] = new Dictionary + { + ["allow_fallbacks"] = options.AllowFallbacks, + ["require_parameters"] = options.RequireProviderParameters + } + }; + + if (ShouldSendParallelToolCallsParameter(model)) + payload["parallel_tool_calls"] = !options.DisableParallelToolCalls; + + using HttpResponseMessage response = await client.PostAsync( + "chat/completions", + new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"), + cancellationToken); + + string body = await response.Content.ReadAsStringAsync(cancellationToken); + if (!response.IsSuccessStatusCode) + throw new InvalidOperationException($"OpenRouter returned HTTP {(int)response.StatusCode}: {body}"); + + using JsonDocument document = JsonDocument.Parse(body); + if (!document.RootElement.TryGetProperty("choices", out JsonElement choices) + || choices.ValueKind != JsonValueKind.Array + || choices.GetArrayLength() == 0) + { + throw new InvalidOperationException("OpenRouter did not return any choices."); + } + + JsonElement message = choices[0].GetProperty("message"); + string assistantContent = message.TryGetProperty("content", out JsonElement contentElement) + ? contentElement.GetString() ?? string.Empty + : string.Empty; + + List toolCalls = []; + if (message.TryGetProperty("tool_calls", out JsonElement toolCallsElement) && toolCallsElement.ValueKind == JsonValueKind.Array) + { + foreach (JsonElement toolCall in toolCallsElement.EnumerateArray()) + { + if (!toolCall.TryGetProperty("id", out JsonElement idElement) + || !toolCall.TryGetProperty("function", out JsonElement functionElement) + || !functionElement.TryGetProperty("name", out JsonElement nameElement)) + { + continue; + } + + toolCalls.Add(new MccModelToolCall( + CallId: idElement.GetString() ?? Guid.NewGuid().ToString("n"), + Name: nameElement.GetString() ?? string.Empty, + ArgumentsJson: functionElement.TryGetProperty("arguments", out JsonElement argumentsElement) + ? argumentsElement.GetString() ?? "{}" + : "{}")); + } + } + + string modelId = document.RootElement.TryGetProperty("model", out JsonElement modelElement) + ? modelElement.GetString() ?? model + : model; + + string? routedProvider = response.Headers.TryGetValues("x-openrouter-provider", out IEnumerable? providerValues) + ? providerValues.FirstOrDefault() + : null; + + return new MccModelTurn(modelId, routedProvider, assistantContent, toolCalls); + } + + private static bool ShouldSendParallelToolCallsParameter(string model) + { + // Some OpenRouter model families reject tool-enabled requests when the parallel_tool_calls + // parameter is present at all, even if it is explicitly set to false. The harness still + // executes all returned tool calls sequentially, so omitting the transport hint for those + // families preserves the intended runtime behavior while keeping the stricter flag for + // compatible models. + return !model.StartsWith("minimax/", StringComparison.OrdinalIgnoreCase) + && !model.StartsWith("google/gemini-", StringComparison.OrdinalIgnoreCase); + } +} + +public sealed record MccModelTurn( + string ModelId, + string? RoutedProvider, + string AssistantContent, + IReadOnlyList ToolCalls); + +public sealed record MccModelToolCall(string CallId, string Name, string ArgumentsJson); diff --git a/DebugTools/MccMcpWebPlayground/Program.cs b/DebugTools/MccMcpWebPlayground/Program.cs index 9b25f0ca..17060301 100644 --- a/DebugTools/MccMcpWebPlayground/Program.cs +++ b/DebugTools/MccMcpWebPlayground/Program.cs @@ -1,1133 +1,40 @@ -using System.Diagnostics; -using System.Net.Http.Headers; -using System.Text; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.RegularExpressions; -using ModelContextProtocol.Client; -using ModelContextProtocol.Protocol; +using DebugTools.MccMcpWebPlayground.Api; +using DebugTools.MccMcpWebPlayground.Harness; +using DebugTools.MccMcpWebPlayground.Infrastructure.Mcp; +using DebugTools.MccMcpWebPlayground.Infrastructure.OpenRouter; +using Microsoft.AspNetCore.Http.Timeouts; var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddOptions() + .Bind(builder.Configuration.GetSection(MccWebHarnessOptions.SectionName)); + +builder.Services.AddRequestTimeouts(options => +{ + options.AddPolicy("mcc-stream", new RequestTimeoutPolicy + { + Timeout = TimeSpan.FromMinutes(10) + }); +}); + builder.Services.AddHttpClient("openrouter", client => { client.Timeout = TimeSpan.FromMinutes(15); }); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddScoped(); + var app = builder.Build(); + +app.UseRequestTimeouts(); app.UseDefaultFiles(); app.UseStaticFiles(); - -const string AgentSystemPrompt = """ -You are an agent controlling Minecraft Console Client (MCC) through MCP tools. -Use a plan-execute-verify loop. - -Operating mode -- For simple social turns like "hello" or "thanks", do not waste tool calls. Finish directly unless MCC state is required. -- For MCC questions and actions, think in steps and use tools to gather evidence before you finish. -- Never output plain assistant text before calling agent_finish(answer). - -Planning policy -- If the task is multi-step or physical, first decompose it into a short internal plan. -- Prefer the smallest plan that can succeed. -- For long or branchy tasks, keep a short checklist and update it as you go. -- Default sequence: - 1) inspect current state - 2) locate the target - 3) move into a valid position if needed - 4) perform the action - 5) verify with fresh tool calls - 6) call agent_finish(answer) -- If a step fails, revise the plan using the latest observation. Do not blindly repeat the same failing action. - -Todo policy -- Use todo_write, todo_read, and todo_list for tasks with 4 or more steps, retries, or branching verification. -- Keep todos short, concrete, and action-oriented. -- Update todo status as facts change. -- Todo state is request-scoped for the current chat request only. -- Skip todo tools for simple one-step tasks. - -Tool-use policy -- Use MCP tools for MCC/game-state questions and actions. -- Prefer the most direct high-signal tool first. -- Prefer structured inventory/container tools over raw window-click tools for chest or container management. -- If a tool result says success=false or includes an errorCode, treat that as a failed observation even if the transport call itself succeeded. -- Do not guess tool arguments repeatedly. If a tool returns invalid_args: - - simplify to the minimum required arguments, - - try at most one nearby variant, - - or switch to a broader inspection tool. -- Avoid long speculative tool chains. - -Verification policy -- Never claim success from intent alone. -- Never claim movement succeeded just because a move command was accepted. Check arrived or a fresh location result. -- Never claim an item was collected unless inventory or nearby entity state changed. -- Never claim blocks were removed unless block/world search results changed. -- If evidence is partial, say it is partial. -- If the request cannot be completed, say exactly what was verified and what remains unverified. - -Action-specific guidance -- Move or approach: - - locate the target, - - choose a reachable nearby standing position when exact occupancy is risky, - - move, - - verify arrival before finishing. -- Dig or collect: - - locate the blocks, - - move next to them if needed, - - dig in a sensible order, - - re-check remaining blocks, - - re-check inventory or nearby item entities before finishing. -- Container inventory: - - locate the target container block, - - open the container first, - - inspect player and container inventory state, - - use structured deposit or withdraw tools instead of raw window clicks, - - verify both player and container counts changed before finishing. -- Search: - - start with the most direct search tool, - - use the user's requested radius when supported, - - if a query fails, simplify it instead of trying many near-duplicates. - -Good examples -1) User: "Pick up those logs." - Good: - - if the task looks long, write a short todo list - - find the logs - - move next to them - - dig them - - verify the logs are gone or reduced - - verify inventory increased - - then finish -2) User: "Is Zarko near you?" - Good: - - call a nearby-player tool - - report the matched player and distance - - then finish -3) User: "Hello" - Good: - - finish with a short greeting - - no MCP tools -4) User: "Put 5 diamonds in the chest." - Good: - - open the chest - - inspect inventory state - - deposit exactly 5 diamonds - - verify the chest count increased and player count decreased by 5 - - then finish - -Wrong examples -1) Wrong: - - inventory did not change - - blocks may still exist - - but you still say "I picked them up" -2) Wrong: - - move returns pathFound=true but arrived=false - - and you still say "I walked there" -3) Wrong: - - a tool returns invalid_args several times - - and you keep guessing similar argument combinations -4) Wrong: - - you write assistant prose before agent_finish(answer) - -Finish rules -- Complete only by calling agent_finish(answer). -- The final answer must be natural language for a human and include exactly: - Reasoning: - - brief bullets with the important verified observations - Answer: - - direct user-facing result with uncertainty stated when relevant -"""; - -const string BudgetReminderPrompt = """ -Budget is nearly exhausted. -Use the strongest verified evidence you already have. -Do not start speculative new branches. -If the task is complete or partially complete, call agent_finish(answer) now and clearly distinguish verified facts from unverified assumptions. -Do not output plain assistant text before finishing. -"""; - -app.MapGet("/api/health", () => Results.Ok(new { ok = true })); -app.MapGet("/api/config", () => -{ - return Results.Ok(new - { - model = GetModel(), - openRouterBaseUrl = GetOpenRouterBaseUrl(), - mcpEndpoint = GetMcpEndpoint(), - hasApiKey = !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("OPENROUTER_API_KEY")) - }); -}); - -app.MapPost("/api/chat/stream", async (ChatStreamRequest request, IHttpClientFactory httpClientFactory, HttpContext context, CancellationToken cancellationToken) => -{ - context.Response.StatusCode = StatusCodes.Status200OK; - context.Response.ContentType = "text/event-stream"; - context.Response.Headers.CacheControl = "no-cache"; - context.Response.Headers["X-Accel-Buffering"] = "no"; - - try - { - string? apiKey = Environment.GetEnvironmentVariable("OPENROUTER_API_KEY"); - if (string.IsNullOrWhiteSpace(apiKey)) - { - await WriteEvent(context.Response, "error", new { message = "OPENROUTER_API_KEY is not set." }, cancellationToken); - return; - } - - List messages = BuildMessages(request.Messages); - if (messages.Count == 0) - { - await WriteEvent(context.Response, "error", new { message = "No messages provided." }, cancellationToken); - return; - } - - string model = GetModel(); - int maxIterations = GetBoundedInt("MCC_WEB_MAX_ITERATIONS", 96, 4, 256); - int maxToolCalls = GetBoundedInt("MCC_WEB_MAX_TOOL_CALLS", 320, 4, 1024); - TimeSpan maxWallTime = TimeSpan.FromSeconds(GetBoundedInt("MCC_WEB_MAX_SECONDS", 900, 10, 3600)); - - await using McpClient mcp = await CreateMcpClientAsync(cancellationToken); - IList mcpTools = await mcp.ListToolsAsync(cancellationToken: cancellationToken); - Dictionary mcpToolsByName = mcpTools - .ToDictionary(tool => tool.Name, StringComparer.OrdinalIgnoreCase); - - object[] openRouterTools = - [ - .. mcpTools.Select(ToOpenRouterTool), - BuildTodoWriteToolSchema(), - BuildTodoReadToolSchema(), - BuildTodoListToolSchema(), - BuildAgentFinishToolSchema() - ]; - - using HttpClient openRouter = httpClientFactory.CreateClient("openrouter"); - openRouter.BaseAddress = new Uri(GetOpenRouterBaseUrl().TrimEnd('/') + "/"); - openRouter.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); - openRouter.DefaultRequestHeaders.TryAddWithoutValidation("HTTP-Referer", "https://localhost/mcc-mcp-web-playground"); - openRouter.DefaultRequestHeaders.TryAddWithoutValidation("X-Title", "MCC MCP Web Playground"); - - Stopwatch wallClock = Stopwatch.StartNew(); - int toolCallCount = 0; - bool reminderInjected = false; - string? finalAnswer = null; - List observations = new(); - Dictionary todos = new(StringComparer.OrdinalIgnoreCase); - int nextTodoOrder = 0; - - for (int iteration = 1; iteration <= maxIterations && !cancellationToken.IsCancellationRequested; iteration++) - { - if (!reminderInjected && ShouldInjectReminder(iteration, maxIterations, toolCallCount, maxToolCalls, wallClock.Elapsed, maxWallTime)) - { - messages.Add(new Dictionary - { - ["role"] = "system", - ["content"] = BudgetReminderPrompt - }); - reminderInjected = true; - } - - if (wallClock.Elapsed >= maxWallTime || toolCallCount >= maxToolCalls) - break; - - JsonElement choiceMessage = await RequestToolIterationAsync(openRouter, model, messages, openRouterTools, context.Response, cancellationToken); - if (choiceMessage.ValueKind == JsonValueKind.Undefined) - return; - - string assistantContent = choiceMessage.TryGetProperty("content", out JsonElement contentElement) - ? contentElement.GetString() ?? string.Empty - : string.Empty; - - if (choiceMessage.TryGetProperty("tool_calls", out JsonElement toolCallsElement) - && toolCallsElement.ValueKind == JsonValueKind.Array - && toolCallsElement.GetArrayLength() > 0) - { - List toolCallsForHistory = new(); - List toolMessages = new(); - bool stopLoop = false; - - foreach (JsonElement toolCall in toolCallsElement.EnumerateArray()) - { - if (!TryReadToolCall(toolCall, out string callId, out string toolName, out string argumentsRaw)) - continue; - - toolCallsForHistory.Add(new Dictionary - { - ["id"] = callId, - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = toolName, - ["arguments"] = argumentsRaw - } - }); - - await WriteEvent(context.Response, "tool_call", new - { - id = callId, - name = toolName, - arguments = argumentsRaw - }, cancellationToken); - - if (TryHandleLocalToolCall(toolName, argumentsRaw, todos, ref nextTodoOrder, out bool localIsError, out string localResultText, out string? completedAnswer)) - { - await WriteEvent(context.Response, "tool_result", new - { - id = callId, - name = toolName, - isError = localIsError, - content = localResultText - }, cancellationToken); - - toolMessages.Add(new Dictionary - { - ["role"] = "tool", - ["tool_call_id"] = callId, - ["content"] = localResultText - }); - - toolCallCount++; - observations.Add(SummarizeObservation(toolName, localResultText, localIsError)); - - if (completedAnswer is not null) - { - finalAnswer = EnsureFinalAnswerFormat(completedAnswer, observations); - stopLoop = true; - break; - } - - continue; - } - - if (!mcpToolsByName.ContainsKey(toolName)) - { - string resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "unknown_tool", - message = $"Unknown tool '{toolName}'." - }); - await WriteEvent(context.Response, "tool_result", new - { - id = callId, - name = toolName, - isError = true, - content = resultText - }, cancellationToken); - - observations.Add($"Tool {toolName} was rejected because it is unknown."); - toolMessages.Add(new Dictionary - { - ["role"] = "tool", - ["tool_call_id"] = callId, - ["content"] = resultText - }); - continue; - } - - if (toolCallCount >= maxToolCalls) - { - stopLoop = true; - break; - } - - bool isError = false; - string toolResultText; - try - { - Dictionary arguments = ParseArguments(argumentsRaw); - CallToolResult toolResult = await mcp.CallToolAsync(toolName, arguments, cancellationToken: cancellationToken); - toolResultText = ReadToolResultText(toolResult); - isError = toolResult.IsError == true || InferStructuredToolError(toolResultText); - } - catch (Exception ex) - { - isError = true; - toolResultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "tool_call_failed", - message = ex.Message - }); - } - - toolCallCount++; - observations.Add(SummarizeObservation(toolName, toolResultText, isError)); - await WriteEvent(context.Response, "tool_result", new - { - id = callId, - name = toolName, - isError, - content = toolResultText - }, cancellationToken); - - toolMessages.Add(new Dictionary - { - ["role"] = "tool", - ["tool_call_id"] = callId, - ["content"] = toolResultText - }); - } - - messages.Add(new Dictionary - { - ["role"] = "assistant", - ["content"] = assistantContent, - ["tool_calls"] = toolCallsForHistory - }); - foreach (object toolMessage in toolMessages) - messages.Add(toolMessage); - - if (finalAnswer is not null || stopLoop) - break; - - continue; - } - - if (!string.IsNullOrWhiteSpace(assistantContent)) - observations.Add($"Model attempted direct text before finishing: {Truncate(assistantContent, 140)}"); - - messages.Add(new Dictionary - { - ["role"] = "assistant", - ["content"] = assistantContent - }); - messages.Add(new Dictionary - { - ["role"] = "system", - ["content"] = "Do not return assistant prose yet. Continue with tool calls and end only by calling agent_finish(answer)." - }); - } - - finalAnswer ??= BuildForcedFinalAnswer(observations, toolCallCount, wallClock.Elapsed, maxIterations, maxToolCalls, maxWallTime); - await StreamFinalAnswer(context.Response, finalAnswer, cancellationToken); - } - catch (OperationCanceledException) - { - await WriteEvent(context.Response, "error", new { message = "Request cancelled." }, CancellationToken.None); - } - catch (Exception ex) - { - await WriteEvent(context.Response, "error", new - { - message = "Unhandled server error.", - detail = ex.Message - }, CancellationToken.None); - } -}); +app.MapMccPlaygroundEndpoints(); app.Run(); - -static string GetModel() -{ - return Environment.GetEnvironmentVariable("OPENROUTER_MODEL") ?? "minimax/minimax-m2.7"; -} - -static string GetOpenRouterBaseUrl() -{ - return Environment.GetEnvironmentVariable("OPENROUTER_BASE_URL") ?? "https://openrouter.ai/api/v1"; -} - -static string GetMcpEndpoint() -{ - return Environment.GetEnvironmentVariable("MCC_MCP_ENDPOINT") ?? "http://127.0.0.1:33333/mcp"; -} - -static async Task CreateMcpClientAsync(CancellationToken cancellationToken) -{ - string endpoint = GetMcpEndpoint(); - string? token = Environment.GetEnvironmentVariable("MCC_MCP_AUTH_TOKEN"); - - return await McpClient.CreateAsync(new HttpClientTransport(new HttpClientTransportOptions - { - Endpoint = new Uri(endpoint), - TransportMode = HttpTransportMode.AutoDetect, - AdditionalHeaders = string.IsNullOrWhiteSpace(token) - ? null - : new Dictionary { ["Authorization"] = $"Bearer {token}" } - }), cancellationToken: cancellationToken); -} - -List BuildMessages(List? incoming) -{ - List messages = - [ - new Dictionary - { - ["role"] = "system", - ["content"] = AgentSystemPrompt - } - ]; - - if (incoming is null) - return messages; - - foreach (ChatMessage message in incoming) - { - if (string.IsNullOrWhiteSpace(message.Role) || string.IsNullOrWhiteSpace(message.Content)) - continue; - - string role = message.Role.Trim().ToLowerInvariant(); - if (role is not ("system" or "user" or "assistant")) - continue; - - messages.Add(new Dictionary - { - ["role"] = role, - ["content"] = message.Content - }); - } - - return messages; -} - -static object ToOpenRouterTool(McpClientTool tool) -{ - JsonNode parameters = JsonNode.Parse(tool.JsonSchema.GetRawText()) ?? new JsonObject - { - ["type"] = "object", - ["properties"] = new JsonObject() - }; - - return new Dictionary - { - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = tool.Name, - ["description"] = tool.Description, - ["parameters"] = parameters - } - }; -} - -static object BuildAgentFinishToolSchema() -{ - return new Dictionary - { - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = "agent_finish", - ["description"] = "Finalize the response to the user after all required tool calls and verification are done.", - ["parameters"] = new Dictionary - { - ["type"] = "object", - ["properties"] = new Dictionary - { - ["answer"] = new Dictionary - { - ["type"] = "string", - ["description"] = "Final natural-language response for the user." - } - }, - ["required"] = new[] { "answer" }, - ["additionalProperties"] = false - } - } - }; -} - -static object BuildTodoWriteToolSchema() -{ - return new Dictionary - { - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = "todo_write", - ["description"] = "Create or update a short request-scoped todo item for complex task tracking.", - ["parameters"] = new Dictionary - { - ["type"] = "object", - ["properties"] = new Dictionary - { - ["id"] = new Dictionary - { - ["type"] = "string", - ["description"] = "Stable todo identifier, for example move_to_logs or verify_inventory." - }, - ["content"] = new Dictionary - { - ["type"] = "string", - ["description"] = "Short actionable todo text. Required when creating a new item." - }, - ["status"] = new Dictionary - { - ["type"] = "string", - ["description"] = "One of pending, in_progress, completed, blocked, cancelled." - }, - ["notes"] = new Dictionary - { - ["type"] = "string", - ["description"] = "Optional brief note with the latest observation." - } - }, - ["required"] = new[] { "id" }, - ["additionalProperties"] = false - } - } - }; -} - -static object BuildTodoReadToolSchema() -{ - return new Dictionary - { - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = "todo_read", - ["description"] = "Read one request-scoped todo item by id.", - ["parameters"] = new Dictionary - { - ["type"] = "object", - ["properties"] = new Dictionary - { - ["id"] = new Dictionary - { - ["type"] = "string", - ["description"] = "Todo identifier." - } - }, - ["required"] = new[] { "id" }, - ["additionalProperties"] = false - } - } - }; -} - -static object BuildTodoListToolSchema() -{ - return new Dictionary - { - ["type"] = "function", - ["function"] = new Dictionary - { - ["name"] = "todo_list", - ["description"] = "List all request-scoped todo items in creation order.", - ["parameters"] = new Dictionary - { - ["type"] = "object", - ["properties"] = new Dictionary(), - ["additionalProperties"] = false - } - } - }; -} - -static bool TryHandleLocalToolCall( - string toolName, - string argumentsRaw, - Dictionary todos, - ref int nextTodoOrder, - out bool isError, - out string resultText, - out string? completedAnswer) -{ - isError = false; - resultText = string.Empty; - completedAnswer = null; - - if (toolName.Equals("agent_finish", StringComparison.OrdinalIgnoreCase)) - { - completedAnswer = ParseAgentFinishAnswer(argumentsRaw); - resultText = JsonSerializer.Serialize(new - { - success = true, - finished = true - }); - return true; - } - - if (toolName.Equals("todo_list", StringComparison.OrdinalIgnoreCase)) - { - resultText = JsonSerializer.Serialize(new - { - success = true, - data = new - { - count = todos.Count, - items = todos.Values - .OrderBy(item => item.Order) - .Select(ToTodoDto) - .ToArray() - } - }); - return true; - } - - Dictionary arguments = ParseArguments(argumentsRaw); - if (toolName.Equals("todo_read", StringComparison.OrdinalIgnoreCase)) - { - string? id = ReadOptionalStringArgument(arguments, "id"); - if (string.IsNullOrWhiteSpace(id)) - { - isError = true; - resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "invalid_args", - message = "todo_read requires a non-empty id." - }); - return true; - } - - if (!todos.TryGetValue(id, out TodoEntry? item)) - { - isError = true; - resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "invalid_state", - message = $"Todo '{id}' does not exist." - }); - return true; - } - - resultText = JsonSerializer.Serialize(new - { - success = true, - data = new - { - item = ToTodoDto(item) - } - }); - return true; - } - - if (!toolName.Equals("todo_write", StringComparison.OrdinalIgnoreCase)) - return false; - - string? todoId = ReadOptionalStringArgument(arguments, "id"); - if (string.IsNullOrWhiteSpace(todoId)) - { - isError = true; - resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "invalid_args", - message = "todo_write requires a non-empty id." - }); - return true; - } - - todos.TryGetValue(todoId, out TodoEntry? existingItem); - string? rawContent = ReadOptionalStringArgument(arguments, "content"); - string content = string.IsNullOrWhiteSpace(rawContent) - ? existingItem?.Content ?? string.Empty - : rawContent.Trim(); - if (content.Length == 0) - { - isError = true; - resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "invalid_args", - message = "todo_write requires content when creating a new item." - }); - return true; - } - - string requestedStatus = ReadOptionalStringArgument(arguments, "status") ?? existingItem?.Status ?? "pending"; - if (!TryNormalizeTodoStatus(requestedStatus, out string normalizedStatus)) - { - isError = true; - resultText = JsonSerializer.Serialize(new - { - success = false, - errorCode = "invalid_args", - message = "Invalid todo status.", - data = new - { - status = requestedStatus, - allowed = GetTodoStatusValues() - } - }); - return true; - } - - string? notes = ReadOptionalStringArgument(arguments, "notes") ?? existingItem?.Notes; - TodoEntry entry = existingItem ?? new TodoEntry - { - Id = todoId, - Order = ++nextTodoOrder - }; - entry.Content = content; - entry.Status = normalizedStatus; - entry.Notes = string.IsNullOrWhiteSpace(notes) ? null : notes.Trim(); - todos[todoId] = entry; - - resultText = JsonSerializer.Serialize(new - { - success = true, - data = new - { - item = ToTodoDto(entry), - totalCount = todos.Count - } - }); - return true; -} - -static async Task RequestToolIterationAsync( - HttpClient openRouter, - string model, - List messages, - object[] tools, - HttpResponse response, - CancellationToken cancellationToken) -{ - var payload = new Dictionary - { - ["model"] = model, - ["messages"] = messages, - ["tools"] = tools, - ["tool_choice"] = "auto" - }; - - using HttpResponseMessage completion = await openRouter.PostAsync( - "chat/completions", - new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"), - cancellationToken); - - string body = await completion.Content.ReadAsStringAsync(cancellationToken); - if (!completion.IsSuccessStatusCode) - { - await WriteEvent(response, "error", new - { - message = "OpenRouter request failed.", - statusCode = (int)completion.StatusCode, - body - }, cancellationToken); - return default; - } - - using JsonDocument doc = JsonDocument.Parse(body); - if (!TryGetFirstChoiceMessage(doc.RootElement, out JsonElement message)) - { - await WriteEvent(response, "error", new { message = "No completion choice returned by OpenRouter." }, cancellationToken); - return default; - } - - return message.Clone(); -} - -static bool TryReadToolCall(JsonElement toolCall, out string id, out string name, out string arguments) -{ - id = string.Empty; - name = string.Empty; - arguments = "{}"; - - if (!toolCall.TryGetProperty("id", out JsonElement idElement) - || !toolCall.TryGetProperty("function", out JsonElement functionElement) - || !functionElement.TryGetProperty("name", out JsonElement nameElement)) - { - return false; - } - - id = idElement.GetString() ?? string.Empty; - name = nameElement.GetString() ?? string.Empty; - arguments = functionElement.TryGetProperty("arguments", out JsonElement argsElement) - ? argsElement.GetString() ?? "{}" - : "{}"; - return true; -} - -static bool TryGetFirstChoiceMessage(JsonElement root, out JsonElement message) -{ - message = default; - if (!root.TryGetProperty("choices", out JsonElement choices) - || choices.ValueKind != JsonValueKind.Array - || choices.GetArrayLength() == 0) - { - return false; - } - - JsonElement first = choices[0]; - return first.TryGetProperty("message", out message); -} - -static Dictionary ParseArguments(string raw) -{ - try - { - using JsonDocument doc = JsonDocument.Parse(string.IsNullOrWhiteSpace(raw) ? "{}" : raw); - if (doc.RootElement.ValueKind != JsonValueKind.Object) - return new Dictionary(); - - Dictionary parsed = new(); - foreach (JsonProperty property in doc.RootElement.EnumerateObject()) - parsed[property.Name] = ConvertJsonElement(property.Value); - return parsed; - } - catch - { - return new Dictionary(); - } -} - -static string? ReadOptionalStringArgument(Dictionary arguments, string key) -{ - if (!arguments.TryGetValue(key, out object? value) || value is null) - return null; - - return value switch - { - string text => text.Trim(), - _ => Convert.ToString(value)?.Trim() - }; -} - -static object? ConvertJsonElement(JsonElement element) -{ - return element.ValueKind switch - { - JsonValueKind.Null => null, - JsonValueKind.True => true, - JsonValueKind.False => false, - JsonValueKind.Number => element.TryGetInt64(out long i64) - ? i64 - : element.TryGetDouble(out double d) ? d : element.GetRawText(), - JsonValueKind.String => element.GetString(), - JsonValueKind.Array => element.EnumerateArray().Select(ConvertJsonElement).ToArray(), - JsonValueKind.Object => element.EnumerateObject().ToDictionary(prop => prop.Name, prop => ConvertJsonElement(prop.Value)), - _ => element.GetRawText() - }; -} - -static string ReadToolResultText(CallToolResult result) -{ - if (result.Content is null) - return result.IsError == true ? "{\"success\":false}" : "{\"success\":true}"; - - StringBuilder sb = new(); - foreach (ContentBlock block in result.Content) - { - if (block is TextContentBlock text && !string.IsNullOrWhiteSpace(text.Text)) - { - if (sb.Length > 0) - sb.Append('\n'); - sb.Append(text.Text); - } - } - - if (sb.Length > 0) - return sb.ToString(); - - return JsonSerializer.Serialize(new { isError = result.IsError }); -} - -static bool InferStructuredToolError(string toolResultText) -{ - try - { - using JsonDocument doc = JsonDocument.Parse(toolResultText); - if (doc.RootElement.ValueKind != JsonValueKind.Object) - return false; - - if (doc.RootElement.TryGetProperty("success", out JsonElement successElement) - && successElement.ValueKind == JsonValueKind.False) - { - return true; - } - - return doc.RootElement.TryGetProperty("errorCode", out JsonElement errorCodeElement) - && errorCodeElement.ValueKind == JsonValueKind.String - && !string.IsNullOrWhiteSpace(errorCodeElement.GetString()); - } - catch - { - return false; - } -} - -static bool TryNormalizeTodoStatus(string rawStatus, out string normalizedStatus) -{ - normalizedStatus = rawStatus.Trim().ToLowerInvariant(); - return normalizedStatus is "pending" or "in_progress" or "completed" or "blocked" or "cancelled"; -} - -static string[] GetTodoStatusValues() -{ - return ["pending", "in_progress", "completed", "blocked", "cancelled"]; -} - -static object ToTodoDto(TodoEntry item) -{ - return new - { - id = item.Id, - content = item.Content, - status = item.Status, - notes = item.Notes, - order = item.Order - }; -} - -static string ParseAgentFinishAnswer(string argumentsRaw) -{ - try - { - using JsonDocument doc = JsonDocument.Parse(string.IsNullOrWhiteSpace(argumentsRaw) ? "{}" : argumentsRaw); - if (doc.RootElement.TryGetProperty("answer", out JsonElement answerElement) - && answerElement.ValueKind == JsonValueKind.String) - { - string answer = answerElement.GetString() ?? string.Empty; - if (!string.IsNullOrWhiteSpace(answer)) - return answer.Trim(); - } - } - catch - { - // ignore and use fallback below - } - - return """ -Reasoning: -- The model requested completion without a textual payload. -- Returning a safe fallback response. - -Answer: -I completed the requested tool workflow but did not receive a final textual answer payload. -"""; -} - -static string EnsureFinalAnswerFormat(string text, IReadOnlyList observations) -{ - string trimmed = text.Trim(); - if (trimmed.Length == 0) - trimmed = "I completed the tool workflow but produced no textual output."; - - bool hasReasoning = trimmed.Contains("Reasoning:", StringComparison.OrdinalIgnoreCase); - bool hasAnswer = trimmed.Contains("Answer:", StringComparison.OrdinalIgnoreCase); - if (hasReasoning && hasAnswer) - return trimmed; - - string[] latestObservations = observations - .TakeLast(3) - .ToArray(); - if (latestObservations.Length == 0) - latestObservations = ["Tool-assisted reasoning completed."]; - - string observationBullets = string.Join('\n', latestObservations.Select(observation => $"- {observation}")); - return $""" -Reasoning: -{observationBullets} -- Final response generated after tool execution and verification. - -Answer: -{trimmed} -"""; -} - -static bool ShouldInjectReminder(int iteration, int maxIterations, int toolCallCount, int maxToolCalls, TimeSpan elapsed, TimeSpan maxWallTime) -{ - return iteration >= maxIterations - 6 - || toolCallCount >= maxToolCalls - 12 - || elapsed >= maxWallTime - TimeSpan.FromSeconds(45); -} - -static string BuildForcedFinalAnswer( - IReadOnlyList observations, - int toolCalls, - TimeSpan elapsed, - int maxIterations, - int maxToolCalls, - TimeSpan maxWallTime) -{ - string lastObservation = observations.Count > 0 ? observations[^1] : "No tool observation was captured."; - return $""" -Reasoning: -- The agent loop reached its safety budget before `agent_finish` was called. -- Last observation: {lastObservation} -- Budget usage: toolCalls={toolCalls}/{maxToolCalls}, elapsed={elapsed.TotalSeconds:F1}s/{maxWallTime.TotalSeconds:F1}s, maxIterations={maxIterations}. - -Answer: -I could not complete this request within the configured tool budget. Ask me to retry and I will continue with a fresh loop. -"""; -} - -static string SummarizeObservation(string toolName, string toolResultText, bool isError) -{ - string status = isError ? "error" : "ok"; - return $"{toolName} => {status}: {Truncate(toolResultText.Replace('\n', ' '), 180)}"; -} - -static string Truncate(string text, int maxLength) -{ - if (string.IsNullOrEmpty(text) || text.Length <= maxLength) - return text; - return text[..maxLength] + "..."; -} - -static async Task StreamFinalAnswer(HttpResponse response, string finalText, CancellationToken cancellationToken) -{ - string text = finalText.Trim(); - if (text.Length == 0) - text = "I completed the request but no final text was generated."; - - MatchCollection tokens = Regex.Matches(text, @"\S+\s*", RegexOptions.CultureInvariant); - if (tokens.Count == 0) - { - await WriteEvent(response, "token", new { text }, cancellationToken); - await WriteEvent(response, "final", new { text }, cancellationToken); - return; - } - - const int wordsPerChunk = 10; - StringBuilder chunk = new(); - int words = 0; - - foreach (Match token in tokens.Cast()) - { - chunk.Append(token.Value); - words++; - if (words >= wordsPerChunk) - { - await WriteEvent(response, "token", new { text = chunk.ToString() }, cancellationToken); - chunk.Clear(); - words = 0; - } - } - - if (chunk.Length > 0) - await WriteEvent(response, "token", new { text = chunk.ToString() }, cancellationToken); - - await WriteEvent(response, "final", new { text }, cancellationToken); -} - -static int GetBoundedInt(string envName, int fallback, int min, int max) -{ - string? raw = Environment.GetEnvironmentVariable(envName); - if (!int.TryParse(raw, out int parsed)) - return fallback; - return Math.Clamp(parsed, min, max); -} - -static async Task WriteEvent(HttpResponse response, string eventName, object payload, CancellationToken cancellationToken) -{ - string json = JsonSerializer.Serialize(payload); - await response.WriteAsync($"event: {eventName}\n", cancellationToken); - await response.WriteAsync($"data: {json}\n\n", cancellationToken); - await response.Body.FlushAsync(cancellationToken); -} - -public sealed class ChatStreamRequest -{ - public List? Messages { get; set; } -} - -public sealed class ChatMessage -{ - public string Role { get; set; } = string.Empty; - public string Content { get; set; } = string.Empty; -} - -public sealed class TodoEntry -{ - public required string Id { get; init; } - public required int Order { get; init; } - public string Content { get; set; } = string.Empty; - public string Status { get; set; } = "pending"; - public string? Notes { get; set; } -} diff --git a/DebugTools/MccMcpWebPlayground/appsettings.Development.json b/DebugTools/MccMcpWebPlayground/appsettings.Development.json index 0c208ae9..6cde4d27 100644 --- a/DebugTools/MccMcpWebPlayground/appsettings.Development.json +++ b/DebugTools/MccMcpWebPlayground/appsettings.Development.json @@ -4,5 +4,11 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + "MccWebHarness": { + "AllowFallbacks": false, + "DisableParallelToolCalls": true, + "ExposeInventoryWindowAction": false, + "ExposeInternalCommandTool": false } } diff --git a/DebugTools/MccMcpWebPlayground/appsettings.json b/DebugTools/MccMcpWebPlayground/appsettings.json index 10f68b8c..869684a5 100644 --- a/DebugTools/MccMcpWebPlayground/appsettings.json +++ b/DebugTools/MccMcpWebPlayground/appsettings.json @@ -5,5 +5,20 @@ "Microsoft.AspNetCore": "Warning" } }, + "MccWebHarness": { + "OpenRouterBaseUrl": "https://openrouter.ai/api/v1", + "McpEndpoint": "http://127.0.0.1:33333/mcp", + "MaxTurns": 48, + "MaxToolCalls": 120, + "MaxWallClockSeconds": 240, + "SoftFinishRemainingTurns": 3, + "SoftFinishRemainingToolCalls": 8, + "SoftFinishRemainingSeconds": 30, + "RequireProviderParameters": true, + "AllowFallbacks": false, + "DisableParallelToolCalls": true, + "ExposeInventoryWindowAction": false, + "ExposeInternalCommandTool": false + }, "AllowedHosts": "*" } diff --git a/DebugTools/MccMcpWebPlayground/wwwroot/app.js b/DebugTools/MccMcpWebPlayground/wwwroot/app.js new file mode 100644 index 00000000..14cd9c0e --- /dev/null +++ b/DebugTools/MccMcpWebPlayground/wwwroot/app.js @@ -0,0 +1,310 @@ +const html = document.documentElement; +const statusEl = document.getElementById("status"); +const sendBtn = document.getElementById("send"); +const stopBtn = document.getElementById("stop"); +const clearBtn = document.getElementById("clear"); +const clearChatBtn = document.getElementById("clear-chat-btn"); +const clearToolsBtn = document.getElementById("clear-tools-btn"); +const promptEl = document.getElementById("prompt"); +const chatEl = document.getElementById("chat"); +const toolsEl = document.getElementById("tools"); +const emptyStateEl = document.getElementById("empty-state"); +const toolsEmptyStateEl = document.getElementById("tools-empty-state"); +const typingIndicatorEl = document.getElementById("typing-indicator"); +const themeToggleBtn = document.getElementById("theme-toggle"); +const themeToggleIconEl = document.getElementById("theme-toggle-icon"); + +let history = []; +let activeAssistantBody = null; +let abortController = null; + +stopBtn.disabled = true; + +loadTheme(); +loadConfig(); + +themeToggleBtn.addEventListener("click", () => { + const next = html.getAttribute("data-theme") === "dark" ? "light" : "dark"; + setTheme(next); +}); + +sendBtn.addEventListener("click", sendPrompt); +stopBtn.addEventListener("click", () => abortController?.abort()); + +clearBtn.addEventListener("click", () => { + history = []; + removeAllMessages(); + removeAllTimelineEvents(); + promptEl.value = ""; + activeAssistantBody = null; + updateEmptyStates(); +}); + +clearChatBtn.addEventListener("click", () => { + history = []; + removeAllMessages(); + promptEl.value = ""; + activeAssistantBody = null; + updateEmptyStates(); +}); + +clearToolsBtn.addEventListener("click", () => { + removeAllTimelineEvents(); + updateEmptyStates(); +}); + +promptEl.addEventListener("keydown", (event) => { + if (event.key === "Enter" && !event.shiftKey) { + event.preventDefault(); + sendPrompt(); + } +}); + +async function loadConfig() { + try { + const response = await fetch("/api/config"); + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const config = await response.json(); + const modelLabel = config.model ? config.model : "Model not configured"; + statusEl.textContent = config.hasApiKey ? modelLabel : `${modelLabel} / missing OPENROUTER_API_KEY`; + } catch (error) { + statusEl.textContent = `Config error: ${error.message}`; + } +} + +async function sendPrompt() { + const prompt = promptEl.value.trim(); + if (!prompt || abortController) { + return; + } + + history.push({ role: "user", content: prompt }); + addMessage("user", prompt); + promptEl.value = ""; + activeAssistantBody = addMessage("assistant", ""); + setBusy(true); + + abortController = new AbortController(); + + try { + const response = await fetch("/api/chat/stream", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ messages: history }), + signal: abortController.signal + }); + + if (!response.ok || !response.body) { + throw new Error(`HTTP ${response.status}`); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + let finalAssistantText = ""; + + while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + + buffer += decoder.decode(value, { stream: true }); + buffer = parseSseChunk(buffer, (eventName, envelope) => { + addTimelineEvent(eventName, envelope); + + if (eventName === "error") { + const errorMessage = envelope.data?.message ?? "Unknown error"; + addMessage("error", errorMessage); + } + + if (eventName === "final") { + finalAssistantText = formatFinalText(envelope.data); + activeAssistantBody.textContent = finalAssistantText; + } + + if (eventName === "state_summary") { + const turnCount = envelope.data?.turnCount ?? "?"; + const toolCallCount = envelope.data?.toolCallCount ?? "?"; + statusEl.textContent = `Running turn ${turnCount}, tools ${toolCallCount}`; + } + }); + } + + if (finalAssistantText.trim().length > 0) { + history.push({ role: "assistant", content: finalAssistantText }); + } + } catch (error) { + if (error.name !== "AbortError") { + addMessage("error", `Request failed: ${error.message}`); + addTimelineEvent("error", { + kind: "error", + data: { + code: "request_failed", + message: error.message + } + }); + } + } finally { + abortController = null; + activeAssistantBody = null; + setBusy(false); + } +} + +function parseSseChunk(buffer, onEvent) { + let blockIndex; + while ((blockIndex = buffer.indexOf("\n\n")) >= 0) { + const rawBlock = buffer.slice(0, blockIndex); + buffer = buffer.slice(blockIndex + 2); + + let eventName = "message"; + let dataText = ""; + for (const line of rawBlock.split("\n")) { + if (line.startsWith("event:")) { + eventName = line.slice(6).trim(); + } else if (line.startsWith("data:")) { + dataText += line.slice(5).trim(); + } + } + + if (!dataText) { + continue; + } + + try { + onEvent(eventName, JSON.parse(dataText)); + } catch (error) { + onEvent("error", { + kind: "error", + data: { + code: "invalid_sse_payload", + message: "Failed to parse SSE payload.", + detail: dataText + } + }); + } + } + + return buffer; +} + +function addMessage(role, content) { + const wrapper = document.createElement("div"); + wrapper.className = `message ${role}`; + + const label = document.createElement("div"); + label.className = "message-label"; + label.textContent = role; + + const body = document.createElement("div"); + body.className = "message-body"; + body.textContent = content; + + wrapper.append(label, body); + chatEl.insertBefore(wrapper, typingIndicatorEl); + chatEl.scrollTop = chatEl.scrollHeight; + updateEmptyStates(); + return body; +} + +function addTimelineEvent(kind, envelope) { + const event = document.createElement("div"); + event.className = `timeline-event kind-${kind}`; + + const label = document.createElement("div"); + label.className = "timeline-label"; + label.textContent = kind.replaceAll("_", " "); + + const body = document.createElement("div"); + body.className = "timeline-body-text"; + body.textContent = JSON.stringify(envelope.data ?? envelope, null, 2); + + event.append(label, body); + toolsEl.appendChild(event); + toolsEl.scrollTop = toolsEl.scrollHeight; + updateEmptyStates(); +} + +function formatFinalText(data) { + if (!data) { + return "The run completed without a final payload."; + } + + const lines = []; + if (data.headline) { + lines.push(data.headline); + lines.push(""); + } + + if (data.answerMarkdown) { + lines.push(data.answerMarkdown); + } + + if (Array.isArray(data.verifiedFacts) && data.verifiedFacts.length > 0) { + lines.push(""); + lines.push("Verified facts:"); + for (const fact of data.verifiedFacts) { + lines.push(`- ${fact}`); + } + } + + if (Array.isArray(data.openIssues) && data.openIssues.length > 0) { + lines.push(""); + lines.push("Open issues:"); + for (const issue of data.openIssues) { + lines.push(`- ${issue}`); + } + } + + if (data.nextAction) { + lines.push(""); + lines.push(`Next action: ${data.nextAction}`); + } + + return lines.join("\n"); +} + +function setBusy(busy) { + sendBtn.disabled = busy; + stopBtn.disabled = !busy; + promptEl.disabled = busy; + typingIndicatorEl.classList.toggle("visible", busy); + statusEl.classList.toggle("busy", busy); + if (!busy) { + loadConfig(); + } else { + statusEl.textContent = "Streaming run..."; + } +} + +function removeAllMessages() { + for (const message of chatEl.querySelectorAll(".message")) { + message.remove(); + } +} + +function removeAllTimelineEvents() { + for (const event of toolsEl.querySelectorAll(".timeline-event")) { + event.remove(); + } +} + +function updateEmptyStates() { + emptyStateEl.style.display = chatEl.querySelectorAll(".message").length === 0 ? "" : "none"; + toolsEmptyStateEl.style.display = toolsEl.querySelectorAll(".timeline-event").length === 0 ? "" : "none"; +} + +function loadTheme() { + const theme = localStorage.getItem("mcc-playground-theme") || "dark"; + setTheme(theme); +} + +function setTheme(theme) { + html.setAttribute("data-theme", theme); + themeToggleIconEl.textContent = theme === "dark" ? "◎" : "◐"; + localStorage.setItem("mcc-playground-theme", theme); +} diff --git a/DebugTools/MccMcpWebPlayground/wwwroot/index.html b/DebugTools/MccMcpWebPlayground/wwwroot/index.html index 68ae6c67..71a9d992 100644 --- a/DebugTools/MccMcpWebPlayground/wwwroot/index.html +++ b/DebugTools/MccMcpWebPlayground/wwwroot/index.html @@ -3,1115 +3,77 @@ - MCC MCP Live Playground + MCC MCP Playground - - + + - - - - -
-
+
+
-

MCC MCP Playground

+
+
MCC MCP Playground
+
Canonical guidance bootstrap, typed run state, verified completion
+
-
-
Booting…
-
- -
- -
+
+
- Chat +

Conversation

- +
-
-
- - - -

No messages yet.
Ask the LLM to control MCC via MCP.

+
+
+

No messages yet.

+

Ask the harness to inspect or act through MCC's MCP server.

-
- Thinking -
- -
+
+
- -
+
- - - - - Tool Events - +

Run Timeline

- - +
-
-
- - - -

No tool events yet.

+
+
+

No run events yet.

+

Typed SSE events will appear here as the harness runs.

- - -
- -