mirror of
https://github.com/TotalFreedomMC/OpenInv.git
synced 2024-12-23 00:15:08 +00:00
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.
This commit is contained in:
parent
802ce28103
commit
d24827ffcb
3 changed files with 73 additions and 2 deletions
|
@ -7,6 +7,7 @@ import com.lishid.openinv.internal.ISpecialPlayerInventory;
|
||||||
|
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface defining behavior for the OpenInv plugin.
|
* Interface defining behavior for the OpenInv plugin.
|
||||||
|
@ -150,4 +151,37 @@ public interface IOpenInv {
|
||||||
*/
|
*/
|
||||||
public Player loadPlayer(final OfflinePlayer offline);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,12 +44,16 @@ import com.lishid.openinv.util.Function;
|
||||||
import com.lishid.openinv.util.InternalAccessor;
|
import com.lishid.openinv.util.InternalAccessor;
|
||||||
import com.lishid.openinv.util.Permissions;
|
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.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
@ -63,13 +67,17 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
||||||
|
|
||||||
private final Map<String, ISpecialPlayerInventory> inventories = new HashMap<String, ISpecialPlayerInventory>();
|
private final Map<String, ISpecialPlayerInventory> inventories = new HashMap<String, ISpecialPlayerInventory>();
|
||||||
private final Map<String, ISpecialEnderChest> enderChests = new HashMap<String, ISpecialEnderChest>();
|
private final Map<String, ISpecialEnderChest> enderChests = new HashMap<String, ISpecialEnderChest>();
|
||||||
|
// TODO: handle plugin unload
|
||||||
|
private final Multimap<String, Class<? extends Plugin>> pluginUsage = HashMultimap.create();
|
||||||
|
|
||||||
private final Cache<String, Player> playerCache = new Cache<String, Player>(300000L,
|
private final Cache<String, Player> playerCache = new Cache<String, Player>(300000L,
|
||||||
new Function<Player>() {
|
new Function<Player>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean run(Player value) {
|
public boolean run(Player value) {
|
||||||
String key = playerLoader.getPlayerDataID(value);
|
String key = playerLoader.getPlayerDataID(value);
|
||||||
return inventories.containsKey(key) && inventories.get(key).isInUse()
|
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>() {
|
new Function<Player>() {
|
||||||
|
@ -427,6 +435,7 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
||||||
return this.playerCache.get(key);
|
return this.playerCache.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: wrap Player to ensure all methods can safely be called offline
|
||||||
Player loaded;
|
Player loaded;
|
||||||
|
|
||||||
if (offline.isOnline()) {
|
if (offline.isOnline()) {
|
||||||
|
@ -479,6 +488,34 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
|
||||||
return 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());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method for handling a Player coming online.
|
* Method for handling a Player coming online.
|
||||||
*
|
*
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<openinv.version>3.0.3-SNAPSHOT</openinv.version>
|
<openinv.version>3.0.4-SNAPSHOT</openinv.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|
Loading…
Reference in a new issue