package miscperipherals.tile; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.WeakHashMap; import java.util.Map.Entry; import java.util.logging.Level; import miscperipherals.api.IDataCart; import miscperipherals.api.IMinecartData; import miscperipherals.core.LuaManager; import miscperipherals.core.MiscPeripherals; import miscperipherals.util.Util; import net.minecraft.entity.ai.EntityMinecartMobSpawner; import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.item.EntityMinecartChest; import net.minecraft.entity.item.EntityMinecartEmpty; import net.minecraft.entity.item.EntityMinecartFurnace; import net.minecraft.entity.item.EntityMinecartHopper; import net.minecraft.entity.item.EntityMinecartTNT; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import cpw.mods.fml.common.FMLCommonHandler; import dan200.computer.api.IComputerAccess; import dan200.computer.api.IPeripheral; public class TileRailReader extends Tile implements IPeripheral { private static final int TICK_RATE = 5; private final Map<IComputerAccess, Boolean> computers = new WeakHashMap<IComputerAccess, Boolean>(); private final Map<EntityMinecart, Boolean> carts = Collections.synchronizedMap(new WeakHashMap<EntityMinecart, Boolean>()); private int ticker = new Random().nextInt(TICK_RATE); @Override public boolean canUpdate() { return !FMLCommonHandler.instance().getEffectiveSide().isClient(); } @Override public void updateEntity() { if (++ticker > TICK_RATE) { ticker = 0; updateMinecarts(); for (EntityMinecart cart : carts.keySet()) { if (!this.carts.containsKey(cart)) { this.carts.put(cart, true); String cartType = "unknown"; Map<Object, Object> cartData = new HashMap<Object, Object>(); for (IMinecartData handler : IMinecartData.handlers) { try { Map<Object, Object> retData = handler.getMinecartData(cart); if (retData != null) { for (Entry<Object, Object> entry : retData.entrySet()) { cartData.put(entry.getKey(), entry.getValue()); } if (retData.containsKey("__CART_TYPE__")) break; } } catch (Throwable e) { MiscPeripherals.log.log(Level.WARNING, "Error processing minecart data handler "+handler, e); } } if (cartData != null) { if (cartData.containsKey("__CART_TYPE__")) { cartType = (String)cartData.get("__CART_TYPE__"); cartData.remove("__CART_TYPE__"); } if (cart instanceof IDataCart) { Object[] data = ((IDataCart) cart).getData(); cartData.put("data", data.length == 1 ? data : Util.arrayToMap(data)); } if (cart instanceof IInventory) { cartData.put("inventory", TileInteractiveSorter.makeInventoryMap((IInventory) cart)); } } for (IComputerAccess computer : computers.keySet()) { computer.queueEvent("minecart", new Object[] {cartType, cart.entityId, cartData}); } } } } } @Override public String getType() { return "railReader"; } @Override public String[] getMethodNames() { return new String[] {"setData"}; } @Override public Object[] callMethod(IComputerAccess computer, int method, Object[] arguments) throws Exception { switch (method) { case 0: { } } return new Object[0]; } @Override public boolean canAttachToSide(int side) { return true; } @Override public void attach(IComputerAccess computer) { LuaManager.mount(computer); computers.put(computer, true); } @Override public void detach(IComputerAccess computer) { computers.remove(computer); } public void updateMinecarts() { double rangeSub = 0.125D; List<EntityMinecart> carts = (List<EntityMinecart>)worldObj.getEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB(xCoord + rangeSub, yCoord + 1, zCoord + rangeSub, xCoord + 1 - rangeSub, yCoord + 2 - rangeSub, zCoord + 1 - rangeSub)); List<EntityMinecart> toRemove = new LinkedList<EntityMinecart>(); for (EntityMinecart cart : this.carts.keySet()) { if (!carts.contains(cart)) toRemove.add(cart); } for (EntityMinecart cart : toRemove) this.carts.remove(cart); } public static class VanillaMinecartData implements IMinecartData { @Override public Map<Object, Object> getMinecartData(EntityMinecart cart) { Map<Object, Object> ret = new HashMap<Object, Object>(); if (cart.getClass() == EntityMinecartEmpty.class) { ret.put("__CART_TYPE__", "basic"); ret.put("occupied", cart.riddenByEntity != null); if (cart.riddenByEntity != null) ret.put("username", cart.riddenByEntity.getEntityName()); } else if (cart.getClass() == EntityMinecartChest.class) { ret.put("__CART_TYPE__", "storage"); } else if (cart.getClass() == EntityMinecartFurnace.class) { ret.put("__CART_TYPE__", "furnace"); NBTTagCompound workaround = new NBTTagCompound(); cart.writeToNBT(workaround); ret.put("fuel", workaround.getInteger("Fuel")); } else if (cart.getClass() == EntityMinecartHopper.class) { ret.put("__CART_TYPE__", "hopper"); } else if (cart.getClass() == EntityMinecartTNT.class) { ret.put("__CART_TYPE__", "tnt"); } else if (cart.getClass() == EntityMinecartMobSpawner.class) { ret.put("__CART_TYPE__", "spawner"); } return ret.containsKey("__CART_TYPE__") ? ret : null; } } static { IMinecartData.handlers.add(new VanillaMinecartData()); } }