mirror of
https://github.com/TotalFreedomMC/OpenInv.git
synced 2024-12-22 16:05:03 +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.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);
|
||||
|
||||
}
|
||||
|
|
|
@ -44,12 +44,16 @@ 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 +67,17 @@ 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>();
|
||||
// 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,
|
||||
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>() {
|
||||
|
@ -427,6 +435,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 +488,34 @@ 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for handling a Player coming online.
|
||||
*
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -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.4-SNAPSHOT</openinv.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
|
Loading…
Reference in a new issue