New invsee implementation

This commit is contained in:
samczsun 2016-05-20 22:51:29 -04:00 committed by Sam Sun
parent 63e3cc8e12
commit ec0e1b9849
6 changed files with 364 additions and 102 deletions

View File

@ -44,7 +44,7 @@ import mineplex.game.clans.clans.commands.*;
import mineplex.game.clans.clans.data.PlayerClan; import mineplex.game.clans.clans.data.PlayerClan;
import mineplex.game.clans.clans.event.ClansPlayerDeathEvent; import mineplex.game.clans.clans.event.ClansPlayerDeathEvent;
import mineplex.game.clans.clans.gui.ClanShop; import mineplex.game.clans.clans.gui.ClanShop;
import mineplex.game.clans.clans.invsee.Invsee; import mineplex.game.clans.clans.invsee.InvseeManager;
import mineplex.game.clans.clans.loot.LootManager; import mineplex.game.clans.clans.loot.LootManager;
import mineplex.game.clans.clans.map.ItemMapManager; import mineplex.game.clans.clans.map.ItemMapManager;
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist; import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
@ -260,7 +260,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
new TntGeneratorManager(plugin, this); new TntGeneratorManager(plugin, this);
new SupplyDropManager(plugin, this); new SupplyDropManager(plugin, this);
new Invsee(this); new InvseeManager(this);
_explosion = new Explosion(plugin, blockRestore); _explosion = new Explosion(plugin, blockRestore);
_warPointEvasion = new WarPointEvasion(plugin); _warPointEvasion = new WarPointEvasion(plugin);

View File

@ -1,23 +0,0 @@
package mineplex.game.clans.clans.invsee;
import mineplex.core.MiniPlugin;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
public class Invsee extends MiniPlugin
{
private ClansManager _clansManager;
public Invsee(ClansManager clansManager)
{
super("Inventory Viewer", clansManager.getPlugin());
_clansManager = clansManager;
}
public void addCommands()
{
addCommand(new InvseeCommand(this));
}
}

View File

@ -0,0 +1,43 @@
package mineplex.game.clans.clans.invsee;
import mineplex.core.MiniPlugin;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class InvseeManager extends MiniPlugin
{
private Map<UUID, InvseeInventory> viewing = new HashMap<>();
public InvseeManager(ClansManager manager)
{
super("Invsee Manager", manager.getPlugin());
}
@Override
public void addCommands()
{
addCommand(new InvseeCommand(this));
}
public void doInvsee(OfflinePlayer target, Player requester)
{
InvseeInventory invseeInventory = viewing.computeIfAbsent(target.getUniqueId(), key -> new InvseeInventory(this, target));
invseeInventory.addAndShowViewer(requester);
}
public void close(UUID target)
{
InvseeInventory invseeInventory = viewing.remove(target);
if (invseeInventory == null)
{
log("Expected non-null inventory when closing " + target);
}
}
}

View File

