From 0ea9dfb0cebab42f58b5638eb856513556abf90d Mon Sep 17 00:00:00 2001 From: DrPerkyLegit Date: Fri, 3 Apr 2026 00:17:06 -0400 Subject: [PATCH] optimize item data communication, options for future item flags --- .../Inventory/Inventory.cs | 12 +++-- .../Inventory/PlayerInventory.cs | 21 +++++--- Minecraft.Server/FourKitNatives.cpp | 48 +++++++++++++------ 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/Minecraft.Server.FourKit/Inventory/Inventory.cs b/Minecraft.Server.FourKit/Inventory/Inventory.cs index 01415128..f98cafbd 100644 --- a/Minecraft.Server.FourKit/Inventory/Inventory.cs +++ b/Minecraft.Server.FourKit/Inventory/Inventory.cs @@ -48,9 +48,15 @@ public class Inventory : IEnumerable for (int i = 0; i < _items.Length; i++) { - int id = buf[i * 3]; - int count = buf[i * 3 + 1]; - int aux = buf[i * 3 + 2]; + int id = buf[i * 3 + 0]; + int aux = buf[i * 3 + 1]; + int packed = buf[i * 3 + 2]; + + ushort count = (ushort)((packed >> 8) & 0xFFFF); + + //byte flags = (byte)((packed >> 24) & 0xFF); + //bool hasMetadata = (flags & 0x1) != 0; //unused here + _items[i]?.UnbindFromInventory(); if (id > 0 && count > 0) { diff --git a/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs b/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs index 9d50fa08..065b1926 100644 --- a/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs +++ b/Minecraft.Server.FourKit/Inventory/PlayerInventory.cs @@ -43,16 +43,25 @@ public class PlayerInventory : Inventory for (int i = 0; i < INVENTORY_SIZE; i++) { - int id = buf[i * 3]; - int count = buf[i * 3 + 1]; - int aux = buf[i * 3 + 2]; + int id = buf[i * 3 + 0]; + int aux = buf[i * 3 + 1]; + int packed = buf[i * 3 + 2]; + + ushort count = (ushort)((packed >> 8) & 0xFFFF); + + byte flags = (byte)((packed >> 24) & 0xFF); + bool hasMetadata = (flags & 0x1) != 0; + _items[i]?.UnbindFromInventory(); if (id > 0 && count > 0) { var stack = new ItemStack(id, count, (short)aux); - var meta = ReadMetaFromNative(entityId, i); - if (meta != null) - stack.setItemMetaInternal(meta); + if (hasMetadata) + { + var meta = ReadMetaFromNative(entityId, i); + if (meta != null) + stack.setItemMetaInternal(meta); + } _items[i] = stack; stack.BindToInventory(this, i); } diff --git a/Minecraft.Server/FourKitNatives.cpp b/Minecraft.Server/FourKitNatives.cpp index d9eceda8..79dcc89f 100644 --- a/Minecraft.Server/FourKitNatives.cpp +++ b/Minecraft.Server/FourKitNatives.cpp @@ -612,9 +612,41 @@ int __cdecl NativeGetPlayerAddress(int entityId, char *outIpBuf, int outIpBufSiz return 1; } +void WriteInventoryItemData(std::shared_ptr item, int index, int* outBuffer) { + if (item) { + //ItemFlags Key: + // 0x1 = hasMetadata (has data that needs to be gotten from "ReadMetaFromNative") + + uint8_t itemFlags = 0; + if (item->getTag() == nullptr) goto doneWithMetadataFlag; + CompoundTag* itemTag = item->getTag(); + + if (itemTag->contains(L"ench")) { + itemFlags |= 0x1; + goto doneWithMetadataFlag; + } + else { //we just want to check one tag for metadata and return for this flag, not all of them + CompoundTag* displayTag = itemTag->getCompound(L"display"); + if (displayTag->contains(L"Name") || displayTag->contains(L"Lore")) { + itemFlags |= 0x1; + goto doneWithMetadataFlag; + } + } + + + doneWithMetadataFlag: + + outBuffer[(index * 3) + 0] = item->id; + outBuffer[(index * 3) + 1] = item->getAuxValue(); + outBuffer[(index * 3) + 2] = (((int)itemFlags << 24) | ((int)item->count << 8)); + } +} void __cdecl NativeGetPlayerInventory(int entityId, int *outData) { + // 9 slots per row, 3 slots in the inventory and the hotbar, 4 armor slots, 1 hand slot + // (((slotsPerRow * Rows) + ArmorSlots) * AmountOfIntsPerSlot) + hand slot + // (((9 * 4) + 4) * 3) + 1 = 121 memset(outData, 0, 121 * sizeof(int)); auto player = FindPlayer(entityId); @@ -627,13 +659,7 @@ void __cdecl NativeGetPlayerInventory(int entityId, int *outData) for (unsigned int i = 0; i < size; i++) { - auto item = player->inventory->getItem(i); - if (item) - { - outData[i * 3] = item->id; - outData[i * 3 + 1] = item->count; - outData[i * 3 + 2] = item->getAuxValue(); - } + WriteInventoryItemData(player->inventory->getItem(i), i, outData); } outData[120] = player->inventory->selected; @@ -667,13 +693,7 @@ void __cdecl NativeGetContainerContents(int entityId, int *outData, int maxSlots for (int i = 0; i < count; i++) { - auto &item = (*items)[i]; - if (item) - { - outData[i * 3] = item->id; - outData[i * 3 + 1] = item->count; - outData[i * 3 + 2] = item->getAuxValue(); - } + WriteInventoryItemData((*items)[i], i, outData); } delete items; }