Package forestry.core.inventory

Source Code of forestry.core.inventory.InvTools

/*******************************************************************************
* Copyright (c) 2011-2014 SirSengir.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Various Contributors including, but not limited to:
* SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
******************************************************************************/
package forestry.core.inventory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.oredict.OreDictionary;

import buildcraft.api.transport.PipeManager;

import forestry.api.core.ISpecialInventory;
import forestry.core.inventory.filters.ArrayStackFilter;
import forestry.core.inventory.filters.IStackFilter;
import forestry.core.inventory.filters.InvertedStackFilter;
import forestry.core.inventory.filters.StackFilter;
import forestry.core.inventory.manipulators.InventoryManipulator;
import forestry.core.inventory.wrappers.ChestWrapper;
import forestry.core.inventory.wrappers.IInvSlot;
import forestry.core.inventory.wrappers.InventoryIterator;
import forestry.core.inventory.wrappers.InventoryMapper;
import forestry.core.inventory.wrappers.SidedInventoryMapper;
import forestry.core.inventory.wrappers.SpecialInventoryMapper;
import forestry.core.utils.PlainInventory;

public abstract class InvTools {

  /*private static final String TAG_ID = "id";
  private static final String TAG_SIZE = "stackSize";
  private static final String TAG_DAMAGE = "Damage";
  private static final String TAG_COUNT = "Count";*/
  private static final String TAG_SLOT = "Slot";

  public static int getXOnSide(int x, ForgeDirection side) {
    return x + side.offsetX;
  }

  public static int getYOnSide(int y, ForgeDirection side) {
    return y + side.offsetY;
  }

  public static int getZOnSide(int z, ForgeDirection side) {
    return z + side.offsetZ;
  }

  public static boolean blockExistsOnSide(World world, int x, int y, int z, ForgeDirection side) {
    return world.blockExists(getXOnSide(x, side), getYOnSide(y, side), getZOnSide(z, side));
  }

  public static int getBlockMetadataOnSide(IBlockAccess world, int i, int j, int k, ForgeDirection side) {
    return world.getBlockMetadata(getXOnSide(i, side), getYOnSide(j, side), getZOnSide(k, side));
  }

  public static Block getBlockOnSide(IBlockAccess world, int x, int y, int z, ForgeDirection side) {
    return world.getBlock(getXOnSide(x, side), getYOnSide(y, side), getZOnSide(z, side));
  }

  public static TileEntity getBlockTileEntityOnSide(World world, int x, int y, int z, ForgeDirection side) {
    int sx = getXOnSide(x, side);
    int sy = getYOnSide(y, side);
    int sz = getZOnSide(z, side);
    if (world.blockExists(sx, sy, sz))
      return world.getTileEntity(sx, sy, sz);
    return null;
  }

  public static TileEntity getBlockTileEntityOnSide(IBlockAccess world, int x, int y, int z, ForgeDirection side) {
    int sx = getXOnSide(x, side);
    int sy = getYOnSide(y, side);
    int sz = getZOnSide(z, side);
    return world.getTileEntity(sx, sy, sz);
  }

  public static List<IInventory> getAdjacentInventories(World world, int i, int j, int k) {
    return getAdjacentInventories(world, i, j, k, null);
  }

  public static List<IInventory> getAdjacentInventories(World world, int i, int j, int k, Class<? extends IInventory> type) {
    List<IInventory> list = new ArrayList<IInventory>(5);
    for (int side = 0; side < 6; side++) {
      IInventory inv = getInventoryFromSide(world, i, j, k, ForgeDirection.getOrientation(side), type, null);
      if (inv != null)
        list.add(inv);
    }
    return list;
  }

  public static Map<Integer, IInventory> getAdjacentInventoryMap(World world, int i, int j, int k) {
    return getAdjacentInventoryMap(world, i, j, k, null);
  }

  public static Map<Integer, IInventory> getAdjacentInventoryMap(World world, int i, int j, int k, Class<? extends IInventory> type) {
    Map<Integer, IInventory> map = new TreeMap<Integer, IInventory>();
    for (int side = 0; side < 6; side++) {
      IInventory inv = getInventoryFromSide(world, i, j, k, ForgeDirection.getOrientation(side), type, null);
      if (inv != null)
        map.put(side, inv);
    }
    return map;
  }

