Relocate Source to proper directory.

This commit is contained in:
AlgorithmX2
2014-09-23 19:26:27 -05:00
parent fe927ce65d
commit 386d18a059
785 changed files with 35585 additions and 35580 deletions
@@ -0,0 +1,60 @@
package appeng.me.storage;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.tiles.ITileStorageMonitorable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IExternalStorageHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.tile.misc.TileCondenser;
public class AEExternalHandler implements IExternalStorageHandler
{
@Override
public boolean canHandle(TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource mySrc)
{
if ( channel == StorageChannel.ITEMS && te instanceof ITileStorageMonitorable )
return ((ITileStorageMonitorable) te).getMonitorable( d, mySrc ) != null;
return te instanceof TileCondenser;
}
@Override
public IMEInventory getInventory(TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource src)
{
if ( te instanceof TileCondenser )
{
if ( channel == StorageChannel.ITEMS )
return new VoidItemInventory( (TileCondenser) te );
else
return new VoidFluidInventory( (TileCondenser) te );
}
if ( te instanceof ITileStorageMonitorable )
{
ITileStorageMonitorable iface = (ITileStorageMonitorable) te;
IStorageMonitorable sm = iface.getMonitorable( d, src );
if ( channel == StorageChannel.ITEMS && sm != null )
{
IMEInventory<IAEItemStack> ii = sm.getItemInventory();
if ( ii != null )
return ii;
}
if ( channel == StorageChannel.FLUIDS && sm != null )
{
IMEInventory<IAEFluidStack> fi = sm.getFluidInventory();
if ( fi != null )
return fi;
}
}
return null;
}
}
@@ -0,0 +1,540 @@
package appeng.me.storage;
import java.util.HashSet;
import java.util.Iterator;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.exceptions.AppEngException;
import appeng.api.implementations.items.IStorageCell;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.ISaveProvider;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class CellInventory implements ICellInventory
{
static final String ITEM_TYPE_TAG = "it";
static final String ITEM_COUNT_TAG = "ic";
static final String ITEM_SLOT = "#";
static final String ITEM_SLOTCOUNT = "@";
static final String ITEM_PRE_FORMATTED_COUNT = "PF";
static final String ITEM_PRE_FORMATTED_SLOT = "PF#";
static final String ITEM_PRE_FORMATTED_NAME = "PN";
static final String ITEM_PRE_FORMATTED_FUZZY = "FP";
static protected String[] ITEM_SLOT_ARR;
static protected String[] ITEM_SLOTCOUNT_ARR;
final protected NBTTagCompound tagCompound;
protected int MAX_ITEM_TYPES = 63;
protected short storedItems = 0;
protected int storedItemCount = 0;
protected IItemList<IAEItemStack> cellItems;
protected ItemStack i;
protected IStorageCell CellType;
final protected ISaveProvider container;
protected CellInventory(NBTTagCompound data, ISaveProvider container) {
tagCompound = data;
this.container = container;
}
protected void loadCellItems()
{
if ( cellItems == null )
cellItems = AEApi.instance().storage().createItemList();
cellItems.resetStatus(); // clears totals and stuff.
int types = (int) getStoredItemTypes();
for (int x = 0; x < types; x++)
{
ItemStack t = ItemStack.loadItemStackFromNBT( tagCompound.getCompoundTag( ITEM_SLOT_ARR[x] ) );
if ( t != null )
{
t.stackSize = tagCompound.getInteger( ITEM_SLOTCOUNT_ARR[x] );
if ( t.stackSize > 0 )
{
cellItems.add( AEItemStack.create( t ) );
}
}
}
// cellItems.clean();
}
void saveChanges()
{
// cellItems.clean();
int itemCount = 0;
// add new pretty stuff...
int x = 0;
Iterator<IAEItemStack> i = cellItems.iterator();
while (i.hasNext())
{
IAEItemStack v = i.next();
itemCount += v.getStackSize();
NBTBase c = tagCompound.getTag( ITEM_SLOT_ARR[x] );
if ( c instanceof NBTTagCompound )
v.writeToNBT( (NBTTagCompound) c );
else
{
NBTTagCompound g = new NBTTagCompound();
v.writeToNBT( g );
tagCompound.setTag( ITEM_SLOT_ARR[x], g );
}
/*
* NBTBase tagSlotCount = tagCompound.getTag( ITEM_SLOTCOUNT_ARR[x] ); if ( tagSlotCount instanceof
* NBTTagInt ) ((NBTTagInt) tagSlotCount).data = (int) v.getStackSize(); else
*/
tagCompound.setInteger( ITEM_SLOTCOUNT_ARR[x], (int) v.getStackSize() );
x++;
}
// NBTBase tagType = tagCompound.getTag( ITEM_TYPE_TAG );
// NBTBase tagCount = tagCompound.getTag( ITEM_COUNT_TAG );
short oldStoreditems = storedItems;
/*
* if ( tagType instanceof NBTTagShort ) ((NBTTagShort) tagType).data = storedItems = (short) cellItems.size();
* else
*/
tagCompound.setShort( ITEM_TYPE_TAG, storedItems = (short) cellItems.size() );
/*
* if ( tagCount instanceof NBTTagInt ) ((NBTTagInt) tagCount).data = storedItemCount = itemCount; else
*/
tagCompound.setInteger( ITEM_COUNT_TAG, storedItemCount = itemCount );
// clean any old crusty stuff...
for (; x < oldStoreditems && x < MAX_ITEM_TYPES; x++)
{
tagCompound.removeTag( ITEM_SLOT_ARR[x] );
tagCompound.removeTag( ITEM_SLOTCOUNT_ARR[x] );
}
if ( container != null )
container.saveChanges( this );
}
protected CellInventory(ItemStack o, ISaveProvider container) throws AppEngException {
if ( ITEM_SLOT_ARR == null )
{
ITEM_SLOT_ARR = new String[MAX_ITEM_TYPES];
ITEM_SLOTCOUNT_ARR = new String[MAX_ITEM_TYPES];
for (int x = 0; x < MAX_ITEM_TYPES; x++)
{
ITEM_SLOT_ARR[x] = ITEM_SLOT + x;
ITEM_SLOTCOUNT_ARR[x] = ITEM_SLOTCOUNT + x;
}
}
if ( o == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
CellType = null;
i = o;
Item type = i.getItem();
if ( type instanceof IStorageCell )
{
CellType = (IStorageCell) i.getItem();
MAX_ITEM_TYPES = CellType.getTotalTypes( i );
}
if ( CellType == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if ( !CellType.isStorageCell( i ) )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if ( MAX_ITEM_TYPES > 63 )
MAX_ITEM_TYPES = 63;
if ( MAX_ITEM_TYPES < 1 )
MAX_ITEM_TYPES = 1;
this.container = container;
tagCompound = Platform.openNbtData( o );
storedItems = tagCompound.getShort( ITEM_TYPE_TAG );
storedItemCount = tagCompound.getInteger( ITEM_COUNT_TAG );
cellItems = null;
}
IItemList<IAEItemStack> getCellItems()
{
if ( cellItems == null )
{
cellItems = AEApi.instance().storage().createItemList();
loadCellItems();
}
return cellItems;
}
@Override
public int getBytesPerType()
{
return CellType.BytePerType( i );
}
@Override
public boolean canHoldNewItem()
{
long bytesFree = getFreeBytes();
return (bytesFree > getBytesPerType() || (bytesFree == getBytesPerType() && getUnusedItemCount() > 0)) && getRemainingItemTypes() > 0;
}
public static IMEInventoryHandler getCell(ItemStack o, ISaveProvider container2)
{
try
{
return new CellInventoryHandler( new CellInventory( o, container2 ) );
}
catch (AppEngException e)
{
return null;
}
}
private static boolean isStorageCell(ItemStack i)
{
if ( i == null )
{
return false;
}
try
{
Item type = i.getItem();
if ( type instanceof IStorageCell )
{
return !((IStorageCell) type).storableInStorageCell();
}
}
catch (Throwable err)
{
return true;
}
return false;
}
public static boolean isCell(ItemStack i)
{
if ( i == null )
{
return false;
}
Item type = i.getItem();
if ( type instanceof IStorageCell )
{
return ((IStorageCell) type).isStorageCell( i );
}
return false;
}
@Override
public long getTotalBytes()
{
return CellType.getBytes( i );
}
@Override
public long getFreeBytes()
{
return getTotalBytes() - getUsedBytes();
}
@Override
public long getUsedBytes()
{
long bytesForItemCount = (getStoredItemCount() + getUnusedItemCount()) / 8;
return getStoredItemTypes() * getBytesPerType() + bytesForItemCount;
}
@Override
public long getTotalItemTypes()
{
return MAX_ITEM_TYPES;
}
@Override
public long getStoredItemTypes()
{
return storedItems;
}
@Override
public long getStoredItemCount()
{
return storedItemCount;
}
private void updateItemCount(long delta)
{
tagCompound.setInteger( ITEM_COUNT_TAG, storedItemCount = (int) (storedItemCount + delta) );
}
@Override
public long getRemainingItemTypes()
{
long basedOnStorage = getFreeBytes() / getBytesPerType();
long baseOnTotal = getTotalItemTypes() - getStoredItemTypes();
return basedOnStorage > baseOnTotal ? baseOnTotal : basedOnStorage;
}
@Override
public long getRemainingItemCount()
{
long remaining = getFreeBytes() * 8 + getUnusedItemCount();
return remaining > 0 ? remaining : 0;
}
@Override
public int getUnusedItemCount()
{
int div = (int) (getStoredItemCount() % 8);
if ( div == 0 )
{
return 0;
}
return 8 - div;
}
private static HashSet<Integer> blackList = new HashSet();
public static void addBasicBlackList(int itemID, int Meta)
{
blackList.add( (Meta << Platform.DEF_OFFSET) | itemID );
}
public static boolean isBlackListed(IAEItemStack input)
{
if ( blackList.contains( (OreDictionary.WILDCARD_VALUE << Platform.DEF_OFFSET) | Item.getIdFromItem( input.getItem() ) ) )
return true;
return blackList.contains( (input.getItemDamage() << Platform.DEF_OFFSET) | Item.getIdFromItem( input.getItem() ) );
}
private boolean isEmpty(IMEInventory meinv)
{
return meinv.getAvailableItems( AEApi.instance().storage().createItemList() ).isEmpty();
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable mode, BaseActionSource src)
{
if ( input == null )
return null;
if ( input.getStackSize() == 0 )
return null;
if ( isBlackListed( input ) || CellType.isBlackListed( i, input ) )
return input;
ItemStack sharedItemStack = input.getItemStack();
if ( CellInventory.isStorageCell( sharedItemStack ) )
{
IMEInventory meinv = getCell( sharedItemStack, null );
if ( meinv != null && !isEmpty( meinv ) )
return input;
}
IAEItemStack l = getCellItems().findPrecise( input );
if ( l != null )
{
long remainingItemSlots = getRemainingItemCount();
if ( remainingItemSlots < 0 )
return input;
if ( input.getStackSize() > remainingItemSlots )
{
IAEItemStack r = input.copy();
r.setStackSize( r.getStackSize() - remainingItemSlots );
if ( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() + remainingItemSlots );
updateItemCount( remainingItemSlots );
saveChanges();
}
return r;
}
else
{
if ( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() + input.getStackSize() );
updateItemCount( input.getStackSize() );
saveChanges();
}
return null;
}
}
if ( canHoldNewItem() ) // room for new type, and for at least one item!
{
int remainingItemCount = (int) getRemainingItemCount() - getBytesPerType() * 8;
if ( remainingItemCount > 0 )
{
if ( input.getStackSize() > remainingItemCount )
{
ItemStack toReturn = Platform.cloneItemStack( sharedItemStack );
toReturn.stackSize = sharedItemStack.stackSize - remainingItemCount;
if ( mode == Actionable.MODULATE )
{
ItemStack toWrite = Platform.cloneItemStack( sharedItemStack );
toWrite.stackSize = remainingItemCount;
cellItems.add( AEItemStack.create( toWrite ) );
updateItemCount( toWrite.stackSize );
saveChanges();
}
return AEItemStack.create( toReturn );
}
if ( mode == Actionable.MODULATE )
{
updateItemCount( input.getStackSize() );
cellItems.add( input );
saveChanges();
}
return null;
}
}
return input;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
if ( request == null )
return null;
ItemStack sharedItem = request.getItemStack();
int size = sharedItem.stackSize;
IAEItemStack Results = null;
IAEItemStack l = getCellItems().findPrecise( request );
if ( l != null )
{
Results = l.copy();
if ( l.getStackSize() <= size )
{
Results.setStackSize( l.getStackSize() );
if ( mode == Actionable.MODULATE )
{
updateItemCount( -l.getStackSize() );
l.setStackSize( 0 );
saveChanges();
}
}
else
{
Results.setStackSize( size );
if ( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() - size );
updateItemCount( -size );
saveChanges();
}
}
}
return Results;
}
@Override
public IItemList getAvailableItems(IItemList out)
{
for (IAEItemStack i : getCellItems())
out.add( i );
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public double getIdleDrain()
{
return CellType.getIdleDrain();
}
@Override
public FuzzyMode getFuzzyMode()
{
return CellType.getFuzzyMode( this.i );
}
@Override
public IInventory getConfigInventory()
{
return CellType.getConfigInventory( this.i );
}
@Override
public IInventory getUpgradesInventory()
{
return CellType.getUpgradesInventory( this.i );
}
@Override
public int getStatusForCell()
{
if ( canHoldNewItem() )
return 1;
if ( getRemainingItemCount() > 0 )
return 2;
return 3;
}
@Override
public ItemStack getItemStack()
{
return i;
}
}
@@ -0,0 +1,123 @@
package appeng.me.storage;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.AEApi;
import appeng.api.config.FuzzyMode;
import appeng.api.config.IncludeExclude;
import appeng.api.config.Upgrades;
import appeng.api.implementations.items.IUpgradeModule;
import appeng.api.storage.ICellInventory;
import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import appeng.util.prioitylist.FuzzyPriorityList;
import appeng.util.prioitylist.PrecisePriorityList;
public class CellInventoryHandler extends MEInventoryHandler<IAEItemStack> implements ICellInventoryHandler
{
NBTTagCompound openNbtData()
{
return Platform.openNbtData( getCellInv().getItemStack() );
}
@Override
public ICellInventory getCellInv()
{
Object o = this.internal;
if ( o instanceof MEPassthru )
o = ((MEPassthru) o).getInternal();
return (ICellInventory) (o instanceof ICellInventory ? o : null);
}
CellInventoryHandler(IMEInventory c) {
super( c, StorageChannel.ITEMS );
ICellInventory ci = getCellInv();
if ( ci != null )
{
IItemList<IAEItemStack> priorityList = AEApi.instance().storage().createItemList();
IInventory upgrades = ci.getUpgradesInventory();
IInventory config = ci.getConfigInventory();
FuzzyMode fzMode = ci.getFuzzyMode();
boolean hasInverter = false;
boolean hasFuzzy = false;
for (int x = 0; x < upgrades.getSizeInventory(); x++)
{
ItemStack is = upgrades.getStackInSlot( x );
if ( is != null && is.getItem() instanceof IUpgradeModule )
{
Upgrades u = ((IUpgradeModule) is.getItem()).getType( is );
if ( u != null )
{
switch (u)
{
case FUZZY:
hasFuzzy = true;
break;
case INVERTER:
hasInverter = true;
break;
default:
}
}
}
}
for (int x = 0; x < config.getSizeInventory(); x++)
{
ItemStack is = config.getStackInSlot( x );
if ( is != null )
priorityList.add( AEItemStack.create( is ) );
}
myWhitelist = hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST;
if ( !priorityList.isEmpty() )
{
if ( hasFuzzy )
myPartitionList = new FuzzyPriorityList<IAEItemStack>( priorityList, fzMode );
else
myPartitionList = new PrecisePriorityList<IAEItemStack>( priorityList );
}
}
}
public boolean isPreformatted()
{
return ! myPartitionList.isEmpty();
}
public boolean isFuzzy()
{
return myPartitionList instanceof FuzzyPriorityList;
}
@Override
public IncludeExclude getIncludeExcludeMode()
{
return myWhitelist;
}
public int getStatusForCell()
{
int val = getCellInv().getStatusForCell();
if ( val == 1 && isPreformatted() )
val = 2;
return val;
}
}
@@ -0,0 +1,115 @@
package appeng.me.storage;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.exceptions.AppEngException;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.items.contents.CellConfig;
import appeng.util.item.AEItemStack;
public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
{
IItemList<IAEItemStack> itemListCache = AEApi.instance().storage().createItemList();
public static IMEInventoryHandler getCell(ItemStack o)
{
try
{
return new CellInventoryHandler( new CreativeCellInventory( o ) );
}
catch (AppEngException e)
{
}
return null;
}
protected CreativeCellInventory(ItemStack o) throws AppEngException {
CellConfig cc = new CellConfig( o );
for (ItemStack is : cc)
if ( is != null )
{
IAEItemStack i = AEItemStack.create( is );
i.setStackSize( Integer.MAX_VALUE );
itemListCache.add( i );
}
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable mode, BaseActionSource src)
{
IAEItemStack local = itemListCache.findPrecise( input );
if ( local == null )
return input;
return null;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
IAEItemStack local = itemListCache.findPrecise( request );
if ( local == null )
return null;
return request.copy();
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
{
for (IAEItemStack ais : itemListCache)
out.add( ais );
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ_WRITE;
}
@Override
public boolean isPrioritized(IAEItemStack input)
{
return itemListCache.findPrecise( input ) != null;
}
@Override
public boolean canAccept(IAEItemStack input)
{
return itemListCache.findPrecise( input ) != null;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,63 @@
package appeng.me.storage;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.ICellHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.data.IAEStack;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
int oldStatus = 0;
final ItemStack is;
final ICellHandler handler;
final IChestOrDrive cord;
public DriveWatcher(IMEInventory<T> i, ItemStack is, ICellHandler han, IChestOrDrive cod) {
super( i, i.getChannel() );
this.is = is;
handler = han;
cord = cod;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
{
long size = input.getStackSize();
T a = super.injectItems( input, type, src );
if ( a == null || a.getStackSize() != size )
{
int newStatus = handler.getStatusForCell( is, getInternal() );
if ( newStatus != oldStatus )
{
cord.blinkCell( getSlot() );
}
}
return a;
}
@Override
public T extractItems(T request, Actionable type, BaseActionSource src)
{
T a = super.extractItems( request, type, src );
if ( a != null )
{
int newStatus = handler.getStatusForCell( is, getInternal() );
if ( newStatus != oldStatus )
{
cord.blinkCell( getSlot() );
}
}
return a;
}
}
@@ -0,0 +1,171 @@
package appeng.me.storage;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.storage.data.IAEStack;
import appeng.me.cache.GridStorageCache;
/**
* Maintain my interests, and a global watch list, they should always be fully synchronized.
*/
public class ItemWatcher implements IStackWatcher
{
class ItemWatcherIterator implements Iterator<IAEStack>
{
final ItemWatcher watcher;
final Iterator<IAEStack> interestIterator;
IAEStack myLast;
public ItemWatcherIterator(ItemWatcher parent, Iterator<IAEStack> i) {
watcher = parent;
interestIterator = i;
}
@Override
public boolean hasNext()
{
return interestIterator.hasNext();
}
@Override
public IAEStack next()
{
return myLast = interestIterator.next();
}
@Override
public void remove()
{
gsc.interestManager.remove( myLast, watcher );
interestIterator.remove();
}
};
GridStorageCache gsc;
IStackWatcherHost myObject;
HashSet<IAEStack> myInterests = new HashSet();
public ItemWatcher(GridStorageCache cache, IStackWatcherHost host) {
gsc = cache;
myObject = host;
}
public IStackWatcherHost getHost()
{
return myObject;
}
@Override
public boolean add(IAEStack e)
{
if ( myInterests.contains( e ) )
return false;
return myInterests.add( e.copy() ) && gsc.interestManager.put( e, this );
}
@Override
public boolean addAll(Collection<? extends IAEStack> c)
{
boolean didChange = false;
for (IAEStack o : c)
didChange = add( o ) || didChange;
return didChange;
}
@Override
public void clear()
{
Iterator<IAEStack> i = myInterests.iterator();
while (i.hasNext())
{
gsc.interestManager.remove( i.next(), this );
i.remove();
}
}
@Override
public boolean contains(Object o)
{
return myInterests.contains( o );
}
@Override
public boolean containsAll(Collection<?> c)
{
return myInterests.containsAll( c );
}
@Override
public boolean isEmpty()
{
return myInterests.isEmpty();
}
@Override
public Iterator<IAEStack> iterator()
{
return new ItemWatcherIterator( this, myInterests.iterator() );
}
@Override
public boolean remove(Object o)
{
return myInterests.remove( o ) && gsc.interestManager.remove( (IAEStack)o, this );
}
@Override
public boolean removeAll(Collection<?> c)
{
boolean didSomething = false;
for (Object o : c)
didSomething = remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll(Collection<?> c)
{
boolean changed = false;
Iterator<IAEStack> i = iterator();
while (i.hasNext())
{
if ( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public int size()
{
return myInterests.size();
}
@Override
public Object[] toArray()
{
return myInterests.toArray();
}
@Override
public <T> T[] toArray(T[] a)
{
return myInterests.toArray( a );
}
}
@@ -0,0 +1,197 @@
package appeng.me.storage;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
{
protected IInventory target;
protected InventoryAdaptor adaptor;
public MEIInventoryWrapper(IInventory m, InventoryAdaptor ia) {
target = m;
adaptor = ia;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public IAEItemStack injectItems(IAEItemStack iox, Actionable mode, BaseActionSource src)
{
ItemStack input = iox.getItemStack();
if ( adaptor != null )
{
ItemStack is = mode == Actionable.SIMULATE ? adaptor.simulateAdd( input ) : adaptor.addItems( input );
if ( is == null )
return null;
return AEItemStack.create( is );
}
ItemStack out = Platform.cloneItemStack( input );
if ( mode == Actionable.MODULATE ) // absolutely no need for a first run in simulate mode.
{
for (int x = 0; x < target.getSizeInventory(); x++)
{
ItemStack t = target.getStackInSlot( x );
if ( Platform.isSameItem( t, input ) )
{
int oriStack = t.stackSize;
t.stackSize += out.stackSize;
target.setInventorySlotContents( x, t );
if ( t.stackSize > target.getInventoryStackLimit() )
{
t.stackSize = target.getInventoryStackLimit();
}
if ( t.stackSize > t.getMaxStackSize() )
{
t.stackSize = t.getMaxStackSize();
}
out.stackSize -= t.stackSize - oriStack;
if ( out.stackSize <= 0 )
{
return null;
}
}
}
}
for (int x = 0; x < target.getSizeInventory(); x++)
{
ItemStack t = target.getStackInSlot( x );
if ( t == null )
{
t = Platform.cloneItemStack( input );
t.stackSize = out.stackSize;
if ( t.stackSize > target.getInventoryStackLimit() )
{
t.stackSize = target.getInventoryStackLimit();
}
out.stackSize -= t.stackSize;
if ( mode == Actionable.MODULATE )
target.setInventorySlotContents( x, t );
if ( out.stackSize <= 0 )
{
return null;
}
}
}
return AEItemStack.create( out );
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
ItemStack Gathered = null;
ItemStack Req = request.getItemStack();
int request_stackSize = Req.stackSize;
if ( request_stackSize > Req.getMaxStackSize() )
{
request_stackSize = Req.getMaxStackSize();
}
Req.stackSize = request_stackSize;
if ( adaptor != null )
{
Gathered = adaptor.removeItems( Req.stackSize, Req, null );
}
else
{
Gathered = request.getItemStack();
Gathered.stackSize = 0;
// try to find matching inventories that already have it...
for (int x = 0; x < target.getSizeInventory(); x++)
{
ItemStack sub = target.getStackInSlot( x );
if ( Platform.isSameItem( sub, Req ) )
{
int reqNum = Req.stackSize;
if ( reqNum > sub.stackSize )
{
reqNum = Req.stackSize;
}
ItemStack retrieved = null;
if ( sub.stackSize < Req.stackSize )
{
retrieved = Platform.cloneItemStack( sub );
sub.stackSize = 0;
}
else
{
retrieved = sub.splitStack( Req.stackSize );
}
if ( sub.stackSize <= 0 )
target.setInventorySlotContents( x, null );
else
target.setInventorySlotContents( x, sub );
if ( retrieved != null )
{
Gathered.stackSize += retrieved.stackSize;
Req.stackSize -= retrieved.stackSize;
}
if ( request_stackSize == Gathered.stackSize )
{
return AEItemStack.create( Gathered );
}
}
}
if ( Gathered.stackSize == 0 )
{
return null;
}
}
return AEItemStack.create( Gathered );
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
{
for (int x = 0; x < target.getSizeInventory(); x++)
{
out.addStorage( AEItemStack.create( target.getStackInSlot( x ) ) );
}
return out;
}
}
@@ -0,0 +1,122 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.IncludeExclude;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.util.prioitylist.DefaultPriorityList;
import appeng.util.prioitylist.IPartitionList;
public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
final StorageChannel channel;
final protected IMEMonitor<T> monitor;
final protected IMEInventoryHandler<T> internal;
public int myPriority = 0;
public IncludeExclude myWhitelist = IncludeExclude.WHITELIST;
public AccessRestriction myAccess = AccessRestriction.READ_WRITE;
public IPartitionList<T> myPartitionList = new DefaultPriorityList<T>();
public MEInventoryHandler(IMEInventory<T> i, StorageChannel channel) {
this.channel = channel;
if ( i instanceof IMEInventoryHandler )
internal = (IMEInventoryHandler<T>) i;
else
internal = new MEPassthru<T>( i, channel );
monitor = internal instanceof IMEMonitor ? (IMEMonitor<T>) internal : null;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
{
if ( !this.canAccept( input ) )
return input;
return internal.injectItems( input, type, src );
}
@Override
public T extractItems(T request, Actionable type, BaseActionSource src)
{
if ( !getAccess().hasPermission( AccessRestriction.READ ) )
return null;
return internal.extractItems( request, type, src );
}
@Override
public IItemList<T> getAvailableItems(IItemList<T> out)
{
if ( !getAccess().hasPermission( AccessRestriction.READ ) )
return out;
return internal.getAvailableItems( out );
}
@Override
public StorageChannel getChannel()
{
return internal.getChannel();
}
@Override
public AccessRestriction getAccess()
{
return myAccess.restrictPermissions( internal.getAccess() );
}
@Override
public boolean isPrioritized(T input)
{
if ( myWhitelist == IncludeExclude.WHITELIST )
return myPartitionList.isListed( input ) || internal.isPrioritized( input );
return false;
}
@Override
public boolean canAccept(T input)
{
if ( !getAccess().hasPermission( AccessRestriction.WRITE ) )
return false;
if ( myWhitelist == IncludeExclude.BLACKLIST && myPartitionList.isListed( input ) )
return false;
if ( myPartitionList.isEmpty() || myWhitelist == IncludeExclude.BLACKLIST )
return internal.canAccept( input );
return myPartitionList.isListed( input ) && internal.canAccept( input );
}
@Override
public int getPriority()
{
return myPriority;
}
@Override
public int getSlot()
{
return internal.getSlot();
}
public IMEInventory<T> getInternal()
{
return internal;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,290 @@
package appeng.me.storage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.StorageFilter;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.ItemSlot;
public class MEMonitorIInventory implements IMEInventory<IAEItemStack>, IMEMonitor<IAEItemStack>
{
class CachedItemStack
{
public CachedItemStack(ItemStack is)
{
if ( is == null )
{
itemStack = null;
aeStack = null;
}
else
{
itemStack = is.copy();
aeStack = AEApi.instance().storage().createItemStack( is );
}
}
final ItemStack itemStack;
final IAEItemStack aeStack;
};
final InventoryAdaptor adaptor;
final TreeMap<Integer, CachedItemStack> memory;
final IItemList<IAEItemStack> list = AEApi.instance().storage().createItemList();
final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap();
public BaseActionSource mySource;
public StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
@Override
public void addListener(IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken)
{
listeners.put( l, verificationToken );
}
@Override
public void removeListener(IMEMonitorHandlerReceiver<IAEItemStack> l)
{
listeners.remove( l );
}
public MEMonitorIInventory(InventoryAdaptor adaptor)
{
this.adaptor = adaptor;
memory = new TreeMap();
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable type, BaseActionSource src)
{
ItemStack out = null;
if ( type == Actionable.SIMULATE )
out = adaptor.simulateAdd( input.getItemStack() );
else
out = adaptor.addItems( input.getItemStack() );
onTick();
if ( out == null )
return null;
// better then doing construction from scratch :3
IAEItemStack o = input.copy();
o.setStackSize( out.stackSize );
return o;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ_WRITE;
}
@Override
public boolean isPrioritized(IAEItemStack input)
{
return false;
}
@Override
public boolean canAccept(IAEItemStack input)
{
return true;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public IItemList<IAEItemStack> getStorageList()
{
return list;
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
{
for (CachedItemStack is : memory.values())
out.addStorage( is.aeStack );
return out;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable type, BaseActionSource src)
{
ItemStack out = null;
if ( type == Actionable.SIMULATE )
out = adaptor.simulateRemove( (int) request.getStackSize(), request.getItemStack(), null );
else
out = adaptor.removeItems( (int) request.getStackSize(), request.getItemStack(), null );
if ( out == null )
return null;
// better then doing construction from scratch :3
IAEItemStack o = request.copy();
o.setStackSize( out.stackSize );
onTick();
return o;
}
public TickRateModulation onTick()
{
boolean changed = false;
LinkedList<IAEItemStack> changes = new LinkedList<IAEItemStack>();
int high = 0;
list.resetStatus();
for (ItemSlot is : adaptor)
{
CachedItemStack old = memory.get( is.slot );
high = Math.max( high, is.slot );
ItemStack newIS = is == null || is.isExtractable == false && mode == StorageFilter.EXTRACTABLE_ONLY ? null : is.getItemStack();
ItemStack oldIS = old == null ? null : old.itemStack;
if ( isDifferent( newIS, oldIS ) )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
memory.put( is.slot, cis );
if ( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if ( cis != null && cis.aeStack != null )
{
changes.add( cis.aeStack );
list.add( cis.aeStack );
}
changed = true;
}
else if ( is != null )
{
int newSize = (newIS == null ? 0 : newIS.stackSize);
int diff = newSize - (oldIS == null ? 0 : oldIS.stackSize);
IAEItemStack stack = (old == null || old.aeStack == null ? AEApi.instance().storage().createItemStack( newIS ) : old.aeStack.copy());
if ( stack != null )
{
stack.setStackSize( newSize );
list.add( stack );
}
if ( diff != 0 && stack != null )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
memory.put( is.slot, cis );
IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
// detect dropped items; should fix non IISided Inventory Changes.
NavigableMap<Integer, CachedItemStack> end = memory.tailMap( high, false );
if ( !end.isEmpty() )
{
for (CachedItemStack cis : end.values())
{
if ( cis != null && cis.aeStack != null )
{
IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if ( !changes.isEmpty() )
postDifference( changes );
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent(ItemStack a, ItemStack b)
{
if ( a == b && b == null )
return false;
if ( (a == null && b != null) || (a != null && b == null) )
return true;
return !Platform.isSameItemPrecise( a, b );
}
private void postDifference(Iterable<IAEItemStack> a)
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if ( a != null )
{
Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = listeners.entrySet().iterator();
while (i.hasNext())
{
Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if ( key.isValid( l.getValue() ) )
key.postChange( this, a, mySource );
else
i.remove();
}
}
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,121 @@
package appeng.me.storage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.util.Platform;
import appeng.util.inv.ItemListIgnoreCrafting;
public class MEMonitorPassthu<T extends IAEStack<T>> extends MEPassthru<T> implements IMEMonitor<T>, IMEMonitorHandlerReceiver<T>
{
HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap();
IMEMonitor<T> monitor;
public BaseActionSource changeSource;
public MEMonitorPassthu(IMEInventory<T> i, StorageChannel channel) {
super( i, channel );
if ( i instanceof IMEMonitor )
monitor = (IMEMonitor<T>) i;
}
@Override
public void setInternal(IMEInventory<T> i)
{
if ( monitor != null )
monitor.removeListener( this );
monitor = null;
IItemList<T> before = getInternal() == null ? channel.createList() : getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( channel.createList() ) );
super.setInternal( i );
if ( i instanceof IMEMonitor )
monitor = (IMEMonitor<T>) i;
IItemList<T> after = getInternal() == null ? channel.createList() : getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( channel.createList() ) );
if ( monitor != null )
monitor.addListener( this, monitor );
Platform.postListChanges( before, after, this, changeSource );
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
{
super.getAvailableItems( new ItemListIgnoreCrafting( out ) );
return out;
}
@Override
public void addListener(IMEMonitorHandlerReceiver<T> l, Object verificationToken)
{
listeners.put( l, verificationToken );
}
@Override
public void removeListener(IMEMonitorHandlerReceiver<T> l)
{
listeners.remove( l );
}
@Override
public IItemList<T> getStorageList()
{
if ( monitor == null )
{
IItemList<T> out = channel.createList();
getInternal().getAvailableItems( new ItemListIgnoreCrafting( out ) );
return out;
}
return monitor.getStorageList();
}
@Override
public boolean isValid(Object verificationToken)
{
return verificationToken == monitor;
}
@Override
public void postChange(IBaseMonitor<T> monitor, Iterable<T> change, BaseActionSource source)
{
Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = listeners.entrySet().iterator();
while (i.hasNext())
{
Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
IMEMonitorHandlerReceiver<T> recv = e.getKey();
if ( recv.isValid( e.getValue() ) )
recv.postChange( this, change, source );
else
i.remove();
}
}
@Override
public void onListUpdate()
{
Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = listeners.entrySet().iterator();
while (i.hasNext())
{
Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
IMEMonitorHandlerReceiver<T> recv = e.getKey();
if ( recv.isValid( e.getValue() ) )
recv.onListUpdate();
else
i.remove();
}
}
}
@@ -0,0 +1,93 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
public class MEPassthru<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
private IMEInventory<T> internal;
final protected StorageChannel channel;
protected IMEInventory<T> getInternal()
{
return internal;
}
public MEPassthru(IMEInventory<T> i, StorageChannel channel) {
this.channel = channel;
setInternal( i );
}
public void setInternal(IMEInventory<T> i)
{
internal = i;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
{
return internal.injectItems( input, type, src );
}
@Override
public T extractItems(T request, Actionable type, BaseActionSource src)
{
return internal.extractItems( request, type, src );
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
{
return internal.getAvailableItems( out );
}
@Override
public StorageChannel getChannel()
{
return internal.getChannel();
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ_WRITE;
}
@Override
public boolean isPrioritized(T input)
{
return false;
}
@Override
public boolean canAccept(T input)
{
return true;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,287 @@
package appeng.me.storage;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.security.PlayerSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.cache.SecurityCache;
import appeng.util.ItemSorters;
public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
private final static Comparator prioritySorter = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2)
{
return ItemSorters.compareInt( o2, o1 );
}
};
final StorageChannel myChannel;
final SecurityCache security;
// final TreeMultimap<Integer, IMEInventoryHandler<T>> priorityInventory;
final TreeMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
public NetworkInventoryHandler(StorageChannel chan, SecurityCache security) {
myChannel = chan;
this.security = security;
priorityInventory = new TreeMap( prioritySorter ); // TreeMultimap.create( prioritySorter, hashSorter );
}
public void addNewStorage(IMEInventoryHandler<T> h)
{
int priority = h.getPriority();
List<IMEInventoryHandler<T>> list = priorityInventory.get( priority );
if ( list == null )
priorityInventory.put( priority, list = new ArrayList() );
list.add( h );
}
static int currentPass = 0;
int myPass = 0;
static final ThreadLocal<LinkedList> depthMod = new ThreadLocal<LinkedList>();
static final ThreadLocal<LinkedList> depthSim = new ThreadLocal<LinkedList>();
private LinkedList getDepth(Actionable type)
{
ThreadLocal<LinkedList> depth = type == Actionable.MODULATE ? depthMod : depthSim;
LinkedList s = depth.get();
if ( s == null )
depth.set( s = new LinkedList() );
return s;
}
private boolean diveList(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
LinkedList cDepth = getDepth( type );
if ( cDepth.contains( networkInventoryHandler ) )
return true;
cDepth.push( this );
return false;
}
private boolean diveIteration(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
LinkedList cDepth = getDepth( type );
if ( cDepth.isEmpty() )
{
currentPass++;
myPass = currentPass;
}
else
{
if ( currentPass == myPass )
return true;
else
myPass = currentPass;
}
cDepth.push( this );
return false;
}
private void surface(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
if ( getDepth( type ).pop() != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
private boolean testPermission(BaseActionSource src, SecurityPermissions permission)
{
if ( src.isPlayer() )
{
if ( !security.hasPermission( ((PlayerSource) src).player, permission ) )
return true;
}
else if ( src.isMachine() )
{
if ( security.isAvailable() )
{
IGridNode n = ((MachineSource) src).via.getActionableNode();
if ( n == null )
return true;
IGrid gn = n.getGrid();
if ( gn != security.myGrid )
{
int playerID = -1;
ISecurityGrid sg = gn.getCache( ISecurityGrid.class );
playerID = sg.getOwner();
if ( !security.hasPermission( playerID, permission ) )
return true;
}
}
}
return false;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
{
if ( diveList( this, type ) )
return input;
if ( testPermission( src, SecurityPermissions.INJECT ) )
{
surface( this, type );
return input;
}
Iterator<List<IMEInventoryHandler<T>>> i = priorityInventory.values().iterator();// asMap().entrySet().iterator();
while (i.hasNext())
{
List<IMEInventoryHandler<T>> invList = i.next();
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
while (ii.hasNext() && input != null)
{
IMEInventoryHandler<T> inv = ii.next();
if ( inv.validForPass( 1 ) && inv.canAccept( input )
&& (inv.isPrioritized( input ) || inv.extractItems( input, Actionable.SIMULATE, src ) != null) )
input = inv.injectItems( input, type, src );
}
ii = invList.iterator();
while (ii.hasNext() && input != null)
{
IMEInventoryHandler<T> inv = ii.next();
if ( inv.validForPass( 2 ) && inv.canAccept( input ) )// ignore crafting on the second pass.
input = inv.injectItems( input, type, src );
}
}
surface( this, type );
return input;
}
@Override
public T extractItems(T request, Actionable mode, BaseActionSource src)
{
if ( diveList( this, mode ) )
return null;
if ( testPermission( src, SecurityPermissions.EXTRACT ) )
{
surface( this, mode );
return null;
}
Iterator<List<IMEInventoryHandler<T>>> i = priorityInventory.descendingMap().values().iterator();// priorityInventory.asMap().descendingMap().entrySet().iterator();
T output = request.copy();
request = request.copy();
output.setStackSize( 0 );
long req = request.getStackSize();
while (i.hasNext())
{
List<IMEInventoryHandler<T>> invList = i.next();
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
while (ii.hasNext() && output.getStackSize() < req)
{
IMEInventoryHandler<T> inv = ii.next();
request.setStackSize( req - output.getStackSize() );
output.add( inv.extractItems( request, mode, src ) );
}
}
surface( this, mode );
if ( output.getStackSize() <= 0 )
return null;
return output;
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
{
if ( diveIteration( this, Actionable.SIMULATE ) )
return out;
// for (Entry<Integer, IMEInventoryHandler<T>> h : priorityInventory.entries())
for (List<IMEInventoryHandler<T>> i : priorityInventory.values())
for (IMEInventoryHandler<T> j : i)
out = j.getAvailableItems( out );
surface( this, Actionable.SIMULATE );
return out;
}
@Override
public StorageChannel getChannel()
{
return myChannel;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ_WRITE;
}
@Override
public boolean isPrioritized(T input)
{
return false;
}
@Override
public boolean canAccept(T input)
{
return true;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,74 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public T injectItems(T input, Actionable mode, BaseActionSource src)
{
return input;
}
@Override
public T extractItems(T request, Actionable mode, BaseActionSource src)
{
return null;
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
{
return out;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ;
}
@Override
public boolean isPrioritized(T input)
{
return false;
}
@Override
public boolean canAccept(T input)
{
return false;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return i == 2;
}
}
@@ -0,0 +1,159 @@
package appeng.me.storage;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.implementations.items.IBiometricCard;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.PlayerSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurity;
import com.mojang.authlib.GameProfile;
public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
{
final TileSecurity securityTile;
final public IItemList<IAEItemStack> storedItems = AEApi.instance().storage().createItemList();
public SecurityInventory(TileSecurity ts) {
securityTile = ts;
}
private boolean hasPermission(BaseActionSource src)
{
if ( src.isPlayer() )
{
try
{
return securityTile.getProxy().getSecurity().hasPermission( ((PlayerSource) src).player, SecurityPermissions.SECURITY );
}
catch (GridAccessException e)
{
// :P
}
}
return false;
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable type, BaseActionSource src)
{
if ( hasPermission( src ) && AEApi.instance().items().itemBiometricCard.sameAsStack( input.getItemStack() ) )
{
if ( canAccept( input ) )
{
if ( type == Actionable.SIMULATE )
return null;
storedItems.add( input );
securityTile.inventoryChanged();
return null;
}
}
return input;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
if ( hasPermission( src ) )
{
IAEItemStack target = storedItems.findPrecise( request );
if ( target != null )
{
IAEItemStack output = target.copy();
if ( mode == Actionable.SIMULATE )
return output;
target.setStackSize( 0 );
securityTile.inventoryChanged();
return output;
}
}
return null;
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
{
for (IAEItemStack ais : storedItems)
out.add( ais );
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.READ_WRITE;
}
@Override
public boolean isPrioritized(IAEItemStack input)
{
return false;
}
@Override
public boolean canAccept(IAEItemStack input)
{
if ( input.getItem() instanceof IBiometricCard )
{
IBiometricCard tbc = (IBiometricCard) input.getItem();
GameProfile newUser = tbc.getProfile( input.getItemStack() );
int PlayerID = AEApi.instance().registries().players().getID( newUser );
if ( securityTile.getOwner() == PlayerID )
return false;
for (IAEItemStack ais : storedItems)
{
if ( ais.isMeaningful() )
{
GameProfile thisUser = tbc.getProfile( ais.getItemStack() );
if ( thisUser == newUser )
return false;
if ( thisUser != null && thisUser.equals( newUser ) )
return false;
}
}
return true;
}
return false;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -0,0 +1,83 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.tile.misc.TileCondenser;
public class VoidFluidInventory implements IMEInventoryHandler<IAEFluidStack>
{
TileCondenser target;
public VoidFluidInventory(TileCondenser te) {
target = te;
}
@Override
public IAEFluidStack injectItems(IAEFluidStack input, Actionable mode, BaseActionSource src)
{
if ( input != null )
target.addPower( (double) input.getStackSize() / 1000.0 );
return null;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.FLUIDS;
}
@Override
public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src)
{
return null;
}
@Override
public IItemList<IAEFluidStack> getAvailableItems(IItemList out)
{
return out;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.WRITE;
}
@Override
public boolean isPrioritized(IAEFluidStack input)
{
return false;
}
@Override
public boolean canAccept(IAEFluidStack input)
{
return true;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return i == 2;
}
}
@@ -0,0 +1,83 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.tile.misc.TileCondenser;
public class VoidItemInventory implements IMEInventoryHandler<IAEItemStack>
{
TileCondenser target;
public VoidItemInventory(TileCondenser te) {
target = te;
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable mode, BaseActionSource src)
{
if ( input != null )
target.addPower( input.getStackSize() );
return null;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
return null;
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
{
return out;
}
@Override
public AccessRestriction getAccess()
{
return AccessRestriction.WRITE;
}
@Override
public boolean isPrioritized(IAEItemStack input)
{
return false;
}
@Override
public boolean canAccept(IAEItemStack input)
{
return true;
}
@Override
public int getPriority()
{
return 0;
}
@Override
public int getSlot()
{
return 0;
}
@Override
public boolean validForPass(int i)
{
return i == 2;
}
}