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

Data not stored / duplication glitch #40

Closed
Kakifrucht opened this issue Mar 22, 2016 · 35 comments
Closed

Data not stored / duplication glitch #40

Kakifrucht opened this issue Mar 22, 2016 · 35 comments

Comments

@Kakifrucht
Copy link

Finally found it. Was driving me nuts figuring this out.
Once you open a players inventory and thus the player.dat file won't be saved properly. When the player logs out, whatever he does in the meantime, will result in keeping the data on login that was stored before the player logged in. This can be used to duplicate entire inventories. You don't even have to have inventory editing permissions, viewing is enough.

To reproduce:

  1. Spec players inv, close it
  2. Teleport him away, do something with him, log out, move items from your inventory into a chest to dupe
  3. On login, his inventory and location will be restored to the state it had before his last login.

This issue existed a very long time, I just never figured out where it came from. Right now I'm on spigot 1.9. I was able to reproduce this on a empty Spigot with only Openinv installed. I wonder how nobody noticed this already.

@EvilOlaf
Copy link

This also means you have to own permissions to view other players inventories, right?

@Kakifrucht
Copy link
Author

Yes

@EvilOlaf
Copy link

Okey, so actually only team mates might be able to use this glitch.
Thank you very much for your investigation and sharing your results.

@Kakifrucht
Copy link
Author

If you only allow your staff to use it, you are quite safe, however lots of servers give out this permission to players.

@EvilOlaf
Copy link

Honestly I see no reason why....

@Kakifrucht
Copy link
Author

Donator perk ;)

@EvilOlaf
Copy link

This would probably the last thing I would grant for a donation...if I would accept donations or similar at all :P

@darkarrow
Copy link

I tested this on a test server and put stuff in my inventory then opened it, removed everything then left and when I came back the stuff I removed was back. Then I did the same thing but waiting a minute before leaving with the same result. However, waiting 5 minutes before leaving it actually saved the inventory properly and I didn't have the items that were supposed to be gone. But as said previously if players can use the command it is a pretty bad bug. Is this in the process of getting fixed or is it being investigated or something?

@EvilOlaf
Copy link

I guess so as @ShadowRanger added a label ;)

@Kakifrucht
Copy link
Author

This propably requires fundamental internal changes. Maybe two technical invsee's, one for online and the other for offline players? Like Essentials online player /invsee, when the player is online and only use the file fetch invsee when the player is offline.

@ShadowRanger
Copy link
Collaborator

I've been a bit busy lately so haven't had a chance to look into this. However, I will try and look into it as soon as I can. Thanks for letting us know of this issue.

@RoboMWM
Copy link

RoboMWM commented Apr 1, 2016

Once you open a players inventory and thus the player.dat file won't be saved properly.

Could you rephrase this, not sure what you're trying to say here.

Teleport him away, do something with him

I'm confused what you mean by this.

I'm just trying to understand what this bug is, since I use OpenInv purely as an admin, informative plugin (I don't edit inventories via it, and only I can use it). Is this scenario affected as well?

@Kakifrucht
Copy link
Author

Yes, it is. Once you open/view a players inventory while he is online this bug will affect the spectated player. For instance if the player has a full inventory, you view his inventory with /openinv, then he moves all his stuff out of his inventory into a chest and relogs he will still have everything he had before the server last saved chached player.dat's onto hard disk. This may be hier initial login state or the state after a save-all.

@RoboMWM
Copy link

RoboMWM commented Apr 1, 2016

So does the player move stuff out of inventory into a chest while you're viewing, or after you've viewed the inventory?

@Kakifrucht
Copy link
Author

Doesn't matter afaik.
But like @darkarrow stated, this only seems to happen until after 5 minutes of closing the players inventory, if he stays on longer than that it will be fine.

@cbarber
Copy link

cbarber commented Apr 10, 2016

Added pull request that fixes this issue: #41

Jikoo added a commit to Jikoo/OpenInv that referenced this issue Apr 11, 2016
@Jikoo
Copy link
Collaborator

Jikoo commented Apr 11, 2016

I was unable to reproduce this on my fork using the steps outlined, however, I could replicate pretty much the same issue with the following steps:

  1. Open player inventory, player can be online or offline.
  2. Log player out and back in
  3. Have player make any inventory modifications and log out - dump items, etc. This is where the issue is - when a player comes back online, their inventory is no longer tied to the inventory being viewed.
  4. Close open inventory to set viewed inventory's contents to player's current
  5. Log back in to old inventory

The root of the issue is that SpecialPlayerInventory#playerOnline does not update PlayerInventory.player or SpecialPlayerInventory.owner. The same sort of applies to ender chests, though they don't suffer a duplication or desync bug because of it.

I do not believe #41 addresses the underlying issue yet, it just reduces useless saves.

@Kakifrucht
Copy link
Author

@Jikoo I tried reproducing with your given steps but couldn't.

Does your fork fix this issue already?

@Jikoo
Copy link
Collaborator

Jikoo commented Apr 11, 2016

