() {
@Override
- public boolean run(Player value) {
- String key = playerLoader.getPlayerDataID(value);
+ public boolean run(final Player value) {
+ String key = OpenInv.this.playerLoader.getPlayerDataID(value);
// Check if inventory is stored, and if it is, remove it and eject all viewers
- if (inventories.containsKey(key)) {
- Inventory inv = inventories.remove(key).getBukkitInventory();
+ if (OpenInv.this.inventories.containsKey(key)) {
+ Inventory inv = OpenInv.this.inventories.remove(key).getBukkitInventory();
for (HumanEntity entity : inv.getViewers()) {
entity.closeInventory();
}
}
// Check if ender chest is stored, and if it is, remove it and eject all viewers
- if (enderChests.containsKey(key)) {
- Inventory inv = enderChests.remove(key).getBukkitInventory();
+ if (OpenInv.this.enderChests.containsKey(key)) {
+ Inventory inv = OpenInv.this.enderChests.remove(key).getBukkitInventory();
for (HumanEntity entity : inv.getViewers()) {
entity.closeInventory();
}
@@ -117,509 +119,9 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
private IInventoryAccess inventoryAccess;
private IAnySilentContainer anySilentContainer;
- @Override
- public void onEnable() {
- // Get plugin manager
- PluginManager pm = getServer().getPluginManager();
-
- accessor = new InternalAccessor(this);
- // Version check
- if (!accessor.isSupported()) {
- getLogger().info("Your version of CraftBukkit (" + accessor.getVersion() + ") is not supported.");
- getLogger().info("Please look for an updated version of OpenInv.");
- pm.disablePlugin(this);
- return;
- }
-
- playerLoader = accessor.newPlayerDataManager();
- inventoryAccess = accessor.newInventoryAccess();
- anySilentContainer = accessor.newAnySilentContainer();
-
- new ConfigUpdater(this).checkForUpdates();
-
- // Register listeners
- pm.registerEvents(new PlayerListener(this), this);
- pm.registerEvents(new PluginListener(this), this);
- pm.registerEvents(new InventoryClickListener(this), this);
- // Bukkit will handle missing events for us, attempt to register InventoryDragEvent without a version check
- pm.registerEvents(new InventoryDragListener(this), this);
-
- // Register commands to their executors
- getCommand("openinv").setExecutor(new OpenInvPluginCommand(this));
- getCommand("openender").setExecutor(new OpenEnderPluginCommand(this));
- SearchInvPluginCommand searchInv = new SearchInvPluginCommand(this);
- getCommand("searchinv").setExecutor(searchInv);
- getCommand("searchender").setExecutor(searchInv);
- getCommand("searchenchant").setExecutor(new SearchEnchantPluginCommand(this));
- getCommand("silentchest").setExecutor(new SilentChestPluginCommand(this));
- getCommand("anychest").setExecutor(new AnyChestPluginCommand(this));
-
- }
-
- @Override
- public void onDisable() {
-
- if (this.disableSaving()) {
- return;
- }
-
- this.playerCache.invalidateAll();
- }
-
- /**
- * Checks if the server version is supported by OpenInv.
- *
- * @return true if the server version is supported
- */
- @Override
- public boolean isSupportedVersion() {
- return this.accessor != null && this.accessor.isSupported();
- }
-
- /**
- * Gets the active IInventoryAccess implementation. May return null if the server version is
- * unsupported.
- *
- * @return the IInventoryAccess
- */
- @Override
- public IInventoryAccess getInventoryAccess() {
- return this.inventoryAccess;
- }
-
- /**
- * Gets the active ISilentContainer implementation. May return null if the server version is
- * unsupported.
- *
- * @return the ISilentContainer
- */
- @Override
- public IAnySilentContainer getAnySilentContainer() {
- return this.anySilentContainer;
- }
-
- /**
- * Gets an ISpecialPlayerInventory for the given Player.
- *
- * @param player the Player
- * @param online true if the Player is currently online
- * @return the ISpecialPlayerInventory
- */
- @Override
- public ISpecialPlayerInventory getInventory(Player player, boolean online) {
- String id = playerLoader.getPlayerDataID(player);
- if (inventories.containsKey(id)) {
- return inventories.get(id);
- }
- ISpecialPlayerInventory inv = accessor.newSpecialPlayerInventory(player, online);
- inventories.put(id, inv);
- playerCache.put(id, player);
- return inv;
- }
-
- /**
- * Gets an ISpecialEnderChest for the given Player.
- *
- * @param player the Player
- * @param online true if the Player is currently online
- * @return the ISpecialEnderChest
- */
- @Override
- public ISpecialEnderChest getEnderChest(Player player, boolean online) {
- String id = playerLoader.getPlayerDataID(player);
- if (enderChests.containsKey(id)) {
- return enderChests.get(id);
- }
- ISpecialEnderChest inv = accessor.newSpecialEnderChest(player, online);
- enderChests.put(id, inv);
- playerCache.put(id, player);
- return inv;
- }
-
- /**
- * Forcibly unload a cached Player's data.
- *
- * @param player the OfflinePlayer to unload
- */
- @Override
- public void unload(OfflinePlayer player) {
- this.playerCache.invalidate(this.playerLoader.getPlayerDataID(player));
- }
-
- /**
- * Check the configuration value for whether or not OpenInv saves player data when unloading
- * players. This is exclusively for users who do not allow editing of inventories, only viewing,
- * and wish to prevent any possibility of bugs such as lishid#40. If true, OpenInv will not ever
- * save any edits made to players.
- *
- * @return false unless configured otherwise
- */
- @Override
- public boolean disableSaving() {
- return getConfig().getBoolean("settings.disable-saving", false);
- }
-
- /**
- * Check the configuration value for whether or not OpenInv displays a notification to the user
- * when a container is activated with SilentChest.
- *
- * @return true unless configured otherwise
- */
- @Override
- public boolean notifySilentChest() {
- return getConfig().getBoolean("notify.silent-chest", true);
- }
-
- /**
- * Check the configuration value for whether or not OpenInv displays a notification to the user
- * when a container is activated with AnyChest.
- *
- * @return true unless configured otherwise
- */
- @Override
- public boolean notifyAnyChest() {
- return getConfig().getBoolean("notify.any-chest", true);
- }
-
- /**
- * Gets a player's SilentChest setting.
- *
- * @param player the OfflinePlayer
- * @return true if SilentChest is enabled
- */
- @Override
- public boolean getPlayerSilentChestStatus(OfflinePlayer player) {
- return getConfig().getBoolean("toggles.silent-chest." + playerLoader.getPlayerDataID(player), false);
- }
-
- /**
- * Sets a player's SilentChest setting.
- *
- * @param player the OfflinePlayer
- * @param status the status
- */
- @Override
- public void setPlayerSilentChestStatus(OfflinePlayer player, boolean status) {
- getConfig().set("toggles.silent-chest." + playerLoader.getPlayerDataID(player), status);
- saveConfig();
- }
-
- /**
- * Gets the provided player's AnyChest setting.
- *
- * @param player the OfflinePlayer
- * @return true if AnyChest is enabled
- */
- @Override
- public boolean getPlayerAnyChestStatus(OfflinePlayer player) {
- return getConfig().getBoolean("toggles.any-chest." + playerLoader.getPlayerDataID(player), false);
- }
-
- /**
- * Sets a player's AnyChest setting.
- *
- * @param player the OfflinePlayer
- * @param status the status
- */
- @Override
- public void setPlayerAnyChestStatus(OfflinePlayer player, boolean status) {
- getConfig().set("toggles.any-chest." + playerLoader.getPlayerDataID(player), status);
- saveConfig();
- }
-
- /**
- * Gets a unique identifier by which the OfflinePlayer can be referenced. Using the value
- * returned to look up a Player will generally be much faster for later implementations.
- *
- * @param offline the OfflinePlayer
- * @return the identifier
- */
- @Override
- public String getPlayerID(OfflinePlayer offline) {
- return this.playerLoader.getPlayerDataID(offline);
- }
-
- /**
- * Get an OfflinePlayer by name.
- *
- * Note: This method is potentially very heavily blocking. It should not ever be called on the
- * main thread, and if it is, a stack trace will be displayed alerting server owners to the
- * call.
- *
- * @param name the name of the Player
- * @return the OfflinePlayer with the closest matching name or null if no players have ever logged in
- */
- @Override
- public OfflinePlayer matchPlayer(String name) {
-
- // Warn if called on the main thread - if we resort to searching offline players, this may take several seconds.
- if (getServer().isPrimaryThread()) {
- getLogger().warning("Call to OpenInv#matchPlayer made on the main thread!");
- getLogger().warning("This can cause the server to hang, potentially severely.");
- getLogger().warning("Trace:");
- for (StackTraceElement element : new Throwable().fillInStackTrace().getStackTrace()) {
- getLogger().warning(element.toString());
- }
- }
-
- // Attempt exact offline match first - adds UUID support for later versions
- OfflinePlayer player = this.playerLoader.getPlayerByID(name);
-
- if (player != null) {
- return player;
- }
-
- // Ensure name is valid if server is in online mode to avoid unnecessary searching
- if (getServer().getOnlineMode() && !name.matches("[a-zA-Z0-9_]{3,16}")) {
- return null;
- }
-
- player = getServer().getPlayerExact(name);
-
- if (player != null) {
- return player;
- }
-
- player = getServer().getOfflinePlayer(name);
-
- /*
- * Compatibility: Pre-UUID, getOfflinePlayer always returns an OfflinePlayer. Post-UUID,
- * getOfflinePlayer will return null if no matching player is found. To preserve
- * compatibility, only return the player if they have played before. Ignoring current online
- * status is fine, they'd have been found by getPlayerExact otherwise.
- */
- if (player != null && player.hasPlayedBefore()) {
- return player;
- }
-
- player = getServer().getPlayer(name);
-
- if (player != null) {
- return player;
- }
-
- int bestMatch = Integer.MAX_VALUE;
- for (OfflinePlayer offline : getServer().getOfflinePlayers()) {
- if (offline.getName() == null) {
- // Loaded by UUID only, name has never been looked up.
- continue;
- }
-
- // Compatibility: Lang3 is only bundled with 1.8+
- int currentMatch = org.apache.commons.lang.StringUtils.getLevenshteinDistance(name, offline.getName());
-
- if (currentMatch == 0) {
- return offline;
- }
-
- if (currentMatch < bestMatch) {
- bestMatch = currentMatch;
- player = offline;
- }
- }
-
- // Only null if no players have played ever, otherwise even the worst match will do.
- return player;
- }
-
- /**
- * Load a Player from an OfflinePlayer. May return null under some circumstances.
- *
- * @param offline the OfflinePlayer to load a Player for
- * @return the Player
- */
- @Override
- public Player loadPlayer(final OfflinePlayer offline) {
-
- if (offline == null) {
- return null;
- }
-
- String key = this.playerLoader.getPlayerDataID(offline);
- if (this.playerCache.containsKey(key)) {
- return this.playerCache.get(key);
- }
-
- // TODO: wrap Player to ensure all methods can safely be called offline
- Player loaded;
-
- if (offline.isOnline()) {
- loaded = offline.getPlayer();
- this.playerCache.put(key, loaded);
- return loaded;
- }
-
- if (Bukkit.isPrimaryThread()) {
- return this.playerLoader.loadPlayer(offline);
- }
-
- Future future = Bukkit.getScheduler().callSyncMethod(this,
- new Callable() {
- @Override
- public Player call() throws Exception {
- return playerLoader.loadPlayer(offline);
- }
- });
-
- int ticks = 0;
- while (!future.isDone() && !future.isCancelled() && ticks < 10) {
- ++ticks;
- try {
- Thread.sleep(50L);
- } catch (InterruptedException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- if (!future.isDone() || future.isCancelled()) {
- return null;
- }
-
- try {
- loaded = future.get();
- } catch (InterruptedException e) {
- e.printStackTrace();
- return null;
- } catch (ExecutionException e) {
- e.printStackTrace();
- return null;
- }
-
- if (loaded != null) {
- this.playerCache.put(key, loaded);
- }
-
- return loaded;
- }
-
- /**
- * @see com.lishid.openinv.IOpenInv#retainPlayer(org.bukkit.entity.Player, org.bukkit.plugin.Plugin)
- */
- @Override
- public void retainPlayer(Player player, Plugin plugin) {
- String key = this.playerLoader.getPlayerDataID(player);
-
- if (this.pluginUsage.containsEntry(key, plugin.getClass())) {
- return;
- }
-
- this.pluginUsage.put(key, plugin.getClass());
- }
-
- /**
- * @see com.lishid.openinv.IOpenInv#releasePlayer(org.bukkit.entity.Player, org.bukkit.plugin.Plugin)
- */
- @Override
- public void releasePlayer(Player player, Plugin plugin) {
- String key = this.playerLoader.getPlayerDataID(player);
-
- if (!this.pluginUsage.containsEntry(key, plugin.getClass())) {
- return;
- }
-
- this.pluginUsage.remove(key, plugin.getClass());
- }
-
- /**
- * Unmark any Players in use by the specified Plugin.
- *
- * @param plugin
- */
- public void releaseAllPlayers(Plugin plugin) {
- this.pluginUsage.removeAll(plugin.getClass());
- }
-
- @SuppressWarnings("unchecked")
- public Collection extends Player> getOnlinePlayers() {
-
- if (this.playerLoader != null) {
- return this.playerLoader.getOnlinePlayers();
- }
-
- Method getOnlinePlayers;
- try {
- getOnlinePlayers = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
- } catch (Exception e) {
- e.printStackTrace();
- return Collections.emptyList();
- }
-
- Object onlinePlayers;
- try {
- onlinePlayers = getOnlinePlayers.invoke(null);
- } catch (Exception e) {
- e.printStackTrace();
- return Collections.emptyList();
- }
-
- if (onlinePlayers instanceof List) {
- return (Collection) onlinePlayers;
- }
-
- return Arrays.asList((Player[]) onlinePlayers);
- }
-
- /**
- * Method for handling a Player coming online.
- *
- * @param player the Player
- */
- public void setPlayerOnline(final Player player) {
-
- String key = this.playerLoader.getPlayerDataID(player);
-
- // Check if the player is cached. If not, neither of their inventories is open.
- if (!this.playerCache.containsKey(key)) {
- return;
- }
-
- this.playerCache.put(key, player);
-
- if (this.inventories.containsKey(key)) {
- this.inventories.get(key).setPlayerOnline(player);
- new BukkitRunnable() {
- @SuppressWarnings("deprecation") // Unlikely to ever be a viable alternative, Spigot un-deprecated.
- @Override
- public void run() {
- if (player.isOnline()) {
- player.updateInventory();
- }
- }
- }.runTask(this);
- }
-
- if (this.enderChests.containsKey(key)) {
- this.enderChests.get(key).setPlayerOnline(player);
- }
- }
-
- /**
- * Method for handling a Player going offline.
- *
- * @param player the Player
- */
- public void setPlayerOffline(final Player player) {
-
- String key = this.playerLoader.getPlayerDataID(player);
-
- // Check if the player is cached. If not, neither of their inventories is open.
- if (!this.playerCache.containsKey(key)) {
- return;
- }
-
- if (this.inventories.containsKey(key)) {
- this.inventories.get(key).setPlayerOffline();
- }
-
- if (this.enderChests.containsKey(key)) {
- this.enderChests.get(key).setPlayerOffline();
- }
- }
-
/**
* Evicts all viewers lacking cross-world permissions from a Player's inventory.
- *
+ *
* @param player the Player
*/
public void changeWorld(final Player player) {
@@ -658,12 +160,503 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
}
}
+ /**
+ * Check the configuration value for whether or not OpenInv saves player data when unloading
+ * players. This is exclusively for users who do not allow editing of inventories, only viewing,
+ * and wish to prevent any possibility of bugs such as lishid#40. If true, OpenInv will not ever
+ * save any edits made to players.
+ *
+ * @return false unless configured otherwise
+ */
+ @Override
+ public boolean disableSaving() {
+ return this.getConfig().getBoolean("settings.disable-saving", false);
+ }
+
+ /**
+ * Gets the active ISilentContainer implementation. May return null if the server version is
+ * unsupported.
+ *
+ * @return the ISilentContainer
+ */
+ @Override
+ public IAnySilentContainer getAnySilentContainer() {
+ return this.anySilentContainer;
+ }
+
+ /**
+ * Gets an ISpecialEnderChest for the given Player.
+ *
+ * @param player the Player
+ * @param online true if the Player is currently online
+ * @return the ISpecialEnderChest
+ */
+ @Override
+ public ISpecialEnderChest getEnderChest(final Player player, final boolean online) {
+ String id = this.playerLoader.getPlayerDataID(player);
+ if (this.enderChests.containsKey(id)) {
+ return this.enderChests.get(id);
+ }
+ ISpecialEnderChest inv = this.accessor.newSpecialEnderChest(player, online);
+ this.enderChests.put(id, inv);
+ this.playerCache.put(id, player);
+ return inv;
+ }
+
+ /**
+ * Gets an ISpecialPlayerInventory for the given Player.
+ *
+ * @param player the Player
+ * @param online true if the Player is currently online
+ * @return the ISpecialPlayerInventory
+ */
+ @Override
+ public ISpecialPlayerInventory getInventory(final Player player, final boolean online) {
+ String id = this.playerLoader.getPlayerDataID(player);
+ if (this.inventories.containsKey(id)) {
+ return this.inventories.get(id);
+ }
+ ISpecialPlayerInventory inv = this.accessor.newSpecialPlayerInventory(player, online);
+ this.inventories.put(id, inv);
+ this.playerCache.put(id, player);
+ return inv;
+ }
+
+ /**
+ * Gets the active IInventoryAccess implementation. May return null if the server version is
+ * unsupported.
+ *
+ * @return the IInventoryAccess
+ */
+ @Override
+ public IInventoryAccess getInventoryAccess() {
+ return this.inventoryAccess;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection extends Player> getOnlinePlayers() {
+
+ if (this.playerLoader != null) {
+ return this.playerLoader.getOnlinePlayers();
+ }
+
+ Method getOnlinePlayers;
+ try {
+ getOnlinePlayers = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+
+ Object onlinePlayers;
+ try {
+ onlinePlayers = getOnlinePlayers.invoke(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+
+ if (onlinePlayers instanceof List) {
+ return (Collection) onlinePlayers;
+ }
+
+ return Arrays.asList((Player[]) onlinePlayers);
+ }
+
+ /**
+ * Gets the provided player's AnyChest setting.
+ *
+ * @param player the OfflinePlayer
+ * @return true if AnyChest is enabled
+ */
+ @Override
+ public boolean getPlayerAnyChestStatus(final OfflinePlayer player) {
+ return this.getConfig().getBoolean("toggles.any-chest." + this.playerLoader.getPlayerDataID(player), false);
+ }
+
+ /**
+ * Gets a unique identifier by which the OfflinePlayer can be referenced. Using the value
+ * returned to look up a Player will generally be much faster for later implementations.
+ *
+ * @param offline the OfflinePlayer
+ * @return the identifier
+ */
+ @Override
+ public String getPlayerID(final OfflinePlayer offline) {
+ return this.playerLoader.getPlayerDataID(offline);
+ }
+
+ /**
+ * Gets a player's SilentChest setting.
+ *
+ * @param player the OfflinePlayer
+ * @return true if SilentChest is enabled
+ */
+ @Override
+ public boolean getPlayerSilentChestStatus(final OfflinePlayer player) {
+ return this.getConfig().getBoolean("toggles.silent-chest." + this.playerLoader.getPlayerDataID(player), false);
+ }
+
+ /**
+ * Checks if the server version is supported by OpenInv.
+ *
+ * @return true if the server version is supported
+ */
+ @Override
+ public boolean isSupportedVersion() {
+ return this.accessor != null && this.accessor.isSupported();
+ }
+
+ /**
+ * Load a Player from an OfflinePlayer. May return null under some circumstances.
+ *
+ * @param offline the OfflinePlayer to load a Player for
+ * @return the Player
+ */
+ @Override
+ public Player loadPlayer(final OfflinePlayer offline) {
+
+ if (offline == null) {
+ return null;
+ }
+
+ String key = this.playerLoader.getPlayerDataID(offline);
+ if (this.playerCache.containsKey(key)) {
+ return this.playerCache.get(key);
+ }
+
+ // TODO: wrap Player to ensure all methods can safely be called offline
+ Player loaded;
+
+ if (offline.isOnline()) {
+ loaded = offline.getPlayer();
+ this.playerCache.put(key, loaded);
+ return loaded;
+ }
+
+ if (Bukkit.isPrimaryThread()) {
+ return this.playerLoader.loadPlayer(offline);
+ }
+
+ Future future = Bukkit.getScheduler().callSyncMethod(this,
+ new Callable() {
+ @Override
+ public Player call() throws Exception {
+ return OpenInv.this.playerLoader.loadPlayer(offline);
+ }
+ });
+
+ int ticks = 0;
+ while (!future.isDone() && !future.isCancelled() && ticks < 10) {
+ ++ticks;
+ try {
+ Thread.sleep(50L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ if (!future.isDone() || future.isCancelled()) {
+ return null;
+ }
+
+ try {
+ loaded = future.get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return null;
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ if (loaded != null) {
+ this.playerCache.put(key, loaded);
+ }
+
+ return loaded;
+ }
+
+ /**
+ * Get an OfflinePlayer by name.
+ *
+ * Note: This method is potentially very heavily blocking. It should not ever be called on the
+ * main thread, and if it is, a stack trace will be displayed alerting server owners to the
+ * call.
+ *
+ * @param name the name of the Player
+ * @return the OfflinePlayer with the closest matching name or null if no players have ever logged in
+ */
+ @Override
+ public OfflinePlayer matchPlayer(final String name) {
+
+ // Warn if called on the main thread - if we resort to searching offline players, this may take several seconds.
+ if (this.getServer().isPrimaryThread()) {
+ this.getLogger().warning("Call to OpenInv#matchPlayer made on the main thread!");
+ this.getLogger().warning("This can cause the server to hang, potentially severely.");
+ this.getLogger().warning("Trace:");
+ for (StackTraceElement element : new Throwable().fillInStackTrace().getStackTrace()) {
+ this.getLogger().warning(element.toString());
+ }
+ }
+
+ // Attempt exact offline match first - adds UUID support for later versions
+ OfflinePlayer player = this.playerLoader.getPlayerByID(name);
+
+ if (player != null) {
+ return player;
+ }
+
+ // Ensure name is valid if server is in online mode to avoid unnecessary searching
+ if (this.getServer().getOnlineMode() && !name.matches("[a-zA-Z0-9_]{3,16}")) {
+ return null;
+ }
+
+ player = this.getServer().getPlayerExact(name);
+
+ if (player != null) {
+ return player;
+ }
+
+ player = this.getServer().getOfflinePlayer(name);
+
+ /*
+ * Compatibility: Pre-UUID, getOfflinePlayer always returns an OfflinePlayer. Post-UUID,
+ * getOfflinePlayer will return null if no matching player is found. To preserve
+ * compatibility, only return the player if they have played before. Ignoring current online
+ * status is fine, they'd have been found by getPlayerExact otherwise.
+ */
+ if (player != null && player.hasPlayedBefore()) {
+ return player;
+ }
+
+ player = this.getServer().getPlayer(name);
+
+ if (player != null) {
+ return player;
+ }
+
+ int bestMatch = Integer.MAX_VALUE;
+ for (OfflinePlayer offline : this.getServer().getOfflinePlayers()) {
+ if (offline.getName() == null) {
+ // Loaded by UUID only, name has never been looked up.
+ continue;
+ }
+
+ // Compatibility: Lang3 is only bundled with 1.8+
+ int currentMatch = org.apache.commons.lang.StringUtils.getLevenshteinDistance(name, offline.getName());
+
+ if (currentMatch == 0) {
+ return offline;
+ }
+
+ if (currentMatch < bestMatch) {
+ bestMatch = currentMatch;
+ player = offline;
+ }
+ }
+
+ // Only null if no players have played ever, otherwise even the worst match will do.
+ return player;
+ }
+
+ /**
+ * Check the configuration value for whether or not OpenInv displays a notification to the user
+ * when a container is activated with AnyChest.
+ *
+ * @return true unless configured otherwise
+ */
+ @Override
+ public boolean notifyAnyChest() {
+ return this.getConfig().getBoolean("notify.any-chest", true);
+ }
+
+ /**
+ * Check the configuration value for whether or not OpenInv displays a notification to the user
+ * when a container is activated with SilentChest.
+ *
+ * @return true unless configured otherwise
+ */
+ @Override
+ public boolean notifySilentChest() {
+ return this.getConfig().getBoolean("notify.silent-chest", true);
+ }
+
+ @Override
+ public void onDisable() {
+
+ if (this.disableSaving()) {
+ return;
+ }
+
+ this.playerCache.invalidateAll();
+ }
+
+ @Override
+ public void onEnable() {
+ // Get plugin manager
+ PluginManager pm = this.getServer().getPluginManager();
+
+ this.accessor = new InternalAccessor(this);
+ // Version check
+ if (!this.accessor.isSupported()) {
+ this.getLogger().info("Your version of CraftBukkit (" + this.accessor.getVersion() + ") is not supported.");
+ this.getLogger().info("If this version is a recent release, check for an update.");
+ this.getLogger().info("If this is an older version, ensure that you've downloaded the legacy support version.");
+ pm.disablePlugin(this);
+ return;
+ }
+
+ this.playerLoader = this.accessor.newPlayerDataManager();
+ this.inventoryAccess = this.accessor.newInventoryAccess();
+ this.anySilentContainer = this.accessor.newAnySilentContainer();
+
+ new ConfigUpdater(this).checkForUpdates();
+
+ // Register listeners
+ pm.registerEvents(new PlayerListener(this), this);
+ pm.registerEvents(new PluginListener(this), this);
+ pm.registerEvents(new InventoryClickListener(this), this);
+ // Bukkit will handle missing events for us, attempt to register InventoryDragEvent without a version check
+ pm.registerEvents(new InventoryDragListener(this), this);
+
+ // Register commands to their executors
+ this.getCommand("openinv").setExecutor(new OpenInvPluginCommand(this));
+ this.getCommand("openender").setExecutor(new OpenEnderPluginCommand(this));
+ SearchInvPluginCommand searchInv = new SearchInvPluginCommand(this);
+ this.getCommand("searchinv").setExecutor(searchInv);
+ this.getCommand("searchender").setExecutor(searchInv);
+ this.getCommand("searchenchant").setExecutor(new SearchEnchantPluginCommand(this));
+ this.getCommand("silentchest").setExecutor(new SilentChestPluginCommand(this));
+ this.getCommand("anychest").setExecutor(new AnyChestPluginCommand(this));
+
+ }
+
+ /**
+ * Unmark any Players in use by the specified Plugin.
+ *
+ * @param plugin
+ */
+ public void releaseAllPlayers(final Plugin plugin) {
+ this.pluginUsage.removeAll(plugin.getClass());
+ }
+
+ /**
+ * @see com.lishid.openinv.IOpenInv#releasePlayer(org.bukkit.entity.Player, org.bukkit.plugin.Plugin)
+ */
+ @Override
+ public void releasePlayer(final Player player, final Plugin plugin) {
+ String key = this.playerLoader.getPlayerDataID(player);
+
+ if (!this.pluginUsage.containsEntry(key, plugin.getClass())) {
+ return;
+ }
+
+ this.pluginUsage.remove(key, plugin.getClass());
+ }
+
+ /**
+ * @see com.lishid.openinv.IOpenInv#retainPlayer(org.bukkit.entity.Player, org.bukkit.plugin.Plugin)
+ */
+ @Override
+ public void retainPlayer(final Player player, final Plugin plugin) {
+ String key = this.playerLoader.getPlayerDataID(player);
+
+ if (this.pluginUsage.containsEntry(key, plugin.getClass())) {
+ return;
+ }
+
+ this.pluginUsage.put(key, plugin.getClass());
+ }
+
+ /**
+ * Sets a player's AnyChest setting.
+ *
+ * @param player the OfflinePlayer
+ * @param status the status
+ */
+ @Override
+ public void setPlayerAnyChestStatus(final OfflinePlayer player, final boolean status) {
+ this.getConfig().set("toggles.any-chest." + this.playerLoader.getPlayerDataID(player), status);
+ this.saveConfig();
+ }
+
+ /**
+ * Method for handling a Player going offline.
+ *
+ * @param player the Player
+ */
+ public void setPlayerOffline(final Player player) {
+
+ String key = this.playerLoader.getPlayerDataID(player);
+
+ // Check if the player is cached. If not, neither of their inventories is open.
+ if (!this.playerCache.containsKey(key)) {
+ return;
+ }
+
+ if (this.inventories.containsKey(key)) {
+ this.inventories.get(key).setPlayerOffline();
+ }
+
+ if (this.enderChests.containsKey(key)) {
+ this.enderChests.get(key).setPlayerOffline();
+ }
+ }
+
+ /**
+ * Method for handling a Player coming online.
+ *
+ * @param player the Player
+ */
+ public void setPlayerOnline(final Player player) {
+
+ String key = this.playerLoader.getPlayerDataID(player);
+
+ // Check if the player is cached. If not, neither of their inventories is open.
+ if (!this.playerCache.containsKey(key)) {
+ return;
+ }
+
+ this.playerCache.put(key, player);
+
+ if (this.inventories.containsKey(key)) {
+ this.inventories.get(key).setPlayerOnline(player);
+ new BukkitRunnable() {
+ @SuppressWarnings("deprecation") // Unlikely to ever be a viable alternative, Spigot un-deprecated.
+ @Override
+ public void run() {
+ if (player.isOnline()) {
+ player.updateInventory();
+ }
+ }
+ }.runTask(this);
+ }
+
+ if (this.enderChests.containsKey(key)) {
+ this.enderChests.get(key).setPlayerOnline(player);
+ }
+ }
+
+ /**
+ * Sets a player's SilentChest setting.
+ *
+ * @param player the OfflinePlayer
+ * @param status the status
+ */
+ @Override
+ public void setPlayerSilentChestStatus(final OfflinePlayer player, final boolean status) {
+ this.getConfig().set("toggles.silent-chest." + this.playerLoader.getPlayerDataID(player), status);
+ this.saveConfig();
+ }
+
/**
* Displays all applicable help for OpenInv commands.
- *
+ *
* @param player the Player to help
*/
- public void showHelp(Player player) {
+ public void showHelp(final Player player) {
// Get registered commands
for (String commandName : this.getDescription().getCommands().keySet()) {
PluginCommand command = this.getCommand(commandName);
@@ -693,4 +686,14 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
}
}
+ /**
+ * Forcibly unload a cached Player's data.
+ *
+ * @param player the OfflinePlayer to unload
+ */
+ @Override
+ public void unload(final OfflinePlayer player) {
+ this.playerCache.invalidate(this.playerLoader.getPlayerDataID(player));
+ }
+
}
diff --git a/pom.xml b/pom.xml
index cdffd78..51be23f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,10 +51,10 @@