diff --git a/MinecraftClient/Inventory/Container.cs b/MinecraftClient/Inventory/Container.cs
index 98908655..f2258fee 100644
--- a/MinecraftClient/Inventory/Container.cs
+++ b/MinecraftClient/Inventory/Container.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace MinecraftClient.Inventory
{
@@ -91,10 +91,11 @@ namespace MinecraftClient.Inventory
/// Container ID
/// Container Type
/// Container Title
- public Container(int id, int typeID, string title)
+ /// Protocol version for version-specific mapping
+ public Container(int id, int typeID, string title, int protocolVersion = 0)
{
ID = id;
- Type = GetContainerType(typeID);
+ Type = GetContainerType(typeID, protocolVersion);
Title = title;
Items = new();
Properties = new();
@@ -131,22 +132,62 @@ namespace MinecraftClient.Inventory
/// Get container type from Type ID
///
/// Container Type ID
+ /// Protocol version (menu registry changed across versions)
/// Container Type
- public static ContainerType GetContainerType(int typeID)
+ public static ContainerType GetContainerType(int typeID, int protocolVersion = 0)
{
- // https://wiki.vg/Inventory didn't state the inventory ID, assume that list start with 0
+ // MC 1.20.4 (protocol 765) added crafter_3x3 at index 7, shifting all subsequent IDs by +1.
+ // Registry order from decompiled MenuType.java:
+ // 1.14-1.20.2: generic_9x1..generic_3x3(6), anvil(7), beacon(8), ... stonecutter(22)
+ // 1.20.4+: generic_9x1..generic_3x3(6), crafter_3x3(7), anvil(8), beacon(9), ... stonecutter(24)
+ if (protocolVersion >= 765)
+ {
+ return typeID switch
+ {
+#pragma warning disable format // @formatter:off
+ 0 => ContainerType.Generic_9x1,
+ 1 => ContainerType.Generic_9x2,
+ 2 => ContainerType.Generic_9x3,
+ 3 => ContainerType.Generic_9x4,
+ 4 => ContainerType.Generic_9x5,
+ 5 => ContainerType.Generic_9x6,
+ 6 => ContainerType.Generic_3x3,
+ 7 => ContainerType.Crafter,
+ 8 => ContainerType.Anvil,
+ 9 => ContainerType.Beacon,
+ 10 => ContainerType.BlastFurnace,
+ 11 => ContainerType.BrewingStand,
+ 12 => ContainerType.Crafting,
+ 13 => ContainerType.Enchantment,
+ 14 => ContainerType.Furnace,
+ 15 => ContainerType.Grindstone,
+ 16 => ContainerType.Hopper,
+ 17 => ContainerType.Lectern,
+ 18 => ContainerType.Loom,
+ 19 => ContainerType.Merchant,
+ 20 => ContainerType.ShulkerBox,
+ 21 => ContainerType.SmightingTable,
+ 22 => ContainerType.Smoker,
+ 23 => ContainerType.Cartography,
+ 24 => ContainerType.Stonecutter,
+ _ => ContainerType.Unknown,
+#pragma warning restore format // @formatter:on
+ };
+ }
+
return typeID switch
{
- 0 => ContainerType.Generic_9x1,
- 1 => ContainerType.Generic_9x2,
- 2 => ContainerType.Generic_9x3,
- 3 => ContainerType.Generic_9x4,
- 4 => ContainerType.Generic_9x5,
- 5 => ContainerType.Generic_9x6,
- 6 => ContainerType.Generic_3x3,
- 7 => ContainerType.Anvil,
- 8 => ContainerType.Beacon,
- 9 => ContainerType.BlastFurnace,
+#pragma warning disable format // @formatter:off
+ 0 => ContainerType.Generic_9x1,
+ 1 => ContainerType.Generic_9x2,
+ 2 => ContainerType.Generic_9x3,
+ 3 => ContainerType.Generic_9x4,
+ 4 => ContainerType.Generic_9x5,
+ 5 => ContainerType.Generic_9x6,
+ 6 => ContainerType.Generic_3x3,
+ 7 => ContainerType.Anvil,
+ 8 => ContainerType.Beacon,
+ 9 => ContainerType.BlastFurnace,
10 => ContainerType.BrewingStand,
11 => ContainerType.Crafting,
12 => ContainerType.Enchantment,
@@ -160,7 +201,8 @@ namespace MinecraftClient.Inventory
20 => ContainerType.Smoker,
21 => ContainerType.Cartography,
22 => ContainerType.Stonecutter,
- _ => ContainerType.Unknown,
+ _ => ContainerType.Unknown,
+#pragma warning restore format // @formatter:on
};
}
diff --git a/MinecraftClient/Inventory/ContainerType.cs b/MinecraftClient/Inventory/ContainerType.cs
index 76d05416..e82878fe 100644
--- a/MinecraftClient/Inventory/ContainerType.cs
+++ b/MinecraftClient/Inventory/ContainerType.cs
@@ -1,4 +1,4 @@
-namespace MinecraftClient.Inventory
+namespace MinecraftClient.Inventory
{
// For MC 1.14 after ONLY
public enum ContainerType
@@ -10,6 +10,7 @@
Generic_9x5,
Generic_9x6,
Generic_3x3,
+ Crafter,
Anvil,
Beacon,
BlastFurnace,
diff --git a/MinecraftClient/Inventory/ContainerTypeExtensions.cs b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
index 4fe16373..4644e553 100644
--- a/MinecraftClient/Inventory/ContainerTypeExtensions.cs
+++ b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
@@ -1,4 +1,4 @@
-namespace MinecraftClient.Inventory
+namespace MinecraftClient.Inventory
{
public static class ContainerTypeExtensions
{
@@ -13,9 +13,14 @@
{
#pragma warning disable format // @formatter:off
ContainerType.PlayerInventory => 46,
+ ContainerType.Generic_9x1 => 45,
+ ContainerType.Generic_9x2 => 54,
ContainerType.Generic_9x3 => 63,
+ ContainerType.Generic_9x4 => 72,
+ ContainerType.Generic_9x5 => 81,
ContainerType.Generic_9x6 => 90,
ContainerType.Generic_3x3 => 45,
+ ContainerType.Crafter => 45,
ContainerType.Crafting => 46,
ContainerType.BlastFurnace => 39,
ContainerType.Furnace => 39,
@@ -27,6 +32,7 @@
ContainerType.Anvil => 39,
ContainerType.Hopper => 41,
ContainerType.ShulkerBox => 63,
+ ContainerType.SmightingTable => 39,
ContainerType.Loom => 40,
ContainerType.Stonecutter => 38,
ContainerType.Lectern => 37,
@@ -52,6 +58,7 @@
ContainerType.Generic_9x3 => AsciiArt.Container_Generic_9x3,
ContainerType.Generic_9x6 => AsciiArt.Container_Generic_9x6,
ContainerType.Generic_3x3 => AsciiArt.Container_Generic_3x3,
+ ContainerType.Crafter => AsciiArt.Container_Generic_3x3,
ContainerType.Crafting => AsciiArt.Container_Crafting,
ContainerType.BlastFurnace => AsciiArt.Container_Furnace,
ContainerType.Furnace => AsciiArt.Container_Furnace,
diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs
index 48568f0f..b6cdcd05 100644
--- a/MinecraftClient/Protocol/Handlers/Protocol18.cs
+++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs
@@ -2319,7 +2319,7 @@ namespace MinecraftClient.Protocol.Handlers
var windowId = dataTypes.ReadNextVarInt(packetData);
var windowType = dataTypes.ReadNextVarInt(packetData);
var title = dataTypes.ReadNextChat(packetData);
- Container inventory = new(windowId, windowType, ChatParser.ParseText(title));
+ Container inventory = new(windowId, windowType, ChatParser.ParseText(title), protocolVersion);
handler.OnInventoryOpen(windowId, inventory);
}
}