diff --git a/legacyver/item_translator.go b/legacyver/item_translator.go index efb1bec..2062e56 100644 --- a/legacyver/item_translator.go +++ b/legacyver/item_translator.go @@ -59,11 +59,14 @@ type DefaultItemTranslator struct { originalToCustom map[int32]int32 customToOriginal map[int32]int32 hasDebugStick bool + + infoUpdateRID int32 } 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, - ridToCustomItem: make(map[int32]world.CustomItem), originalToCustom: make(map[int32]int32), customToOriginal: make(map[int32]int32)} + ridToCustomItem: make(map[int32]world.CustomItem), originalToCustom: make(map[int32]int32), customToOriginal: make(map[int32]int32), infoUpdateRID: infoUpdateRID} } func (t *DefaultItemTranslator) DowngradeItemType(input protocol.ItemType) protocol.ItemType { @@ -104,6 +107,36 @@ func (t *DefaultItemTranslator) DowngradeItemType(input protocol.ItemType) proto } } +func (t *DefaultItemTranslator) TryDowngradeItemStack(input protocol.ItemStack) (protocol.ItemStack, bool) { + if t.latest == t.mapping || input.NetworkID == 0 { + return input, true + } + input.ItemType = t.DowngradeItemType(input.ItemType) + if input.ItemType.NetworkID == t.infoUpdateRID { + return input, false + } + + blockRuntimeId := uint32(0) + if input.NetworkID != t.mapping.Air() { + name, _ := t.mapping.ItemRuntimeIDToName(input.NetworkID) + if latestBlockState, ok := item.BlockStateFromItemName(name, input.MetadataValue); ok { + var found bool + if blockRuntimeId, found = t.blockMapping.StateToRuntimeID(latestBlockState); !found { + blockRuntimeId = t.blockMapping.Air() + } + } + } + return protocol.ItemStack{ + ItemType: input.ItemType, + BlockRuntimeID: int32(blockRuntimeId), + Count: input.Count, + NBTData: input.NBTData, + CanBePlacedOn: input.CanBePlacedOn, + CanBreak: input.CanBreak, + HasNetworkID: input.HasNetworkID, + }, true +} + func (t *DefaultItemTranslator) DowngradeItemStack(input protocol.ItemStack) protocol.ItemStack { if t.latest == t.mapping || input.NetworkID == 0 { return input @@ -458,10 +491,17 @@ func (t *DefaultItemTranslator) DowngradeItemPackets(pks []packet.Packet, _ *min } pk.ItemInteractionData.HeldItem = t.DowngradeItemInstance(pk.ItemInteractionData.HeldItem) case *packet.CreativeContent: - for i, creativeItem := range pk.Items { - creativeItem.Item = t.DowngradeItemStack(creativeItem.Item) - - pk.Items[i] = creativeItem + newItems := make([]protocol.CreativeItem, 0, len(pk.Items)) + for _, creativeItem := range pk.Items { + if newItem, ok := t.TryDowngradeItemStack(creativeItem.Item); ok { + creativeItem.Item = newItem + newItems = append(newItems, creativeItem) + } + } + pk.Items = newItems + for i, group := range pk.Groups { + group.Icon = t.DowngradeItemStack(group.Icon) + pk.Groups[i] = group } case *packet.InventoryTransaction: for i, action := range pk.Actions { diff --git a/legacyver/protocol.go b/legacyver/protocol.go index be30ab7..9533619 100644 --- a/legacyver/protocol.go +++ b/legacyver/protocol.go @@ -696,16 +696,11 @@ func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) [ } case *packet.CreativeContent: items := make([]proto.CreativeItem, len(pk.Items)) - groups := make([]protocol.CreativeGroup, len(pk.Groups)) for i, it := range pk.Items { items[i] = (&proto.CreativeItem{}).FromLatest(it) } - for i, gr := range pk.Groups { - gr.Icon = p.itemTranslator.DowngradeItemStack(gr.Icon) - groups[i] = gr - } pks[pkIndex] = &legacypacket.CreativeContent{ - Groups: groups, + Groups: pk.Groups, Items: items, } case *packet.UpdateAbilities: