package crazypants.enderio.machine.invpanel.client; import crazypants.enderio.machine.invpanel.InventoryDatabase; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import com.enderio.core.common.network.CompressedDataInput; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; public class InventoryDatabaseClient extends InventoryDatabase<ItemEntry> { private final ArrayList<ItemEntry> clientItems; private final HashSet<Integer> requestedItems; private int itemsChangeCount; private int countChangeCount; InventoryDatabaseClient(int generation) { this.generation = generation; clientItems = new ArrayList<ItemEntry>(); requestedItems = new HashSet<Integer>(); } public int getItemsChangeCount() { return itemsChangeCount; } public int getCountChangeCount() { return countChangeCount; } public void getItems(List<ItemEntry> outList) { outList.addAll(clientItems); } public void readCompressedItems(byte[] compressed) throws IOException { CompressedDataInput cdi = new CompressedDataInput(compressed); try { int numEntries = cdi.readVariable(); for(int i=0 ; i<numEntries ; i++) { int code = cdi.readVariable(); int itemID = cdi.readVariable(); int meta = cdi.readVariable(); NBTTagCompound nbt = null; int dbIndex = code >> 1; if((code & 1) == 1) { nbt = CompressedStreamTools.read(cdi); } // item order can vary, ensure that the slot exists complexItems.ensureCapacity(dbIndex + 1); while(complexItems.size() <= dbIndex) { complexItems.add(null); } ItemEntry entry = complexItems.get(dbIndex); if(entry == null) { entry = createItemEntry(dbIndex + COMPLEX_DBINDEX_START, itemID, meta, nbt); complexItems.set(dbIndex, entry); complexRegistry.put(entry, entry); } int count = cdi.readVariable(); setItemCount(entry, count); } itemsChangeCount++; countChangeCount++; } finally { cdi.close(); } } public List<Integer> readCompressedItemList(byte[] compressed) throws IOException { CompressedDataInput cdi = new CompressedDataInput(compressed); try { List<Integer> missingItems = null; int changed = cdi.readVariable(); if(changed > 0) { for(int i = 0; i < changed; i++) { int dbID = cdi.readVariable(); int count = cdi.readVariable(); ItemEntry entry = getItem(dbID); if(entry != null) { setItemCount(entry, count); } else { missingItems = addMissingItems(missingItems, dbID); } } countChangeCount++; } else { for(ItemEntry entry : clientItems) { entry.count = 0; } clientItems.clear(); requestedItems.clear(); int count = cdi.readVariable(); while(count > 0) { int dbID = cdi.readUnsignedShort(); ItemEntry entry = getSimpleItem(dbID); entry.count = count; clientItems.add(entry); count = cdi.readVariable(); } count = cdi.readVariable(); int dbID = COMPLEX_DBINDEX_START; while(count > 0) { dbID += cdi.readVariable(); ItemEntry entry = getItem(dbID); if(entry != null) { entry.count = count; clientItems.add(entry); } else { missingItems = addMissingItems(missingItems, dbID); } count = cdi.readVariable(); } itemsChangeCount++; countChangeCount++; } return missingItems; } finally { cdi.close(); } } private void setItemCount(ItemEntry entry, int count) { if(entry.count == 0 && count > 0) { clientItems.add(entry); itemsChangeCount++; } else if(entry.count > 0 && count == 0) { clientItems.remove(entry); itemsChangeCount++; } entry.count = count; } private List<Integer> addMissingItems(List<Integer> list, Integer dbId) { if(!requestedItems.contains(dbId)) { if(list == null) { list = new ArrayList<Integer>(); } list.add(dbId); requestedItems.add(dbId); } return list; } @Override protected ItemEntry createItemEntry(int dbId, int hash, int itemID, int meta, NBTTagCompound nbt) { return new ItemEntry(dbId, hash, itemID, meta, nbt); } }