The bug
After killing the dragon and exiting the end portal, all status effects are removed.
How to reproduce
Drink a potion/eat a golden apple
Enter the end
Kill the dragon
Make sure you have time remaining on the effects
Enter the exit portal and skip the credits
❌ "wake up" and all of the effects will be gone
Analysis
Code analysis by @unknown can be found in this comment.
Related issues
is duplicated by
relates to
Attachments
Comments


did you lose the effects or only the indication of the effects, see MC-3668 ?
I lost the indication of the effects and the effects themselves, I wasn't
moving nearly as fast.
Sounds like a duplicate of the bug mentioned by [OCD] Xavier Brown.
I'll look more closely for similar bugs next time.
Joseph Sirna
On Sun, Jan 6, 2013 at 12:04 PM, [Mod] Kumasasa (JIRA) <
I think this is not a duplicate of MC-3668, it mentions the effects are lost when entering through the portal spawned when killing the ender dragon at the end, the one I mentioned in the comments there, and Kumasasa told me it was another issue, that MC-3668 mentions about the effect animations. If I'm right, my issue (MC-11628) is a duplicate of this one, not of MC-3668.
If a mod can reopen this issue if I'm right with my comment above...

Reopened, since not a duplicate of (but related to) MC-3668
Added the 3 screenshots from MC-11628 plus 2 extra screenshots.
And this affects to Minecraft 1.5, and Minecraft 1.5.1
Added other 4 screenshots.
It was already reopened by Kumasasa @Tails.

Confirmed for 14w34b

Confirmed for 1.8-pre2.

Confirmed for
15w45a

Confirmed for
15w51b
The reason for this is that the player respawns when he leaves the end through the portal. Therefor a new player instance is created and most data is copied, however for example active potion effects are not.
Confirmed for 1.9 Full realese
confirmed for singleplayer
confirmed for 16w42a
confirmed for 1.11
Affects 1.13-pre6!
Confirmed for 1.13.1.

Confirmed for 19w09a

Confirmed for 1.14.4
Occurs in 1.15, 1.15.1, 1.15.2 also
Confirmed for 1.16 Pre-release 4
Confirmed for 1.16 Pre-release 5
Confirmed for 1.16-rc1
Confirmed for 1.16.2
Confirmed for 1.16.3-rc1
Can confirm 20w48a.

confirmed 21w03a
Can confirm in 21w05b.
Can confirm in 21w07a.
Can confirm in 21w15a.
Can confirm in 21w17a.

Can confirm in 21w18a.
Further, testing discovered MC-225055.

in 1.17 rc1
Can confirm in 1.17.1.
Can confirm in 1.18 experimental snapshot 2
@unknown, just to inform you, the 1.18 experimental snapshots are not supported on the bug tracker and this cannot be added as an affected version.

