Paper icon indicating copy to clipboard operation
Paper copied to clipboard

EXP not correctly updated when using an anvil

Open EBro912 opened this issue 4 years ago • 4 comments

Expected behavior

On my server, we use a plugin that allows players to store experience in ender chests. Data for players is retrieved via getTotalExperience(), and given/taken via giveExp() (negative values for take). A player can deposit their experience and withdraw their experience, and the exp is stored as whole numbers between transactions, just like in Vanilla Minecraft. So if a player were to use an anvil, lose a few levels, and then go deposit their experience, the amount given to the plugin should be equal to their current total experience amount.

Observed/Actual behavior

When a player uses an anvil, their level is updated accordingly. However, on the server side, this data is not updated when removing levels from the player. This can be observed by a player using an anvil, and then depositing their exp, which will deposit the amount of experience before the anvil instead of the actual current amount.

Steps/models to reproduce

  1. Player has 8 levels, XP bar progress doesn't matter
  2. Player uses an anvil and loses X levels.
  3. Player deposits all experience into an Ender Chest. Note that the plugin responds that Player has 8 levels worth of experience points.
  4. Player withdraws all experience from the Ender Chest.
  5. Player will be back at 8 levels, instead of X.

Plugin list

ExpStorage (custom)

Paper version

[22:40:23 INFO]: Checking version, please wait... [22:40:24 INFO]: This server is running Paper version git-Paper-124 (MC: 1.17.1) (Implementing API version 1.17.1-R0.1-SNAPSHOT) (Git: 170382f) You are running the latest version Previous version: git-Paper-119 (MC: 1.17.1)

Agreements

  • [X] I am running the latest version of Paper available from https://papermc.io/downloads.
  • [X] I have searched for and ensured there isn't already an open issue regarding this.
  • [X] My version of Minecraft is supported by Paper.

Other

I have already confirmed the plugin is not the culprit, because the plugin actually suffered the same bug when trying to give and take whole levels to/from players. Also, the plugin has no interaction with anvils whatsoever. The reason there is only one plugin listed is because I tested it on a test server with no other plugins and the bug persisted.

EBro912 avatar Jul 23 '21 02:07 EBro912

I looked at the Paper server code a bit and the bug appears to be in Player#giveExperienceLevels. Things like anvils use this (see AnvilMenu#onTake. I believe this method is just changing the player's level but NOT the total experience. Player#giveTotalExperience works as expected because it first updates the total experience then the level, but using giveExperienceLevels directly does not work, breaking minecraft functions and the API.

UnknownSilicon avatar Jul 23 '21 19:07 UnknownSilicon

Does this happen in vanilla then too?

(I mean the underlying issue, I understand you cant replicate plugin behavior in vanilla)

I just don't see where cb, spigot, or paper modifies what giveExperienceLevels does.

Machine-Maker avatar Jul 23 '21 22:07 Machine-Maker

I just tested it. It's kind of hard to test the same way since the plugin we used made it easier to test the getTotalExperience method. I think it's related to/is this bug https://bugs.mojang.com/browse/MC-118008

UnknownSilicon avatar Jul 23 '21 23:07 UnknownSilicon

Ok turns out this seems to be more of a problem of misleading documentation. From what I understand, getTotalExperience is the total experience a player has collected since they last died (the score when a player dies). Setting the level isn't suppose to update total experience. All interaction with exp should probably be done with get/giveLevels and get/giveExp. I'm going to go add an API patch that has a more useful method for this.

UnknownSilicon avatar Jul 24 '21 02:07 UnknownSilicon