From 109f1f990bc74da5dad8b9c250274f8a13be0a3f Mon Sep 17 00:00:00 2001 From: Andrewkydev Date: Wed, 25 Feb 2026 21:22:45 +0300 Subject: [PATCH] sync latest item entries for runtime-id remap stability --- legacyver/item_translator.go | 10 ++++++++++ legacyver/protocol.go | 24 ++++++++++++++++++++---- mapping/item.go | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/legacyver/item_translator.go b/legacyver/item_translator.go index 2062e56..fe50a59 100644 --- a/legacyver/item_translator.go +++ b/legacyver/item_translator.go @@ -63,6 +63,16 @@ type DefaultItemTranslator struct { infoUpdateRID int32 } +func (t *DefaultItemTranslator) SyncLatestEntries(entries []protocol.ItemEntry) { + for _, entry := range entries { + version := uint8(protocol.ItemEntryVersionDataDriven) + if entry.Version >= 0 && entry.Version <= 255 { + version = uint8(entry.Version) + } + t.latest.UpsertEntryRID(entry.Name, int32(entry.RuntimeID), version, entry.Data) + } +} + func NewItemTranslator(mapping mapping.Item, latestMapping mapping.Item, blockMapping mapping.Block, blockMappingLatest mapping.Block) *DefaultItemTranslator { infoUpdateRID, _ := mapping.ItemNameToRuntimeID("minecraft:info_update") return &DefaultItemTranslator{mapping: mapping, latest: latestMapping, blockMapping: blockMapping, blockMappingLatest: blockMappingLatest, diff --git a/legacyver/protocol.go b/legacyver/protocol.go index 9533619..a44a2b6 100644 --- a/legacyver/protocol.go +++ b/legacyver/protocol.go @@ -193,6 +193,18 @@ func (p *Protocol) ConvertFromLatest(pk packet.Packet, conn *minecraft.Conn) []p } func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet { + if it, ok := p.itemTranslator.(*DefaultItemTranslator); ok { + if len(p.Items) > 0 { + it.SyncLatestEntries(p.Items) + } + if conn != nil { + gameItems := conn.GameData().Items + if len(gameItems) > 0 { + it.SyncLatestEntries(gameItems) + } + } + } + translator, ok := p.blockTranslator.(*DefaultBlockTranslator) if !ok { return pks @@ -202,7 +214,7 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [ case *packet.DimensionData: translator.dimensionDefinitions = pk.Definitions case *packet.ClientCacheStatus: - // pk.Enabled = false // TODO: enable when chunk translation is not broken + //pk.Enabled = false // TODO: enable when chunk translation is not broken case *packet.SetActorMotion: pks[pkIndex] = &legacypacket.SetActorMotion{ EntityRuntimeID: pk.EntityRuntimeID, @@ -534,8 +546,12 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [ pk.GameVersion = p.ver pk.BaseGameVersion = p.ver - items := make([]proto.LegacyItemRegistryEntry, len(p.Items)) - for i, it := range p.Items { + sourceItems := p.Items + if len(sourceItems) == 0 && conn != nil { + sourceItems = conn.GameData().Items + } + items := make([]proto.LegacyItemRegistryEntry, len(sourceItems)) + for i, it := range sourceItems { items[i] = (&proto.LegacyItemRegistryEntry{}).FromLatest(it) } @@ -844,7 +860,7 @@ func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []p for pkIndex, pk := range pks { switch pk := pk.(type) { case *packet.ClientCacheStatus: - // pk.Enabled = false // TODO: enable when chunk translation is not broken + pk.Enabled = false case *legacypacket.SetActorMotion: pks[pkIndex] = &packet.SetActorMotion{ EntityRuntimeID: pk.EntityRuntimeID, diff --git a/mapping/item.go b/mapping/item.go index ffdcac6..81f8539 100644 --- a/mapping/item.go +++ b/mapping/item.go @@ -19,6 +19,7 @@ type Item interface { ItemRuntimeIDToData(int32) (map[string]any, bool) RegisterEntry(string) int32 RegisterEntryRID(string, int32, uint8, map[string]any) + UpsertEntryRID(string, int32, uint8, map[string]any) Air() int32 ItemVersion() uint16 ItemEntries() []ItemEntry @@ -159,6 +160,29 @@ func (m *DefaultItemMapping) RegisterEntryRID(name string, rid int32, version ui } } +func (m *DefaultItemMapping) UpsertEntryRID(name string, rid int32, version uint8, data map[string]any) { + defer m.mu.Unlock() + m.mu.Lock() + + if oldRID, ok := m.itemNamesToRuntimeIDs[name]; ok && oldRID != rid { + delete(m.itemRuntimeIDsToNames, oldRID) + delete(m.itemRuntimeIDToVersion, oldRID) + delete(m.itemRuntimeIDToData, oldRID) + } + if oldName, ok := m.itemRuntimeIDsToNames[rid]; ok && oldName != name { + delete(m.itemNamesToRuntimeIDs, oldName) + } + + m.itemNamesToRuntimeIDs[name] = rid + m.itemRuntimeIDsToNames[rid] = name + m.itemRuntimeIDToVersion[rid] = version + if data != nil { + m.itemRuntimeIDToData[rid] = data + } else { + delete(m.itemRuntimeIDToData, rid) + } +} + func (m *DefaultItemMapping) Air() int32 { defer m.mu.Unlock() m.mu.Lock()