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 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/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 badadb9964..e21e3cdef6 100644 --- a/MinecraftClient/Inventory/EnchantmentMapping.cs +++ b/MinecraftClient/Inventory/EnchantmentMapping.cs @@ -10,168 +10,214 @@ 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 }, - { 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 Dictionary() + 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+ - private static Dictionary enchantmentMappings = new Dictionary() + // 1.19 - 1.20.4 + 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() + { + //id type + { 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"); - 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_21_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) + public static string GetEnchantmentName(Enchantments 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("Enchantments.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..13fdd5952b 100644 --- a/MinecraftClient/Inventory/Enchantments.cs +++ b/MinecraftClient/Inventory/Enchantments.cs @@ -1,46 +1,49 @@ namespace MinecraftClient.Inventory { // Not implemented for 1.14 - public enum Enchantment : short + public enum Enchantments : 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/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/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/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/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/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/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/EntityMetadataPalette.cs b/MinecraftClient/Mapping/EntityMetadataPalette.cs index 1596323145..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_4_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.20.4 + + <= Protocol18Handler.MC_1_21_Version => new EntityMetadataPalette1194(), // 1.19.4 - 1.21 + _ => throw new NotImplementedException() }; } 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/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 f92ce1b8d7..5076191452 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -119,6 +119,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; } @@ -144,9 +147,13 @@ 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; + 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; @@ -182,6 +189,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) @@ -317,6 +325,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 @@ -2869,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/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/Program.cs b/MinecraftClient/Program.cs index e36f6bc74a..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.4"; + 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 c9ca6e5956..0648601aa2 100644 --- a/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/ConfigurationPacketTypesIn.cs @@ -2,16 +2,23 @@ namespace MinecraftClient.Protocol.Handlers; public enum ConfigurationPacketTypesIn { - PluginMessage, + CookieRequest, + CustomReportDetails, Disconnect, + FeatureFlags, FinishConfiguration, KeepAlive, + KnownDataPacks, Ping, + PluginMessage, RegistryData, - ResourcePack, RemoveResourcePack, - FeatureFlags, + ResetChat, + ResourcePack, + ServerLinks, + 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/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index dd109709cb..dc953c5630 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,94 @@ 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 (itemCount <= 0) return null; + + itemId = ReadNextVarInt(cache); + item = new Item(itemPalette.FromId(itemId), itemCount, null); + + var numberOfComponentsToAdd = ReadNextVarInt(cache); + var numberofComponentsToRemove = ReadNextVarInt(cache); + + for (var i = 0; i < numberOfComponentsToAdd; i++) + { + var componentTypeId = ReadNextVarInt(cache); - if (!itemPresent) - return null; + var strcuturedComponentHandler = new StructuredComponentsHandler(protocolversion, this, itemPalette); + strcturedComponentsToAdd.Add(strcuturedComponentHandler.Parse(componentTypeId, cache)); + } - var itemId = ReadNextVarInt(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 + + return item; + case >= Protocol18Handler.MC_1_13_Version: + { + var itemPresent = ReadNextBool(cache); - if (itemId == -1) - return null; + if (!itemPresent) + return null; - var type = itemPalette.FromId(itemId); - var itemCount = ReadNextByte(cache); - var nbt = ReadNextNbt(cache); - return new Item(type, itemCount, nbt); - } - else - { - var itemId = ReadNextShort(cache); + itemId = ReadNextVarInt(cache); - if (itemId == -1) - return null; + if (itemId == -1) + return null; - var itemCount = ReadNextByte(cache); - var data = ReadNextShort(cache); - var nbt = ReadNextNbt(cache); + 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; - // 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); + 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); } } @@ -674,188 +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 - if (ReadNextBool(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.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; } /// @@ -879,15 +948,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 +973,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 +998,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 +1009,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 +1036,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 +1051,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 +1063,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 +1074,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 +1088,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 +1112,26 @@ 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 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) + 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; } } @@ -1020,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 /// @@ -1424,6 +1561,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/Packet/s2c/DeclareCommands.cs b/MinecraftClient/Protocol/Handlers/Packet/s2c/DeclareCommands.cs index 07d37c7207..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) @@ -103,7 +109,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 +134,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/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/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 e012f853e3..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_4_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(), @@ -67,7 +67,9 @@ 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(), + <= 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 b4b8debc88..d3feabb737 100644 --- a/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs +++ b/MinecraftClient/Protocol/Handlers/PacketTypesIn.cs @@ -29,9 +29,12 @@ public enum PacketTypesIn CloseWindow, // CollectItem, // 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 DeclareCommands, // DeclareRecipes, // DestroyEntities, // @@ -83,6 +86,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 @@ -92,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 @@ -115,6 +120,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 +128,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 4053a94a86..f8a8c42728 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -71,8 +71,10 @@ 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; + 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; @@ -122,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_4_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_4_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_4_Version) + protocolVersion is < MC_1_8_Version or > MC_1_21_Version) { log.Error($"§c{Translations.extra_entity_disabled}"); handler.SetEntityHandlingEnabled(false); @@ -145,8 +147,9 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan Block.Palette = protocolVersion switch { // Block palette - > MC_1_20_4_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_4_Version => new Palette1204(), >= MC_1_20_Version => new Palette120(), MC_1_19_4_Version => new Palette1194(), @@ -163,8 +166,9 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan entityPalette = protocolVersion switch { // Entity palette - > MC_1_20_4_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_4_Version => new EntityPalette1204(), >= MC_1_20_Version => new EntityPalette120(), MC_1_19_4_Version => new EntityPalette1194(), @@ -185,8 +189,9 @@ public Protocol18Handler(TcpClient Client, int protocolVersion, IMinecraftComHan itemPalette = protocolVersion switch { // Item palette - > MC_1_20_4_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_4_Version => new ItemPalette1204(), >= MC_1_20_Version => new ItemPalette120(), MC_1_19_4_Version => new ItemPalette1194(), @@ -345,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 @@ -396,8 +401,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; @@ -409,6 +422,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)); @@ -428,11 +448,52 @@ 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 + { + // 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 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) + { + // TODO: Parse in case when the server data packs differ from the client + dataTypes.ReadNextNbt(packetData); + } + + if (registryId == "minecraft:chat_type") + avaliableChats.Add(i, entryId); + else dimensionType.Add(i, entryId); + } + + if (registryId == "minecraft:chat_type") + ChatParser.ReadChatType(avaliableChats); + else + { + World.LoadDefaultDimensions1206Plus(); + } + } break; @@ -444,6 +505,34 @@ 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); + + 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: @@ -594,7 +683,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()) @@ -662,7 +751,7 @@ 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; } @@ -713,8 +802,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()) @@ -733,6 +833,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 @@ -1125,7 +1228,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; @@ -1168,10 +1271,21 @@ private bool HandlePlayPackets(int packetId, Queue packetData) case PacketTypesIn.Respawn: string? dimensionTypeNameRespawn = null; Dictionary? dimensionTypeRespawn = null; + if (protocolVersion >= MC_1_16_Version) { 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"; + break; case >= MC_1_19_Version: dimensionTypeNameRespawn = dataTypes.ReadNextString(packetData); // Dimension Type: Identifier @@ -1209,7 +1323,7 @@ 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; } @@ -2196,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); } @@ -2282,7 +2405,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) @@ -2389,11 +2512,41 @@ 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" }, + { 22, "generic.submerged_mining_speed" }, + { 23, "generic.sweeping_damage_ratio" }, + { 24, "generic.water_movement_efficiency" } + }; 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(); @@ -2403,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) @@ -2439,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_4_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, @@ -2529,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; @@ -2662,6 +2828,26 @@ 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); + + McClient.Instance?.Transfer(host, port); + break; + default: return false; //Ignored packet } @@ -2759,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)) @@ -2865,9 +3051,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 @@ -2902,7 +3094,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(); @@ -2922,6 +3114,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) { @@ -2991,6 +3187,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: { @@ -3013,6 +3210,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; @@ -3277,14 +3478,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; @@ -3294,85 +3495,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; @@ -3390,7 +3584,7 @@ public bool SendChatCommand(string command, PlayerKeyPair? playerKeyPair) return false; } } - + /// /// Send a chat message to the server /// @@ -3892,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; } @@ -4558,7 +4759,91 @@ 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; + } + + McClient.Instance?.DeleteCookie(name); + 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]; @@ -4579,6 +4864,7 @@ internal enum CurrentState { Login = 0, Configuration, - Play + Play, + Transfer } } 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/1_20_6/AttributeModifiersComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs new file mode 100644 index 0000000000..d969d1b473 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/AttributeModifiersComponent.cs @@ -0,0 +1,41 @@ +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 AttributeModifiersComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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((AttributeSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.Attribute, data)); + + ShowInTooltip = dataTypes.ReadNextBool(data); + } + + public override Queue Serialize() + { + var data = new List(); + data.AddRange(DataTypes.GetVarInt(NumberOfAttributes)); + + 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()); + + 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/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/BundleContentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.cs new file mode 100644 index 0000000000..063d1d2000 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/BundleContentsComponent.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 BundleContentsComponent(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/CanBreakComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent.cs new file mode 100644 index 0000000000..06ca3a7b83 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanBreakComponent.cs @@ -0,0 +1,41 @@ +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 CanBreakComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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((BlockPredicateSubcomponent)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/CanPlaceOnComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent.cs new file mode 100644 index 0000000000..581c089f3a --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CanPlaceOnComponent.cs @@ -0,0 +1,41 @@ +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 CanPlaceOnComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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((BlockPredicateSubcomponent)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/ChargedProjectilesComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.cs new file mode 100644 index 0000000000..ef0875ef0e --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ChargedProjectilesComponent.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 ChargedProjectilesComponent(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/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/CreativeSlotLockComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent.cs new file mode 100644 index 0000000000..06989ec99d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CreativeSlotLockComponent.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 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/CustomDataComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent.cs new file mode 100644 index 0000000000..22b22b70e3 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomDataComponent.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 CustomDataComponent(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/CustomModelDataComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent.cs new file mode 100644 index 0000000000..e8c055281d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomModelDataComponent.cs @@ -0,0 +1,22 @@ +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 CustomModelDataComponent(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); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs new file mode 100644 index 0000000000..024b7a439a --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/CustomNameComponent.cs @@ -0,0 +1,24 @@ +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 CustomNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/DamageComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent.cs new file mode 100644 index 0000000000..9ac84800ee --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DamageComponent.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 DamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/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/DyeColorComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent.cs new file mode 100644 index 0000000000..fc6de3d0ae --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/DyeColorComponent.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 DyeColorComponent(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/EnchantmentGlintOverrideComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.cs new file mode 100644 index 0000000000..bdeb1d2433 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentGlintOverrideComponent.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 EnchantmentGlintOverrideComponent(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/EnchantmentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.cs new file mode 100644 index 0000000000..e38b41fde1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/EnchantmentsComponent.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 EnchantmentsComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/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/FireResistantComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent.cs new file mode 100644 index 0000000000..e0eed96cad --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FireResistantComponent.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 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/FoodComponentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.cs new file mode 100644 index 0000000000..f848750d36 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/FoodComponentComponent.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 FoodComponentComponent(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((EffectSubComponent)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/HideAdditionalTooltipComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent.cs new file mode 100644 index 0000000000..13a7197aeb --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideAdditionalTooltipComponent.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 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/HideTooltipComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent.cs new file mode 100644 index 0000000000..b1d0783edc --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/HideTooltipComponent.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 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/IntangibleProjectileComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent.cs new file mode 100644 index 0000000000..cba25e6eb4 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/IntangibleProjectileComponent.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 IntangibleProjectileComponent(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/ItemNameComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs new file mode 100644 index 0000000000..a7c8bda336 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ItemNameComponent.cs @@ -0,0 +1,24 @@ +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 ItemNameComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/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/LoreComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs new file mode 100644 index 0000000000..8aa711ef1d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/LoreComponent.cs @@ -0,0 +1,36 @@ +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, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/MapColorComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent.cs new file mode 100644 index 0000000000..7c7e918644 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapColorComponent.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 MapColorComponent(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/MapDecorationsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent.cs new file mode 100644 index 0000000000..c6f8f3438f --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapDecorationsComponent.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 MapDecorationsComponent(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/MapIdComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent.cs new file mode 100644 index 0000000000..2df65305e5 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapIdComponent.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 MapIdComponent(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/MapPostProcessingComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent.cs new file mode 100644 index 0000000000..3d02a8bfff --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MapPostProcessingComponent.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 MapPostProcessingComponent(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/MaxDamageComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent.cs new file mode 100644 index 0000000000..8edbd0c2c1 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxDamageComponent.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 MaxDamageComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/MaxStackSizeComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent.cs new file mode 100644 index 0000000000..11855c6a22 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/MaxStackSizeComponent.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 MaxStackSizeComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/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/PotionContentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs new file mode 100644 index 0000000000..715cacd308 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/PotionContentsComponent.cs @@ -0,0 +1,51 @@ +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 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; } + 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 + 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++) + Effects.Add((PotionEffectSubComponent)subComponentRegistry.ParseSubComponent(SubComponents.PotionEffect, 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)); + + 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/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/RarityComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent.cs new file mode 100644 index 0000000000..4da4cb0024 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RarityComponent.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_20_6; + +public class RarityComponent(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/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/RepairCostComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent.cs new file mode 100644 index 0000000000..ccd1e2b555 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/RepairCostComponent.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 RepairCostComponent(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/StoredEnchantmentsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent.cs new file mode 100644 index 0000000000..0ddbc43139 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/StoredEnchantmentsComponent.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 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/SuspiciousStewEffectsComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent.cs new file mode 100644 index 0000000000..a6d81d9a02 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/SuspiciousStewEffectsComponent.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 SuspiciousStewEffectsComponent(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/ToolComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent.cs new file mode 100644 index 0000000000..3c09e43e28 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/ToolComponent.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 ToolComponent(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((RuleSubComponent)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/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/UnbreakableComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent.cs new file mode 100644 index 0000000000..39c190144c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/UnbreakableComponent.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 UnbrekableComponent1206(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) + : StructuredComponent(dataTypes, itemPalette, 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/1_20_6/WritableBlookContentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.cs new file mode 100644 index 0000000000..9c782d5572 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WritableBlookContentComponent.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 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); + + 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/WrittenBlookContentComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.cs new file mode 100644 index 0000000000..bf315b3dd3 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/1_20_6/WrittenBlookContentComponent.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 WrittenBlookContentComponent(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/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/EmptyComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs new file mode 100644 index 0000000000..8b49c90822 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/EmptyComponent.cs @@ -0,0 +1,17 @@ +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, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) : StructuredComponent(dataTypes, itemPalette, subComponentRegistry) +{ + public override void Parse(Queue data) + { + } + + public override Queue Serialize() + { + return new Queue(); + } +} \ No newline at end of file diff --git a/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.cs new file mode 100644 index 0000000000..a29374e11b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/AttributeSubComponent.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 AttributeSubComponent(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/BlockPredicateSubcomponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.cs new file mode 100644 index 0000000000..9a56284006 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockPredicateSubcomponent.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 BlockPredicateSubcomponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public bool HasBlocks { get; set; } + public BlockSetSubcomponent? 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 = (BlockSetSubcomponent)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((PropertySubComponent)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/BlockSetSubcomponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent.cs new file mode 100644 index 0000000000..dbc7c40ac8 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/BlockSetSubcomponent.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 BlockSetSubcomponent(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/DetailsSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent.cs new file mode 100644 index 0000000000..7394e13db7 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/DetailsSubComponent.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 DetailsSubComponent(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 DetailsSubComponent? 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 = (DetailsSubComponent)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/EffectSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent.cs new file mode 100644 index 0000000000..a676cfcaa0 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/EffectSubComponent.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 EffectSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public PotionEffectSubComponent TypeId { get; set; } + public float Probability { get; set; } + + protected override void Parse(Queue data) + { + TypeId = (PotionEffectSubComponent)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/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/PotionEffectSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent.cs new file mode 100644 index 0000000000..13cc55f98d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PotionEffectSubComponent.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 PotionEffectSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public int TypeId { get; set; } + public DetailsSubComponent Details { get; set; } + + protected override void Parse(Queue data) + { + TypeId = dataTypes.ReadNextVarInt(data); + Details = (DetailsSubComponent)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/PropertySubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.cs new file mode 100644 index 0000000000..0b8e41ebd2 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/PropertySubComponent.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 PropertySubComponent(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/1_20_6/RuleSubComponent.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent.cs new file mode 100644 index 0000000000..ca8807b54b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/1_20_6/RuleSubComponent.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 RuleSubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) : SubComponent(dataTypes, subComponentRegistry) +{ + public BlockSetSubcomponent 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 = (BlockSetSubcomponent)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/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 new file mode 100644 index 0000000000..9fdc974cf4 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Components/Subcomponents/SubComponents.cs @@ -0,0 +1,15 @@ +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Components.Subcomponents; + +public abstract class SubComponents +{ + public const string BlockPredicate = "BlockPredicate"; + 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"; + public const string FireworkExplosion = "FireworkExplosion"; + public const string SoundEvent = "SoundEvent"; +} \ 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..7465740b6e --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponent.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +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(); +} \ 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..11c48e1f1d --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/StructuredComponentRegistry.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using MinecraftClient.Inventory.ItemPalettes; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class StructuredComponentRegistry(DataTypes dataTypes, ItemPalette itemPalette, SubComponentRegistry subComponentRegistry) +{ + 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, itemPalette, 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..be235a9163 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponent.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +public abstract class SubComponent(DataTypes dataTypes, SubComponentRegistry subComponentRegistry) +{ + protected DataTypes DataTypes { get; private set; } = dataTypes; + protected SubComponentRegistry SubComponentRegistry { get; private set; } = subComponentRegistry; + + 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 new file mode 100644 index 0000000000..90123fe68b --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Core/SubComponentRegistry.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +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, this) as SubComponent ?? + throw new InvalidOperationException($"Could not create instance of a sub component parser type: {subComponentParserType.Name}"); + + 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 new file mode 100644 index 0000000000..afc5a1342c --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/StructuredComponentsRegistry1206.cs @@ -0,0 +1,69 @@ +using MinecraftClient.Inventory.ItemPalettes; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Components._1_20_6; +using MinecraftClient.Protocol.Handlers.StructuredComponents.Core; + +namespace MinecraftClient.Protocol.Handlers.StructuredComponents.Registries; + +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(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: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/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/SubComponentRegistry1206.cs b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs new file mode 100644 index 0000000000..2e270842be --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/Registries/Subcomponents/SubComponentRegistry1206.cs @@ -0,0 +1,22 @@ +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; + +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); + RegisterSubComponent(SubComponents.Effect); + RegisterSubComponent(SubComponents.PotionEffect); + RegisterSubComponent(SubComponents.Details); + RegisterSubComponent(SubComponents.Rule); + RegisterSubComponent(SubComponents.FireworkExplosion); + } +} \ 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 new file mode 100644 index 0000000000..2fd0cb82c2 --- /dev/null +++ b/MinecraftClient/Protocol/Handlers/StructuredComponents/StructuredComponentsHandler.cs @@ -0,0 +1,46 @@ +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, + ItemPalette itemPalette) + { + // 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(SubComponentRegistry1206), + Protocol18Handler.MC_1_21_Version => typeof(SubComponentRegistry121), + _ => 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), + Protocol18Handler.MC_1_21_Version => typeof(StructuredComponentsRegistry121), + _ => throw new NotSupportedException($"Protocol version {protocolVersion} is not supported for structured component registries!") + }; + + ComponentRegistry = Activator.CreateInstance(registryType, dataTypes, itemPalette, subcomponentRegistry) 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 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..a64021b58e 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -44,7 +44,12 @@ public interface IMinecraftComHandler int GetProtocolVersion(); Container? GetInventory(int inventoryID); 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. /// 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/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/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index cbf1b1cd90..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 + 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) @@ -345,6 +345,12 @@ 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; + case "1.21": + case "1.21.1": + return 767; default: return 0; } @@ -424,6 +430,8 @@ public static string ProtocolVersion2MCVer(int protocol) 763 => "1.20", 764 => "1.20.2", 765 => "1.20.4", + 766 => "1.20.6", + 767 => "1.21", _ => "0.0" }; } 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) { 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() 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,