diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/AnySilentChest.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/AnySilentChest.java
new file mode 100644
index 0000000..6eab905
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/AnySilentChest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+import java.util.Iterator;
+
+import org.bukkit.entity.Player;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.internal.IAnySilentChest;
+
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+
+import org.bukkit.craftbukkit.v1_8_R2.entity.*;
+
+public class AnySilentChest implements IAnySilentChest {
+ public boolean IsAnyChestNeeded(Player p, int x, int y, int z) {
+ // FOR REFERENCE, LOOK AT net.minecraft.server.BlockChest
+ BlockPosition position = new BlockPosition(x, y, z);
+ EntityPlayer player = ((CraftPlayer) p).getHandle();
+ World world = player.world;
+ BlockChest chest = (BlockChest) (((BlockChest) world.getType(position).getBlock()).b == 1 ?
+ Block.getByName("trapped_chest") : Block.getByName("chest"));
+
+ // If block on top
+ if (topBlocking(world, position)) {
+ return true;
+ }
+
+ // If block next to chest is chest and has a block on top
+ for (EnumDirection direction : EnumDirectionList.HORIZONTAL) {
+ BlockPosition sidePosition = position.shift(direction);
+ Block var8 = world.getType(sidePosition).getBlock();
+ if (var8 == chest) {
+ if (this.topBlocking(world, sidePosition)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ private boolean topBlocking(World world, BlockPosition position) {
+ return this.blockOnTop(world, position) || this.ocelotOnTop(world, position);
+ }
+
+ private boolean blockOnTop(World world, BlockPosition position) {
+ return world.getType(position.up()).getBlock().isOccluding();
+ }
+
+ private boolean ocelotOnTop(World world, BlockPosition position) {
+ Iterator var3 = world.a(EntityOcelot.class,
+ new AxisAlignedBB((double) position.getX(), (double) (position.getY() + 1),
+ (double) position.getZ(), (double) (position.getX() + 1),
+ (double) (position.getY() + 2), (double) (position.getZ() + 1))).iterator();
+
+ EntityOcelot var5;
+ do {
+ if (!var3.hasNext()) {
+ return false;
+ }
+
+ Entity var4 = (Entity) var3.next();
+ var5 = (EntityOcelot) var4;
+ } while (!var5.isSitting());
+
+ return true;
+ }
+
+ public boolean ActivateChest(Player p, boolean anychest, boolean silentchest, int x, int y, int z) {
+ BlockPosition position = new BlockPosition(x, y, z);
+ EntityPlayer player = ((CraftPlayer) p).getHandle();
+ World world = player.world;
+ if (world.isClientSide) {
+ return true;
+ }
+
+ BlockChest chest = (BlockChest) (((BlockChest) world.getType(position).getBlock()).b == 1 ?
+ Block.getByName("trapped_chest") : Block.getByName("chest"));
+
+ TileEntity tileEntity = world.getTileEntity(position);
+ if (!(tileEntity instanceof TileEntityChest)) {
+ return true;
+ }
+
+ ITileInventory tileInventory = (ITileInventory) tileEntity;
+ if (!anychest && this.topBlocking(world, position)) {
+ return true;
+ }
+
+ for (EnumDirection direction : EnumDirectionList.HORIZONTAL) {
+ BlockPosition side = position.shift(direction);
+ Block block = world.getType(side).getBlock();
+ if (block == chest) {
+ if (!anychest && this.topBlocking(world, side)) {
+ return true;
+ }
+
+ TileEntity sideTileEntity = world.getTileEntity(side);
+ if (sideTileEntity instanceof TileEntityChest) {
+ if (direction != EnumDirection.WEST && direction != EnumDirection.NORTH) {
+ tileInventory = new InventoryLargeChest("container.chestDouble", tileInventory, (TileEntityChest) sideTileEntity);
+ } else {
+ tileInventory = new InventoryLargeChest("container.chestDouble", (TileEntityChest) sideTileEntity, tileInventory);
+ }
+ }
+ }
+ }
+
+ boolean returnValue = true;
+ if (silentchest) {
+ tileInventory = new SilentInventory(tileInventory);
+ if (OpenInv.NotifySilentChest()) {
+ p.sendMessage("You are opening a chest silently.");
+ }
+ returnValue = false;
+ }
+
+ player.openContainer(tileInventory);
+
+ if (anychest && OpenInv.NotifyAnyChest()) {
+ p.sendMessage("You are opening a blocked chest.");
+ }
+
+ return returnValue;
+ }
+}
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/EnumDirectionList.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/EnumDirectionList.java
new file mode 100644
index 0000000..eae6abf
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/EnumDirectionList.java
@@ -0,0 +1,24 @@
+package com.lishid.openinv.internal.v1_8_R2;
+
+import com.google.common.collect.Iterators;
+import net.minecraft.server.v1_8_R2.EnumDirection;
+import net.minecraft.server.v1_8_R2.EnumDirection.EnumDirectionLimit;
+
+import java.util.Iterator;
+
+public enum EnumDirectionList implements Iterable {
+ HORIZONTAL(EnumDirectionLimit.HORIZONTAL),
+ VERTICAL(EnumDirectionLimit.VERTICAL);
+
+ private EnumDirectionLimit list;
+
+ private EnumDirectionList(EnumDirectionLimit list) {
+ this.list = list;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return Iterators.forArray(list.a());
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/InventoryAccess.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/InventoryAccess.java
new file mode 100644
index 0000000..0381d3b
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/InventoryAccess.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+import java.lang.reflect.Field;
+
+
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.inventory.Inventory;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.Permissions;
+import com.lishid.openinv.internal.IInventoryAccess;
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.craftbukkit.v1_8_R2.inventory.*;
+
+public class InventoryAccess implements IInventoryAccess {
+ public boolean check(Inventory inventory, HumanEntity player) {
+ IInventory inv = grabInventory(inventory);
+
+ if (inv instanceof SpecialPlayerInventory) {
+ if (!OpenInv.hasPermission(player, Permissions.PERM_EDITINV)) {
+ return false;
+ }
+ }
+
+ else if (inv instanceof SpecialEnderChest) {
+ if (!OpenInv.hasPermission(player, Permissions.PERM_EDITENDER)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private IInventory grabInventory(Inventory inventory) {
+ if(inventory instanceof CraftInventory) {
+ return ((CraftInventory) inventory).getInventory();
+ }
+
+ //Use reflection to find the inventory
+ Class extends Inventory> clazz = inventory.getClass();
+ IInventory result = null;
+ for(Field f : clazz.getDeclaredFields()) {
+ f.setAccessible(true);
+ if(IInventory.class.isAssignableFrom(f.getDeclaringClass())) {
+ try {
+ result = (IInventory) f.get(inventory);
+ }
+ catch (Exception e) {
+ OpenInv.log(e);
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/PlayerDataManager.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/PlayerDataManager.java
new file mode 100644
index 0000000..c03ed13
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/PlayerDataManager.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+import java.util.UUID;
+
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.internal.IPlayerDataManager;
+import com.mojang.authlib.GameProfile;
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+
+import org.bukkit.craftbukkit.v1_8_R2.*;
+
+public class PlayerDataManager implements IPlayerDataManager {
+ public Player loadPlayer(String name) {
+ try {
+ UUID uuid = matchUser(name);
+ if (uuid == null) {
+ return null;
+ }
+
+ OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
+ if (player == null) {
+ return null;
+ }
+ GameProfile profile = new GameProfile(uuid, player.getName());
+ MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
+ // Create an entity to load the player data
+ EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(0), profile, new PlayerInteractManager(server.getWorldServer(0)));
+
+ // Get the bukkit entity
+ Player target = entity.getBukkitEntity();
+ if (target != null) {
+ // Load data
+ target.loadData();
+ // Return the entity
+ return target;
+ }
+ }
+ catch (Exception e) {
+ OpenInv.log(e);
+ }
+
+ return null;
+ }
+
+ private static UUID matchUser(String search) {
+ UUID found = null;
+
+ String lowerSearch = search.toLowerCase();
+ int delta = 2147483647;
+
+ OfflinePlayer[] offlinePlayers = Bukkit.getOfflinePlayers();
+ for (OfflinePlayer player : offlinePlayers) {
+ String name = player.getName();
+
+ if (name == null){
+ continue;
+ }
+ if (name.equalsIgnoreCase(search)){
+ return player.getUniqueId();
+ }
+ if (name.toLowerCase().startsWith(lowerSearch)) {
+ int curDelta = name.length() - lowerSearch.length();
+ if (curDelta < delta) {
+ found = player.getUniqueId();
+ delta = curDelta;
+ }
+ if (curDelta == 0) {
+ break;
+ }
+ }
+ }
+
+ return found;
+ }
+}
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentContainerChest.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentContainerChest.java
new file mode 100644
index 0000000..aaed14c
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentContainerChest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+
+
+public class SilentContainerChest extends ContainerChest {
+ public IInventory inv;
+
+ public SilentContainerChest(IInventory i1, IInventory i2, EntityHuman human) {
+ super(i1, i2, human);
+ inv = i2;
+ // close signal
+ inv.closeContainer(human);
+ }
+
+ @Override
+ public void b(EntityHuman paramEntityHuman) {
+ // Don't send close signal twice, might screw up
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentInventory.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentInventory.java
new file mode 100644
index 0000000..fb6c881
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SilentInventory.java
@@ -0,0 +1,162 @@
+package com.lishid.openinv.internal.v1_8_R2;
+
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftHumanEntity;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.inventory.InventoryHolder;
+
+import java.util.List;
+
+public class SilentInventory implements ITileInventory {
+ public ITileInventory inv;
+
+ public SilentInventory(ITileInventory inv) {
+ this.inv = inv;
+ }
+
+ @Override
+ public boolean r_() {
+ return inv.r_();
+ }
+
+ @Override
+ public void a(ChestLock chestLock) {
+ inv.a(chestLock);
+ }
+
+ @Override
+ public ChestLock i() {
+ return inv.i();
+ }
+
+ @Override
+ public int getSize() {
+ return inv.getSize();
+ }
+
+ @Override
+ public ItemStack getItem(int i) {
+ return inv.getItem(i);
+ }
+
+ @Override
+ public ItemStack splitStack(int i, int i1) {
+ return inv.splitStack(i, i1);
+ }
+
+ @Override
+ public ItemStack splitWithoutUpdate(int i) {
+ return inv.splitWithoutUpdate(i);
+ }
+
+ @Override
+ public void setItem(int i, ItemStack itemStack) {
+ inv.setItem(i, itemStack);
+ }
+
+ @Override
+ public int getMaxStackSize() {
+ return inv.getMaxStackSize();
+ }
+
+ @Override
+ public void update() {
+ inv.update();
+ }
+
+ @Override
+ public boolean a(EntityHuman entityHuman) {
+ return inv.a(entityHuman);
+ }
+
+ @Override
+ public void startOpen(EntityHuman entityHuman) {
+ //Don't do anything
+ }
+
+ @Override
+ public void closeContainer(EntityHuman entityHuman) {
+ //Don't do anything
+ }
+
+ @Override
+ public boolean b(int i, ItemStack itemStack) {
+ return inv.b(i, itemStack);
+ }
+
+ @Override
+ public int getProperty(int i) {
+ return inv.getProperty(i);
+ }
+
+ @Override
+ public void b(int i, int i1) {
+ inv.b(i, i1);
+ }
+
+ @Override
+ public int g() {
+ return inv.g();
+ }
+
+ @Override
+ public void l() {
+ inv.l();
+ }
+
+ @Override
+ public ItemStack[] getContents() {
+ return inv.getContents();
+ }
+
+ @Override
+ public void onOpen(CraftHumanEntity craftHumanEntity) {
+ inv.onOpen(craftHumanEntity);
+ }
+
+ @Override
+ public void onClose(CraftHumanEntity craftHumanEntity) {
+ inv.onClose(craftHumanEntity);
+ }
+
+ @Override
+ public List getViewers() {
+ return inv.getViewers();
+ }
+
+ @Override
+ public InventoryHolder getOwner() {
+ return inv.getOwner();
+ }
+
+ @Override
+ public void setMaxStackSize(int i) {
+ inv.setMaxStackSize(i);
+ }
+
+ @Override
+ public String getName() {
+ return inv.getName();
+ }
+
+ @Override
+ public boolean hasCustomName() {
+ return inv.hasCustomName();
+ }
+
+ @Override
+ public IChatBaseComponent getScoreboardDisplayName() {
+ return inv.getScoreboardDisplayName();
+ }
+
+ @Override
+ public Container createContainer(PlayerInventory playerInventory, EntityHuman entityHuman) {
+ //Don't let the chest itself create the container.
+ return new ContainerChest(playerInventory, this, entityHuman);
+ }
+
+ @Override
+ public String getContainerName() {
+ return inv.getContainerName();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialEnderChest.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialEnderChest.java
new file mode 100644
index 0000000..3e63216
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialEnderChest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.internal.ISpecialEnderChest;
+
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.craftbukkit.v1_8_R2.entity.*;
+import org.bukkit.craftbukkit.v1_8_R2.inventory.*;
+
+public class SpecialEnderChest extends InventorySubcontainer implements ISpecialEnderChest {
+ private CraftInventory inventory = new CraftInventory(this);
+ private InventoryEnderChest enderChest;
+ private CraftPlayer owner;
+ private boolean playerOnline = false;
+
+ public SpecialEnderChest(Player p, Boolean online) {
+ this(p, ((CraftPlayer) p).getHandle().getEnderChest(), online);
+ }
+
+ public SpecialEnderChest(Player p, InventoryEnderChest enderchest, boolean online) {
+ super(enderchest.getName(), enderchest.hasCustomName(), enderchest.getSize());
+ this.owner = (CraftPlayer) p;
+ this.enderChest = enderchest;
+ this.items = enderChest.getContents();
+ this.playerOnline = online;
+ OpenInv.enderChests.put(owner.getName().toLowerCase(), this);
+ }
+
+ private void saveOnExit() {
+ if (transaction.isEmpty() && !playerOnline) {
+ owner.saveData();
+ OpenInv.enderChests.remove(owner.getName().toLowerCase());
+ }
+ }
+
+ private void linkInventory(InventoryEnderChest inventory) {
+ inventory.items = this.items;
+ }
+
+ public Inventory getBukkitInventory() {
+ return inventory;
+ }
+
+ public void playerOnline(Player p) {
+ if (!playerOnline) {
+ linkInventory(((CraftPlayer) p).getHandle().getEnderChest());
+ p.saveData();
+ playerOnline = true;
+ }
+ }
+
+ public void playerOffline() {
+ playerOnline = false;
+ owner.loadData();
+ linkInventory(owner.getHandle().getEnderChest());
+ saveOnExit();
+ }
+
+ @Override
+ public void onClose(CraftHumanEntity who) {
+ super.onClose(who);
+ saveOnExit();
+ }
+
+ @Override
+ public InventoryHolder getOwner() {
+ return this.owner;
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ enderChest.update();
+ }
+}
diff --git a/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialPlayerInventory.java b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialPlayerInventory.java
new file mode 100644
index 0000000..468c818
--- /dev/null
+++ b/src/main/java/com/lishid/openinv/internal/v1_8_R2/SpecialPlayerInventory.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2011-2014 lishid. All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lishid.openinv.internal.v1_8_R2;
+
+import org.bukkit.entity.Player;
+
+import org.bukkit.inventory.Inventory;
+
+import com.lishid.openinv.OpenInv;
+import com.lishid.openinv.internal.ISpecialPlayerInventory;
+
+//Volatile
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.craftbukkit.v1_8_R2.entity.*;
+import org.bukkit.craftbukkit.v1_8_R2.inventory.*;
+
+public class SpecialPlayerInventory extends PlayerInventory implements ISpecialPlayerInventory {
+ private CraftInventory inventory = new CraftInventory(this);
+ private ItemStack[] extra = new ItemStack[5];
+ private CraftPlayer owner;
+ private boolean playerOnline = false;
+
+ public SpecialPlayerInventory(Player p, Boolean online) {
+ super(((CraftPlayer) p).getHandle());
+ this.owner = (CraftPlayer) p;
+ this.items = player.inventory.items;
+ this.armor = player.inventory.armor;
+ this.playerOnline = online;
+ OpenInv.inventories.put(owner.getName().toLowerCase(), this);
+ }
+
+ public Inventory getBukkitInventory() {
+ return inventory;
+ }
+
+ private void saveOnExit() {
+ if (transaction.isEmpty() && !playerOnline) {
+ owner.saveData();
+ OpenInv.inventories.remove(owner.getName().toLowerCase());
+ }
+ }
+
+ private void linkInventory(PlayerInventory inventory) {
+ inventory.items = this.items;
+ inventory.armor = this.armor;
+ }
+
+ public void playerOnline(Player player) {
+ if (!playerOnline) {
+ CraftPlayer p = (CraftPlayer) player;
+ linkInventory(p.getHandle().inventory);
+ p.saveData();
+ playerOnline = true;
+ }
+ }
+
+ public void playerOffline() {
+ playerOnline = false;
+ owner.loadData();
+ linkInventory(owner.getHandle().inventory);
+ saveOnExit();
+ }
+
+ @Override
+ public void onClose(CraftHumanEntity who) {
+ super.onClose(who);
+ this.saveOnExit();
+ }
+
+ @Override
+ public ItemStack[] getContents() {
+ ItemStack[] C = new ItemStack[getSize()];
+ System.arraycopy(items, 0, C, 0, items.length);
+ System.arraycopy(items, 0, C, items.length, armor.length);
+ return C;
+ }
+
+ @Override
+ public int getSize() {
+ return super.getSize() + 5;
+ }
+
+ @Override
+ public ItemStack getItem(int i) {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.armor;
+ } else {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.extra;
+ } else if (is == this.armor) {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ return is[i];
+ }
+
+ @Override
+ public ItemStack splitStack(int i, int j) {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.armor;
+ } else {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.extra;
+ } else if (is == this.armor) {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ if (is[i] != null) {
+ ItemStack itemstack;
+
+ if (is[i].count <= j) {
+ itemstack = is[i];
+ is[i] = null;
+ return itemstack;
+ } else {
+ itemstack = is[i].a(j);
+ if (is[i].count == 0) {
+ is[i] = null;
+ }
+
+ return itemstack;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public ItemStack splitWithoutUpdate(int i) {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.armor;
+ } else {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.extra;
+ } else if (is == this.armor) {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ if (is[i] != null) {
+ ItemStack itemstack = is[i];
+
+ is[i] = null;
+ return itemstack;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setItem(int i, ItemStack itemstack) {
+ ItemStack[] is = this.items;
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.armor;
+ } else {
+ i = getReversedItemSlotNum(i);
+ }
+
+ if (i >= is.length) {
+ i -= is.length;
+ is = this.extra;
+ } else if (is == this.armor) {
+ i = getReversedArmorSlotNum(i);
+ }
+
+ // Effects
+ if (is == this.extra) {
+ owner.getHandle().drop(itemstack, true);
+ itemstack = null;
+ }
+
+ is[i] = itemstack;
+
+ owner.getHandle().defaultContainer.b();
+ }
+
+ private int getReversedItemSlotNum(int i) {
+ if (i >= 27)
+ return i - 27;
+ else
+ return i + 9;
+ }
+
+ private int getReversedArmorSlotNum(int i) {
+ if (i == 0)
+ return 3;
+ if (i == 1)
+ return 2;
+ if (i == 2)
+ return 1;
+ if (i == 3)
+ return 0;
+ else
+ return i;
+ }
+
+ @Override
+ public boolean hasCustomName() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return player.getName();
+ }
+
+ @Override
+ public boolean a(EntityHuman entityhuman) {
+ return true;
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ player.inventory.update();
+ }
+}
\ No newline at end of file