Update plugin to jikoo/master - numerous fixes and changes

* Added permissions to commands in plugin.yml
* Removed item wand functionality - see 3549431fbc for reasoning
* Changed a lot of player loading logic
* Added config option DisableSaving - see Jikoo#6
* Fixed closing SilentChest not dropping item on cursor
* Added SilentChest support for shulker boxes
This commit is contained in:
Jikoo
2016-11-25 16:42:06 -05:00
parent 3bf7225712
commit 4335b8dc2c
41 changed files with 1829 additions and 2476 deletions

View File

@@ -1,174 +0,0 @@
/*
* 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.v1_11_R1;
import java.util.Iterator;
import com.lishid.openinv.OpenInv;
import com.lishid.openinv.internal.IAnySilentChest;
import org.bukkit.entity.Player;
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.Block;
import net.minecraft.server.v1_11_R1.BlockChest;
import net.minecraft.server.v1_11_R1.BlockChest.Type;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityOcelot;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EnumDirection;
import net.minecraft.server.v1_11_R1.ITileInventory;
import net.minecraft.server.v1_11_R1.InventoryLargeChest;
import net.minecraft.server.v1_11_R1.TileEntity;
import net.minecraft.server.v1_11_R1.TileEntityChest;
import net.minecraft.server.v1_11_R1.World;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
public class AnySilentChest implements IAnySilentChest {
private final OpenInv plugin;
public AnySilentChest(OpenInv plugin) {
this.plugin = plugin;
}
@Override
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()).g == Type.TRAP ?
Block.getByName("trapped_chest") : Block.getByName("chest"));
// If a block is on top
if (topBlocking(world, position)) {
return true;
}
// If the block next to the chest is chest and has a block on top
for (EnumDirection direction : EnumDirectionList.HORIZONTAL) {
BlockPosition sidePosition = position.shift(direction);
Block block = world.getType(sidePosition).getBlock();
if (block == 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);
}
@SuppressWarnings("deprecation")
private boolean blockOnTop(World world, BlockPosition position) {
Block block = world.getType(position.up()).getBlock();
return block.isOccluding(block.getBlockData());
}
private boolean ocelotOnTop(World world, BlockPosition position) {
Iterator iterator = world.a(EntityOcelot.class,
new AxisAlignedBB(position.getX(), position.getY() + 1,
position.getZ(), position.getX() + 1,
position.getY() + 2, position.getZ() + 1)).iterator();
EntityOcelot entityOcelot;
do {
if (!iterator.hasNext()) {
return false;
}
Entity entity = (Entity) iterator.next();
entityOcelot = (EntityOcelot) entity;
} while (!entityOcelot.isSitting());
return true;
}
@Override
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()).g == Type.TRAP ?
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 (plugin.getConfiguration().notifySilentChest()) {
OpenInv.sendMessage(p, "You are opening a chest silently.");
}
returnValue = false;
}
player.openContainer(tileInventory);
if (anyChest && plugin.getConfiguration().notifyAnyChest()) {
OpenInv.sendMessage(p, "You are opening a blocked chest.");
}
return returnValue;
}
}

View File

@@ -0,0 +1,276 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_11_R1;
import com.lishid.openinv.internal.IAnySilentContainer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
// Volatile
import net.minecraft.server.v1_11_R1.AxisAlignedBB;
import net.minecraft.server.v1_11_R1.Block;
import net.minecraft.server.v1_11_R1.BlockChest;
import net.minecraft.server.v1_11_R1.BlockChest.Type;
import net.minecraft.server.v1_11_R1.BlockEnderChest;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.BlockShulkerBox;
import net.minecraft.server.v1_11_R1.Container;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityOcelot;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EnumDirection;
import net.minecraft.server.v1_11_R1.IBlockData;
import net.minecraft.server.v1_11_R1.IInventory;
import net.minecraft.server.v1_11_R1.ITileInventory;
import net.minecraft.server.v1_11_R1.InventoryEnderChest;
import net.minecraft.server.v1_11_R1.InventoryLargeChest;
import net.minecraft.server.v1_11_R1.PacketPlayOutOpenWindow;
import net.minecraft.server.v1_11_R1.StatisticList;
import net.minecraft.server.v1_11_R1.TileEntity;
import net.minecraft.server.v1_11_R1.TileEntityChest;
import net.minecraft.server.v1_11_R1.TileEntityEnderChest;
import net.minecraft.server.v1_11_R1.TileEntityShulkerBox;
import net.minecraft.server.v1_11_R1.World;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
public class AnySilentContainer implements IAnySilentContainer {
@Override
public boolean isAnySilentContainer(org.bukkit.block.Block block) {
if (block.getType() == Material.ENDER_CHEST) {
return true;
}
BlockState state = block.getState();
return state instanceof org.bukkit.block.Chest || state instanceof org.bukkit.block.ShulkerBox;
}
@Override
public boolean isAnyContainerNeeded(Player p, org.bukkit.block.Block b) {
EntityPlayer player = ((CraftPlayer) p).getHandle();
World world = player.world;
BlockPosition blockPosition = new BlockPosition(b.getX(), b.getY(), b.getZ());
Block block = world.getType(blockPosition).getBlock();
if (block instanceof BlockShulkerBox) {
return isBlockedShulkerBox(world, blockPosition, block);
}
if (block instanceof BlockEnderChest) {
// Ender chests are not blocked by ocelots.
return world.getType(blockPosition.up()).m();
}
// Check if chest is blocked or has an ocelot on top
if (isBlockedChest(world, blockPosition)) {
return true;
}
// Check for matching adjacent chests that are blocked or have an ocelot on top
for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
BlockPosition localBlockPosition = blockPosition.shift(localEnumDirection);
Block localBlock = world.getType(localBlockPosition).getBlock();
if (localBlock != block) {
continue;
}
TileEntity localTileEntity = world.getTileEntity(localBlockPosition);
if (!(localTileEntity instanceof TileEntityChest)) {
continue;
}
if (isBlockedChest(world, localBlockPosition)) {
return true;
}
}
return false;
}
private boolean isBlockedShulkerBox(World world, BlockPosition blockPosition, Block block) {
// For reference, look at net.minecraft.server.BlockShulkerBox
TileEntity tile = world.getTileEntity(blockPosition);
if (!(tile instanceof TileEntityShulkerBox)) {
return false;
}
IBlockData iBlockData = block.getBlockData();
EnumDirection enumDirection = iBlockData.get(BlockShulkerBox.a);
if (((TileEntityShulkerBox) tile).p() == TileEntityShulkerBox.AnimationPhase.CLOSED) {
AxisAlignedBB axisAlignedBB = BlockShulkerBox.j.b(0.5F * enumDirection.getAdjacentX(),
0.5F * enumDirection.getAdjacentY(), 0.5F * enumDirection.getAdjacentZ())
.a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(),
enumDirection.getAdjacentZ());
return world.b(axisAlignedBB.a(blockPosition.shift(enumDirection)));
}
return false;
}
private boolean isBlockedChest(World world, BlockPosition blockPosition) {
// For reference, loot at net.minecraft.server.BlockChest
return world.getType(blockPosition.up()).m() || hasOcelotOnTop(world, blockPosition);
}
private boolean hasOcelotOnTop(World world, BlockPosition blockPosition) {
for (Entity localEntity : world.a(EntityOcelot.class,
new AxisAlignedBB(blockPosition.getX(), blockPosition.getY() + 1,
blockPosition.getZ(), blockPosition.getX() + 1, blockPosition.getY() + 2,
blockPosition.getZ() + 1))) {
EntityOcelot localEntityOcelot = (EntityOcelot) localEntity;
if (localEntityOcelot.isSitting()) {
return true;
}
}
return false;
}
@Override
public boolean activateContainer(Player p, boolean silentchest, org.bukkit.block.Block b) {
EntityPlayer player = ((CraftPlayer) p).getHandle();
// Silent ender chest is pretty much API-only
if (silentchest && b.getType() == Material.ENDER_CHEST) {
p.openInventory(p.getEnderChest());
player.b(StatisticList.X);
return true;
}
final World world = player.world;
final BlockPosition blockPosition = new BlockPosition(b.getX(), b.getY(), b.getZ());
Object tile = world.getTileEntity(blockPosition);
if (tile == null) {
return false;
}
if (tile instanceof TileEntityEnderChest) {
// Anychest ender chest. See net.minecraft.server.BlockEnderChest
InventoryEnderChest enderChest = player.getEnderChest();
enderChest.a((TileEntityEnderChest) tile);
player.openContainer(enderChest);
player.b(StatisticList.X);
return true;
}
if (!(tile instanceof IInventory)) {
return false;
}
Block block = world.getType(blockPosition).getBlock();
Container container = null;
if (block instanceof BlockChest) {
BlockChest blockChest = (BlockChest) block;
for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) {
BlockPosition localBlockPosition = blockPosition.shift(localEnumDirection);
Block localBlock = world.getType(localBlockPosition).getBlock();
if (localBlock != block) {
continue;
}
TileEntity localTileEntity = world.getTileEntity(localBlockPosition);
if (!(localTileEntity instanceof TileEntityChest)) {
continue;
}
if ((localEnumDirection == EnumDirection.WEST) || (localEnumDirection == EnumDirection.NORTH)) {
tile = new InventoryLargeChest("container.chestDouble",
(TileEntityChest) localTileEntity, (ITileInventory) tile);
} else {
tile = new InventoryLargeChest("container.chestDouble",
(ITileInventory) tile, (TileEntityChest) localTileEntity);
}
break;
}
if (blockChest.g == Type.BASIC)
player.b(StatisticList.ac);
else if (blockChest.g == Type.TRAP) {
player.b(StatisticList.W);
}
if (silentchest) {
container = new SilentContainerChest(player.inventory, ((IInventory) tile), player);
}
}
if (block instanceof BlockShulkerBox) {
player.b(StatisticList.ae);
if (silentchest && tile instanceof TileEntityShulkerBox) {
// Set value to current + 1. Ensures consistency later when resetting.
SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile,
SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) + 1);
container = new SilentContainerShulkerBox(player.inventory, (IInventory) tile, player);
}
}
boolean returnValue = false;
final IInventory iInventory = (IInventory) tile;
if (!silentchest || container == null) {
player.openContainer(iInventory);
returnValue = true;
} else {
try {
int windowId = player.nextContainerCounter();
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, iInventory.getName(), iInventory.getScoreboardDisplayName(), iInventory.getSize()));
player.activeContainer = container;
player.activeContainer.windowId = windowId;
player.activeContainer.addSlotListener(player);
returnValue = true;
if (tile instanceof TileEntityShulkerBox) {
new BukkitRunnable() {
@Override
public void run() {
// TODO hacky
Object tile = world.getTileEntity(blockPosition);
if (!(tile instanceof TileEntityShulkerBox)) {
return;
}
TileEntityShulkerBox box = (TileEntityShulkerBox) tile;
// Reset back - we added 1, and calling TileEntityShulkerBox#startOpen adds 1 more.
SilentContainerShulkerBox.setOpenValue(box,
SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) - 2);
}
}.runTaskLater(Bukkit.getPluginManager().getPlugin("OpenInv"), 2);
}
} catch (Exception e) {
e.printStackTrace();
p.sendMessage(ChatColor.RED + "Error while sending silent chest.");
}
}
return returnValue;
}
}

View File

@@ -1,25 +0,0 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.util.Iterator;
import com.google.common.collect.Iterators;
import net.minecraft.server.v1_11_R1.EnumDirection;
import net.minecraft.server.v1_11_R1.EnumDirection.EnumDirectionLimit;
public enum EnumDirectionList implements Iterable<EnumDirection> {
HORIZONTAL(EnumDirectionLimit.HORIZONTAL),
VERTICAL(EnumDirectionLimit.VERTICAL);
private final EnumDirectionLimit list;
EnumDirectionList(EnumDirectionLimit list) {
this.list = list;
}
@Override
public Iterator<EnumDirection> iterator() {
return Iterators.forArray(list.a());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 lishid. All rights reserved.
* 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
@@ -16,61 +16,64 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.lang.reflect.Field;
import com.lishid.openinv.internal.IInventoryAccess;
import com.lishid.openinv.internal.ISpecialEnderChest;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import com.lishid.openinv.internal.InternalAccessor;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.Inventory;
import com.lishid.openinv.OpenInv;
import com.lishid.openinv.Permissions;
// Volatile
import net.minecraft.server.v1_11_R1.IInventory;
public class InventoryAccess {
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
private final OpenInv plugin;
public class InventoryAccess implements IInventoryAccess {
public InventoryAccess(OpenInv plugin) {
this.plugin = plugin;
}
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) {
@Override
public boolean isSpecialPlayerInventory(Inventory inventory) {
if (inventory instanceof CraftInventory) {
return ((CraftInventory) inventory).getInventory();
return ((CraftInventory) inventory).getInventory() instanceof ISpecialPlayerInventory;
}
// 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) {
plugin.log(e);
}
}
return InternalAccessor.grabFieldOfTypeFromObject(IInventory.class, inventory) instanceof ISpecialPlayerInventory;
}
@Override
public ISpecialPlayerInventory getSpecialPlayerInventory(Inventory inventory) {
IInventory inv;
if (inventory instanceof CraftInventory) {
inv = ((CraftInventory) inventory).getInventory();
} else {
inv = InternalAccessor.grabFieldOfTypeFromObject(IInventory.class, inventory);
}
return result;
if (inv instanceof SpecialPlayerInventory) {
return (SpecialPlayerInventory) inv;
}
return null;
}
@Override
public boolean isSpecialEnderChest(Inventory inventory) {
if (inventory instanceof CraftInventory) {
return ((CraftInventory) inventory).getInventory() instanceof ISpecialEnderChest;
}
return InternalAccessor.grabFieldOfTypeFromObject(IInventory.class, inventory) instanceof ISpecialEnderChest;
}
@Override
public ISpecialEnderChest getSpecialEnderChest(Inventory inventory) {
IInventory inv;
if (inventory instanceof CraftInventory) {
inv = ((CraftInventory) inventory).getInventory();
} else {
inv = InternalAccessor.grabFieldOfTypeFromObject(IInventory.class, inventory);
}
if (inv instanceof SpecialEnderChest) {
return (SpecialEnderChest) inv;
}
return null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 lishid. All rights reserved.
* 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
@@ -16,54 +16,49 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
import com.mojang.authlib.GameProfile;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
import org.bukkit.entity.Player;
import com.lishid.openinv.OpenInv;
import com.mojang.authlib.GameProfile;
// Volatile
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.MinecraftServer;
import net.minecraft.server.v1_11_R1.PlayerInteractManager;
public class PlayerDataManager {
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
private final OpenInv plugin;
public class PlayerDataManager implements IPlayerDataManager {
public PlayerDataManager(OpenInv plugin) {
this.plugin = plugin;
}
public Player loadPlayer(UUID uuid) {
try {
OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
if (player == null || !player.hasPlayedBefore()) {
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) {
plugin.log(e);
@Override
public Player loadPlayer(OfflinePlayer offline) {
// Ensure player has data
if (offline == null || !offline.hasPlayedBefore()) {
return null;
}
return null;
// Create a profile and entity to load the player data
GameProfile profile = new GameProfile(offline.getUniqueId(), offline.getName());
MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(0), profile,
new PlayerInteractManager(server.getWorldServer(0)));
// Get the bukkit entity
Player target = (entity == null) ? null : entity.getBukkitEntity();
if (target != null) {
// Load data
target.loadData();
}
// Return the entity
return target;
}
@Override
public String getPlayerDataID(OfflinePlayer player) {
return player.getUniqueId().toString();
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_11_R1;
// Volatile
import net.minecraft.server.v1_11_R1.ContainerChest;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.IInventory;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.PlayerInventory;
public class SilentContainerChest extends ContainerChest {
public SilentContainerChest(PlayerInventory playerInventory, IInventory iInventory,
EntityHuman entityHuman) {
super(playerInventory, iInventory, entityHuman);
// Send close signal
iInventory.closeContainer(entityHuman);
}
@Override
public void b(EntityHuman entityHuman) {
// Don't send close signal twice, might screw up
PlayerInventory playerinventory = entityHuman.inventory;
if (playerinventory.getCarried() != ItemStack.a) {
ItemStack carried = playerinventory.getCarried();
playerinventory.setCarried(ItemStack.a);
entityHuman.drop(carried, false);
}
}
}

View File

@@ -0,0 +1,56 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.lang.reflect.Field;
import net.minecraft.server.v1_11_R1.ContainerShulkerBox;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.IInventory;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.PlayerInventory;
import net.minecraft.server.v1_11_R1.TileEntityShulkerBox;
public class SilentContainerShulkerBox extends ContainerShulkerBox {
private static Field fieldShulkerActionData;
public SilentContainerShulkerBox(PlayerInventory playerInventory, IInventory iInventory,
EntityHuman entityHuman) {
super(playerInventory, iInventory, entityHuman);
}
@Override
public void b(EntityHuman entityHuman) {
PlayerInventory playerinventory = entityHuman.inventory;
if (!playerinventory.getCarried().isEmpty()) {
entityHuman.drop(playerinventory.getCarried(), false);
playerinventory.setCarried(ItemStack.a);
}
}
private static Field exposeOpenStatus() throws NoSuchFieldException, SecurityException {
if (fieldShulkerActionData == null) {
fieldShulkerActionData = TileEntityShulkerBox.class.getDeclaredField("h");
fieldShulkerActionData.setAccessible(true);
}
return fieldShulkerActionData;
}
public static void setOpenValue(TileEntityShulkerBox tileShulkerBox, Object value) {
try {
exposeOpenStatus().set(tileShulkerBox, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Integer getOpenValue(TileEntityShulkerBox tileShulkerBox) {
try {
return (Integer) exposeOpenStatus().get(tileShulkerBox);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}

View File

@@ -1,183 +0,0 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftHumanEntity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.InventoryHolder;
import net.minecraft.server.v1_11_R1.ChestLock;
import net.minecraft.server.v1_11_R1.Container;
import net.minecraft.server.v1_11_R1.ContainerChest;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.IChatBaseComponent;
import net.minecraft.server.v1_11_R1.ITileInventory;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.PlayerInventory;
public class SilentInventory implements ITileInventory {
public ITileInventory inv;
public SilentInventory(ITileInventory inv) {
this.inv = inv;
}
@Override
public boolean isLocked()
{
return inv.isLocked();
}
@Override
public void a(ChestLock chestLock) {
inv.a(chestLock);
}
@Override
public ChestLock getLock() {
return inv.getLock();
}
@Override
public int getSize() {
return inv.getSize();
}
@Override
public boolean w_() {
return inv.w_();
}
@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 setProperty(int i, int i1) {
inv.setProperty(i, i1);
}
@Override
public int h() {
return inv.h();
}
@Override
public void clear() {
inv.clear();
}
@Override
public List<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<HumanEntity> getViewers() {
return inv.getViewers();
}
@Override
public InventoryHolder getOwner() {
return inv.getOwner();
}
@Override
public void setMaxStackSize(int i) {
inv.setMaxStackSize(i);
}
@Override
public Location getLocation() {
return inv.getLocation();
}
@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();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 lishid. All rights reserved.
* 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
@@ -17,50 +17,48 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import net.minecraft.server.v1_11_R1.NonNullList;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
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_11_R1.IInventory;
import net.minecraft.server.v1_11_R1.InventoryEnderChest;
import net.minecraft.server.v1_11_R1.InventorySubcontainer;
import net.minecraft.server.v1_11_R1.ItemStack;
public class SpecialEnderChest extends InventorySubcontainer {
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
public class SpecialEnderChest extends InventorySubcontainer implements IInventory, ISpecialEnderChest {
private final CraftInventory inventory = new CraftInventory(this);
private final InventoryEnderChest enderChest;
private CraftPlayer owner;
private boolean playerOnline;
private final CraftInventory inventory = new CraftInventory(this);
private boolean playerOnline = false;
public SpecialEnderChest(Player p, boolean online) {
this(p, ((CraftPlayer) p).getHandle().getEnderChest(), online);
public SpecialEnderChest(Player player, Boolean online) {
super(((CraftPlayer) player).getHandle().getEnderChest().getName(),
((CraftPlayer) player).getHandle().getEnderChest().hasCustomName(),
((CraftPlayer) player).getHandle().getEnderChest().getSize());
CraftPlayer craftPlayer = (CraftPlayer) player;
this.enderChest = craftPlayer.getHandle().getEnderChest();
this.bukkitOwner = craftPlayer;
setItemLists(this, enderChest.getContents());
}
public SpecialEnderChest(Player p, InventoryEnderChest enderChest, boolean online) {
super(enderChest.getName(), enderChest.hasCustomName(), enderChest.getSize());
this.owner = (CraftPlayer) p;
this.enderChest = enderChest;
this.playerOnline = online;
reflectContents(getClass().getSuperclass(), this, this.enderChest.getContents());
}
private void saveOnExit() {
if (transaction.isEmpty() && !playerOnline) {
owner.saveData();
}
}
private void reflectContents(Class clazz, InventorySubcontainer enderChest, List<ItemStack> items) {
private void setItemLists(InventorySubcontainer subcontainer, List<ItemStack> list) {
try {
Field itemsField = clazz.getDeclaredField("items");
itemsField.setAccessible(true);
itemsField.set(enderChest, items);
// Prepare to remove final modifier
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
// Access and replace main inventory array
Field field = InventorySubcontainer.class.getField("items");
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(subcontainer, list);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
@@ -72,46 +70,31 @@ public class SpecialEnderChest extends InventorySubcontainer {
}
}
private void linkInventory(InventoryEnderChest inventory) {
reflectContents(inventory.getClass(), inventory, this.items);
}
@Override
public Inventory getBukkitInventory() {
return inventory;
}
public boolean inventoryRemovalCheck(boolean save) {
boolean offline = transaction.isEmpty() && !playerOnline;
if (offline && save) {
owner.saveData();
}
return offline;
}
public void playerOnline(Player p) {
@Override
public void setPlayerOnline(Player player) {
if (!playerOnline) {
owner = (CraftPlayer) p;
linkInventory(((CraftPlayer) p).getHandle().getEnderChest());
try {
this.bukkitOwner = player;
CraftPlayer craftPlayer = (CraftPlayer) player;
setItemLists(craftPlayer.getHandle().getEnderChest(), this.items);
} catch (Exception e) {}
playerOnline = true;
}
}
public boolean playerOffline() {
@Override
public void setPlayerOffline() {
playerOnline = false;
return inventoryRemovalCheck(false);
}
@Override
public void onClose(CraftHumanEntity who) {
super.onClose(who);
inventoryRemovalCheck(true);
}
@Override
public InventoryHolder getOwner() {
return this.owner;
public boolean isInUse() {
return !this.getViewers().isEmpty();
}
@Override
@@ -119,4 +102,5 @@ public class SpecialEnderChest extends InventorySubcontainer {
super.update();
enderChest.update();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 lishid. All rights reserved.
* 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
@@ -17,101 +17,94 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import net.minecraft.server.v1_11_R1.*;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
public class SpecialPlayerInventory extends PlayerInventory {
import net.minecraft.server.v1_11_R1.ContainerUtil;
// Volatile
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.NonNullList;
import net.minecraft.server.v1_11_R1.PlayerInventory;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_11_R1.inventory.CraftInventory;
public class SpecialPlayerInventory extends PlayerInventory implements ISpecialPlayerInventory {
private final CraftInventory inventory = new CraftInventory(this);
private final NonNullList<ItemStack> extra = NonNullList.a();
private CraftPlayer owner;
private NonNullList<ItemStack>[] arrays;
private boolean playerOnline;
private boolean playerOnline = false;
public SpecialPlayerInventory(Player p, boolean online) {
super(((CraftPlayer) p).getHandle());
this.owner = (CraftPlayer) p;
public SpecialPlayerInventory(Player bukkitPlayer, Boolean online) {
super(((CraftPlayer) bukkitPlayer).getHandle());
this.playerOnline = online;
reflectContents(getClass().getSuperclass(), player.inventory, this);
setItemArrays(this, player.inventory.items, player.inventory.armor, player.inventory.extraSlots);
}
private void reflectContents(Class clazz, PlayerInventory src, PlayerInventory dest) {
private void setItemArrays(PlayerInventory inventory, NonNullList<ItemStack> items,
NonNullList<ItemStack> armor, NonNullList<ItemStack> extraSlots) {
try {
Field itemsField = clazz.getDeclaredField("items");
itemsField.setAccessible(true);
itemsField.set(dest, src.items);
// Prepare to remove final modifier
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
Field armorField = clazz.getDeclaredField("armor");
armorField.setAccessible(true);
armorField.set(dest, src.armor);
// Access and replace main inventory array
Field field = PlayerInventory.class.getField("items");
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(inventory, items);
Field extraSlotsField = clazz.getDeclaredField("extraSlots");
extraSlotsField.setAccessible(true);
extraSlotsField.set(dest, src.extraSlots);
// Access and replace armor inventory array
field = PlayerInventory.class.getField("armor");
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(inventory, armor);
// Access and replace offhand inventory array
field = PlayerInventory.class.getField("extraSlots");
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(inventory, extraSlots);
// Access and replace array containing all inventory arrays
field = PlayerInventory.class.getDeclaredField("g");
field.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(inventory, Arrays.asList(new NonNullList[] { items, armor, extraSlots }));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
// Unable to set final fields to item arrays, we're screwed. Noisily fail.
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//noinspection unchecked
arrays = new NonNullList[] { this.items, this.armor, this.extraSlots, this.extra };
}
private void linkInventory(PlayerInventory inventory) {
reflectContents(inventory.getClass(), inventory, this);
}
@Override
public Inventory getBukkitInventory() {
return inventory;
}
public boolean inventoryRemovalCheck(boolean save) {
boolean offline = transaction.isEmpty() && !playerOnline;
if (offline && save) {
owner.saveData();
}
return offline;
}
public void playerOnline(Player player) {
@Override
public void setPlayerOnline(Player player) {
if (!playerOnline) {
owner = (CraftPlayer) player;
this.player = owner.getHandle();
linkInventory(owner.getHandle().inventory);
this.player = ((CraftPlayer) player).getHandle();
setItemArrays(this.player.inventory, items, armor, extraSlots);
playerOnline = true;
}
}
public boolean playerOffline() {
@Override
public void setPlayerOffline() {
playerOnline = false;
return inventoryRemovalCheck(false);
}
@Override
public void onClose(CraftHumanEntity who) {
super.onClose(who);
inventoryRemovalCheck(true);
}
@Override
public NonNullList<ItemStack> getContents() {
NonNullList<ItemStack> contents = NonNullList.a();
contents.addAll(this.items);
contents.addAll(this.armor);
contents.addAll(this.extraSlots);
return contents;
public boolean isInUse() {
return !this.getViewers().isEmpty();
}
@Override
@@ -121,153 +114,142 @@ public class SpecialPlayerInventory extends PlayerInventory {
@Override
public ItemStack getItem(int i) {
NonNullList<ItemStack> is = null;
NonNullList<ItemStack>[] contents = this.arrays;
int j = contents.length;
NonNullList<ItemStack> list = this.items;
for (int k = 0; k < j; ++k) {
NonNullList<ItemStack> is2 = contents[k];
if (i < is2.size()) {
is = is2;
break;
}
i -= is2.size();
}
if (is == this.items) {
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
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 ? ItemStack.a : is.get(i);
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = getReversedArmorSlotNum(i);
}
if (i >= list.size()) {
return ItemStack.a;
}
return list.get(i);
}
@Override
public ItemStack splitStack(int i, int j) {
NonNullList<ItemStack> is = null;
NonNullList<ItemStack>[] contents = this.arrays;
int k = contents.length;
NonNullList<ItemStack> list = this.items;
for (int l = 0; l < k; ++l) {
NonNullList<ItemStack> is2 = contents[l];
if (i < is2.size()) {
is = is2;
break;
}
i -= is2.size();
}
if (is == this.items) {
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
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.get(i).isEmpty() ? ContainerUtil.a(is, i, j) : ItemStack.a;
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = getReversedArmorSlotNum(i);
}
if (i >= list.size()) {
return ItemStack.a;
}
return list == null || list.get(i).isEmpty() ? ItemStack.a : ContainerUtil.a(list, i, j);
}
@Override
public ItemStack splitWithoutUpdate(int i) {
NonNullList<ItemStack> is = null;
NonNullList<ItemStack>[] contents = this.arrays;
int j = contents.length;
NonNullList<ItemStack> list = this.items;
for (int object = 0; object < j; ++object) {
NonNullList<ItemStack> is2 = contents[object];
if (i < is2.size()) {
is = is2;
break;
}
i -= is2.size();
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
i = getReversedItemSlotNum(i);
}
if (is != null && !is.get(i).isEmpty()) {
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
}
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = getReversedArmorSlotNum(i);
}
Object object = is.get(i);
is.set(i, ItemStack.a);
return (ItemStack) object;
} else {
if (i >= list.size()) {
return ItemStack.a;
}
if (list != null && !list.get(i).isEmpty()) {
ItemStack itemstack = list.get(i);
list.set(i, ItemStack.a);
return itemstack;
}
return ItemStack.a;
}
@Override
public void setItem(int i, ItemStack itemStack) {
NonNullList<ItemStack> is = null;
NonNullList<ItemStack>[] contents = this.arrays;
int j = contents.length;
public void setItem(int i, ItemStack itemstack) {
NonNullList<ItemStack> list = this.items;
for (int k = 0; k < j; ++k) {
NonNullList<ItemStack> is2 = contents[k];
if (i < is2.size()) {
is = is2;
break;
}
i -= is2.size();
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
i = getReversedItemSlotNum(i);
}
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 = ItemStack.a;
}
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = getReversedArmorSlotNum(i);
}
is.set(i, itemStack);
if (i >= list.size()) {
player.drop(itemstack, true);
return;
}
owner.getHandle().defaultContainer.b();
if (list != null) {
list.set(i, itemstack);
}
}
private int getReversedItemSlotNum(int i) {
return (i >= 27) ? (i - 27) : (i + 9);
if (i >= 27) {
return i - 27;
}
return 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;
if (i == 0) {
return 3;
}
if (i == 1) {
return 2;
}
if (i == 2) {
return 1;
}
if (i == 3) {
return 0;
}
return i;
}
@Override
public String getName() {
if (player.getName().length() > 16) {
return player.getName().substring(0, 16);
}
return player.getName();
}
@@ -276,9 +258,4 @@ public class SpecialPlayerInventory extends PlayerInventory {
return true;
}
@Override
public void update() {
super.update();
player.inventory.update();
}
}