Yeah, I fixed my fork today. I diverged back when 1.8 came out because lookups were horrible, so I'm not too surprised there are differences in how it manifests, but the issue itself extended back all the way to pre-versioned-packaging. Kind of amazing that it had never been noticed or fixed before, nice spot.

@cbarber
Copy link

cbarber commented Apr 12, 2016

@Jikoo, #41 resets the open inventory to the player's inventory on login, reverting any changes but keeping inventories consistent in their saves. I tested all paths of login/logout of the players interacting in the inventory. I did not test a third (it does not look like that is intended to work in the command method).

You're right about the proper fix, however, SpecialPlayerInventory passes player/owner handles to its super constructor. You would need to close the current instance and create a new instance to make sure all of the internals are set correctly and hopefully (more) future proof. That would be a much larger overhaul.

@ShadowRanger
Copy link
Collaborator

I've just merged a pull request of my fork which contains cbarber's fix for this issue as well as a few other changes which are listed in the pull request. I will release the updated version of this plugin on BukkitDev within the next couple of days. If anyone has any other issues or changes they would like to put forward before I do so, please let me know. Thanks.

@cbarber
Copy link

cbarber commented Apr 14, 2016

I was thinking about this more, and the bug will still exist between player/player interactions.

  • Player A opens Player B's inventory while player B is offline.
  • Player A moves items out of the inventory to another storage.
  • Player B signs on. The open inventory is reverted to the current .dat file.

I think the correct way to handle a player signing on is to clone the current contents to their inventory, close the open inventory, and open a new inventory using the current player's handle (passing it down to super).

[Edit] - "player B is offline" not A.

@Kakifrucht
Copy link
Author

Yeah, noticed that behaviour with your fix too, @Jikoo's implementation is fine however.

@Jikoo
Copy link
Collaborator

Jikoo commented Apr 14, 2016

I know @cbarber's argument against my fix was that we don't know that the internals are all set properly, however, since we already need to read a little NMS for every update, I don't think it's too outlandish to decompile PlayerInventory and see that the constructor populates the fields player, g, the inventory arrays, and a couple of other minor things we don't need to mess with. I did have to correct my method for setting item arrays with reflection to include the field g, but that would have been a bug from the release of 1.9 anyway. Beyond that, setting player to the new EntityPlayer and setting the player's item arrays works like a charm.
For your consideration, here's how I set item arrays and set the owner online to correct the existing inventory.

Edit: I guess this fix is becoming more an issue of "do you continue to use a lot of NMS or do you slowly work towards a more API-based solution." It's up to the repo owners I suppose, it's certainly possible to achieve either way.

@ShadowRanger
Copy link
Collaborator

I don't mind how the fix is achieved, just as long as it resolves the issue properly. I can't seem to tell what the argument is against Jikoo's way of doing it if it works properly and fixes the issue though?

@cbarber
Copy link

cbarber commented Apr 15, 2016

The argument is tighter coupling between PlayerInventory's implementation and SpecialPlayerInventory. The consequence of this is there is a higher chance future changes to PlayerInventory will break SpecialPlayerInventory. The importance of that risk is up to the maintainers as they'll be the ones to decompile and test after updates. If you don't mind, run with it.

@JohOply
Copy link

JohOply commented Apr 17, 2016

Same bug : in case where admin see his self enderchest

  1. Check enderchest (/oe)
  2. Change something in your inventory
  3. Logout, then login
  4. Enderchest is empty, inventory rollbacked, location not saved

in case where admin see his self inventory

  1. Check inventory (/oi)
  2. Change something in your inventory, change world...
  3. Logout, then login
  4. Inventory save, location not saved

@PseudoKnight
Copy link

Could this be related to how 1.9 doesn't save inventories on player logout anymore? It used to but doesn't anymore. This is why after 5 minutes the problem resolves itself, because that's probably when the save interval occurs.

@Kakifrucht
Copy link
Author

@PseudoKnight no, you can reproduce this on any version. It happened well before 1.9 aswell.

@Johandrex
Copy link

Jesus christ how haven't this been fixed yet?

@Kakifrucht
Copy link
Author

Use @Jikoo's fork.

@Johandrex
Copy link

@Kakifrucht ah thanks, I should've read the earlier posts lol.

@ShadowRanger
Copy link
Collaborator

Alright so I've finally gotten around to being able to implement Jikoo's fix for this issue. Sorry for taking so long. @Jikoo if you could please check over my pull request containing your fixes before I merge it, it would be much appreciated. You can view it here: https://github.com/ShadowRanger/OpenInv/commit/ba9396ad5ca39b27d5e5b883f1d7ffa144394198 Please let me know if I have missed anything or made any mistakes. Thanks.

@Jikoo
Copy link
Collaborator

Jikoo commented May 4, 2016

I'll take a look tomorrow, unfortunately right now it's 1am for me and I have work at 7:30. Great life choices were made today.

@Jikoo
Copy link
Collaborator

Jikoo commented May 4, 2016

Looks good to me, can't see anything wrong. I see you also opted to include the feature to reduce duplicate saves 👍

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

10 participants