From 08c5c15557495bae780748e69c569cb6d2288ca7 Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 16 Jun 2024 01:19:09 +0200 Subject: [PATCH 01/38] 1.20.6 - Not working yet --- .../Inventory/EnchantmentMapping.cs | 88 +++++-- MinecraftClient/Inventory/Enchantments.cs | 63 ++--- .../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, 648 insertions(+), 75 deletions(-) create mode 100644 MinecraftClient/Protocol/Handlers/PacketPalettes/PacketPalette1206.cs diff --git a/MinecraftClient/Inventory/EnchantmentMapping.cs b/MinecraftClient/Inventory/EnchantmentMapping.cs index badadb9964..1768482e96 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -10,7 +10,7 @@ public class EnchantmentMapping { #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 @@ public class EnchantmentMapping }; // 1.16 - 1.18 - private static Dictionary enchantmentMappings116 = new Dictionary() + private static Dictionary enchantmentMappings116 = new() { //id type { 0, Enchantment.Protection }, @@ -93,8 +93,8 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public static Enchantment GetEnchantmentById(int protocolVersion, short id) if (protocolVersion < Protocol18Handler.MC_1_14_Version) throw new Exception("Enchantments mappings are not implemented bellow 1.14"); - Dictionary map = 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; + 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 (!map.ContainsKey(id)) - throw new Exception("Got an Unknown Enchantment ID '" + id + "', please update the Mappings!"); + if (!map.TryGetValue(id, out var value)) + 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 34279de0b0..f1087d519e 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, + AquaAffinity = 0, + BaneOfArthropods, + BindingCurse, BlastProtection, - ProjectileProtection, - Respiration, - AquaAffinity, - Thorns, + Breach, + Channeling, DepthStrieder, - FrostWalker, - BindingCurse, - SoulSpeed, - SwiftSneak, - Sharpness, - Smite, - BaneOfArthropods, - Knockback, - FireAspect, - Looting, - Sweeping, + Density, Efficency, - SilkTouch, - Unbreaking, - Fortune, - Power, - Punch, + FeatherFalling, + FireAspect, + FireProtection, Flame, + Fortune, + FrostWalker, + Impaling, Infinity, + Knockback, + Looting, LuckOfTheSea, - Lure, Loyality, - Impaling, - Riptide, - Channeling, + Lure, + Mending, Multishot, - QuickCharge, Piercing, - Mending, - VanishingCurse + 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 1596323145..5b220474c1 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,7 @@ public static EntityMetadataPalette GetPalette(int protocolVersion) <= 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 f7dd7fcdf6..8149a06cea 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -118,6 +118,9 @@ public enum MovementType { Sneak, Walk, Sprint } // 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 @@ public enum MovementType { Sneak, Walk, Sprint } 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 80137cffaa..c70d7c3125 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ static class Program 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 c9ca6e5956..f6add9cfae 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 f951a38d0f..32a99ec247 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 0000000000..2a5abce546 --- /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 e012f853e3..5deac47bd3 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,7 +48,7 @@ public PacketTypePalette GetTypeHandler(int protocol) { 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 @@ public PacketTypePalette GetTypeHandler(int protocol) <= 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 b4b8debc88..9eab7b390e 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -29,9 +29,11 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 61221968d6..1149a71f78 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesOut.cs @@ -20,6 +20,8 @@ public enum PacketTypesOut 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 @@ public enum PacketTypesOut HeldItemChange, // InteractEntity, // KeepAlive, // + KnownDataPacks, // Added in 1.20.6 LockDifficulty, // MessageAcknowledgment, // Added in 1.19.1 (1.19.2) NameItem, // @@ -52,6 +55,7 @@ public enum PacketTypesOut 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 e4faf0bf58..969d5e119e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -236,6 +236,16 @@ public int GetNetMainThreadId() 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 43962bb345..43a45030fd 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -70,6 +70,7 @@ class Protocol18Handler : IMinecraftCom 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) } 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) }; } - // 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session) 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 @@ public bool Login(PlayerKeyPair? playerKeyPair, SessionToken session) /// /// 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 @@ private bool StartEncryption(string uuid, string sessionID, LoginType type, byte if (session.SessionPreCheckTask.Result) // PreCheck Success needCheckSession = false; } + + // 1.20.6++ + if (shouldAuthetnicate) + needCheckSession = true; if (needCheckSession) { @@ -2971,6 +3102,7 @@ private bool StartEncryption(string uuid, string sessionID, LoginType type, byte handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); return false; + //Login successful case 0x02: { @@ -2993,6 +3125,10 @@ private bool StartEncryption(string uuid, string sessionID, LoginType type, byte } } + // 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 @@ public bool SendRenameItem(string itemName) 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 @@ internal enum CurrentState { 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 eb5d03ed27..12cdee09bc 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -273,5 +273,18 @@ public interface IMinecraftCom : IDisposable, IAutoComplete /// /// 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 138913ecaa..d6033e9b12 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -44,7 +44,9 @@ public interface IMinecraftComHandler 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 5bfd2b668a..b540e3b630 100644 --- a/MinecraftClient/Protocol/Message/ChatParser.cs +++ b/MinecraftClient/Protocol/Message/ChatParser.cs @@ -31,9 +31,32 @@ public enum MessageType 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 cbf1b1cd90..a2ea85b512 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -153,7 +153,7 @@ public static IMinecraftCom GetProtocolHandler(TcpClient client, int protocolVer 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 @@ public static int MCVer2ProtocolVersion(string mcVersion) 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 @@ public static string ProtocolVersion2MCVer(int 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 02/38] 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 0b2e02f96e..f2f285b461 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -69,6 +69,149 @@ public static void StoreDimensionList(Dictionary registryCodec) } } + 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 @@ public static void SetDimension(string name) curDimension = dimensionList[name]; // Should not fail } - /// /// Get current dimension /// diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 8149a06cea..35cc97e40c 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -148,9 +148,11 @@ public enum MovementType { Sneak, Walk, Sprint } 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 @@ public McClient(SessionToken session, PlayerKeyPair? playerKeyPair, string serve 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 @@ public McClient(SessionToken session, PlayerKeyPair? playerKeyPair, string serve } } } + + 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 43a45030fd..e089e78d0e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -449,6 +449,9 @@ internal bool HandlePacket(int packetId, Queue packetData) } 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ public void Acknowledge(ChatMessage message) 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 @@ public bool SendChatCommand(string command, PlayerKeyPair? playerKeyPair) 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 @@ public bool SendChatCommand(string command, PlayerKeyPair? playerKeyPair) return false; } } - + /// /// Send a chat message to the server /// @@ -4687,21 +4689,22 @@ public bool SendCookieResponse(string name, byte[]? data) 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 d6033e9b12..a64021b58e 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -46,6 +46,9 @@ public interface IMinecraftComHandler 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 03/38] 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 f284d94968..7a6a6d7928 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette110.cs @@ -71,7 +71,7 @@ static ItemPalette110() 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 9d9f20bbb0..02f2694809 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette111.cs @@ -71,7 +71,7 @@ static ItemPalette111() 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 2826641dea..b6758b62c0 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette112.cs @@ -62,7 +62,7 @@ static ItemPalette112() 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 8c67fff8a7..35593662da 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs @@ -88,7 +88,7 @@ static ItemPalette115() 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 @@ static ItemPalette115() 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 20dae2adf7..4bdb9006af 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs @@ -101,7 +101,7 @@ static ItemPalette1161() 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 @@ static ItemPalette1161() 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 bdacf33a74..5a82eef4ba 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs @@ -101,7 +101,7 @@ static ItemPalette1162() 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 @@ static ItemPalette1162() 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 f21c946575..be1bd51716 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs @@ -158,7 +158,7 @@ static ItemPalette117() 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 @@ static ItemPalette117() 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 8db5182659..bc3f25ad21 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs @@ -158,7 +158,7 @@ static ItemPalette118() 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 @@ static ItemPalette118() 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 a47104e789..a1ab48d320 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs @@ -449,7 +449,7 @@ static ItemPalette119() 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 @@ static ItemPalette119() 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 563b16a5cb..6677721ea4 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1193.cs @@ -473,7 +473,7 @@ static ItemPalette1193() 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 @@ static ItemPalette1193() 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 5306eac3f9..ef04e7dc62 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1194.cs @@ -495,7 +495,7 @@ static ItemPalette1194() 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 @@ static ItemPalette1194() 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 fdce6150a2..2ca03bed78 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette120.cs @@ -505,7 +505,7 @@ static ItemPalette120() 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 @@ static ItemPalette120() 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 13f7676e22..3796e4cb9f 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1204.cs @@ -1025,7 +1025,7 @@ static ItemPalette1204() 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 0000000000..d0dceeeb09 --- /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 0d8cc23134..57f942d9f9 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette18.cs @@ -70,7 +70,7 @@ static ItemPalette18() 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 332ff5b730..c4251f6240 100644 --- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs +++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette19.cs @@ -66,7 +66,7 @@ static ItemPalette19() 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 175ebcefff..bfe150d1c3 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -47,6 +47,8 @@ public enum ItemType Anvil, Apple, ArcherPotterySherd, + ArmadilloScute, + ArmadilloSpawnEgg, ArmorStand, ArmsUpPotterySherd, Arrow, @@ -143,6 +145,8 @@ public enum ItemType BlueStainedGlassPane, BlueTerracotta, BlueWool, + BoggedSpawnEgg, + BoltArmorTrimSmithingTemplate, Bone, BoneBlock, BoneMeal, @@ -154,6 +158,7 @@ public enum ItemType BrainCoralBlock, BrainCoralFan, Bread, + BreezeRod, BreezeSpawnEgg, BrewerPotterySherd, BrewingStand, @@ -478,6 +483,9 @@ public enum ItemType FletchingTable, Flint, FlintAndSteel, + FlowArmorTrimSmithingTemplate, + FlowBannerPattern, + FlowPotterySherd, FlowerBannerPattern, FlowerPot, FloweringAzalea, @@ -525,7 +533,6 @@ public enum ItemType GraniteSlab, GraniteStairs, GraniteWall, - Grass, // 1.20.3+ renamed to ShortGrass GrassBlock, Gravel, GrayBanner, @@ -557,11 +564,14 @@ public enum ItemType Grindstone, GuardianSpawnEgg, Gunpowder, + GusterBannerPattern, + GusterPotterySherd, HangingRoots, HayBlock, HeartOfTheSea, HeartPotterySherd, HeartbreakPotterySherd, + HeavyCore, HeavyWeightedPressurePlate, HoglinSpawnEgg, HoneyBlock, @@ -693,6 +703,7 @@ public enum ItemType LlamaSpawnEgg, Lodestone, Loom, + Mace, MagentaBanner, MagentaBed, MagentaCandle, @@ -825,6 +836,8 @@ public enum ItemType Obsidian, OcelotSpawnEgg, OchreFroglight, + OminousBottle, + OminousTrialKey, OrangeBanner, OrangeBed, OrangeCandle, @@ -1027,12 +1040,12 @@ public enum ItemType SandstoneStairs, SandstoneWall, Scaffolding, + ScrapePotterySherd, Sculk, SculkCatalyst, SculkSensor, SculkShrieker, SculkVein, - Scute, SeaLantern, SeaPickle, Seagrass, @@ -1200,8 +1213,10 @@ public enum ItemType TuffWall, TurtleEgg, TurtleHelmet, + TurtleScute, TurtleSpawnEgg, TwistingVines, + Vault, VerdantFroglight, VexArmorTrimSmithingTemplate, VexSpawnEgg, @@ -1295,11 +1310,13 @@ public enum ItemType 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 186916218c..f6a363582d 100644 --- a/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs +++ b/MinecraftClient/Mapping/BlockPalettes/BlockPalette120.cs @@ -641,7 +641,7 @@ static Palette120() 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 023d1c05ee..cdfd4a5386 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette112.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette112.cs @@ -43,7 +43,7 @@ public class Palette112 : BlockPalette { 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 847728bd36..239df04932 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs @@ -167,7 +167,7 @@ static Palette113() 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 97c1223178..4e51ffea81 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs @@ -167,7 +167,7 @@ static Palette114() 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 aabe901bb8..449b95bebc 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs @@ -167,7 +167,7 @@ static Palette115() 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 abc31d57c1..8927218f7b 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs @@ -164,7 +164,7 @@ static Palette116() 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 34cccd754a..154c62cc9d 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs @@ -172,7 +172,7 @@ static Palette117() 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 d8e9d76074..548df06f62 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs @@ -554,7 +554,7 @@ static Palette119() 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 eb1e61fb01..cb15a64f44 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1193.cs @@ -604,7 +604,7 @@ static Palette1193() 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 83c7ff29ca..c5a45ef47b 100644 --- a/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs +++ b/MinecraftClient/Mapping/BlockPalettes/Palette1194.cs @@ -639,7 +639,7 @@ static Palette1194() 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 0000000000..070d6dbb47 --- /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 0000000000..734a431d4c --- /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 9a036bac37..1b628729b0 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -16,6 +16,7 @@ public enum EntityType { Allay, AreaEffectCloud, + Armadillo, ArmorStand, Arrow, Axolotl, @@ -24,7 +25,9 @@ public enum EntityType Blaze, BlockDisplay, Boat, + Bogged, Breeze, + BreezeWindCharge, Camel, Cat, CaveSpider, @@ -84,6 +87,7 @@ public enum EntityType Mooshroom, Mule, Ocelot, + OminousItemSpawner, Painting, Panda, Parrot, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index f5cbc9aad4..6830061050 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -409,7 +409,6 @@ public enum Material GraniteSlab, GraniteStairs, GraniteWall, - Grass, // 1.20.3+ renamed to ShortGrass GrassBlock, Gravel, GrayBanner, @@ -443,6 +442,7 @@ public enum Material Grindstone, HangingRoots, HayBlock, + HeavyCore, HeavyWeightedPressurePlate, HoneyBlock, HoneycombBlock, @@ -965,6 +965,7 @@ public enum Material TurtleEgg, TwistingVines, TwistingVinesPlant, + Vault, VerdantFroglight, Vine, VoidAir, diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs index 34c09c6cd5..659924807e 100644 --- a/MinecraftClient/Mapping/Material2Tool.cs +++ b/MinecraftClient/Mapping/Material2Tool.cs @@ -365,7 +365,7 @@ public static class Material2Tool Material.CyanConcretePowder, Material.Dirt, Material.Farmland, - Material.Grass, + Material.ShortGrass, Material.GrassBlock, Material.DirtPath, Material.Gravel, @@ -374,6 +374,7 @@ public static class Material2Tool 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 dd109709cb..d3b7794527 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -797,10 +797,12 @@ private object ReadNbtField(Queue cache, int fieldType) }; 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) } 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 07d37c7207..6e4575ab5b 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -103,7 +103,8 @@ public static void Read(DataTypes dataTypes, Queue packetData, int protoco 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 @@ public static void Read(DataTypes dataTypes, Queue packetData, int protoco 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 5a67294a34..b682551f16 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -123,21 +123,21 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 63b027d84aefec55528b02a2fe247ea3a8ac414d Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 1 Sep 2024 20:42:39 +0200 Subject: [PATCH 04/38] First Version of Structured Components --- .../Protocol/Handlers/DataTypes.cs | 105 ++++++++++++++---- .../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, 313 insertions(+), 25 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 d3b7794527..b62d511cdd 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -6,6 +6,8 @@ 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 @@ public Dictionary ReadNextNbt(Queue cache) /// 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); - } - else - { - var itemId = ReadNextShort(cache); + 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; - if (itemId == -1) - return null; + itemId = ReadNextVarInt(cache); - var itemCount = ReadNextByte(cache); - var data = ReadNextShort(cache); - var nbt = ReadNextNbt(cache); + if (itemId == -1) + return null; - // 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); + 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); + } + } + } + + 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) + { + ReadNextDetail(cache); } } diff --git a/MinecraftClient/Protocol/Handlers/SocketWrapper.cs b/MinecraftClient/Protocol/Handlers/SocketWrapper.cs index d9793024b7..e74fc84a6f 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 0000000000..fbed4b70b7 --- /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 0000000000..befa121729 --- /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 0000000000..01995dc2f2 --- /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 0000000000..4dffe45768 --- /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 0000000000..af63dce808 --- /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 0000000000..844107c130 --- /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 0000000000..d69507abb3 --- /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 0000000000..c10bbc495c --- /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 0000000000..6a03e0404f --- /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 76e873ed54c15cb3c97b0cac003b8b935de84f1e Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 11 Sep 2024 19:12:31 +0200 Subject: [PATCH 05/38] 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 0000000000..09b513f998 --- /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 c42dd92009..427fe01291 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 1768482e96..4f6fca4789 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -10,184 +10,184 @@ public class EnchantmentMapping { #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 @@ public static Enchantment GetEnchantmentById(int protocolVersion, short id) 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 f1087d519e..13fdd5952b 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 0000000000..a6cc03308e --- /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 f777556438..5076191452 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2948,27 +2948,27 @@ public void OnWindowProperties(byte inventoryID, short propertyId, short propert // 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 0000000000..c2eaa2dace --- /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 0000000000..24d50cf590 --- /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 0000000000..f19211b6d2 --- /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 0000000000..58732f0a7a --- /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 0000000000..965c404015 --- /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 0000000000..71d950018f --- /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 0000000000..2e6bbadd22 --- /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 0000000000..be5b6e811e --- /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 0000000000..1c3d5f8485 --- /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 0000000000..c93fa8f930 --- /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 0000000000..161072442b --- /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 0000000000..5a88e04be8 --- /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 0000000000..c3890dfb69 --- /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 0000000000..de210a2b61 --- /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 0000000000..f14b6d4db8 --- /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 0000000000..a3dfd78649 --- /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 fbed4b70b7..0cc4076236 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 0000000000..c7d63dd3db --- /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 0000000000..fae29a94ef --- /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 0000000000..a35eeec130 --- /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 0000000000..64742c5f32 --- /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 0000000000..9de0e9ade4 --- /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 befa121729..0000000000 --- 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 af63dce808..be235a9163 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs @@ -2,10 +2,11 @@ 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 844107c130..90123fe68b 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 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 ?? + 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 d69507abb3..da70c45454 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 0000000000..b242818536 --- /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 c10bbc495c..0000000000 --- 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 6a03e0404f..f22405b1e9 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -18,7 +18,7 @@ public 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 14ac29d10e..eff94a09f3 100644 --- a/MinecraftClient/Scripting/ChatBot.cs +++ b/MinecraftClient/Scripting/ChatBot.cs @@ -400,9 +400,9 @@ public virtual void OnInventoryProperties(byte inventoryID, short propertyId, sh /// 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 06/38] 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 b62d511cdd..45b74645c4 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -445,18 +445,20 @@ public Dictionary ReadNextNbt(Queue cache) { 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 @@ public byte[] GetLocation(Location location) /// 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 c2eaa2dace..08e0e5f24a 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 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!"); + 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 0000000000..075c7a7b0b --- /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 24d50cf590..cf0433d836 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 f19211b6d2..ef2057c94d 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 0000000000..842af0329f --- /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 0000000000..5d78ac1f15 --- /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 58732f0a7a..a359522b3e 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 965c404015..a734faac33 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 71d950018f..59483d4aea 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 2e6bbadd22..6d135ec121 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 0000000000..3667cdc599 --- /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 0000000000..a5ac05e1d2 --- /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 be5b6e811e..3e84922079 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 0000000000..89d4a6af9d --- /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 0000000000..ad9b6fd91d --- /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 1c3d5f8485..d3b9df8316 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 c93fa8f930..a7b23fb81a 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 0000000000..e9f9439624 --- /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 161072442b..3cb8af440b 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 5a88e04be8..8aa711ef1d 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 0000000000..17f84f6b8e --- /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 0000000000..9111f5b675 --- /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 0000000000..283cf024b8 --- /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 0000000000..c9abbca121 --- /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 c3890dfb69..abdd483fb1 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 de210a2b61..ec598351c0 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 0000000000..e8a28d653c --- /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 f14b6d4db8..100072c93a 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 0000000000..e41536177a --- /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 0000000000..05f5e2d8b5 --- /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 0000000000..6a04585b5e --- /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 a3dfd78649..39c190144c 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 0cc4076236..8b49c90822 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 0000000000..289d432c3f --- /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 0000000000..b7cd111711 --- /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 0000000000..c325e3130c --- /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 0000000000..e5830f4d1e --- /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 9de0e9ade4..1c4e8d8d2c 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 01995dc2f2..7465740b6e 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 4dffe45768..11c48e1f1d 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 StructuredComponent ParseComponent(int id, Queue data) 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 da70c45454..586f887011 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 StructuredComponentsRegistry1206(SubComponentRegistry subComponentRegistr 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 b242818536..91fa60eae6 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs @@ -12,5 +12,9 @@ public SubComponentRegistry1206(DataTypes dataTypes) : base(dataTypes) 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 f22405b1e9..9550246346 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 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 07/38] 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 0000000000..c7ec7e44f3 --- /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 0000000000..7b1b555395 --- /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 e8a28d653c..cf86da9b5d 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 @@ 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 0000000000..00e74b80ce --- /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 0000000000..4e32ef37af --- /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 0000000000..8bc2f06092 --- /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 586f887011..12c6169571 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -40,7 +40,9 @@ public StructuredComponentsRegistry1206(DataTypes dataTypes, ItemPalette itemPal 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 08/38] 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 0000000000..7047bde249 --- /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 08e0e5f24a..d969d1b473 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 @@ 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 override void Parse(Queue data) 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 0000000000..82df01c96c --- /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 0000000000..0f2d962082 --- /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 0000000000..f0630fe197 --- /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 0000000000..be3950fe05 --- /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 075c7a7b0b..063d1d2000 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 @@ 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 cf0433d836..06ca3a7b83 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 @@ 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 override void Parse(Queue data) 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 ef2057c94d..581c089f3a 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 @@ 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 override void Parse(Queue data) 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 842af0329f..ef0875ef0e 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 @@ 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 0000000000..2b050aff0b --- /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 0000000000..d0f951ae02 --- /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 5d78ac1f15..06989ec99d 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 @@ 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 9111f5b675..22b22b70e3 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 @@ 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 a734faac33..e8c055281d 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 @@ 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 59483d4aea..024b7a439a 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 @@ 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 6d135ec121..9ac84800ee 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 @@ 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 0000000000..7cfc68e48e --- /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 3667cdc599..fc6de3d0ae 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 @@ 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 a5ac05e1d2..bdeb1d2433 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 @@ 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 3e84922079..e38b41fde1 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 @@ 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 0000000000..a4e6ef98ed --- /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 a7b23fb81a..e0eed96cad 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 @@ 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 0000000000..eeb4e876d3 --- /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 0000000000..c670e95d36 --- /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 ad9b6fd91d..f848750d36 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 @@ 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 override void Parse(Queue data) 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 d3b9df8316..13a7197aeb 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 @@ 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 89d4a6af9d..b1d0783edc 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 @@ 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 0000000000..87bb17be88 --- /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 e9f9439624..cba25e6eb4 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 @@ 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 3cb8af440b..a7c8bda336 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 @@ 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 0000000000..c9ebe0b03b --- /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 0000000000..702b8763f4 --- /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 17f84f6b8e..7c7e918644 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 @@ 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 a359522b3e..c6f8f3438f 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 @@ 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 283cf024b8..2df65305e5 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 @@ 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 c9abbca121..3d02a8bfff 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 @@ 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 abdd483fb1..8edbd0c2c1 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 @@ 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 ec598351c0..11855c6a22 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 @@ 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 0000000000..d4c0a15729 --- /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 0000000000..f92a23e7e2 --- /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 0000000000..74607228bd --- /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 cf86da9b5d..be00c31f74 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 @@ 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 override void Parse(Queue data) 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 0000000000..fc8dc441d6 --- /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 100072c93a..4da4cb0024 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 @@ 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 0000000000..a1101eca9b --- /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 e41536177a..ccd1e2b555 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 @@ 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 05f5e2d8b5..0ddbc43139 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 @@ 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 00e74b80ce..a6d81d9a02 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 @@ 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 6a04585b5e..3c09e43e28 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 @@ 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 override void Parse(Queue data) 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 0000000000..25d30c4a7d --- /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 4e32ef37af..9c782d5572 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 @@ 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 8bc2f06092..bf315b3dd3 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 @@ 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 c7d63dd3db..a29374e11b 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 @@ 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 fae29a94ef..9a56284006 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 @@ 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 @@ protected override void Parse(Queue data) 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 @@ protected override void Parse(Queue data) 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 a35eeec130..dbc7c40ac8 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 @@ 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 289d432c3f..7394e13db7 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 @@ 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 @@ protected override void Parse(Queue data) 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 b7cd111711..a676cfcaa0 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 @@ 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 0000000000..e4c67cc73c --- /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 c325e3130c..13cc55f98d 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 @@ 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 64742c5f32..0b8e41ebd2 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 @@ 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 e5830f4d1e..ca8807b54b 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 @@ 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 1c4e8d8d2c..5152c9cd85 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 12c6169571..ebf75e418c 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 91fa60eae6..2e270842be 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 7bd213a154f263c6238c3912b2bf3e0bddb9db0c Mon Sep 17 00:00:00 2001 From: Anon Date: Wed, 4 Dec 2024 21:25:22 +0100 Subject: [PATCH 09/38] Fixed the potion component crash --- .../Protocol/Handlers/DataTypes.cs | 342 +++++++++--------- .../1_20_6/PotionContentsComponent.cs | 7 +- 2 files changed, 180 insertions(+), 169 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 45b74645c4..160e0fb8c3 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -733,190 +733,198 @@ private object ReadNbtField(Queue cache, int fieldType) 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 - { - type = metadataPalette.GetDataType(typeId); - } - catch (KeyNotFoundException) + while (key != terminteValue) { - 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)) - { + break; + case EntityMetaDataType.OptionalChat: // Optional Chat + if (ReadNextBool(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.Direction: // Direction (VarInt) - value = ReadNextVarInt(cache); - break; - case EntityMetaDataType.OptionalUuid: // Optional UUID - if (ReadNextBool(cache)) - { - value = ReadNextUUID(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 + 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)) - { + 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 be00c31f74..715cacd308 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 override void Parse(Queue data) 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 f83e7c570794277052c5c7d44a49110f379beb30 Mon Sep 17 00:00:00 2001 From: Anon Date: Fri, 6 Dec 2024 16:45:48 +0100 Subject: [PATCH 10/38] 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 4f6fca4789..e21e3cdef6 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -196,7 +196,7 @@ public static Enchantments GetEnchantmentById(int protocolVersion, short id) { >= 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 5b220474c1..db544f3948 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,7 @@ public static EntityMetadataPalette GetPalette(int protocolVersion) <= 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 6ff4d63b73..1b68583d7b 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -17,7 +17,6 @@ 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 @@ static class Program 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 @@ static void Main(string[] args) options.EnableTracing = true; options.SendDefaultPii = false; }); + + AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) => + { + SentrySdk.CaptureException((Exception)eventArgs.ExceptionObject); + }; } Task.Run(() => @@ -208,7 +212,7 @@ static void Main(string[] args) } if (!Config.Main.Advanced.EnableSentry) - _sentrySdk.Dispose(); + _sentrySdk?.Dispose(); } //Other command-line arguments @@ -355,7 +359,7 @@ static void Main(string[] args) 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 @@ static void Main(string[] args) 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 @@ static void Main(string[] args) } // 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 @@ private static void InitializeClient() 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 @@ private static void InitializeClient() } else { - HandleFailure(Translations.error_realms_disabled, false, null); + HandleFailure(Translations.error_realms_disabled); return; } } @@ -560,7 +564,7 @@ private static void InitializeClient() 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 @@ private static void InitializeClient() 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 @@ private static void InitializeClient() } else { - HandleFailure(Translations.error_forgeforce, true, ChatBots.AutoRelog.DisconnectReason.ConnectionLost); + HandleFailure(Translations.error_forgeforce, true, ChatBot.DisconnectReason.ConnectionLost); return; } } @@ -672,8 +676,7 @@ private static void InitializeClient() 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 @@ public static void WriteBackSettings(bool enableBackup = true) /// 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 @@ public static void Restart(int delaySeconds = 0, bool keepAccountAndServerSettin 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 @@ public static void DoExit(int exitcode = 0) /// public static void Exit(int exitcode = 0) { - new Thread(new ThreadStart(() => { DoExit(exitcode); })).Start(); + new Thread(() => { DoExit(exitcode); }).Start(); } /// @@ -759,7 +763,7 @@ public static void Exit(int exitcode = 0) /// 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 f6add9cfae..0648601aa2 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 160e0fb8c3..dc953c5630 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -974,7 +974,7 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) ReadDustParticle(cache); break; case 13: - // 1.20,6+ - minecraft:dust + // 1.20.6+ - minecraft:dust ReadDustParticle(cache); break; case 14: @@ -1038,7 +1038,7 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ public void ReadParticleData(Queue cache, ItemPalette itemPalette) 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 @@ private void ReadDustParticleColorTransition(Queue cache) 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 6e4575ab5b..a0a0d117c4 100644 --- a/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs +++ b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs @@ -10,6 +10,12 @@ internal static class DeclareCommands 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 0000000000..fc8b64bba0 --- /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 5deac47bd3..7d80d4eee9 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -48,7 +48,7 @@ public PacketTypePalette GetTypeHandler(int protocol) { 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 @@ public PacketTypePalette GetTypeHandler(int protocol) <= 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 9eab7b390e..d3feabb737 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -31,6 +31,7 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 b682551f16..f8a8c42728 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -72,8 +72,9 @@ class Protocol18Handler : IMinecraftCom 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ internal Tuple> ReadNextPacket() //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 @@ internal bool HandlePacket(int packetId, Queue packetData) } 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 @@ private void SendPacket(int packetId, IEnumerable packetData) //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 @@ public bool SendUseItem(int hand, int sequenceId) 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 0000000000..d97b9cf863 --- /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 0000000000..cfa0f833e5 --- /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 5152c9cd85..9fdc974cf4 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 ebf75e418c..afc5a1342c 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -25,7 +25,7 @@ public StructuredComponentsRegistry1206(DataTypes dataTypes, ItemPalette itemPal 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 0000000000..076b49d029 --- /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 0000000000..7515020fb8 --- /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 9550246346..2fd0cb82c2 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -20,6 +20,7 @@ public 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 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 a2ea85b512..b53354ee90 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -153,7 +153,7 @@ public static IMinecraftCom GetProtocolHandler(TcpClient client, int protocolVer 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 @@ public static int MCVer2ProtocolVersion(string mcVersion) 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 @@ public static string ProtocolVersion2MCVer(int protocol) 764 => "1.20.2", 765 => "1.20.4", 766 => "1.20.6", + 767 => "1.21", _ => "0.0" }; } From 7152072598e2afb524d4345d58080a90eff40a7f Mon Sep 17 00:00:00 2001 From: Anon Date: Sun, 22 Dec 2024 13:20:04 +0100 Subject: [PATCH 11/38] 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 70470019bd..bd71f18a4e 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 8d524fa80b..9af643c7e6 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 @@ public static class KeysCache 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 956f6ab2f6..1b64fea032 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 @@ public static class SessionCache 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 @@ public static SessionToken Get(string login) /// 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 @@ private static void HandlePending(object? sender, ElapsedEventArgs e) /// 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 @@ private static bool LoadFromDisk() } } - //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 @@ private static bool LoadFromDisk() 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 @@ private static bool LoadFromDisk() { 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 @@ private static void SaveToDisk() 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 12/38] 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 8d500156a2..db5e6fb802 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 13/38] 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 812d3fa0ed..8687b99f86 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 ff1c570a783fc4df1adb741d64e8efb0c7f2f5a7 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Thu, 19 Mar 2026 00:11:13 +0800 Subject: [PATCH 14/38] 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 25e75a74b2..c0c3aa8e89 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 @@ public override void Update() 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 cdc26e1432..2068c662c0 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 @@ private static int LogChunkStatus(CmdResult r, Location? pos = null, Tuple packetData) // 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 15/38] 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 f552b2f913..a274b6e438 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2521,9 +2521,9 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 16/38] 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 | 44 ++++++++++--------- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index b6240ffc13..8add5c2319 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 @@ public class World 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 @@ public static void LoadDefaultDimensions1206Plus() 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 a274b6e438..3a0abe274d 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -458,40 +458,41 @@ internal bool HandlePacket(int packetId, Queue packetData) } 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); - + + Dictionary? nbtData = null; if (hasData) + nbtData = dataTypes.ReadNextNbt(packetData); + + if (isChat) + availableChats!.Add(i, entryId); + else if (isDimension) { - // TODO: Parse in case when the server data packs differ from the client - dataTypes.ReadNextNbt(packetData); + dimensionIdMap!.Add(i, entryId); + if (nbtData != null && handler.GetTerrainEnabled()) + World.StoreOneDimension(entryId, nbtData); } - - if (registryId == "minecraft:chat_type") - avaliableChats.Add(i, entryId); - else dimensionType.Add(i, entryId); } - 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 17/38] 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 3a0abe274d..dab9f2e0f5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -753,10 +753,9 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 18/38] 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 b9d867559a..247d45ea7c 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 @@ public class Item /// 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 @@ public Item(ItemType itemType, int count, int data, Dictionary? 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 @@ public bool IsEmpty } /// - /// 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 @@ public string? DisplayName } /// - /// 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 @@ public string[]? Lores } /// - /// 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 @@ public int Damage } } + /// + /// 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 @@ public string ToFullString() 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 96dcb61533..e9b0b38c69 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 @@ private static bool TryMergeSlot(Container inventory, Item item, int slotId, Ite /// 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 @@ public bool DoWindowAction(int windowId, int slotId, WindowActionType action) { // 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 @@ public bool DoWindowAction(int windowId, int slotId, WindowActionType action) { // 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 dc953c5630..af09909ca3 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 @@ public Dictionary ReadNextNbt(Queue cache) } 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 @@ public byte[] GetLocation(Location location) /// 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) + { + if (item == null || item.IsEmpty) + { + slotData.AddRange(GetVarInt(0)); + } + else + { + 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) { - // MC 1.13 and greater if (item == null || item.IsEmpty) - slotData.AddRange(GetBool(false)); // No item + slotData.AddRange(GetBool(false)); else { - slotData.AddRange(GetBool(true)); // Item is present + 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 @@ public byte[] GetItemSlot(Item? item, ItemPalette itemPalette) } 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 7465740b6e..2c0b66e360 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 11c48e1f1d..3ae070579e 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs @@ -35,7 +35,8 @@ public StructuredComponent ParseComponent(int id, Queue data) 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 19/38] 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 0000000000..16c65cd810 --- /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 e9b0b38c69..c632569b99 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -425,8 +425,8 @@ private void RegisterBots(bool reload = false) 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 d3db4e38f2..f907eadd30 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 @@ private static string NbtToString(Dictionary nbt) { 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 @@ private static string NbtToString(Dictionary nbt) { 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 20/38] 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 8add5c2319..be666f4f02 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -28,6 +28,11 @@ public class World /// 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 @@ public static bool HasAnyDimension() 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 dab9f2e0f5..7806af21ea 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -463,9 +463,11 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) if (!handler.GetTerrainEnabled() || !World.HasAnyDimension()) World.LoadDefaultDimensions1206Plus(); } + else if (isAttribute) + World.SetAttributeIdMap(attributeIdMap!); } break; @@ -2502,39 +2514,19 @@ private bool HandlePlayPackets(int packetId, Queue packetData) ? 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 21/38] 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 be666f4f02..c09997613c 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -244,12 +244,46 @@ public static void SetAttributeIdMap(Dictionary idMap) /// /// 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 7806af21ea..e34306b712 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2556,7 +2556,7 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 22/38] 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 063d1d2000..5c5044f762 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 ef0875ef0e..7305ee8c2b 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 2b050aff0b..053fc918a3 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 f848750d36..aac861c2aa 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 override Queue Serialize() { 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 23/38] 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 | 37 ++++++------ 2 files changed, 47 insertions(+), 47 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 87bb17be88..ccfcf9159f 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 715cacd308..e8b3443e6b 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 override Queue Serialize() { var data = new List(); data.AddRange(DataTypes.GetBool(HasPotionId)); - data.AddRange(DataTypes.GetVarInt(PotiononId)); + if (HasPotionId) + data.AddRange(DataTypes.GetVarInt(PotionId)); + data.AddRange(DataTypes.GetBool(HasCustomColor)); - data.AddRange(DataTypes.GetInt(CustomColor)); + if (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()); - } + 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 24/38] 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 e21e3cdef6..4d576bcf51 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public class EnchantmentMapping { 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 @@ public static Enchantments GetEnchantmentById(int protocolVersion, short id) 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 13fdd5952b..4a08987920 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 @@ public enum Enchantments : short BlastProtection, Breach, Channeling, - DepthStrieder, + DepthStrider, Density, - Efficency, + Efficiency, FeatherFalling, FireAspect, FireProtection, @@ -23,7 +23,7 @@ public enum Enchantments : short 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 e38b41fde1..bfc942a1db 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 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))); + { + 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 override Queue Serialize() 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 25/38] =?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 | 38 ++++++++++--------- .../1_20_6/WrittenBlookContentComponent.cs | 33 ++++++++-------- 5 files changed, 75 insertions(+), 58 deletions(-) diff --git a/MinecraftClient/Inventory/BookPage.cs b/MinecraftClient/Inventory/BookPage.cs index c7ec7e44f3..9240d77e67 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 af09909ca3..d36ab2572b 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -1231,18 +1231,31 @@ private byte[] GetNbt(Dictionary? nbt, bool root) 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 fc8dc441d6..17853fbdef 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 override Queue Serialize() 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 25d30c4a7d..374f1962d2 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 override void Parse(Queue data) 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 override void Parse(Queue data) { 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 override Queue Serialize() 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,23 +89,23 @@ public override Queue Serialize() data.AddRange(DataTypes.GetString(assetName)); } } - data.AddRange(DataTypes.GetString(Description)); + data.AddRange(DataTypes.GetNbt(DescriptionNbt)); + } - 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.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.GetBool(ShowInTooltip)); + 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); } } \ No newline at end of file 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 bf315b3dd3..1f7cc905e3 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 override void Parse(Queue data) 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 override Queue Serialize() 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 26/38] =?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 | 18 +++++++++++------- 2 files changed, 14 insertions(+), 8 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 9a56284006..c8bf2369a3 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 override Queue Serialize() 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 0b8e41ebd2..6170dffaec 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 @@ protected override void Parse(Queue data) IsExactMatch = dataTypes.ReadNextBool(data); if (IsExactMatch) + { ExactValue = dataTypes.ReadNextString(data); - else // Ranged Match + } + else { - MinValue = dataTypes.ReadNextString(data); - MaxValue = dataTypes.ReadNextString(data); + MinValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; + MaxValue = dataTypes.ReadNextBool(data) ? dataTypes.ReadNextString(data) : null; } } @@ -45,11 +47,13 @@ public override Queue Serialize() } 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 27/38] =?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 bdeb1d2433..af5ff63c71 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 28/38] =?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 024b7a439a..f4f2fc9297 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 a7c8bda336..6fc8ae3ebd 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 8aa711ef1d..aaca1b7217 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 override void Parse(Queue data) 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 29/38] =?UTF-8?q?refactor:=20StructuredComponents=20batch?= =?UTF-8?q?=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 be3950fe05..8037d07c75 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 053fc918a3..c132e06f5e 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 74607228bd..0acc10e6b5 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 9c782d5572..e22c714a24 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 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!"); + data.AddRange(DataTypes.GetVarInt(Pages.Count)); foreach (var page in Pages) { @@ -45,7 +41,7 @@ public override Queue Serialize() 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 30/38] 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 0000000000..6759d89977 --- /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 bfe150d1c3..299eeb3eab 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 @@ public enum ItemType 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 31/38] 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 e34306b712..77dc845c91 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -191,6 +191,7 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan // 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 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 0000000000..6357e47fff --- /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 90123fe68b..4966570936 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs @@ -16,6 +16,11 @@ protected void RegisterSubComponent(string name) where T : SubComponent _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 7515020fb8..2afd285295 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 32/38] 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 | 33 ++++++--------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index c09997613c..0a83ff975a 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -257,6 +257,9 @@ public static void SetAttributeIdMap(Dictionary idMap) 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 @@ private static void LoadDefaultAttributes() { 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 77dc845c91..735ce498da 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -2687,39 +2687,30 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 - - // Explosion Sound - dataTypes.ReadNextString(packetData); // Sound Name - - if (protocolVersion < MC_1_21_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) - 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 33/38] 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 db24f77b20..53afecfa80 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 db544f3948..e7e5c97883 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -22,7 +22,8 @@ public static EntityMetadataPalette GetPalette(int protocolVersion) <= 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 0000000000..67b61cc3cc --- /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 d36ab2572b..271d98f88e 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -842,9 +842,13 @@ private object ReadNbtField(Queue cache, int fieldType) 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 @@ private object ReadNbtField(Queue cache, int fieldType) 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 @@ private object ReadNbtField(Queue cache, int fieldType) 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 34/38] 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 0000000000..b7f264646d --- /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 fc8f35e055..2ebfd2d8c0 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 0000000000..cce914df61 --- /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 0000000000..cc26c31f2f --- /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 0000000000..ab914cf80d --- /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 0000000000..9264397783 --- /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 35/38] 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 994e34ae42..2df6a92fb4 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 @@ private int UseBlockAtLocation(CmdResult r, Location block) 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 4d576bcf51..cf25ea9466 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -207,9 +207,74 @@ public static Enchantments GetEnchantmentById(int protocolVersion, short id) } 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 @@ public static int GetRegistryId1206ByEnchantment(Enchantments enchantment) 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 c632569b99..86d205d16d 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -2392,10 +2392,19 @@ public bool InteractEntity(int entityID, InteractType type, Hand hand = Hand.Mai /// /// 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 735ce498da..3f5590a974 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -465,10 +465,12 @@ internal bool HandlePacket(int packetId, Queue packetData) 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 @@ internal bool HandlePacket(int packetId, Queue packetData) } 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 @@ internal bool HandlePacket(int packetId, Queue packetData) } else if (isAttribute) World.SetAttributeIdMap(attributeIdMap!); + else if (isEnchantment) + EnchantmentMapping.SetDynamicEnchantmentIdMap(enchantmentIdMap!); } break; @@ -2339,6 +2344,8 @@ private bool HandlePlayPackets(int packetId, Queue packetData) { 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 d969d1b473..3cac3667aa 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.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 override void Parse(Queue data) 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 36/38] 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 0000000000..42edc7fd36 --- /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 299eeb3eab..318eb1fad1 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -121,6 +121,7 @@ public enum ItemType BlackStainedGlassPane, BlackTerracotta, BlackWool, + BlackBundle, Blackstone, BlackstoneSlab, BlackstoneStairs, @@ -145,6 +146,7 @@ public enum ItemType BlueStainedGlassPane, BlueTerracotta, BlueWool, + BlueBundle, BoggedSpawnEgg, BoltArmorTrimSmithingTemplate, Bone, @@ -152,6 +154,7 @@ public enum ItemType BoneMeal, Book, Bookshelf, + BordureIndentedBannerPattern, Bow, Bowl, BrainCoral, @@ -182,6 +185,7 @@ public enum ItemType BrownStainedGlassPane, BrownTerracotta, BrownWool, + BrownBundle, Brush, BubbleCoral, BubbleCoralBlock, @@ -298,6 +302,8 @@ public enum ItemType CrackedStoneBricks, Crafter, CraftingTable, + CreakingHeart, + CreakingSpawnEgg, CreeperBannerPattern, CreeperHead, CreeperSpawnEgg, @@ -339,6 +345,7 @@ public enum ItemType CyanStainedGlassPane, CyanTerracotta, CyanWool, + CyanBundle, DamagedAnvil, Dandelion, DangerPotterySherd, @@ -472,6 +479,7 @@ public enum ItemType Feather, FermentedSpiderEye, Fern, + FieldMasonedBannerPattern, FilledMap, FireCharge, FireCoral, @@ -548,6 +556,7 @@ public enum ItemType GrayStainedGlassPane, GrayTerracotta, GrayWool, + GrayBundle, GreenBanner, GreenBed, GreenCandle, @@ -561,6 +570,7 @@ public enum ItemType GreenStainedGlassPane, GreenTerracotta, GreenWool, + GreenBundle, Grindstone, GuardianSpawnEgg, Gunpowder, @@ -668,6 +678,7 @@ public enum ItemType LightBlueStainedGlassPane, LightBlueTerracotta, LightBlueWool, + LightBlueBundle, LightGrayBanner, LightGrayBed, LightGrayCandle, @@ -681,6 +692,7 @@ public enum ItemType LightGrayStainedGlassPane, LightGrayTerracotta, LightGrayWool, + LightGrayBundle, LightWeightedPressurePlate, LightningRod, Lilac, @@ -699,6 +711,7 @@ public enum ItemType LimeStainedGlassPane, LimeTerracotta, LimeWool, + LimeBundle, LingeringPotion, LlamaSpawnEgg, Lodestone, @@ -717,6 +730,7 @@ public enum ItemType MagentaStainedGlassPane, MagentaTerracotta, MagentaWool, + MagentaBundle, MagmaBlock, MagmaCream, MagmaCubeSpawnEgg, @@ -855,6 +869,7 @@ public enum ItemType OrangeTerracotta, OrangeTulip, OrangeWool, + OrangeBundle, OxeyeDaisy, OxidizedChiseledCopper, OxidizedCopper, @@ -868,6 +883,26 @@ public enum ItemType 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 @@ public enum ItemType PinkTerracotta, PinkTulip, PinkWool, + PinkBundle, Piston, PitcherPlant, PitcherPod, @@ -970,6 +1006,7 @@ public enum ItemType PurpleStainedGlassPane, PurpleTerracotta, PurpleWool, + PurpleBundle, PurpurBlock, PurpurPillar, PurpurSlab, @@ -1020,6 +1057,7 @@ public enum ItemType RedTerracotta, RedTulip, RedWool, + RedBundle, Redstone, RedstoneBlock, RedstoneLamp, @@ -1167,6 +1205,8 @@ public enum ItemType StrippedMangroveWood, StrippedOakLog, StrippedOakWood, + StrippedPaleOakLog, + StrippedPaleOakWood, StrippedSpruceLog, StrippedSpruceWood, StrippedWarpedHyphae, @@ -1312,6 +1352,7 @@ public enum ItemType WhiteTerracotta, WhiteTulip, WhiteWool, + WhiteBundle, WildArmorTrimSmithingTemplate, WindCharge, WitchSpawnEgg, @@ -1341,6 +1382,7 @@ public enum ItemType 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 0000000000..e46c7650e0 --- /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 e7e5c97883..0e86e828fa 100644 --- a/MinecraftClient/Mapping/EntityMetadataPalette.cs +++ b/MinecraftClient/Mapping/EntityMetadataPalette.cs @@ -23,7 +23,7 @@ public static EntityMetadataPalette GetPalette(int protocolVersion) <= 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 0000000000..894738d2a1 --- /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 1b628729b0..2aab335807 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 @@ public enum EntityType Camel, Cat, CaveSpider, + CherryBoat, + CherryChestBoat, ChestBoat, ChestMinecart, Chicken, Cod, CommandBlockMinecart, Cow, + Creaking, + CreakingTransient, Creeper, + DarkOakBoat, + DarkOakChestBoat, Dolphin, Donkey, DragonFireball, @@ -77,18 +89,26 @@ public enum EntityType 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 @@ public enum EntityType SpawnerMinecart, SpectralArrow, Spider, + SpruceBoat, + SpruceChestBoat, Squid, Stray, Strider, diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 6830061050..6c93239706 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 @@ public enum Material CrackedStoneBricks, Crafter, CraftingTable, + CreakingHeart, CreeperHead, CreeperWallHead, CrimsonButton, @@ -662,6 +663,26 @@ public enum Material 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 @@ public enum Material PottedOakSapling, PottedOrangeTulip, PottedOxeyeDaisy, + PottedPaleOakSapling, PottedPinkTulip, PottedPoppy, PottedRedMushroom, @@ -926,6 +948,8 @@ public enum Material StrippedMangroveWood, StrippedOakLog, StrippedOakWood, + StrippedPaleOakLog, + StrippedPaleOakWood, StrippedSpruceLog, StrippedSpruceWood, StrippedWarpedHyphae, diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index b8a1f788e7..ee6eda7442 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -46,7 +46,7 @@ static class Program 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 3f5590a974..13b8640894 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -73,6 +73,7 @@ class Protocol18Handler : IMinecraftCom 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 b53354ee90..6ac6ca24f0 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 @@ public static IMinecraftCom GetProtocolHandler(TcpClient client, int protocolVer 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 @@ public static int MCVer2ProtocolVersion(string mcVersion) case "1.21": case "1.21.1": return 767; + case "1.21.2": + return 768; default: return 0; } @@ -432,6 +434,7 @@ public static string ProtocolVersion2MCVer(int 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 37/38] 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 0000000000..76deae7e75 --- /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 7d80d4eee9..9141627b97 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 @@ public PacketTypePalette GetTypeHandler(int protocol) { 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 @@ public PacketTypePalette GetTypeHandler(int protocol) <= 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 d3feabb737..19d724559c 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 @@ public enum PacketTypesIn EntityMovement, // EntityPosition, // EntityPositionAndRotation, // + EntityPositionSync, // Added in 1.21.2 EntityProperties, // EntityRotation, // EntitySoundEffect, // @@ -58,6 +59,7 @@ public enum PacketTypesIn EntityTeleport, // EntityVelocity, // Explosion, // + MoveMinecartAlongTrack, // Added in 1.21.2 FacePlayer, // FeatureFlags, // Added in 1.19.3 HeldItemChange, // @@ -84,6 +86,7 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 @@ public enum PacketTypesIn 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 1149a71f78..9512024af8 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 @@ public enum PacketTypesOut 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 @@ public enum PacketTypesOut 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 13b8640894..1b1cb1fe17 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1411,18 +1411,40 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) } } - 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool StartEncryption(string uuid, string sessionID, LoginType type, byte } } - // 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 @@ public bool SendClientSettings(string language, byte viewDistance, byte difficul 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 0000000000..ad931c61ea --- /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 0000000000..25592d2f76 --- /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 0000000000..36c596903d --- /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 0000000000..4ef63563ea --- /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 0000000000..c63e3f4dc9 --- /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 0000000000..1832234dec --- /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 0000000000..1aa739d077 --- /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 0000000000..65cdac8c50 --- /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 0000000000..08dcb91c0b --- /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 0000000000..aed0af3457 --- /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 0000000000..60f175c683 --- /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 0000000000..ead551aade --- /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 0000000000..361cbfae62 --- /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 0000000000..ba5df82180 --- /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 2fd0cb82c2..9729e5f426 100644 --- a/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -21,6 +21,7 @@ public 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 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 38/38] 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 1b1cb1fe17..3ef61f97a5 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -125,21 +125,21 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) // 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) 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 @@ private bool HandlePlayPackets(int packetId, Queue packetData) } 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 @@ public bool SendWindowAction(int windowId, int slotId, WindowActionType action, 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 @@ public bool SendCloseWindow(int windowId) 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)