Merge pull request #42 from ShadowRanger/master

Implement Jikoo's data duplication glitch fix
This commit is contained in:
ShadowRanger 2016-05-05 11:25:28 +10:00
commit 582a958195
8 changed files with 132 additions and 119 deletions

View file

@ -45,8 +45,8 @@ import com.lishid.openinv.listeners.OpenInvPlayerListener;
public class OpenInv extends JavaPlugin { public class OpenInv extends JavaPlugin {
public static final Map<UUID, SpecialPlayerInventory> inventories = new HashMap<UUID, SpecialPlayerInventory>(); private final Map<UUID, SpecialPlayerInventory> inventories = new HashMap<UUID, SpecialPlayerInventory>();
public static final Map<UUID, SpecialEnderChest> enderChests = new HashMap<UUID, SpecialEnderChest>(); private final Map<UUID, SpecialEnderChest> enderChests = new HashMap<UUID, SpecialEnderChest>();
private Configuration configuration; private Configuration configuration;
@ -120,6 +120,62 @@ public class OpenInv extends JavaPlugin {
return anySilentChest; 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. * Logs a message to console.
* *

View file

@ -128,17 +128,18 @@ public class OpenEnderCommand implements CommandExecutor {
} }
private void openInventory(Player player, Player target) { private void openInventory(Player player, Player target) {
// Null target check
if (target == null) { if (target == null) {
player.sendMessage(ChatColor.RED + "Player not found!"); player.sendMessage(ChatColor.RED + "Player not found!");
return; return;
} }
// Permissions checks
if (target != player && !OpenInv.hasPermission(player, Permissions.PERM_ENDERCHEST_ALL)) { 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."); player.sendMessage(ChatColor.RED + "You do not have permission to access other player's ender chests.");
return; return;
} }
// Permissions checks
if (!OpenInv.hasPermission(player, Permissions.PERM_OVERRIDE) && OpenInv.hasPermission(target, Permissions.PERM_EXEMPT)) { if (!OpenInv.hasPermission(player, Permissions.PERM_OVERRIDE) && OpenInv.hasPermission(target, Permissions.PERM_EXEMPT)) {
player.sendMessage(ChatColor.RED + target.getDisplayName() + "'s ender chest is protected!"); player.sendMessage(ChatColor.RED + target.getDisplayName() + "'s ender chest is protected!");
return; return;
@ -153,13 +154,8 @@ public class OpenEnderCommand implements CommandExecutor {
// Record the target // Record the target
openEnderHistory.put(player.getUniqueId(), target.getUniqueId()); openEnderHistory.put(player.getUniqueId(), target.getUniqueId());
// Create the inventory // Get the inventory and open it
SpecialEnderChest chest = OpenInv.enderChests.get(target.getUniqueId()); SpecialEnderChest enderChest = plugin.getPlayerEnderChest(target, true);
if (chest == null) { player.openInventory(enderChest.getBukkitInventory());
chest = new SpecialEnderChest(target, target.isOnline());
}
// Open the inventory
player.openInventory(chest.getBukkitInventory());
} }
} }

View file

@ -123,6 +123,7 @@ public class OpenInvCommand implements CommandExecutor {
} }
private void openInventory(Player player, Player target) { private void openInventory(Player player, Player target) {
// Null target check
if (target == null) { if (target == null) {
player.sendMessage(ChatColor.RED + "Player not found!"); player.sendMessage(ChatColor.RED + "Player not found!");
return; return;
@ -149,13 +150,8 @@ public class OpenInvCommand implements CommandExecutor {
// Record the target // Record the target
openInvHistory.put(player.getUniqueId(), target.getUniqueId()); openInvHistory.put(player.getUniqueId(), target.getUniqueId());
// Create the inventory // Get the inventory and open it
SpecialPlayerInventory inv = OpenInv.inventories.get(target.getUniqueId()); SpecialPlayerInventory inventory = plugin.getPlayerInventory(target, true);
if (inv == null) { player.openInventory(inventory.getBukkitInventory());
inv = new SpecialPlayerInventory(target, target.isOnline());
}
// Open the inventory
player.openInventory(inv.getBukkitInventory());
} }
} }

View file

@ -42,9 +42,7 @@ public class InventoryAccess {
if (!OpenInv.hasPermission(player, Permissions.PERM_EDITINV)) { if (!OpenInv.hasPermission(player, Permissions.PERM_EDITINV)) {
return false; return false;
} }
} } else if (inv instanceof SpecialEnderChest) {
else if (inv instanceof SpecialEnderChest) {
if (!OpenInv.hasPermission(player, Permissions.PERM_EDITENDER)) { if (!OpenInv.hasPermission(player, Permissions.PERM_EDITENDER)) {
return false; return false;
} }

View file

@ -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
}
}

View file

@ -23,8 +23,6 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import com.lishid.openinv.OpenInv;
import net.minecraft.server.v1_9_R1.InventoryEnderChest; import net.minecraft.server.v1_9_R1.InventoryEnderChest;
import net.minecraft.server.v1_9_R1.InventorySubcontainer; import net.minecraft.server.v1_9_R1.InventorySubcontainer;
@ -32,7 +30,7 @@ public class SpecialEnderChest extends InventorySubcontainer {
private final CraftInventory inventory = new CraftInventory(this); private final CraftInventory inventory = new CraftInventory(this);
private final InventoryEnderChest enderChest; private final InventoryEnderChest enderChest;
private final CraftPlayer owner; private CraftPlayer owner;
private boolean playerOnline; private boolean playerOnline;
public SpecialEnderChest(Player p, boolean online) { public SpecialEnderChest(Player p, boolean online) {
@ -45,7 +43,6 @@ public class SpecialEnderChest extends InventorySubcontainer {
this.enderChest = enderChest; this.enderChest = enderChest;
this.items = this.enderChest.getContents(); this.items = this.enderChest.getContents();
this.playerOnline = online; this.playerOnline = online;
OpenInv.enderChests.put(owner.getUniqueId(), this);
} }
private void saveOnExit() { private void saveOnExit() {
@ -62,26 +59,32 @@ public class SpecialEnderChest extends InventorySubcontainer {
return inventory; return inventory;
} }
public boolean inventoryRemovalCheck(boolean save) {
boolean offline = transaction.isEmpty() && !playerOnline;
if (offline && save) {
owner.saveData();
}
return offline;
}
public void playerOnline(Player p) { public void playerOnline(Player p) {
if (!playerOnline) { if (!playerOnline) {
owner = (CraftPlayer) p;
linkInventory(((CraftPlayer) p).getHandle().getEnderChest()); linkInventory(((CraftPlayer) p).getHandle().getEnderChest());
p.saveData();
playerOnline = true; playerOnline = true;
} }
} }
public void playerOffline() { public boolean playerOffline() {
playerOnline = false; playerOnline = false;
owner.loadData(); return inventoryRemovalCheck(false);
linkInventory(owner.getHandle().getEnderChest());
saveOnExit();
} }
@Override @Override
public void onClose(CraftHumanEntity who) { public void onClose(CraftHumanEntity who) {
super.onClose(who); super.onClose(who);
saveOnExit(); inventoryRemovalCheck(true);
OpenInv.enderChests.remove(owner.getUniqueId());
} }
@Override @Override

View file

@ -24,8 +24,6 @@ import org.bukkit.craftbukkit.v1_9_R1.inventory.CraftInventory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import com.lishid.openinv.OpenInv;
import net.minecraft.server.v1_9_R1.ContainerUtil; import net.minecraft.server.v1_9_R1.ContainerUtil;
import net.minecraft.server.v1_9_R1.EntityHuman; import net.minecraft.server.v1_9_R1.EntityHuman;
import net.minecraft.server.v1_9_R1.ItemStack; import net.minecraft.server.v1_9_R1.ItemStack;
@ -35,16 +33,15 @@ public class SpecialPlayerInventory extends PlayerInventory {
private final CraftInventory inventory = new CraftInventory(this); private final CraftInventory inventory = new CraftInventory(this);
private final ItemStack[] extra = new ItemStack[4]; private final ItemStack[] extra = new ItemStack[4];
private final CraftPlayer owner; private CraftPlayer owner;
private ItemStack[][] arrays; private ItemStack[][] arrays;
private boolean playerOnline; private boolean playerOnline;
public SpecialPlayerInventory(Player p, boolean online) { public SpecialPlayerInventory(Player p, boolean online) {
super(((CraftPlayer) p).getHandle()); super(((CraftPlayer) p).getHandle());
this.owner = (CraftPlayer) p; this.owner = (CraftPlayer) p;
reflectContents(getClass().getSuperclass(), player.inventory, this);
this.playerOnline = online; this.playerOnline = online;
OpenInv.inventories.put(owner.getUniqueId(), this); reflectContents(getClass().getSuperclass(), player.inventory, this);
} }
private void reflectContents(Class clazz, PlayerInventory src, PlayerInventory dest) { private void reflectContents(Class clazz, PlayerInventory src, PlayerInventory dest) {
@ -73,41 +70,41 @@ public class SpecialPlayerInventory extends PlayerInventory {
arrays = new ItemStack[][] { this.items, this.armor, this.extraSlots, this.extra }; 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) { private void linkInventory(PlayerInventory inventory) {
reflectContents(inventory.getClass(), inventory, this); 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) { public void playerOnline(Player player) {
if (!playerOnline) { if (!playerOnline) {
CraftPlayer p = (CraftPlayer) player; owner = (CraftPlayer) player;
linkInventory(p.getHandle().inventory); this.player = owner.getHandle();
p.saveData(); linkInventory(owner.getHandle().inventory);
playerOnline = true; playerOnline = true;
} }
} }
public void playerOffline() { public boolean playerOffline() {
playerOnline = false; playerOnline = false;
owner.loadData(); return inventoryRemovalCheck(false);
linkInventory(owner.getHandle().inventory);
saveOnExit();
} }
@Override @Override
public void onClose(CraftHumanEntity who) { public void onClose(CraftHumanEntity who) {
super.onClose(who); super.onClose(who);
this.saveOnExit(); inventoryRemovalCheck(true);
OpenInv.inventories.remove(owner.getUniqueId());
} }
@Override @Override

View file

@ -48,43 +48,48 @@ public class OpenInvPlayerListener implements Listener {
configuration = plugin.getConfiguration(); configuration = plugin.getConfiguration();
} }
@EventHandler(priority = EventPriority.LOWEST) @SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); final Player player = event.getPlayer();
SpecialPlayerInventory inventory = OpenInv.inventories.get(player.getUniqueId()); new BukkitRunnable() {
@Override
public void run() {
if (!player.isOnline()) {
return;
}
SpecialPlayerInventory inventory = plugin.getPlayerInventory(player, false);
if (inventory != null) { if (inventory != null) {
inventory.playerOnline(event.getPlayer()); inventory.playerOnline(player);
player.updateInventory();
} }
SpecialEnderChest enderChest = OpenInv.enderChests.get(player.getUniqueId()); SpecialEnderChest chest = plugin.getPlayerEnderChest(player, false);
if (enderChest != null) { if (chest != null) {
enderChest.playerOnline(event.getPlayer()); chest.playerOnline(player);
} }
} }
}.runTask(plugin);
}
@EventHandler @EventHandler
public void onPlayerQuit(PlayerQuitEvent event) { public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
final SpecialPlayerInventory inventory = OpenInv.inventories.get(player.getUniqueId()); SpecialPlayerInventory inventory = plugin.getPlayerInventory(player, false);
if (inventory != null) { if (inventory != null) {
new BukkitRunnable() { if (inventory.playerOffline()) {
@Override plugin.removeLoadedInventory(event.getPlayer());
public void run() {
inventory.playerOffline();
} }
}.runTaskLater(plugin, 1);
} }
final SpecialEnderChest enderChest = OpenInv.enderChests.get(player.getUniqueId()); SpecialEnderChest enderChest = plugin.getPlayerEnderChest(player, false);
if (enderChest != null) { if (enderChest != null) {
new BukkitRunnable() { if (enderChest.playerOffline()) {
@Override plugin.removeLoadedEnderChest(event.getPlayer());
public void run() {
enderChest.playerOffline();
} }
}.runTaskLater(plugin, 1);
} }
} }