From f4c27628815be1c843adc8cab6ceb8c8965ed106 Mon Sep 17 00:00:00 2001 From: OpenCode Date: Wed, 5 Aug 2026 21:19:07 +0200 Subject: [PATCH] fix: update 26.2 SlotDisplay mapper with 3 new types from decompiled source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add with_any_potion (id 2), only_with_component (id 3), dyed (id 7) - Shift existing IDs: item 2→4, item_stack 3→5, tag 4→6, smithing_trim 5→8, with_remainder 6→9, composite 7→10 - RecipeBookAdd now decodes successfully (was index not found) - Verified against decompiled client jar via SlotDisplays.bootstrap() --- ...st.go => reg_166_25d845b5d0023d22_test.go} | 8 +- mc/proto_generated/v1_12_2/proto.go | 2 +- mc/proto_generated/v1_14_4/proto.go | 2 +- mc/proto_generated/v1_16_5/proto.go | 2 +- mc/proto_generated/v1_21_11/proto.go | 2 +- mc/proto_generated/v1_21_8/proto.go | 2 +- mc/proto_generated/v1_21_9/proto.go | 2 +- mc/proto_generated/v1_8/proto.go | 2 +- mc/proto_generated/v26_1/proto.go | 2 +- mc/proto_generated/v26_2/proto.go | 96 ++++++++++++++++++- 10 files changed, 104 insertions(+), 16 deletions(-) rename cmd/strom/print_replay/testdata/{166_25d845b5d0023d22_test.go => reg_166_25d845b5d0023d22_test.go} (86%) diff --git a/cmd/strom/print_replay/testdata/166_25d845b5d0023d22_test.go b/cmd/strom/print_replay/testdata/reg_166_25d845b5d0023d22_test.go similarity index 86% rename from cmd/strom/print_replay/testdata/166_25d845b5d0023d22_test.go rename to cmd/strom/print_replay/testdata/reg_166_25d845b5d0023d22_test.go index fcef0eb..4c52bcb 100644 --- a/cmd/strom/print_replay/testdata/166_25d845b5d0023d22_test.go +++ b/cmd/strom/print_replay/testdata/reg_166_25d845b5d0023d22_test.go @@ -7,12 +7,12 @@ import ( generated "github.com/admin-else/strom/mc/proto_generated/v26_2" ) -// Error: index not found -func TestFailedPacket25D845B5D0023D22(t *testing.T) { +// Decode regression: recipe_book_add (26.2) - SlotDisplay type fix +func TestRegressionPacket25D845B5D0023D22(t *testing.T) { p := &generated.PlayToClientPacketRecipeBookAdd{} b := bytes.NewReader([]byte{0x1, 0xbe, 0x2, 0x1, 0x2, 0x2, 0x4, 0x6, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x6, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x6, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x6, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x5, 0xe8, 0x2, 0x1, 0x0, 0x0, 0x4, 0xe8, 0x2, 0x0, 0x3, 0x1, 0x4, 0x0, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x0, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x0, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x0, 0x10, 0x6d, 0x69, 0x6e, 0x65, 0x63, 0x72, 0x61, 0x66, 0x74, 0x3a, 0x70, 0x6c, 0x61, 0x6e, 0x6b, 0x73, 0x2, 0x1}) err := p.Decode(b) - if err == nil { - t.Fatalf("expected decode error but got nil") + if err != nil { + t.Fatalf("regression: decode failed: %v", err) } } diff --git a/mc/proto_generated/v1_12_2/proto.go b/mc/proto_generated/v1_12_2/proto.go index 4635d72..dfd9e56 100644 --- a/mc/proto_generated/v1_12_2/proto.go +++ b/mc/proto_generated/v1_12_2/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.12.2/protocol.json (sha256:21c57208db654a5e14a34cb696570080df179c5c642e53b16120399eee9232be) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_12_2 import ( diff --git a/mc/proto_generated/v1_14_4/proto.go b/mc/proto_generated/v1_14_4/proto.go index 92d4d9c..68894cd 100644 --- a/mc/proto_generated/v1_14_4/proto.go +++ b/mc/proto_generated/v1_14_4/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.14.4/protocol.json (sha256:b6edff5abaaf234037b5019024d749e27e746250a23253bb4ad77d8f76e93167) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_14_4 import ( diff --git a/mc/proto_generated/v1_16_5/proto.go b/mc/proto_generated/v1_16_5/proto.go index 9f1fdfe..8bd827d 100644 --- a/mc/proto_generated/v1_16_5/proto.go +++ b/mc/proto_generated/v1_16_5/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.16.2/protocol.json (sha256:d96a3c5a7a7ddf2105e23990c2471b3aeafe4a6975e0c9d7d7943b599af9dfb3) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_16_5 import ( diff --git a/mc/proto_generated/v1_21_11/proto.go b/mc/proto_generated/v1_21_11/proto.go index 33f0926..55eb5ce 100644 --- a/mc/proto_generated/v1_21_11/proto.go +++ b/mc/proto_generated/v1_21_11/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.21.11/protocol.json (sha256:97d2726cce3a39cc967a954f27f4ebf029ec3f0f655bb21942aab8745d13cdab) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_21_11 import ( diff --git a/mc/proto_generated/v1_21_8/proto.go b/mc/proto_generated/v1_21_8/proto.go index 4139620..f26c8c4 100644 --- a/mc/proto_generated/v1_21_8/proto.go +++ b/mc/proto_generated/v1_21_8/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.21.8/protocol.json (sha256:930fbb4c69fd2ecadddcee3c38d3f02908adc23b54b707cb21112e7ab1e9dba1) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_21_8 import ( diff --git a/mc/proto_generated/v1_21_9/proto.go b/mc/proto_generated/v1_21_9/proto.go index c892d76..c6f21c9 100644 --- a/mc/proto_generated/v1_21_9/proto.go +++ b/mc/proto_generated/v1_21_9/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.21.9/protocol.json (sha256:9861cee397931c678c3b1837dcdf82e3fc885442c6bd0e4a60522fbf26653e59) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_21_9 import ( diff --git a/mc/proto_generated/v1_8/proto.go b/mc/proto_generated/v1_8/proto.go index cf60063..ce8ac63 100644 --- a/mc/proto_generated/v1_8/proto.go +++ b/mc/proto_generated/v1_8/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/1.8/protocol.json (sha256:79fe774bfc255dd281899c004fbb9c7adc40fb107de9353da1dd0371ea4b53af) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v1_8 import ( diff --git a/mc/proto_generated/v26_1/proto.go b/mc/proto_generated/v26_1/proto.go index 1361f27..3fc2d8b 100644 --- a/mc/proto_generated/v26_1/proto.go +++ b/mc/proto_generated/v26_1/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. // source: minecraft-data/pc/26.1/protocol.json (sha256:dfb6318886cd3ceab617f75ac05e24f9836a64501d60551071289b904ebfc389) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v26_1 import ( diff --git a/mc/proto_generated/v26_2/proto.go b/mc/proto_generated/v26_2/proto.go index ea17ad0..e53a1c8 100644 --- a/mc/proto_generated/v26_2/proto.go +++ b/mc/proto_generated/v26_2/proto.go @@ -1,6 +1,6 @@ // Code generated by strom. DO NOT EDIT. -// source: minecraft-data/pc/26.2/protocol.json (sha256:7ba66411adcc68a668f38211e1b00eeb386a345d5eb16fadd6dc1c7f94bb175f) -// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) +// source: minecraft-data/pc/26.2/protocol.json (sha256:795e78495a67b7311837c19c714f0c3fb2598fcf407a76779403a65ba1272457) +// version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2) package v26_2 import ( @@ -11306,7 +11306,7 @@ type PlayToClientSlotDisplay struct { Data any } -var PlayToClientSlotDisplayTypeMap = map[int32]string{0: "empty", 1: "any_fuel", 2: "item", 3: "item_stack", 4: "tag", 5: "smithing_trim", 6: "with_remainder", 7: "composite"} +var PlayToClientSlotDisplayTypeMap = map[int32]string{0: "empty", 1: "any_fuel", 10: "composite", 2: "with_any_potion", 3: "only_with_component", 4: "item", 5: "item_stack", 6: "tag", 7: "dyed", 8: "smithing_trim", 9: "with_remainder"} func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) { var PlayToClientSlotDisplayTypeKey int32 @@ -11340,6 +11340,20 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) { PlayToClientSlotDisplayDataCompositeTmp = append(PlayToClientSlotDisplayDataCompositeTmp, PlayToClientSlotDisplayDataCompositeTmpElement) } ret.Data = PlayToClientSlotDisplayDataCompositeTmp + case "dyed": + var PlayToClientSlotDisplayDataDyedTmp struct { + Dye PlayToClientSlotDisplay + Target PlayToClientSlotDisplay + } + err = PlayToClientSlotDisplayDataDyedTmp.Dye.Decode(r) + if err != nil { + return + } + err = PlayToClientSlotDisplayDataDyedTmp.Target.Decode(r) + if err != nil { + return + } + ret.Data = PlayToClientSlotDisplayDataDyedTmp case "empty": var PlayToClientSlotDisplayDataEmptyTmp struct { } @@ -11358,6 +11372,20 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) { return } ret.Data = PlayToClientSlotDisplayDataItemStackTmp + case "only_with_component": + var PlayToClientSlotDisplayDataOnlyWithComponentTmp struct { + Source PlayToClientSlotDisplay + Component IDSet + } + err = PlayToClientSlotDisplayDataOnlyWithComponentTmp.Source.Decode(r) + if err != nil { + return + } + err = PlayToClientSlotDisplayDataOnlyWithComponentTmp.Component.Decode(r) + if err != nil { + return + } + ret.Data = PlayToClientSlotDisplayDataOnlyWithComponentTmp case "smithing_trim": var PlayToClientSlotDisplayDataSmithingTrimTmp struct { Base PlayToClientSlotDisplay @@ -11395,6 +11423,15 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) { return } ret.Data = PlayToClientSlotDisplayDataTagTmp + case "with_any_potion": + var PlayToClientSlotDisplayDataWithAnyPotionTmp struct { + Display PlayToClientSlotDisplay + } + err = PlayToClientSlotDisplayDataWithAnyPotionTmp.Display.Decode(r) + if err != nil { + return + } + ret.Data = PlayToClientSlotDisplayDataWithAnyPotionTmp case "with_remainder": var PlayToClientSlotDisplayDataWithRemainderTmp struct { Input PlayToClientSlotDisplay @@ -11413,7 +11450,7 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) { return } -var PlayToClientSlotDisplayTypeReverseMap = map[string]int32{"empty": 0, "any_fuel": 1, "item": 2, "item_stack": 3, "tag": 4, "smithing_trim": 5, "with_remainder": 6, "composite": 7} +var PlayToClientSlotDisplayTypeReverseMap = map[string]int32{"empty": 0, "any_fuel": 1, "composite": 10, "with_any_potion": 2, "only_with_component": 3, "item": 4, "item_stack": 5, "tag": 6, "dyed": 7, "smithing_trim": 8, "with_remainder": 9} func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) { var vPlayToClientSlotDisplayType int32 @@ -11450,6 +11487,25 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) { return } } + case "dyed": + PlayToClientSlotDisplayData, ok := ret.Data.(struct { + Dye PlayToClientSlotDisplay + Target PlayToClientSlotDisplay + }) + if !ok { + err = proto_base.BadTypeError + return + } + PlayToClientSlotDisplayDataDyeEncTmp := PlayToClientSlotDisplayData.Dye + err = PlayToClientSlotDisplayDataDyeEncTmp.Encode(w) + if err != nil { + return + } + PlayToClientSlotDisplayDataTargetEncTmp := PlayToClientSlotDisplayData.Target + err = PlayToClientSlotDisplayDataTargetEncTmp.Encode(w) + if err != nil { + return + } case "empty": _, ok := ret.Data.(struct { }) @@ -11478,6 +11534,25 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) { if err != nil { return } + case "only_with_component": + PlayToClientSlotDisplayData, ok := ret.Data.(struct { + Source PlayToClientSlotDisplay + Component IDSet + }) + if !ok { + err = proto_base.BadTypeError + return + } + PlayToClientSlotDisplayDataSourceEncTmp := PlayToClientSlotDisplayData.Source + err = PlayToClientSlotDisplayDataSourceEncTmp.Encode(w) + if err != nil { + return + } + PlayToClientSlotDisplayDataComponentEncTmp := PlayToClientSlotDisplayData.Component + err = PlayToClientSlotDisplayDataComponentEncTmp.Encode(w) + if err != nil { + return + } case "smithing_trim": PlayToClientSlotDisplayData, ok := ret.Data.(struct { Base PlayToClientSlotDisplay @@ -11527,6 +11602,19 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) { if err != nil { return } + case "with_any_potion": + PlayToClientSlotDisplayData, ok := ret.Data.(struct { + Display PlayToClientSlotDisplay + }) + if !ok { + err = proto_base.BadTypeError + return + } + PlayToClientSlotDisplayDataDisplayEncTmp := PlayToClientSlotDisplayData.Display + err = PlayToClientSlotDisplayDataDisplayEncTmp.Encode(w) + if err != nil { + return + } case "with_remainder": PlayToClientSlotDisplayData, ok := ret.Data.(struct { Input PlayToClientSlotDisplay