[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: |
![]() ![]() ![]() |
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. |