Can confirm in 21w39a
Time for a code analysis. I made a working fix for the bug using this analysis, so I can say 100% that this is the issue. Fix
All Code Analysis is done in 1.17.1 using Mojang Mappings
Explanation of the problem:
When the player travels from the end to the overworld, it does not use the normal teleportation code or dimension change code. The reason for this is because the player might be watching the credits, so instead the player is removed from all worlds and awaits for the client to send a packet saying it's done to the server. It does this whether you are seeing the credits or not.
The issue is with the code that does this:
net/minecraft/server/level/ServerPlayer.java - restoreFrom(ServerPlayer, boolean)
public void restoreFrom(ServerPlayer oldPlayer, boolean alive) {
...
if (alive) {
this.getInventory().replaceWith(oldPlayer.getInventory());
this.setHealth(oldPlayer.getHealth());
this.foodData = oldPlayer.foodData;
this.experienceLevel = oldPlayer.experienceLevel;
this.totalExperience = oldPlayer.totalExperience;
this.experienceProgress = oldPlayer.experienceProgress;
this.setScore(oldPlayer.getScore());
this.portalEntrancePos = oldPlayer.portalEntrancePos;
} else if (this.level.getGameRules().getBoolean(RULE_KEEPINVENTORY) || oldPlayer.isSpectator()) {
this.getInventory().replaceWith(oldPlayer.getInventory());
this.experienceLevel = oldPlayer.experienceLevel;
this.totalExperience = oldPlayer.totalExperience;
this.experienceProgress = oldPlayer.experienceProgress;
this.setScore(oldPlayer.getScore());
}
...
}
When you respawn using the end portal, it uses this function. Nothing else in the game uses restoreFrom(player,true)
where alive is set to true. So I am sure that everything that happens here, only happens for the end portal.
As you can see, everything inside of if (alive)
is what gets transferred from the old player instance in the end to the new player instance in the overworld. Although player status is kept in the variable: activeEffects
which it inherits from LivingEntity.java
So the fix is simply to add:
this.activeEffects.putAll(oldPlayer.activeEffects);
After: this.portalEntrancePos = oldPlayer.portalEntrancePos;
Although that's not all, after doing my testing there was another issue that happened. The effects do not instantly appear once you travel through, it takes a while. This is because like most other data, you need to tell the client about these changes. Here's where you can do that:
net/minecraft/server/players/PlayerList.java - respawn(ServerPlayer, boolean)
public ServerPlayer respawn(ServerPlayer oldPlayer, boolean ) {
...
ServerPlayer newPlayer = new ServerPlayer(this.server, newLevel, oldPlayer.getGameProfile());
...
newPlayer.restoreFrom(oldPlayer, alive); //This is where the other function is called from
...
LevelData levelData = lvt9.level.getLevelData();
newPlayer.connection.send(new ClientboundRespawnPacket(...));
newPlayer.connection.teleport(...);
newPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(...));
newPlayer.connection.send(new ClientboundChangeDifficultyPacket(...));
newPlayer.connection.send(new ClientboundSetExperiencePacket(...));
...
return newPlayer;
}
What you can notice from this code is that there are multiple newPlayer.connection.send()
happening here to update the client's information, what we need to do is add another one for the status effects.
Unfortunately, the status effects packet has not been modified in a long time and still only transfers one status effect at a time, unlike many of the newly upgraded packets which send all their info at once. So we need to send a packet for each effect until that is changed.
Here is how you would do this, you would simply add:
// player = newPlayer
player.activeEffects.forEach((_,eff) -> {
player.connection.send(new ClientboundUpdateMobEffectPacket(player.getId(), eff));
});
Right after the last connection.send
, which in this case is: newPlayer.connection.send(new ClientboundSetExperiencePacket(...));
That's it, now the effects are correctly transferred to the player when going from the overworld to the end & the client is updated so that they have the effects right before loading!

can confirm in 1.18.1
Can confirm in 1.18.2.

Affects 22w13a.

Affects 22w18a.
affects 1.19 pre 3

Present in 1.19-pre4.

Present in 1.19-pre5.

Present in 1.19-rc1.

Present in 1.19-rc2.
relates to MC-175210 and MCCE-1990
Present in 1.19 full release.
Can someone check if this bug affects 1.19.1 pre releases ?
Can confirm in 1.19.2.

Affects 23w05a.

It seems to only affect players not mobs with effects.
[media]
Affects 23w06a.

Affects 23w07a.

Affects 1.19.4 Pre-release 1.

Affects 1.19.4 Pre-release 3.

Affects 1.19.4 Pre-release 4.

Affects 1.19.4 Release Candidate 1.

Affects 1.19.4 Release Candidate 2.

Affects 1.19.4 Release Candidate 3.

Affects 23w12a.

Affects 23w13a.

Affects 23w14a.

Affects 23w16a.

Affects 23w17a.

Affects 23w18a.

Affects 1.20 Pre-release 1.

Affects 1.20 Pre-release 2.

Affects 1.20 Pre-release 4.

Affects 1.20 Pre-release 5.

Affects 1.20 Pre-release 6.

Affects 1.20 Pre-release 7.
Can confirm in 1.20.4
Can confirm in 24w06a
Can confirm in 24w14a

Affects 1.20.5 Release Candidate 2
Can confirm in 24w19b