Skip to content

PlayerTeleportEvent called after PlayerQuitEvent when player is inside vehicle. #13516

@WouterGritter

Description

@WouterGritter

Expected behavior

PlayerTeleportEvent should not be called after PlayerQuitEvent when a player leaves the server while inside a vehicle (e.g. boat).

This event is called when the Minecraft server teleports a player that is inside a vehicle while leaving the server, after Paper has already called PlayerQuitEvent.

Observed/Actual behavior

As the title says, when a player is inside a vehicle (e.g. a boat) and quits, a dangling PlayerTeleportEvent is called after PlayerQuitEvent has already been called. This might not be a bug/incompatibility, but this also might not be the behavior plugin developers expect.

Stacktrace for the PlayerTeleportEvent called after PlayerQuitEvent below. Note that the IllegalStateException exception is generated internally in the plugin, which only ever occurs if PlayerQuitEvent had been called before PlayerTeleportEvent.

[12:33:18 ERROR]: Could not pass event PlayerTeleportEvent to <plugin> v1.0.0
java.lang.IllegalStateException: <plugin generated message>
        at <plugin>-1.0-SNAPSHOT.jar//<plugin method> ~[?:?]
        at <plugin>-1.0-SNAPSHOT.jar//<plugin class>.onPlayerTeleportEvent(<plugin class>.java:117) ~[?:?]
        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.11-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[paper-api-1.21.11-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.11-R0.1-SNAPSHOT.jar:?]
        at net.minecraft.server.network.ServerGamePacketListenerImpl.teleport(ServerGamePacketListenerImpl.java:1851) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.level.ServerPlayer.teleportTo(ServerPlayer.java:2245) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.level.ServerPlayer.dismountTo(ServerPlayer.java:2234) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.world.entity.LivingEntity.dismountVehicle(LivingEntity.java:2955) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.world.entity.LivingEntity.stopRiding(LivingEntity.java:3923) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.world.entity.Entity.stopRiding(Entity.java:3328) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.players.PlayerList.remove(PlayerList.java:471) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.players.PlayerList.remove(PlayerList.java:430) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.network.ServerGamePacketListenerImpl.removePlayerFromWorld(ServerGamePacketListenerImpl.java:2259) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.network.ServerGamePacketListenerImpl.onDisconnect(ServerGamePacketListenerImpl.java:2237) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.network.Connection.handleDisconnection(Connection.java:820) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.network.ServerConnectionListener.tick(ServerConnectionListener.java:244) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.tickConnection(MinecraftServer.java:1872) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.dedicated.DedicatedServer.tickConnection(DedicatedServer.java:549) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1835) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1613) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.dedicated.DedicatedServer.tickServer(DedicatedServer.java:427) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.processPacketsAndTick(MinecraftServer.java:1669) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1337) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at net.minecraft.server.MinecraftServer.lambda$spin$2(MinecraftServer.java:388) ~[paper-1.21.11.jar:1.21.11-69-94d0c97]
        at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]

Steps/models to reproduce

Inside a Paper plugin, create a Listener that:

  • Contains a Set<Player> seenPlayers;
  • Listens for PlayerJoinEvent and adds the player to the set
  • Listens for PlayerQuitEvent and removes the player from the set
  • Listens for PlayerTeleportEvent and throw if PlayerTeleportEvent#getPlayer is not contained in seenPlayers
  • Join the server, get inside a boat and quit

Plugin and Datapack List

n/a

Paper version

> version
[12:44:32 INFO]: Checking version, please wait...
[12:44:32 INFO]: This server is running Paper version 1.21.11-69-main@94d0c97 (2025-12-30T20:33:30Z) (Implementing API version 1.21.11-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.10-115-af06383 (MC: 1.21.10)

Other

If I am mistaken and "dangling" player events may be called after PlayerQuitEvent has been called, I think the javadoc should mention this.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions