fix: update 26.2 SlotDisplay mapper with 3 new types from decompiled source

- 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()
This commit is contained in:
OpenCode
2026-08-05 21:19:07 +02:00
parent 53d366ae53
commit f4c2762881
10 changed files with 104 additions and 16 deletions
@@ -7,12 +7,12 @@ import (
generated "github.com/admin-else/strom/mc/proto_generated/v26_2" generated "github.com/admin-else/strom/mc/proto_generated/v26_2"
) )
// Error: index not found // Decode regression: recipe_book_add (26.2) - SlotDisplay type fix
func TestFailedPacket25D845B5D0023D22(t *testing.T) { func TestRegressionPacket25D845B5D0023D22(t *testing.T) {
p := &generated.PlayToClientPacketRecipeBookAdd{} 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}) 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) err := p.Decode(b)
if err == nil { if err != nil {
t.Fatalf("expected decode error but got nil") t.Fatalf("regression: decode failed: %v", err)
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.12.2/protocol.json (sha256:21c57208db654a5e14a34cb696570080df179c5c642e53b16120399eee9232be) // 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 package v1_12_2
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.14.4/protocol.json (sha256:b6edff5abaaf234037b5019024d749e27e746250a23253bb4ad77d8f76e93167) // 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 package v1_14_4
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.16.2/protocol.json (sha256:d96a3c5a7a7ddf2105e23990c2471b3aeafe4a6975e0c9d7d7943b599af9dfb3) // 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 package v1_16_5
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.11/protocol.json (sha256:97d2726cce3a39cc967a954f27f4ebf029ec3f0f655bb21942aab8745d13cdab) // 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 package v1_21_11
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.8/protocol.json (sha256:930fbb4c69fd2ecadddcee3c38d3f02908adc23b54b707cb21112e7ab1e9dba1) // 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 package v1_21_8
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.21.9/protocol.json (sha256:9861cee397931c678c3b1837dcdf82e3fc885442c6bd0e4a60522fbf26653e59) // 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 package v1_21_9
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/1.8/protocol.json (sha256:79fe774bfc255dd281899c004fbb9c7adc40fb107de9353da1dd0371ea4b53af) // 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 package v1_8
import ( import (
+1 -1
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/26.1/protocol.json (sha256:dfb6318886cd3ceab617f75ac05e24f9836a64501d60551071289b904ebfc389) // 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 package v26_1
import ( import (
+92 -4
View File
@@ -1,6 +1,6 @@
// Code generated by strom. DO NOT EDIT. // Code generated by strom. DO NOT EDIT.
// source: minecraft-data/pc/26.2/protocol.json (sha256:7ba66411adcc68a668f38211e1b00eeb386a345d5eb16fadd6dc1c7f94bb175f) // source: minecraft-data/pc/26.2/protocol.json (sha256:795e78495a67b7311837c19c714f0c3fb2598fcf407a76779403a65ba1272457)
// version: v0.6.6-0.20260805173638-56ac8e154ea1+dirty (go1.26.2) // version: v0.6.6-0.20260805175346-53d366ae5301+dirty (go1.26.2)
package v26_2 package v26_2
import ( import (
@@ -11306,7 +11306,7 @@ type PlayToClientSlotDisplay struct {
Data any 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) { func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) {
var PlayToClientSlotDisplayTypeKey int32 var PlayToClientSlotDisplayTypeKey int32
@@ -11340,6 +11340,20 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) {
PlayToClientSlotDisplayDataCompositeTmp = append(PlayToClientSlotDisplayDataCompositeTmp, PlayToClientSlotDisplayDataCompositeTmpElement) PlayToClientSlotDisplayDataCompositeTmp = append(PlayToClientSlotDisplayDataCompositeTmp, PlayToClientSlotDisplayDataCompositeTmpElement)
} }
ret.Data = PlayToClientSlotDisplayDataCompositeTmp 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": case "empty":
var PlayToClientSlotDisplayDataEmptyTmp struct { var PlayToClientSlotDisplayDataEmptyTmp struct {
} }
@@ -11358,6 +11372,20 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) {
return return
} }
ret.Data = PlayToClientSlotDisplayDataItemStackTmp 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": case "smithing_trim":
var PlayToClientSlotDisplayDataSmithingTrimTmp struct { var PlayToClientSlotDisplayDataSmithingTrimTmp struct {
Base PlayToClientSlotDisplay Base PlayToClientSlotDisplay
@@ -11395,6 +11423,15 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) {
return return
} }
ret.Data = PlayToClientSlotDisplayDataTagTmp 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": case "with_remainder":
var PlayToClientSlotDisplayDataWithRemainderTmp struct { var PlayToClientSlotDisplayDataWithRemainderTmp struct {
Input PlayToClientSlotDisplay Input PlayToClientSlotDisplay
@@ -11413,7 +11450,7 @@ func (ret *PlayToClientSlotDisplay) Decode(r io.ReadSeeker) (err error) {
return 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) { func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) {
var vPlayToClientSlotDisplayType int32 var vPlayToClientSlotDisplayType int32
@@ -11450,6 +11487,25 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) {
return 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": case "empty":
_, ok := ret.Data.(struct { _, ok := ret.Data.(struct {
}) })
@@ -11478,6 +11534,25 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) {
if err != nil { if err != nil {
return 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": case "smithing_trim":
PlayToClientSlotDisplayData, ok := ret.Data.(struct { PlayToClientSlotDisplayData, ok := ret.Data.(struct {
Base PlayToClientSlotDisplay Base PlayToClientSlotDisplay
@@ -11527,6 +11602,19 @@ func (ret *PlayToClientSlotDisplay) Encode(w io.Writer) (err error) {
if err != nil { if err != nil {
return 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": case "with_remainder":
PlayToClientSlotDisplayData, ok := ret.Data.(struct { PlayToClientSlotDisplayData, ok := ret.Data.(struct {
Input PlayToClientSlotDisplay Input PlayToClientSlotDisplay