[SPIGOT-5285] Exception when players teleport to a different world just after they got hit by an entity Created: 25/Aug/19  Updated: 01/Mar/22  Resolved: 01/Mar/22

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Tamás Ádám Assignee: Unassigned
Resolution: Done Votes: 1
Labels: None

Attachments: Text File 2019-08-25-8.log     PNG File 2019-08-25_10.39.37.png     File EntityDamageTest.jar    
Version: git-Spigot-798ea6a-b2bcde8 (MC: 1.14.4) (Implementing API version 1.14.4-R0.1-SNAPSHOT)
Guidelines Read: Yes

 Description   

It's a bit complicated, but I'll try my best to explain it. So when player is hit by an arrow or a projectile of some kind and in that moment he teleports to a different world, an exception will be thrown. But why does this matter? I have a minigame plugin where players can join arenas and fight with each other. When one of them dies, the plugin teleports him back to the location where he joined from. If the damage before the teleportation was caused by another player (so not by a projectile whose shooter was the player, but an item or even bare hand) it works just fine. But in other cases the player gets stuck in "nothing".

 

You can reproduce this using the code below:

 

@EventHandler
public void onDamage(EntityDamageByEntityEvent event){
    if(!(event.getEntity() instanceof Player)){
        return;
    }
    
    Player player = (Player)event.getEntity();
    if(player.getHealth() - event.getDamage() < 0.0D){
        System.out.println("Cancelling event...");
        System.out.println("Damage cause: " + event.getDamager().toString());
        event.setCancelled(true);
        Location targetLoc = new Location(Bukkit.getWorld("world_nether"),    0.0D, 128.0D, 0.0D);
        player.teleport(targetLoc);
    }
}

The reason why I'm teleporting him to the nether is to simulate that he's joined from a different world (which happens almost all the time). So the code above generates an exception like this (when the damager is an arrow for instance):

 

[11:25:06] [Server thread/ERROR]: Could not pass event EntityDamageByEntityEvent to EntityDamageTest v0.0org.bukkit.event.EventException: null    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:320) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:529) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:514) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.callEvent(CraftEventFactory.java:220) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.callEntityDamageEvent(CraftEventFactory.java:892) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.handleEntityDamageEvent(CraftEventFactory.java:791) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory.handleLivingEntityDamageEvent(CraftEventFactory.java:924) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityLiving.damageEntity0(EntityLiving.java:1620) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityHuman.damageEntity0(EntityHuman.java:847) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityLiving.damageEntity(EntityLiving.java:1073) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityHuman.damageEntity(EntityHuman.java:770) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityPlayer.damageEntity(EntityPlayer.java:674) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityArrow.a(EntityArrow.java:365) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityArrow.a(EntityArrow.java:277) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityArrow.tick(EntityArrow.java:188) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.EntityTippedArrow.tick(EntityTippedArrow.java:87) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.WorldServer.entityJoinedWorld(WorldServer.java:568) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.World.a(World.java:745) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.WorldServer.doTick(WorldServer.java:344) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.MinecraftServer.b(MinecraftServer.java:1068) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.DedicatedServer.b(DedicatedServer.java:393) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.MinecraftServer.a(MinecraftServer.java:970) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.MinecraftServer.run(MinecraftServer.java:815) [spigot.jar:git-Spigot-798ea6a-b2bcde8]    at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]Caused by: java.lang.IllegalStateException: Removing entity while ticking!    at net.minecraft.server.v1_14_R1.WorldServer.removeEntity(WorldServer.java:1116) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.WorldServer.removePlayer(WorldServer.java:1135) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at net.minecraft.server.v1_14_R1.PlayerList.moveToWorld(PlayerList.java:568) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer.teleport(CraftPlayer.java:667) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity.teleport(CraftEntity.java:451) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    at test.Test.onDamage(Test.java:38) ~[?:?]    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:316) ~[spigot.jar:git-Spigot-798ea6a-b2bcde8]    ... 24 more

If I don't check the health just teleport the player on damage, I get the same result. This solution to teleport players when they get damaged worked on 1.13 perfectly, so when I first saw the error, I thought I messed up something (which may be the case), but I wasn't able to figure out what the problem might be and how to solve it.

 

I should also mension that those handy plugins, that remove the deathscreen by respawning dead players instantly, cause the same issue when the damager was an arrow, or potion, or fireball.

 

Also, I attached my server log a screenshot and the testplugin as well, in case you need it for further testing.



 Comments   
Comment by Marvin Rieple [ 01/Mar/22 ]

Was able to reproduce in 1.14.4 and 1.16.5 but no longer in 1.17.1 and 1.18.2. It works as expected in 1.18.2.

Comment by Tamás Ádám [ 25/Aug/19 ]

This wasn't an issue in 1.13 so i guess something has changed.

Comment by Duy Anh [ 25/Aug/19 ]

lel I don't think Spigot can fix that. There should be a reason why people can not "Removing entity while ticking!". You can edit your code to teleport the dead player after a tick (use BukkitRunnable#runTask). So the exception may not throw.
And about the way you are using to listen for a death, EntityDamageByEntityEvent is inefficient. In this case, I would use PlayerDeathEvent.

Generated at Tue Apr 22 03:12:14 UTC 2025 using Jira 10.3.5#10030005-sha1:190c783f2bd6c69cd5accdb70f97e48812a78d14.