Fix 26.1 RecipeBookAdd crash: update SlotDisplay registry IDs for 26.1

MC 26.1 changed the minecraft:slot_display registry, inserting 3 new
types (with_any_potion, only_with_component, dyed) and shifting all
existing IDs. This caused MCC to misparse recipe display data, leading
to a Queue empty crash in SkipItemHolderSet.

Add version-gated ReadSlotDisplayLabel with correct 26.1 type mapping
and reader methods for the 3 new slot display types.

Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/47b0c937-1491-4216-8ee0-1aca866e99ab

Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-30 08:09:33 +00:00
parent c55d32bb70
commit 962c8b1ab2
3 changed files with 52 additions and 1 deletions

1
.gitignore vendored
View file

@ -437,3 +437,4 @@ FodyWeavers.xsd
/.specstory/ /.specstory/
/.vscode/settings.json /.vscode/settings.json
/Sentry/ /Sentry/
server.pid

View file

@ -3470,6 +3470,29 @@ namespace MinecraftClient.Protocol.Handlers
private string ReadSlotDisplayLabel(Queue<byte> packetData) private string ReadSlotDisplayLabel(Queue<byte> packetData)
{ {
int slotDisplayType = dataTypes.ReadNextVarInt(packetData); int slotDisplayType = dataTypes.ReadNextVarInt(packetData);
// 26.1 changed the slot display registry order, inserting 3 new types:
// Pre-26.1: 0=empty, 1=any_fuel, 2=item, 3=item_stack, 4=tag, 5=smithing_trim, 6=with_remainder, 7=composite
// 26.1+: 0=empty, 1=any_fuel, 2=with_any_potion, 3=only_with_component, 4=item, 5=item_stack, 6=tag, 7=dyed, 8=smithing_trim, 9=with_remainder, 10=composite
if (protocolVersion >= MC_26_1_Version)
{
return slotDisplayType switch
{
0 => "Empty",
1 => "Any Fuel",
2 => ReadWithAnyPotionSlotDisplayLabel(packetData),
3 => ReadOnlyWithComponentSlotDisplayLabel(packetData),
4 => Item.GetTypeString(itemPalette.FromId(dataTypes.ReadNextVarInt(packetData))),
5 => dataTypes.ReadNextItemSlot(packetData, itemPalette)?.GetTypeString() ?? "Empty",
6 => "#" + dataTypes.ReadNextString(packetData),
7 => ReadDyedSlotDisplayLabel(packetData),
8 => ReadSmithingTrimSlotDisplayLabel(packetData),
9 => ReadWithRemainderSlotDisplayLabel(packetData),
10 => ReadCompositeSlotDisplayLabel(packetData),
_ => $"slot_display_{slotDisplayType}",
};
}
return slotDisplayType switch return slotDisplayType switch
{ {
0 => "Empty", 0 => "Empty",
@ -3484,6 +3507,34 @@ namespace MinecraftClient.Protocol.Handlers
}; };
} }
/// <summary>
/// Reads a with_any_potion slot display (26.1+): contains a nested SlotDisplay.
/// </summary>
private string ReadWithAnyPotionSlotDisplayLabel(Queue<byte> packetData)
{
return ReadSlotDisplayLabel(packetData);
}
/// <summary>
/// Reads an only_with_component slot display (26.1+): contains a nested SlotDisplay and a DataComponentType VarInt ID.
/// </summary>
private string ReadOnlyWithComponentSlotDisplayLabel(Queue<byte> packetData)
{
string sourceLabel = ReadSlotDisplayLabel(packetData);
_ = dataTypes.ReadNextVarInt(packetData); // DataComponentType registry id
return sourceLabel;
}
/// <summary>
/// Reads a dyed slot display (26.1+): contains two nested SlotDisplays (dye + target).
/// </summary>
private string ReadDyedSlotDisplayLabel(Queue<byte> packetData)
{
_ = ReadSlotDisplayLabel(packetData); // dye
string targetLabel = ReadSlotDisplayLabel(packetData); // target
return targetLabel;
}
private string ReadSmithingTrimSlotDisplayLabel(Queue<byte> packetData) private string ReadSmithingTrimSlotDisplayLabel(Queue<byte> packetData)
{ {
string baseLabel = ReadSlotDisplayLabel(packetData); string baseLabel = ReadSlotDisplayLabel(packetData);

View file

@ -1 +0,0 @@
5586