Files
OpenInv/src/main/java/com/lishid/openinv/internal/SpecialPlayerInventory.java
2016-03-09 14:14:27 +11:00

287 lines
7.9 KiB
Java

/*
* Copyright (C) 2011-2016 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 <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal;
import java.lang.reflect.Field;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
// Volatile
import net.minecraft.server.v1_9_R1.*;
import org.bukkit.craftbukkit.v1_9_R1.entity.*;
import org.bukkit.craftbukkit.v1_9_R1.inventory.*;
import com.lishid.openinv.OpenInv;
public class SpecialPlayerInventory extends PlayerInventory {
private final CraftInventory inventory = new CraftInventory(this);
private final ItemStack[] extra = new ItemStack[4];
private final ItemStack[][] arrays;
private final CraftPlayer owner;
private boolean playerOnline;
public SpecialPlayerInventory(Player p, boolean online) {
super(((CraftPlayer) p).getHandle());
this.owner = (CraftPlayer) p;
reflectContents(getClass().getSuperclass(), player.inventory, this);
this.arrays = new ItemStack[][] { this.items, this.armor, this.extraSlots, this.extra };
this.playerOnline = online;
OpenInv.inventories.put(owner.getUniqueId(), this);
}
private void reflectContents(Class clazz, PlayerInventory src, PlayerInventory dest) {
try {
Field itemsField = clazz.getDeclaredField("items");
itemsField.setAccessible(true);
itemsField.set(dest, src.items);
Field armorField = clazz.getDeclaredField("armor");
armorField.setAccessible(true);
armorField.set(dest, src.armor);
Field extraSlotsField = clazz.getDeclaredField("extraSlots");
extraSlotsField.setAccessible(true);
extraSlotsField.set(dest, src.extraSlots);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public Inventory getBukkitInventory() {
return inventory;
}
private void saveOnExit() {
if (transaction.isEmpty() && !playerOnline) {
owner.saveData();
OpenInv.inventories.remove(owner.getUniqueId());
}
}
private void linkInventory(PlayerInventory inventory) {
reflectContents(inventory.getClass(), inventory, this);
}
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[] contents = new ItemStack[getSize()];
System.arraycopy(this.items, 0, contents, 0, this.items.length);
System.arraycopy(this.armor, 0, contents, this.items.length, this.armor.length);
System.arraycopy(this.extraSlots, 0, contents, this.items.length + this.armor.length, this.extraSlots.length);
return contents;
}
@Override
public int getSize() {
return super.getSize() + 4;
}
@Override
public ItemStack getItem(int i) {
ItemStack[] is = null;
ItemStack[][] contents = this.arrays;
int j = contents.length;
for (int k = 0; k < j; ++k) {
ItemStack[] is2 = contents[k];
if (i < is2.length) {
is = is2;
break;
}
i -= is2.length;
}
if (is == this.items) {
i = getReversedItemSlotNum(i);
} else if (is == this.armor) {
i = getReversedArmorSlotNum(i);
} else if (is == this.extraSlots) {
// Do nothing
} else if (is == this.extra) {
// Do nothing
}
return is == null ? null : is[i];
}
@Override
public ItemStack splitStack(int i, int j) {
ItemStack[] is = null;
ItemStack[][] contents = this.arrays;
int k = contents.length;
for (int l = 0; l < k; ++l) {
ItemStack[] is2 = contents[l];
if (i < is2.length) {
is = is2;
break;
}
i -= is2.length;
}
if (is == this.items) {
i = getReversedItemSlotNum(i);
} else if (is == this.armor) {
i = getReversedArmorSlotNum(i);
} else if (is == this.extraSlots) {
// Do nothing
} else if (is == this.extra) {
// Do nothing
}
return is != null && is[i] != null ? ContainerUtil.a(is, i, j) : null;
}
@Override
public ItemStack splitWithoutUpdate(int i) {
ItemStack[] is = null;
ItemStack[][] contents = this.arrays;
int j = contents.length;
for (int object = 0; object < j; ++object) {
ItemStack[] is2 = contents[object];
if (i < is2.length) {
is = is2;
break;
}
i -= is2.length;
}
if (is != null && is[i] != null) {
if (is == this.items) {
i = getReversedItemSlotNum(i);
} else if (is == this.armor) {
i = getReversedArmorSlotNum(i);
} else if (is == this.extraSlots) {
// Do nothing
} else if (is == this.extra) {
// Do nothing
}
Object object = is[i];
is[i] = null;
return (ItemStack) object;
} else {
return null;
}
}
@Override
public void setItem(int i, ItemStack itemStack) {
ItemStack[] is = null;
ItemStack[][] contents = this.arrays;
int j = contents.length;
for (int k = 0; k < j; ++k) {
ItemStack[] is2 = contents[k];
if (i < is2.length) {
is = is2;
break;
}
i -= is2.length;
}
if (is != null) {
if (is == this.items) {
i = getReversedItemSlotNum(i);
} else if (is == this.armor) {
i = getReversedArmorSlotNum(i);
} else if (is == this.extraSlots) {
// Do nothing
} else if (is == this.extra) {
owner.getHandle().drop(itemStack, true);
itemStack = null;
}
is[i] = itemStack;
owner.getHandle().defaultContainer.b();
}
}
private int getReversedItemSlotNum(int i) {
return (i >= 27) ? (i - 27) : (i + 9);
}
private int getReversedArmorSlotNum(int i) {
if (i == 0) return 3;
if (i == 1) return 2;
if (i == 2) return 1;
return (i == 3) ? 0 : 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();
}
}