Implement Jikoo's data duplication glitch fix #42
@@ -45,8 +45,8 @@ import com.lishid.openinv.listeners.OpenInvPlayerListener;
 | 
			
		||||
 | 
			
		||||
public class OpenInv extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
    public static final Map<UUID, SpecialPlayerInventory> inventories = new HashMap<UUID, SpecialPlayerInventory>();
 | 
			
		||||
    public static final Map<UUID, SpecialEnderChest> enderChests = new HashMap<UUID, SpecialEnderChest>();
 | 
			
		||||
    private final Map<UUID, SpecialPlayerInventory> inventories = new HashMap<UUID, SpecialPlayerInventory>();
 | 
			
		||||
    private final Map<UUID, SpecialEnderChest> enderChests = new HashMap<UUID, SpecialEnderChest>();
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user