@ -1,50 +1,83 @@
package mineplex.game.clans.clans.invsee.commands; package mineplex.game.clans.clans.invsee.commands;
import com.mojang.authlib.GameProfile;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.game.clans.clans.invsee.Invsee; import mineplex.game.clans.clans.invsee.InvseeManager;
import mineplex.game.clans.clans.invsee.ui.InvseeInventory; import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.WorldNBTStorage;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_8_R3.CraftOfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class InvseeCommand extends CommandBase<Invsee> import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public class InvseeCommand extends CommandBase<InvseeManager>
{ {
public InvseeCommand(Invsee plugin) public InvseeCommand(InvseeManager plugin)
{ {
super(plugin, Rank.ADMIN, "invsee"); super(plugin, Rank.ADMIN, "invsee");
} }
@SuppressWarnings("deprecation")
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
{ {
if (args.length == 0) if (args.length == 0)
{ {
UtilPlayer.message(caller, F.help("/invsee <Player>", "View a player's inventory", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/invsee <playername/playeruuid>", "View a player's inventory", Rank.ADMIN));
return;
} }
else UUID uuid = null;
try
{ {
String name = args[0]; uuid = UUID.fromString(args[0]);
}
catch (IllegalArgumentException failed)
{
}
OfflinePlayer player = Bukkit.getServer().getPlayer(name); OfflinePlayer exactPlayer = Bukkit.getServer().getPlayerExact(args[0]);
if (exactPlayer == null)
if (player == null) {
if (uuid == null)
{ {
player = Bukkit.getServer().getOfflinePlayer(name); // We don't want to open the wrong OfflinePlayer's inventory, so if we can't fetch the UUID then abort
GameProfile gameProfile = MinecraftServer.getServer().getUserCache().getProfile(args[0]);
if (gameProfile == null)
{
UtilPlayer.message(caller, F.main("Invsee", "Player is offline and we could not find the UUID. Aborting"));
return;
}
uuid = gameProfile.getId();
} }
if (uuid == null)
if (player == null)
{ {
UtilPlayer.message(caller, F.main("Clans", "Specified player is neither online nor offline. Perhaps they changed their name?")); UtilPlayer.message(caller, F.main("Invsee", "Something has gone very wrong. Please report the username/uuid you tried to look up"));
return; return;
} }
// We need to check if we actually have data on this player
new InvseeInventory(player).ShowTo(caller); NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(uuid.toString());
if (compound == null)
{
UtilPlayer.message(caller, F.main("Invsee", "The player exists, but has never joined this server. No inventory to show"));
return;
}
exactPlayer = Bukkit.getServer().getOfflinePlayer(uuid);
} }
if (exactPlayer == null)
{
UtilPlayer.message(caller, F.main("Invsee", "Could not load offline player data. Does the player exist?"));
return;
}
Plugin.doInvsee(exactPlayer, caller);
} }
} }

View File

@ -1,54 +1,236 @@
package mineplex.game.clans.clans.invsee.ui; package mineplex.game.clans.clans.invsee.ui;
import mineplex.core.common.util.*;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.game.clans.clans.ClansManager;
import mineplex.game.clans.clans.invsee.InvseeManager;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventoryCrafting;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventoryPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilCollections;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;
public class InvseeInventory implements Listener public class InvseeInventory implements Listener
{ {
private OfflinePlayer _player; private final InvseeManager invseeManager;
private final UUID uuid;
// This is the current player. It will switch when the player joins/quits
private OfflinePlayer targetPlayer;
private Inventory _inventory; private Inventory _inventory;
private boolean _online; private net.minecraft.server.v1_8_R3.PlayerInventory playerInventory;
private Player _admin; private List<Player> viewers = new ArrayList<>();
private boolean dontUpdate = false;
public InvseeInventory(OfflinePlayer player)
public InvseeInventory(InvseeManager manager, OfflinePlayer player)
{ {
_online = (_player = player) instanceof Player; invseeManager = manager;
uuid = player.getUniqueId();
_inventory = UtilServer.getServer().createInventory(null, 54, player.getName() + " " + (_online ? C.cGreen + "ONLINE" : C.cRed + "OFFLINE")); targetPlayer = player;
updateInventory();
_inventory = UtilServer.getServer().createInventory(null, 6 * 9, player.getName());
for (int index = 38; index < 45; index++)
{
_inventory.setItem(index, ItemStackFactory.Instance.CreateStack(Material.BARRIER, (byte) 0, 1, C.Bold));
}
UtilServer.RegisterEvents(this); UtilServer.RegisterEvents(this);
} }
public void ShowTo(Player admin) /*
* Add the player to the list of viewers and open the inventory for him
*/
public void addAndShowViewer(Player requester)
{ {
_admin = admin; viewers.add(requester);
admin.openInventory(_inventory); requester.openInventory(_inventory);
} }
@EventHandler
public void quit(PlayerQuitEvent event) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void on(PlayerJoinEvent event)
{ {
if (_online && event.getPlayer().equals(_player)) if (uuid.equals(event.getPlayer().getUniqueId()))
{ {
_admin.closeInventory(); targetPlayer = event.getPlayer();
updateInventory();
} }
} }
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void on(PlayerQuitEvent event)
{
// If a viewer quit, this will clean it up
viewers.remove(event.getPlayer());
if (viewers.size() == 0)
{
invseeManager.close(uuid);
}
else
{
// This should always work
targetPlayer = Bukkit.getOfflinePlayer(uuid);
updateInventory();
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void on(InventoryCloseEvent event)
{
if (_inventory.equals(event.getInventory()))
{
viewers.remove(event.getPlayer());
if (viewers.size() == 0)
{
invseeManager.close(uuid);
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on(InventoryClickEvent event)
{
if (_inventory.equals(event.getClickedInventory()))
{
if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.BARRIER
&& event.getCurrentItem().getItemMeta() != null
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(C.Bold))
{
event.setCancelled(true);
return;
}
if (MAPPING_INVENTORY_REVERSE.containsKey(event.getRawSlot()))
{
dontUpdate = true;
ClansManager.getInstance().runSync(() ->
{
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
playerInventory.setItem(MAPPING_INVENTORY_REVERSE.get(event.getRawSlot()), iInventoryThis.getItem(event.getRawSlot()));
saveInventory();
dontUpdate = false;
});
}
else if (MAPPING_CRAFTING_REVERSE.containsKey(event.getRawSlot()))
{
if (targetPlayer.isOnline())
{
dontUpdate = true;
ClansManager.getInstance().runSync(() ->
{
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
EntityPlayer entityPlayer = ((CraftPlayer) targetPlayer).getHandle();
ContainerPlayer containerPlayer = (ContainerPlayer) entityPlayer.defaultContainer;
containerPlayer.craftInventory.setItem(MAPPING_CRAFTING_REVERSE.get(event.getRawSlot()), iInventoryThis.getItem(event.getRawSlot()));
dontUpdate = false;
});
}
else
{
event.setCancelled(true);
}
}
else if (event.getRawSlot() == 49)
{
if (targetPlayer.isOnline())
{
dontUpdate = true;
ClansManager.getInstance().runSync(() ->
{
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
playerInventory.setCarried(iInventoryThis.getItem(49));
saveInventory();
((Player) targetPlayer).updateInventory();
dontUpdate = false;
});
}
else
{
event.setCancelled(true);
}
}
}
}
/*
* Updates the inventory instance
*/
private void updateInventory()
{
if (targetPlayer.isOnline())
{
playerInventory = ((CraftPlayer) targetPlayer).getHandle().inventory;
}
else
{
NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(uuid.toString());
// Should not matter if null
playerInventory = new PlayerInventory(null);
if (compound.hasKeyOfType("Inventory", 9))
{
playerInventory.b(compound.getList("Inventory", 10));
}
}
}
private void saveInventory()
{
if (!targetPlayer.isOnline())
{
try
{
WorldNBTStorage worldNBTStorage = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager());
NBTTagCompound compound = worldNBTStorage.getPlayerData(uuid.toString());
compound.set("Inventory", new NBTTagList());
playerInventory.a(compound.getList("Inventory", 10));
File file = new File(worldNBTStorage.getPlayerDir(), targetPlayer.getUniqueId().toString() + ".dat.tmp");
File file1 = new File(worldNBTStorage.getPlayerDir(), targetPlayer.getUniqueId().toString() + ".dat");
NBTCompressedStreamTools.a(compound, new FileOutputStream(file));
if (file1.exists())
{
file1.delete();
}
file.renameTo(file1);
}
catch (Exception var5)
{
invseeManager.log("Failed to save player inventory for " + targetPlayer.getName());
for (Player player : viewers)
{
UtilPlayer.message(player, F.main("Invsee", "Could not save inventory for " + targetPlayer.getName()));
}
var5.printStackTrace(System.out);
}
}
}
@EventHandler @EventHandler
public void update(UpdateEvent event) public void update(UpdateEvent event)
{ {
@ -56,44 +238,71 @@ public class InvseeInventory implements Listener
{ {
return; return;
} }
if (dontUpdate)
if (_online)
{ {
if (!UtilCollections.equal(_inventory.getContents(), ((Player) _player).getInventory().getContents())) return;
}
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
// Update items on hotbar
for (int otherSlot = 0; otherSlot < 9; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), playerInventory.getItem(otherSlot));
}
// Update main inventory
for (int otherSlot = 9; otherSlot < 36; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), playerInventory.getItem(otherSlot));
}
// Update armor
for (int otherSlot = 36; otherSlot < 40; otherSlot++)
{
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), playerInventory.getItem(otherSlot));
}
if (targetPlayer.isOnline())
{
ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) targetPlayer).getHandle().defaultContainer;
for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++)
{ {
_inventory.setContents(((Player) _player).getInventory().getContents()); iInventoryThis.setItem(MAPPING_CRAFTING.get(craftingIndex), containerPlayer.craftInventory.getItem(craftingIndex));
}
}
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
if (event.getClickedInventory().equals(((Player) _player).getInventory()))
{
_inventory.setContents(((Player) _player).getInventory().getContents());
}
else if (event.getClickedInventory().equals(_inventory))
{
if (_online)
{
((Player) _player).getInventory().setContents(_inventory.getContents());
}
}
}
@EventHandler
public void closeInventory(InventoryCloseEvent event)
{
if (event.getInventory().equals(_inventory))
{
UtilServer.Unregister(this);
if (!_online)
{
// save offline inv
} }
} }
iInventoryThis.setItem(49, playerInventory.getCarried());
} }
// Maps slot indices of player inventories to slot indices of double chests
private static final Map<Integer, Integer> MAPPING_INVENTORY = new HashMap<>();
private static final Map<Integer, Integer> MAPPING_INVENTORY_REVERSE = new HashMap<>();
private static final Map<Integer, Integer> MAPPING_CRAFTING = new HashMap<>();
private static final Map<Integer, Integer> MAPPING_CRAFTING_REVERSE = new HashMap<>();
static
{
int[] inventoryMapping = new int[]
{
27, 28, 29, 30, 31, 32, 33, 34, 35, //Hotbar
0, 1, 2, 3, 4, 5, 6, 7, 8, // Top row inventory
9, 10, 11, 12, 13, 14, 15, 16, 17, //Second row inventory
18, 19, 20, 21, 22, 23, 24, 25, 26, //Third row inventory
53, 52, 51, 50 //Armor
};
int[] craftingMapping = new int[]
{
36, 37, //Top crafting
45, 46 //Bottom crafting
};
for (int i = 0; i < inventoryMapping.length; i++)
{
MAPPING_INVENTORY.put(i, inventoryMapping[i]);
MAPPING_INVENTORY_REVERSE.put(inventoryMapping[i], i);
}
for (int i = 0; i < craftingMapping.length; i++)
{
MAPPING_CRAFTING.put(i, craftingMapping[i]);
MAPPING_CRAFTING_REVERSE.put(craftingMapping[i], i);
}
}
} }

View File

@ -132,7 +132,7 @@ public class SiegeWeaponRepository extends MinecraftRepository
public void updateWeapon(SiegeWeaponToken token) public void updateWeapon(SiegeWeaponToken token)
{ {
System.out.println("Siege Repo> Updating weapon " + token.UniqueId); // System.out.println("Siege Repo> Updating weapon " + token.UniqueId);
_siegeManager.runAsync(() -> _siegeManager.runAsync(() ->
executeUpdate(UPDATE_WEAPON, executeUpdate(UPDATE_WEAPON,