  public static IInventory getInventoryFromSide(World world, int x, int y, int z, ForgeDirection side, final Class<? extends IInventory> type, final Class<? extends IInventory> exclude) {
    return getInventoryFromSide(world, x, y, z, side, new ITileFilter() {
      @Override
      public boolean matches(TileEntity tile) {
        if (type != null && !type.isAssignableFrom(tile.getClass()))
          return false;
        if (exclude != null && exclude.isAssignableFrom(tile.getClass()))
          return false;
        return true;
      }
    });
  }

  public static IInventory getInventoryFromSide(World world, int x, int y, int z, ForgeDirection side, ITileFilter filter) {
    TileEntity tile = getBlockTileEntityOnSide(world, x, y, z, side);
    if (tile == null || !(tile instanceof IInventory) || !filter.matches(tile))
      return null;
    return getInventoryFromTile(tile, side.getOpposite());
  }

  public static IInventory getInventoryFromTile(TileEntity tile, ForgeDirection side) {
    if (tile == null || !(tile instanceof IInventory))
      return null;

    if (!PipeManager.canExtractItems(null, tile.getWorldObj(), tile.xCoord, tile.yCoord, tile.zCoord))
      return null;

    if (tile instanceof TileEntityChest) {
      TileEntityChest chest = (TileEntityChest) tile;
      return new ChestWrapper(chest);
    }
    return getInventory((IInventory) tile, side);
  }

  public static IInventory getInventory(IInventory inv, ForgeDirection side) {
    if (inv == null)
      return null;

    if (inv instanceof ISpecialInventory)
      inv = new SpecialInventoryMapper((ISpecialInventory) inv, side);
    else if (inv instanceof ISidedInventory)
      inv = new SidedInventoryMapper((ISidedInventory) inv, side);
    return inv;
  }

  public static int[] buildSlotArray(int start, int size) {
    int[] slots = new int[size];
    for (int i = 0; i < size; i++) {
      slots[i] = start + i;
    }
    return slots;
  }

  /*public static void addItemToolTip(ItemStack stack, String tag, String msg) {
    NBTTagCompound nbt = getItemData(stack);
    NBTTagCompound display = nbt.getCompoundTag("display");
    nbt.setTag("display", display);
    NBTTagList lore = display.getTagList("Lore", 8); // 8 = String
    display.setTag("Lore", lore);
    //lore.appendTag(new NBTTagString(tag, msg));
    lore.appendTag(new NBTTagString(msg));
  }*/

  public static NBTTagCompound getItemData(ItemStack stack) {
    NBTTagCompound nbt = stack.getTagCompound();
    if (nbt == null) {
      nbt = new NBTTagCompound();
      stack.setTagCompound(nbt);
    }
    return nbt;
  }

  public static ItemStack depleteItem(ItemStack stack) {
    if (stack.stackSize == 1)
      return stack.getItem().getContainerItem(stack);
    else {
      stack.splitStack(1);
      return stack;
    }
  }

  public static ItemStack damageItem(ItemStack stack, int damage) {
    if (!stack.isItemStackDamageable())
      return stack;
    int curDamage = stack.getItemDamage();
    curDamage += damage;
    stack.setItemDamage(curDamage);
    if (stack.getItemDamage() > stack.getMaxDamage()) {
      stack.stackSize--;
      stack.setItemDamage(0);
    }
    if (stack.stackSize <= 0)
      stack = null;
    return stack;
  }

  public static void dropItem(ItemStack stack, World world, double x, double y, double z) {
    if (stack == null || stack.stackSize < 1)
      return;
    EntityItem entityItem = new EntityItem(world, x, y + 1.5, z, stack);
    entityItem.delayBeforeCanPickup = 10;
    world.spawnEntityInWorld(entityItem);
  }

  public static boolean isInventoryEmpty(IInventory inv, ForgeDirection side) {
    return isInventoryEmpty(getInventory(inv, side));
  }

