From ba9396ad5ca39b27d5e5b883f1d7ffa144394198 Mon Sep 17 00:00:00 2001 From: ShadowRanger Date: Wed, 4 May 2016 14:38:10 +1000 Subject: [PATCH] Implement Jikoo's data duplication glitch fix --- src/main/java/com/lishid/openinv/OpenInv.java | 60 ++++++++++++++++++- .../openinv/commands/OpenEnderCommand.java | 14 ++--- .../openinv/commands/OpenInvCommand.java | 12 ++-- .../openinv/internal/InventoryAccess.java | 4 +- .../internal/SilentContainerChest.java | 38 ------------ .../openinv/internal/SpecialEnderChest.java | 27 ++++++--- .../internal/SpecialPlayerInventory.java | 43 +++++++------ .../listeners/OpenInvPlayerListener.java | 53 ++++++++-------- 8 files changed, 137 insertions(+), 114 deletions(-) delete mode 100644 src/main/java/com/lishid/openinv/internal/SilentContainerChest.java diff --git a/src/main/java/com/lishid/openinv/OpenInv.java b/src/main/java/com/lishid/openinv/OpenInv.java index 198faf0..c7fa0fc 100644 --- a/src/main/java/com/lishid/openinv/OpenInv.java +++ b/src/main/java/com/lishid/openinv/OpenInv.java @@ -45,8 +45,8 @@ import com.lishid.openinv.listeners.OpenInvPlayerListener; public class OpenInv extends JavaPlugin { - public static final Map inventories = new HashMap(); - public static final Map enderChests = new HashMap(); + private final Map inventories = new HashMap(); + private final Map enderChests = new HashMap(); private Configuration configuration; @@ -120,6 +120,62 @@ public class OpenInv extends JavaPlugin { return anySilentChest; } + /** + * Returns a player's SpecialPlayerInventory. + * + * @param player the player to get the SpecialPlayerInventory of + * @param createIfNull whether or not to create it if it doesn't exist + * @return the player's SpecialPlayerInventory or null + */ + public SpecialPlayerInventory getPlayerInventory(Player player, boolean createIfNull) { + SpecialPlayerInventory inventory = inventories.get(player.getUniqueId()); + if (inventory == null && createIfNull) { + inventory = new SpecialPlayerInventory(player, player.isOnline()); + inventories.put(player.getUniqueId(), inventory); + } + + return inventory; + } + + /** + * Returns a player's SpecialEnderChest. + * + * @param player the player to get the SpecialEnderChest of + * @param createIfNull whether or not to create it if it doesn't exist + * @return the player's SpecialEnderChest or null + */ + public SpecialEnderChest getPlayerEnderChest(Player player, boolean createIfNull) { + SpecialEnderChest enderChest = enderChests.get(player.getUniqueId()); + if (enderChest == null && createIfNull) { + enderChest = new SpecialEnderChest(player, player.isOnline()); + enderChests.put(player.getUniqueId(), enderChest); + } + + return enderChest; + } + + /** + * Removes a player's loaded inventory if it exists. + * + * @param player the player to remove the loaded inventory of + */ + public void removeLoadedInventory(Player player) { + if (inventories.containsKey(player.getUniqueId())) { + inventories.remove(player.getUniqueId()); + } + } + + /** + * Removes a player's loaded ender chest if it exists. + * + * @param player the player to remove the loaded ender chest of + */ + public void removeLoadedEnderChest(Player player) { + if (enderChests.containsKey(player.getUniqueId())) { + enderChests.remove(player.getUniqueId()); + } + } + /** * Logs a message to console. * diff --git a/src/main/java/com/lishid/openinv/commands/OpenEnderCommand.java b/src/main/java/com/lishid/openinv/commands/OpenEnderCommand.java index ab4320d..6ff14b9 100644 --- a/src/main/java/com/lishid/openinv/commands/OpenEnderCommand.java +++ b/src/main/java/com/lishid/openinv/commands/OpenEnderCommand.java @@ -128,17 +128,18 @@ public class OpenEnderCommand implements CommandExecutor { } private void openInventory(Player player, Player target) { + // Null target check if (target == null) { player.sendMessage(ChatColor.RED + "Player not found!"); return; } + // Permissions checks if (target != player && !OpenInv.hasPermission(player, Permissions.PERM_ENDERCHEST_ALL)) { player.sendMessage(ChatColor.RED + "You do not have permission to access other player's ender chests."); return; } - // Permissions checks if (!OpenInv.hasPermission(player, Permissions.PERM_OVERRIDE) && OpenInv.hasPermission(target, Permissions.PERM_EXEMPT)) { player.sendMessage(ChatColor.RED + target.getDisplayName() + "'s ender chest is protected!"); return; @@ -153,13 +154,8 @@ public class OpenEnderCommand implements CommandExecutor { // Record the target openEnderHistory.put(player.getUniqueId(), target.getUniqueId()); - // Create the inventory - SpecialEnderChest chest = OpenInv.enderChests.get(target.getUniqueId()); - if (chest == null) { - chest = new SpecialEnderChest(target, target.isOnline()); - } - - // Open the inventory - player.openInventory(chest.getBukkitInventory()); + // Get the inventory and open it + SpecialEnderChest enderChest = plugin.getPlayerEnderChest(target, true); + player.openInventory(enderChest.getBukkitInventory()); } } diff --git a/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java b/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java index 66effa6..cae130e 100644 --- a/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java +++ b/src/main/java/com/lishid/openinv/commands/OpenInvCommand.java @@ -123,6 +123,7 @@ public class OpenInvCommand implements CommandExecutor { } private void openInventory(Player player, Player target) { + // Null target check if (target == null) { player.sendMessage(ChatColor.RED + "Player not found!"); return; @@ -149,13 +150,8 @@ public class OpenInvCommand implements CommandExecutor { // Record the target openInvHistory.put(player.getUniqueId(), target.getUniqueId()); - // Create the inventory - SpecialPlayerInventory inv = OpenInv.inventories.get(target.getUniqueId()); - if (inv == null) { - inv = new SpecialPlayerInventory(target, target.isOnline()); - } - - // Open the inventory - player.openInventory(inv.getBukkitInventory()); + // Get the inventory and open it + SpecialPlayerInventory inventory = plugin.getPlayerInventory(target, true); + player.openInventory(inventory.getBukkitInventory()); } } diff --git a/src/main/java/com/lishid/openinv/internal/InventoryAccess.java b/src/main/java/com/lishid/openinv/internal/InventoryAccess.java index 9aacb51..29738c7 100644 --- a/src/main/java/com/lishid/openinv/internal/InventoryAccess.java +++ b/src/main/java/com/lishid/openinv/internal/InventoryAccess.java @@ -42,9 +42,7 @@ public class InventoryAccess { if (!OpenInv.hasPermission(player, Permissions.PERM_EDITINV)) { return false; } - } - - else if (inv instanceof SpecialEnderChest) { + } else if (inv instanceof SpecialEnderChest) { if (!OpenInv.hasPermission(player, Permissions.PERM_EDITENDER)) { return false; } diff --git a/src/main/java/com/lishid/openinv/internal/SilentContainerChest.java b/src/main/java/com/lishid/openinv/internal/SilentContainerChest.java deleted file mode 100644 index 7c9c5c3..0000000 --- a/src/main/java/com/lishid/openinv/internal/SilentContainerChest.java +++ /dev/null @@ -1,38 +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 . - */ - -package com.lishid.openinv.internal; - -import net.minecraft.server.v1_9_R1.ContainerChest; -import net.minecraft.server.v1_9_R1.EntityHuman; -import net.minecraft.server.v1_9_R1.IInventory; - -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 - } -} diff --git a/src/main/java/com/lishid/openinv/internal/SpecialEnderChest.java b/src/main/java/com/lishid/openinv/internal/SpecialEnderChest.java index f2adfde..15546b6 100644 --- a/src/main/java/com/lishid/openinv/internal/SpecialEnderChest.java +++ b/src/main/java/com/lishid/openinv/internal/SpecialEnderChest.java @@ -32,7 +32,7 @@ public class SpecialEnderChest extends InventorySubcontainer { private final CraftInventory inventory = new CraftInventory(this); private final InventoryEnderChest enderChest; - private final CraftPlayer owner; + private CraftPlayer owner; private boolean playerOnline; public SpecialEnderChest(Player p, boolean online) { @@ -45,7 +45,6 @@ public class SpecialEnderChest extends InventorySubcontainer { this.enderChest = enderChest; this.items = this.enderChest.getContents(); this.playerOnline = online; - OpenInv.enderChests.put(owner.getUniqueId(), this); } private void saveOnExit() { @@ -62,26 +61,38 @@ public class SpecialEnderChest extends InventorySubcontainer { return inventory; } + public boolean inventoryRemovalCheck(boolean save) { + boolean offline = transaction.isEmpty() && !playerOnline; + if (offline && save) { + owner.saveData(); + } + + return offline; + } + public void playerOnline(Player p) { if (!playerOnline) { + owner = (CraftPlayer) p; + linkInventory(((CraftPlayer) p).getHandle().getEnderChest()); + playerOnline = true; + + /* linkInventory(((CraftPlayer) p).getHandle().getEnderChest()); p.saveData(); playerOnline = true; + */ } } - public void playerOffline() { + public boolean playerOffline() { playerOnline = false; - owner.loadData(); - linkInventory(owner.getHandle().getEnderChest()); - saveOnExit(); + return inventoryRemovalCheck(false); } @Override public void onClose(CraftHumanEntity who) { super.onClose(who); - saveOnExit(); - OpenInv.enderChests.remove(owner.getUniqueId()); + inventoryRemovalCheck(true); } @Override diff --git a/src/main/java/com/lishid/openinv/internal/SpecialPlayerInventory.java b/src/main/java/com/lishid/openinv/internal/SpecialPlayerInventory.java index b0994ad..f00acae 100644 --- a/src/main/java/com/lishid/openinv/internal/SpecialPlayerInventory.java +++ b/src/main/java/com/lishid/openinv/internal/SpecialPlayerInventory.java @@ -35,16 +35,15 @@ public class SpecialPlayerInventory extends PlayerInventory { private final CraftInventory inventory = new CraftInventory(this); private final ItemStack[] extra = new ItemStack[4]; - private final CraftPlayer owner; + private CraftPlayer owner; private ItemStack[][] arrays; private boolean playerOnline; public SpecialPlayerInventory(Player p, boolean online) { super(((CraftPlayer) p).getHandle()); this.owner = (CraftPlayer) p; - reflectContents(getClass().getSuperclass(), player.inventory, this); this.playerOnline = online; - OpenInv.inventories.put(owner.getUniqueId(), this); + reflectContents(getClass().getSuperclass(), player.inventory, this); } private void reflectContents(Class clazz, PlayerInventory src, PlayerInventory dest) { @@ -73,41 +72,41 @@ public class SpecialPlayerInventory extends PlayerInventory { arrays = new ItemStack[][] { this.items, this.armor, this.extraSlots, this.extra }; } - public Inventory getBukkitInventory() { - return inventory; - } - - private void saveOnExit() { - if (transaction.isEmpty() && !playerOnline) { - owner.saveData(); - } - } - private void linkInventory(PlayerInventory inventory) { reflectContents(inventory.getClass(), inventory, this); } + 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) { if (!playerOnline) { - CraftPlayer p = (CraftPlayer) player; - linkInventory(p.getHandle().inventory); - p.saveData(); + owner = (CraftPlayer) player; + this.player = owner.getHandle(); + linkInventory(owner.getHandle().inventory); playerOnline = true; } } - public void playerOffline() { + public boolean playerOffline() { playerOnline = false; - owner.loadData(); - linkInventory(owner.getHandle().inventory); - saveOnExit(); + return inventoryRemovalCheck(false); } @Override public void onClose(CraftHumanEntity who) { super.onClose(who); - this.saveOnExit(); - OpenInv.inventories.remove(owner.getUniqueId()); + inventoryRemovalCheck(true); } @Override diff --git a/src/main/java/com/lishid/openinv/listeners/OpenInvPlayerListener.java b/src/main/java/com/lishid/openinv/listeners/OpenInvPlayerListener.java index 2eb3ff1..df7d2b7 100644 --- a/src/main/java/com/lishid/openinv/listeners/OpenInvPlayerListener.java +++ b/src/main/java/com/lishid/openinv/listeners/OpenInvPlayerListener.java @@ -48,43 +48,48 @@ public class OpenInvPlayerListener implements Listener { configuration = plugin.getConfiguration(); } - @EventHandler(priority = EventPriority.LOWEST) + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); + final Player player = event.getPlayer(); - SpecialPlayerInventory inventory = OpenInv.inventories.get(player.getUniqueId()); - if (inventory != null) { - inventory.playerOnline(event.getPlayer()); - } + new BukkitRunnable() { + @Override + public void run() { + if (!player.isOnline()) { + return; + } - SpecialEnderChest enderChest = OpenInv.enderChests.get(player.getUniqueId()); - if (enderChest != null) { - enderChest.playerOnline(event.getPlayer()); - } + SpecialPlayerInventory inventory = plugin.getPlayerInventory(player, false); + if (inventory != null) { + inventory.playerOnline(player); + player.updateInventory(); + } + + SpecialEnderChest chest = plugin.getPlayerEnderChest(player, false); + if (chest != null) { + chest.playerOnline(player); + } + } + }.runTask(plugin); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); - final SpecialPlayerInventory inventory = OpenInv.inventories.get(player.getUniqueId()); + SpecialPlayerInventory inventory = plugin.getPlayerInventory(player, false); if (inventory != null) { - new BukkitRunnable() { - @Override - public void run() { - inventory.playerOffline(); - } - }.runTaskLater(plugin, 1); + if (inventory.playerOffline()) { + plugin.removeLoadedInventory(event.getPlayer()); + } } - final SpecialEnderChest enderChest = OpenInv.enderChests.get(player.getUniqueId()); + SpecialEnderChest enderChest = plugin.getPlayerEnderChest(player, false); if (enderChest != null) { - new BukkitRunnable() { - @Override - public void run() { - enderChest.playerOffline(); - } - }.runTaskLater(plugin, 1); + if (enderChest.playerOffline()) { + plugin.removeLoadedEnderChest(event.getPlayer()); + } } }