Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Option to disable offline inventory viewing #171

Closed
Combustible opened this issue Dec 3, 2020 · 7 comments
Closed

Enhancement: Option to disable offline inventory viewing #171

Combustible opened this issue Dec 3, 2020 · 7 comments

Comments

@Combustible
Copy link

We've got a relatively complicated data storage system on my server which redirects the player data storage to a database. So there are no files to store locally - this allows us to share player data across multiple worlds (the plugin we developed for this is https://github.com/TeamMonumenta/monumenta-redis-sync)

It took us a long time to track down an obscure inventory corruption bug, and eventually tracked it back to the way OpenInv switches a player to offline mode. What would happen is that a moderator would open a player's inventory on server 1, then they would transfer to server 2, change their inventory, and go back to server 1. From server 1's perspective, the player logs out, then logs back in - so openinv helpfully overwrites their inventory with the state from before (and thus losing any changes the player made on server 2).

We've been working around this by building our own OpenInv version with the following patch. It'd be nice if we had some config file option so we wouldn't need to build our own version for this. Totally understand if it's not worth your time - this is obviously a special case that will probably never effect many people. Just thought I'd ask.

+++ b/plugin/src/main/java/com/lishid/openinv/OpenInv.java
@@ -447,12 +447,23 @@ public class OpenInv extends JavaPlugin implements IOpenInv {
         // Replace stored player with our own version
         this.playerCache.put(key, this.accessor.getPlayerDataManager().inject(player));

+        /* Remove the cached entry if it exists */
+        this.playerCache.invalidate(key);
+
         if (this.inventories.containsKey(key)) {
-            this.inventories.get(key).setPlayerOffline();
+            Iterator<HumanEntity> iterator = this.inventories.remove(key).getBukkitInventory().getViewers().iterator();
+            while (iterator.hasNext()) {
+                HumanEntity human = iterator.next();
+                human.closeInventory();
+            }
         }

         if (this.enderChests.containsKey(key)) {
-            this.enderChests.get(key).setPlayerOffline();
+            Iterator<HumanEntity> iterator = this.enderChests.remove(key).getBukkitInventory().getViewers().iterator();
+            while (iterator.hasNext()) {
+                HumanEntity human = iterator.next();
+                human.closeInventory();
+            }
         }
     }
@Jikoo
Copy link
Collaborator

Jikoo commented Dec 3, 2020

I'm definitely interested in helping work around this case, but isn't it possible to work around already without patching OpenInv? I.E.:

@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
  closeAll(event.getPlayer().getInventory().getViewers());
  closeAll(event.getPlayer().getEnderChest().getViewers());
  OpenInv.getPlugin(OpenInv.class).unload(event.getPlayer());
}

private void closeAll(Iterable<HumanEntity> viewers) {
  Iterator<HumanEntity> iterator = viewers.iterator();
  while (iterator.hasNext()) {
    iterator.next().closeInventory();
  }
}

Deny moderators OpenInv.openoffline and voila, no offline access, right?

@Combustible
Copy link
Author

Hadn't thought of that - yeah, that does seem like it would work. I wish the permission wasn't needed though - because if anyone did want to use my redis sync plugin and openinv, that'd be something they'd have to do manually and if they forget they'd randomly lose data randomly for a long time before figuring out why. This was our problem - it wasn't at all clear that this was the interaction causing this, since it's quite rare to have someone's inventory opened when they log out. If I could solve it purely by "integrating" my plugin with the OpenInv API (the code snippet) then that would be perfect.

Could be as simple as an API method that says "disableOfflineViewing()"... but not sure if you think that's too ugly. Would only be a couple lines of code & no config file change though...

Actually, on second thought... I might not need to deny the permission. There's no player data for openinv to open - so I assume if the player file is missing, it just fails and doesn't open anything. Cool. I'll give this a try.

@Jikoo
Copy link
Collaborator

Jikoo commented Dec 12, 2020

Yeah, OpenInv shouldn't open a nonexistent player. Alternately, it should be possible to force users to not have permission to view offline via a PermissionAttachment if you're after maximum portability in a hurry - on login, just slap a new attachment with the node set to false on everyone.

I'm definitely still interested in implementing a cleaner solution on the OpenInv end, but I've been focused elsewhere and haven't really been working on this project much.

@Combustible
Copy link
Author

Hmm... No, this doesn't quite work, even though it seems like it should. Apparently getPlayer().getInventory().getViewers() is empty when I have an OpenInv viewer attached to it.

It looks like OpenInv's .getBukkitInventory().getViewers() is returning more things somehow. I don't really understand why this is happening, but it definitely is.

@Jikoo
Copy link
Collaborator

Jikoo commented Dec 14, 2020

Hm. I know Bukkit and NMS actually keep separate lists, probably has to do with it. I think we used to manage the Bukkit list but it ended up causing duplicate entries. Will definitely look into that Eventually(TM).

Jikoo added a commit to Jikoo/OpenInv that referenced this issue May 15, 2022
Fixes various permissions not being respected during login/logout with inventories already open. This will result in a performance hit for repeated open/closes - there will be significantly more disk I/O.

Closes lishid#171
Closes #56
Jikoo added a commit to Jikoo/OpenInv that referenced this issue Jun 7, 2022
Fixes various permissions not being respected during login/logout with inventories already open. This will result in a performance hit for repeated open/closes - there will be significantly more disk I/O.

Closes lishid#171
Closes #56
@Jikoo
Copy link
Collaborator

Jikoo commented Jun 8, 2022

@Jikoo Jikoo closed this as completed Jun 8, 2022
@Combustible
Copy link
Author

Just discovered this as I'm trying to rebase my ancient disabling patch onto OpenInv so I can update my server to 1.18.2. Hooray, thank you very much for implementing this! My one-patch fork can finally die :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants