diff --git a/api/src/main/java/com/lishid/openinv/IOpenInv.java b/api/src/main/java/com/lishid/openinv/IOpenInv.java index 28514fc..775a63b 100644 --- a/api/src/main/java/com/lishid/openinv/IOpenInv.java +++ b/api/src/main/java/com/lishid/openinv/IOpenInv.java @@ -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. + *
+ * 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. + *
+ * 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. + *
+ * 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);
+
}
diff --git a/plugin/plugin-core/src/main/java/com/lishid/openinv/OpenInv.java b/plugin/plugin-core/src/main/java/com/lishid/openinv/OpenInv.java
index 60f4733..334e5cc 100644
--- a/plugin/plugin-core/src/main/java/com/lishid/openinv/OpenInv.java
+++ b/plugin/plugin-core/src/main/java/com/lishid/openinv/OpenInv.java
@@ -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