  public static boolean isInventoryEmpty(IInventory inv) {
    ItemStack stack = null;
    for (IInvSlot slot : InventoryIterator.getIterable(inv)) {
      stack = slot.getStackInSlot();
      if (stack != null)
        break;
    }
    return stack == null;
  }

  public static boolean isInventoryFull(IInventory inv, ForgeDirection side) {
    return isInventoryFull(getInventory(inv, side));
  }

  public static boolean isInventoryFull(IInventory inv) {
    ItemStack stack = null;
    for (IInvSlot slot : InventoryIterator.getIterable(inv)) {
      stack = slot.getStackInSlot();
      if (stack == null)
        break;
    }
    return stack != null;
  }

  /**
   * Counts the number of items.
   *
   * @param inv
   * @return
   */
  public static int countItems(IInventory inv) {
    int count = 0;
    for (IInvSlot slot : InventoryIterator.getIterable(inv)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack != null)
        count += stack.stackSize;
    }
    return count;
  }

  public static int countItems(IInventory inv, IStackFilter filter) {
    int count = 0;
    for (IInvSlot slot : InventoryIterator.getIterable(inv)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack != null && filter.matches(stack))
        count += stack.stackSize;
    }
    return count;
  }

  public static boolean numItemsMoreThan(IInventory inv, int amount) {
    int count = 0;
    for (IInvSlot slot : InventoryIterator.getIterable(inv)) {
      ItemStack stack = slot.getStackInSlot();
      if (stack != null)
        count += stack.stackSize;
      if (count >= amount)
        return true;
    }
    return false;
  }

  /**
   * Counts the number of items that match the filter. Ignores
   * ISpecialInventory and ISidedInventory, and bypasses InventoryMapper to
   * count from the base IInventory.
   *
   * @param inv
   * @param filters
   * @return
   */
  public static int countItems(IInventory inv, ItemStack... filters) {
    if (inv instanceof InventoryMapper)
      inv = ((InventoryMapper) inv).getBaseInventory();
    boolean hasFilter = false;
    for (ItemStack filter : filters) {
      if (filter != null) {
        hasFilter = true;
        break;
      }
    }

    if (!hasFilter)
      return countItems(inv);

    int count = 0;
    ItemStack stack = null;
    for (int slot = 0; slot < inv.getSizeInventory(); slot++) {
      stack = inv.getStackInSlot(slot);
      if (stack != null)
        for (ItemStack filter : filters) {
          if (filter != null && isItemEqual(stack, filter)) {
            count += stack.stackSize;
            break;
          }
        }
    }
    return count;
  }

  public static int countItems(Collection<IInventory> inventories, ItemStack... filter) {
    int count = 0;
    for (IInventory inv : inventories) {
      count += InvTools.countItems(inv, filter);
    }
    return count;
  }

  /**
   * Returns true if the inventory contains the specified item.
   *
   * @param inv The IIinventory to check
   * @param item The ItemStack to look for
   * @return true is exists
   */
  public static boolean containsItem(IInventory inv, ItemStack item) {
    return countItems(inv, item) > 0;
  }

  /**
   * Returns a map backed by an
   * <code>ItemStackMap</code> that lists the total number of each type of
   * item in the inventory.
   *
   * @param inv The <code>IInventory</code> to generate the manifest for
   * @return A <code>Map</code> that lists how many of each item is in * * *
   * the <code>IInventory</code>
   * @see ItemStackMap
   */
  public static Map<ItemStack, Integer> getManifest(IInventory inv) {
    Map<ItemStack, Integer> manifest = new ItemStackMap<Integer>();
    for (int i = 0; i < inv.getSizeInventory(); i++) {
      ItemStack slot = inv.getStackInSlot(i);
      if (slot != null) {
        Integer count = manifest.get(slot);
        if (count == null)
          count = 0;
        count += slot.stackSize;
        manifest.put(slot, count);
      }
    }
    return manifest;
  }

  /**
   * Attempts to move a single item from one inventory to another.
   *
   * @param source
   * @param dest
   * @return null if nothing was moved, the stack moved otherwise
   */
  public static ItemStack moveOneItem(IInventory source, IInventory dest) {
    return moveOneItem(source, dest, StackFilter.ALL);
  }

  /**
   * Attempts to move a single item from one inventory to another.
   *
   * @param source
   * @param dest
   * @param filer an ItemStack[] to match against
   * @return null if nothing was moved, the stack moved otherwise
   */
  public static ItemStack moveOneItem(IInventory source, IInventory dest, ItemStack... filters) {
    return moveOneItem(source, dest, new ArrayStackFilter(filters));
  }

  /**
   * Attempts to move a single item from one inventory to another.
   *
   * @param source
   * @param dest
   * @param filer an IItemType to match against
   * @return null if nothing was moved, the stack moved otherwise
   */
  public static ItemStack moveOneItem(IInventory source, IInventory dest, IStackFilter filter) {
    InventoryManipulator imSource = InventoryManipulator.get(source);
    return imSource.moveItem(dest, filter);
  }

  /**
   * Attempts to move one item from a collection of inventories.
   *
   * @param sources
   * @param dest
   * @param filters
   * @return
   */
  public static ItemStack moveOneItem(Collection<IInventory> sources, IInventory dest, ItemStack... filters) {
    for (IInventory inv : sources) {
      ItemStack moved = InvTools.moveOneItem(inv, dest, filters);
      if (moved != null)
        return moved;
    }
    return null;
  }

  /**
   * Attempts to move one item from a collection of inventories.
   *
   * @param sources
   * @param dest
   * @param filters
   * @return
   */
  public static ItemStack moveOneItem(Collection<IInventory> sources, IInventory dest, IStackFilter filter) {
    for (IInventory inv : sources) {
      ItemStack moved = InvTools.moveOneItem(inv, dest, filter);
      if (moved != null)
        return moved;
    }
    return null;
  }

  /**
   * Attempts to move one item to a collection of inventories.
   *
   * @param sources
   * @param dest
   * @param filters
   * @return
   */
  public static ItemStack moveOneItem(IInventory source, Collection<IInventory> destinations, ItemStack... filters) {
    for (IInventory dest : destinations) {
      ItemStack moved = InvTools.moveOneItem(source, dest, filters);
      if (moved != null)
        return moved;
    }
    return null;
  }

  /**
   * Attempts to move a single item from one inventory to another.
   *
   * Will not move any items in the filter.
   *
   * @param source
   * @param dest
   * @param filer an ItemStack[] to exclude
   * @return null if nothing was moved, the stack moved otherwise
   */
  public static ItemStack moveOneItemExcept(IInventory source, IInventory dest, ItemStack... filters) {
    return moveOneItem(source, dest, new InvertedStackFilter(new ArrayStackFilter(filters)));
  }

  /**
   * Attempts to move one item from a collection of inventories.
   *
   * @param sources
   * @param dest
   * @param filters
   * @return
   */
  public static ItemStack moveOneItemExcept(Collection<IInventory> sources, IInventory dest, ItemStack... filters) {
    for (IInventory inv : sources) {
      ItemStack moved = InvTools.moveOneItemExcept(inv, dest, filters);
      if (moved != null)
        return moved;
    }
    return null;
  }

  /**
   * Attempts to move one item to a collection of inventories.
   *
   * @param sources
   * @param dest
   * @param filters
   * @return
   */
  public static ItemStack moveOneItemExcept(IInventory source, Collection<IInventory> destinations, ItemStack... filters) {
    for (IInventory dest : destinations) {
      ItemStack moved = InvTools.moveOneItemExcept(source, dest, filters);
      if (moved != null)
        return moved;
    }
    return null;
  }

  public static boolean isWildcard(ItemStack stack) {
    return isWildcard(stack.getItemDamage());
  }

  public static boolean isWildcard(int damage) {
    return damage == -1 || damage == OreDictionary.WILDCARD_VALUE;
  }

  /**
   * A more robust item comparison function.
   *
   * Compares stackSize as well.
   *
   * Two null stacks will return true, unlike the other functions.
   *
   * This function is primarily intended to be used to track changes to an
   * ItemStack.
   *
   * @param a An ItemStack
   * @param b An ItemStack
   * @return True if equal
   */
  public static boolean isItemEqualStrict(ItemStack a, ItemStack b) {
    if (a == null && b == null)
      return true;
    if (a == null || b == null)
      return false;
    if (a.getItem() != b.getItem())
      return false;
    if (a.stackSize != b.stackSize)
      return false;
    if (a.getItemDamage() != b.getItemDamage())
      return false;
    if (a.stackTagCompound != null && !a.stackTagCompound.equals(b.stackTagCompound))
      return false;
    return true;
  }

  /**
   * A more robust item comparison function.
   *
   * Compares stackSize as well.
   *
   * Two null stacks will return true, unlike the other functions.
   *
   * This function is primarily intended to be used to track changes to an
   * ItemStack.
   *
   * @param a An ItemStack
   * @param b An ItemStack
   * @return True if equal
   */
  public static boolean isItemEqualSemiStrict(ItemStack a, ItemStack b) {
    if (a == null && b == null)
      return true;
    if (a == null || b == null)
      return false;
    if (a.getItem() != b.getItem())
      return false;
    if (a.getItemDamage() != b.getItemDamage())
      return false;
    if (a.stackTagCompound != null && !a.stackTagCompound.equals(b.stackTagCompound))
      return false;
    return true;
  }

  /**
   * A more robust item comparison function. Supports items with damage = -1
   * matching any sub-type.
   *
   * @param a An ItemStack
   * @param b An ItemStack
   * @return True if equal
   */
  public static boolean isItemEqual(ItemStack a, ItemStack b) {
    return isItemEqual(a, b, true, true);
  }

  /**
   * A more robust item comparison function. Supports items with damage = -1
   * matching any sub-type.
   *
   * @param a An ItemStack
   * @param b An ItemStack
   * @return True if equal
   */
  public static boolean isItemEqualIgnoreNBT(ItemStack a, ItemStack b) {
    return isItemEqual(a, b, true, false);
  }

  public static boolean isItemEqual(final ItemStack a, final ItemStack b, final boolean matchDamage, final boolean matchNBT) {
    if (a == null || b == null)
      return false;
    if (a.getItem() != b.getItem())
      return false;
    if (matchNBT && !ItemStack.areItemStackTagsEqual(a, b))
      return false;
    if (matchDamage && a.getHasSubtypes()) {
      if (isWildcard(a) || isWildcard(b))
        return true;
      if (a.getItemDamage() != b.getItemDamage())
        return false;
    }
    return true;
  }

  /**
   * Returns true if the item is equal to any one of several possible matches.
   *
   * @param stack
   * @param matches
   * @return
   */
  public static boolean isItemEqual(ItemStack stack, ItemStack... matches) {
    for (ItemStack match : matches) {
      if (isItemEqual(stack, match))
        return true;
    }
    return false;
  }

  /**
   * Returns true if the item is equal to any one of several possible matches.
   *
   * @param stack
   * @param matches
   * @return
   */
  public static boolean isItemEqual(ItemStack stack, Collection<ItemStack> matches) {
    for (ItemStack match : matches) {
      if (isItemEqual(stack, match))
        return true;
    }
    return false;
  }

  /**
   * Places an ItemStack in a destination IInventory. Will attempt to move as
   * much of the stack as possible, returning any remainder.
   *
   * @param stack The ItemStack to put in the inventory.
   * @param dest The destination IInventory.
   * @return Null if itemStack was completely moved, a new itemStack with
   * remaining stackSize if part or none of the stack was moved.
   */
  public static ItemStack moveItemStack(ItemStack stack, IInventory dest) {
    InventoryManipulator im = InventoryManipulator.get(dest);
    return im.addStack(stack);
  }

  /**
   * Checks if there is room for the ItemStack in the inventory.
   *
   * @param stack The ItemStack
   * @param dest The IInventory
   * @return true if room for stack
   */
  public static boolean isRoomForStack(ItemStack stack, IInventory dest) {
    if (stack == null || dest == null)
      return false;
    InventoryManipulator im = InventoryManipulator.get(dest);
    return im.canAddStack(stack);
  }

  /**
   * Removes a up to numItems worth of items from the inventory, not caring
   * about what the items are.
   *
   * @param inv
   * @param numItems
   * @return
   */
  public static ItemStack[] removeItems(IInventory inv, int numItems) {
    if (inv instanceof ISpecialInventory)
      return ((ISpecialInventory) inv).extractItem(true, ForgeDirection.UNKNOWN, numItems);
    PlainInventory output = new PlainInventory(27, "temp");
    for (int i = 0; i < inv.getSizeInventory(); i++) {
      if (numItems <= 0)
        break;
      ItemStack slot = inv.getStackInSlot(i);
      if (slot == null)
        continue;
      ItemStack removed = inv.decrStackSize(i, numItems);
      numItems -= removed.stackSize;
      ItemStack remainder = moveItemStack(removed, output);
      if (remainder != null) {
        moveItemStack(remainder, inv);
        numItems += remainder.stackSize;
        break;
      }
    }

    List<ItemStack> list = new LinkedList<ItemStack>();
    for (ItemStack stack : output.getContents()) {
      if (stack != null)
        list.add(stack);
    }
    return list.toArray(new ItemStack[0]);
  }

  /**
   * Removes and returns a single item from the inventory.
   *
   * @param inv The inventory
   * @return An ItemStack
   */
  public static ItemStack removeOneItem(IInventory inv) {
    return removeOneItem(inv, StackFilter.ALL);
  }

  /**
   * Removes and returns a single item from the inventory that matches the
   * filter.
   *
   * @param inv The inventory
   * @param filter ItemStack to match against
   * @return An ItemStack
   */
  public static ItemStack removeOneItem(IInventory inv, ItemStack... filter) {
    return removeOneItem(inv, new ArrayStackFilter(filter));
  }

  /**
   * Removes and returns a single item from the inventory that matches the
   * filter.
   *
   * @param inv The inventory
   * @param filter EnumItemType to match against
   * @return An ItemStack
   */
  public static ItemStack removeOneItem(IInventory inv, IStackFilter filter) {
    InventoryManipulator im = InventoryManipulator.get(inv);
    return im.removeItem(filter);
  }

  /**
   * Removes and returns a single item from the inventory that matches the
   * filter.
   *
   * @param inv The inventory
   * @param filter EnumItemType to match against
   * @return An ItemStack
   */
  public static ItemStack removeOneItem(Collection<IInventory> invs, IStackFilter filter) {
    for (IInventory inv : invs) {
      ItemStack stack = removeOneItem(inv, filter);
      if (stack != null)
        return stack;
    }
    return null;
  }

  public static void writeInvToNBT(IInventory inv, String tag, NBTTagCompound data) {
    NBTTagList list = new NBTTagList();
    for (byte slot = 0; slot < inv.getSizeInventory(); slot++) {
      ItemStack stack = inv.getStackInSlot(slot);
      if (stack != null) {
        NBTTagCompound itemTag = new NBTTagCompound();
        itemTag.setByte(TAG_SLOT, slot);
        writeItemToNBT(stack, itemTag);
        list.appendTag(itemTag);
      }
    }
    data.setTag(tag, list);
  }

  public static void readInvFromNBT(IInventory inv, String tag, NBTTagCompound data) {
    NBTTagList list = data.getTagList(tag, 10);
    for (byte entry = 0; entry < list.tagCount(); entry++) {
      NBTTagCompound itemTag = list.getCompoundTagAt(entry);
      int slot = itemTag.getByte(TAG_SLOT);
      if (slot >= 0 && slot < inv.getSizeInventory()) {
        ItemStack stack = ItemStack.loadItemStackFromNBT(itemTag);
        inv.setInventorySlotContents(slot, stack);
      }
    }
  }

  public static void writeItemToNBT(ItemStack stack, NBTTagCompound data) {
    if (stack == null || stack.stackSize <= 0)
      return;
    if (stack.stackSize > 127)
      stack.stackSize = 127;
    stack.writeToNBT(data);
  }
}
TOP

Related Classes of forestry.core.inventory.InvTools

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.