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 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.
*

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

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

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.InventoryHolder;
import com.lishid.openinv.OpenInv;
import net.minecraft.server.v1_9_R1.InventoryEnderChest;
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 InventoryEnderChest enderChest;
private final CraftPlayer owner;
private CraftPlayer owner;
private boolean playerOnline;
public SpecialEnderChest(Player p, boolean online) {
@ -45,7 +43,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 +59,32 @@ 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());
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

View file

@ -24,8 +24,6 @@ import org.bukkit.craftbukkit.v1_9_R1.inventory.CraftInventory;
import org.bukkit.entity.Player;
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.EntityHuman;
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 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 +70,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

View file

@ -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());
}
}
}