287 lines
7.9 KiB
Java
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();
|
|
}
|
|
}
|