Compare commits

...

4 Commits
3.0.3 ... 3.0.5

Author SHA1 Message Date
Jikoo
9b6e32a775 Fix statistic changes breaking silent/anycontainer in 1.11.1+
C'mon Spigot team, this is why the revision bumps existed in the first place, to allow plugins that deal with NMS to easily and gracefully fail on unsupported versions. 1.11.1 should be R2, 1.11.2 should be R3. I get that NMS isn't officially supported, but honestly, either do away with the versioned packages entirely or keep up with them properly. It's a single string change, it's not like it's prohibitively difficult.
2016-12-29 09:05:01 -05:00
Jikoo
f05110c9b8 Fix getOnlinePlayers call to support all versions
Moved IPlayerDataManager from api module to common module - it is not part of the API as there is no supported way to obtain an instance of it.
2016-12-22 09:55:51 -05:00
Jikoo
a41f89b011 Release any players held by a disabling plugin 2016-12-16 15:13:04 -05:00
Jikoo
d24827ffcb Allow plugins to indicate to OpenInv that a Player is in use
This allows API users to prevent issues caused by multiple different copies of the Player being loaded, such as #49. Multiple instances of the same player could be obtained by calling IOpenInv#loadPlayer, waiting for OpenInv to remove it from the cache, then calling the method again.
2016-12-14 19:49:18 -05:00
28 changed files with 319 additions and 13 deletions

View File

@@ -7,6 +7,7 @@ import com.lishid.openinv.internal.ISpecialPlayerInventory;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
/**
* Interface defining behavior for the OpenInv plugin.
@@ -150,4 +151,37 @@ public interface IOpenInv {
*/
public Player loadPlayer(final OfflinePlayer offline);
/**
* Mark a Player as in use by a Plugin to prevent it from being removed from the cache. Used to
* prevent issues with multiple copies of the same Player being loaded such as lishid#49.
* Changes made to loaded copies overwrite changes to the others when saved, leading to
* duplication bugs and more.
* <p>
* When finished with the Player object, be sure to call {@link #releasePlayer(Player, Plugin)}
* to prevent the cache from keeping it stored until the plugin is disabled.
* <p>
* When using a Player object from OpenInv, you must handle the Player coming online, replacing
* your Player reference with the Player from the PlayerJoinEvent. In addition, you must change
* any values in the Player to reflect any unsaved alterations to the existing Player which do
* not affect the inventory or ender chest contents.
* <p>
* OpenInv only saves player data when unloading a Player from the cache, and then only if
* {@link #disableSaving()} returns false. If you are making changes that OpenInv does not cause
* to persist when a Player logs in as noted above, it is suggested that you manually call
* {@link Player#saveData()} when releasing your reference to ensure your changes persist.
*
* @param player the Player
* @param plugin the Plugin holding the reference to the Player
*/
public void retainPlayer(Player player, Plugin plugin);
/**
* Mark a Player as no longer in use by a Plugin to allow OpenInv to remove it from the cache
* when eligible.
*
* @param player the Player
* @param plugin the Plugin no longer holding a reference to the Player
*/
public void releasePlayer(Player player, Plugin plugin);
}

View File

