optimize item data communication, options for future item flags

This commit is contained in:
DrPerkyLegit 2026-04-03 00:17:06 -04:00
parent f364a5bb07
commit 0ea9dfb0ce
3 changed files with 58 additions and 23 deletions

View file

@ -48,9 +48,15 @@ public class Inventory : IEnumerable<ItemStack>
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)
{

View file

@ -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);
}

View file

@ -612,9 +612,41 @@ int __cdecl NativeGetPlayerAddress(int entityId, char *outIpBuf, int outIpBufSiz
return 1;
}
void WriteInventoryItemData(std::shared_ptr<ItemInstance> 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;
}