@@ -16,6 +16,8 @@
package com.lishid.openinv.internal;
import java.util.Collection;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
@@ -47,4 +49,11 @@ public interface IPlayerDataManager {
*/
public OfflinePlayer getPlayerByID(String identifier);
/**
* Gets a Collection of all Players currently online.
*
* @return the Collection of Players
*/
public Collection<? extends Player> getOnlinePlayers();
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_4_5;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_4_6;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_10_R1;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -157,7 +157,7 @@ public class AnySilentContainer implements IAnySilentContainer {
// Silent ender chest is pretty much API-only
if (silentchest && b.getType() == Material.ENDER_CHEST) {
p.openInventory(p.getEnderChest());
player.b(StatisticList.X);
player.b(StatisticList.getStatistic("stat.enderchestOpened"));
return true;
}
@@ -174,7 +174,7 @@ public class AnySilentContainer implements IAnySilentContainer {
InventoryEnderChest enderChest = player.getEnderChest();
enderChest.a((TileEntityEnderChest) tile);
player.openContainer(enderChest);
player.b(StatisticList.X);
player.b(StatisticList.getStatistic("stat.enderchestOpened"));
return true;
}
@@ -212,9 +212,9 @@ public class AnySilentContainer implements IAnySilentContainer {
}
if (blockChest.g == Type.BASIC) {
player.b(StatisticList.ac);
player.b(StatisticList.getStatistic("stat.chestOpened"));
} else if (blockChest.g == Type.TRAP) {
player.b(StatisticList.W);
player.b(StatisticList.getStatistic("stat.trappedChestTriggered"));
}
if (silentchest) {
@@ -223,7 +223,7 @@ public class AnySilentContainer implements IAnySilentContainer {
}
if (block instanceof BlockShulkerBox) {
player.b(StatisticList.ae);
player.b(StatisticList.getStatistic("stat.shulkerBoxOpened"));
if (silentchest && tile instanceof TileEntityShulkerBox) {
// Set value to current + 1. Ensures consistency later when resetting.

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_11_R1;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_4_R1;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -70,4 +73,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_5_R2;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_5_R3;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_6_R1;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_6_R2;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_6_R3;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -69,4 +72,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_7_R1;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -70,4 +73,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,9 @@
package com.lishid.openinv.internal.v1_7_R2;
import java.util.Arrays;
import java.util.Collection;
import com.lishid.openinv.internal.IPlayerDataManager;
import org.bukkit.Bukkit;
@@ -71,4 +74,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return player;
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -16,6 +16,8 @@
package com.lishid.openinv.internal.v1_7_R3;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -78,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Arrays.asList(Bukkit.getOnlinePlayers());
}
}

View File

@@ -17,6 +17,12 @@
<artifactId>openinvcommon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.7.10-R0.1-snapshot</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_7_R4;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -78,4 +79,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_8_R1;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_8_R2;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_8_R3;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_9_R1;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,7 @@
package com.lishid.openinv.internal.v1_9_R2;
import java.util.Collection;
import java.util.UUID;
import com.lishid.openinv.internal.IPlayerDataManager;
@@ -79,4 +80,9 @@ public class PlayerDataManager implements IPlayerDataManager {
}
}
@Override
public Collection<? extends Player> getOnlinePlayers() {
return Bukkit.getOnlinePlayers();
}
}

View File

@@ -16,6 +16,10 @@
package com.lishid.openinv;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -38,18 +42,23 @@ import com.lishid.openinv.internal.ISpecialPlayerInventory;
import com.lishid.openinv.listeners.InventoryClickListener;
import com.lishid.openinv.listeners.InventoryDragListener;
import com.lishid.openinv.listeners.PlayerListener;
import com.lishid.openinv.listeners.PluginListener;
import com.lishid.openinv.util.Cache;
import com.lishid.openinv.util.ConfigUpdater;
import com.lishid.openinv.util.Function;
import com.lishid.openinv.util.InternalAccessor;
import com.lishid.openinv.util.Permissions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
@@ -63,13 +72,16 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
private final Map<String, ISpecialPlayerInventory> inventories = new HashMap<String, ISpecialPlayerInventory>();
private final Map<String, ISpecialEnderChest> enderChests = new HashMap<String, ISpecialEnderChest>();
private final Multimap<String, Class<? extends Plugin>> pluginUsage = HashMultimap.create();
private final Cache<String, Player> playerCache = new Cache<String, Player>(300000L,
new Function<Player>() {
@Override
public boolean run(Player value) {
String key = playerLoader.getPlayerDataID(value);
return inventories.containsKey(key) && inventories.get(key).isInUse()
|| enderChests.containsKey(key) && enderChests.get(key).isInUse();
|| enderChests.containsKey(key) && enderChests.get(key).isInUse()
|| pluginUsage.containsKey(key);
}
},
new Function<Player>() {
@@ -127,6 +139,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
// 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);
@@ -134,10 +147,10 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
// Register commands to their executors
getCommand("openinv").setExecutor(new OpenInvPluginCommand(this));
getCommand("openender").setExecutor(new OpenEnderPluginCommand(this));
SearchInvPluginCommand searchInv = new SearchInvPluginCommand();
SearchInvPluginCommand searchInv = new SearchInvPluginCommand(this);
getCommand("searchinv").setExecutor(searchInv);
getCommand("searchender").setExecutor(searchInv);
getCommand("searchenchant").setExecutor(new SearchEnchantPluginCommand());
getCommand("searchenchant").setExecutor(new SearchEnchantPluginCommand(this));
getCommand("silentchest").setExecutor(new SilentChestPluginCommand(this));
getCommand("anychest").setExecutor(new AnyChestPluginCommand(this));
@@ -427,6 +440,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
return this.playerCache.get(key);
}
// TODO: wrap Player to ensure all methods can safely be called offline
Player loaded;
if (offline.isOnline()) {
@@ -479,6 +493,73 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
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<Player>) onlinePlayers;
}
return Arrays.asList((Player[]) onlinePlayers);
}
/**
* Method for handling a Player coming online.
*

View File

@@ -1,6 +1,7 @@
package com.lishid.openinv.commands;
import org.bukkit.Bukkit;
import com.lishid.openinv.OpenInv;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -19,6 +20,12 @@ import org.bukkit.inventory.meta.ItemMeta;
*/
public class SearchEnchantPluginCommand implements CommandExecutor {
private final OpenInv plugin;
public SearchEnchantPluginCommand(OpenInv plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0) {
@@ -45,7 +52,7 @@ public class SearchEnchantPluginCommand implements CommandExecutor {
}
StringBuilder players = new StringBuilder();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
for (Player player : plugin.getOnlinePlayers()) {
boolean flagInventory = containsEnchantment(player.getInventory(), enchant, level);
boolean flagEnder = containsEnchantment(player.getEnderChest(), enchant, level);

View File

@@ -16,7 +16,8 @@
package com.lishid.openinv.commands;
import org.bukkit.Bukkit;
import com.lishid.openinv.OpenInv;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
@@ -27,6 +28,12 @@ import org.bukkit.inventory.Inventory;
public class SearchInvPluginCommand implements CommandExecutor {
private final OpenInv plugin;
public SearchInvPluginCommand(OpenInv plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@@ -54,7 +61,7 @@ public class SearchInvPluginCommand implements CommandExecutor {
}
StringBuilder players = new StringBuilder();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
for (Player player : plugin.getOnlinePlayers()) {
Inventory inventory = command.getName().equals("searchinv") ? player.getInventory() : player.getEnderChest();
if (inventory.contains(material, count)) {
players.append(player.getName()).append(", ");

View File

@@ -0,0 +1,27 @@
package com.lishid.openinv.listeners;
import com.lishid.openinv.OpenInv;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
/**
* Listener for plugin-related events.
*
* @author Jikoo
*/
public class PluginListener implements Listener {
private final OpenInv plugin;
public PluginListener(OpenInv plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPluginDisable(PluginDisableEvent event) {
plugin.releaseAllPlayers(event.getPlugin());
}
}

View File

@@ -12,7 +12,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<openinv.version>3.0.3-SNAPSHOT</openinv.version>
<openinv.version>3.0.6-SNAPSHOT</openinv.version>
</properties>
<modules>