diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java index 14b27eaaf7..84703b5d17 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java @@ -11,16 +11,28 @@ import org.jetbrains.annotations.Nullable; public class PlayerQuitEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); private net.kyori.adventure.text.Component quitMessage; // Paper + private final QuitReason reason; // Paper @Deprecated // Paper public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage) { + // Paper start + this(who, quitMessage, null); + } + @Deprecated // Paper + public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage, @Nullable QuitReason quitReason) { super(who); this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper + this.reason = quitReason == null ? QuitReason.DISCONNECTED : quitReason; } // Paper start + @Deprecated public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage) { + this(who, quitMessage, null); + } + public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage, @Nullable QuitReason quitReason) { super(who); this.quitMessage = quitMessage; + this.reason = quitReason == null ? QuitReason.DISCONNECTED : quitReason; } /** @@ -75,4 +87,39 @@ public class PlayerQuitEvent extends PlayerEvent { public static HandlerList getHandlerList() { return handlers; } + + // Paper start + @NotNull + public QuitReason getReason() { + return this.reason; + } + + public enum QuitReason { + /** + * The player left on their own behalf. + *
+ * This does not mean they pressed the disconnect button in their client, but rather that the client severed the + * connection themselves. This may occur if no keep-alive packet is received on their side, among other things. + */ + DISCONNECTED, + + /** + * The player was kicked from the server. + */ + KICKED, + + /** + * The player has timed out. + */ + TIMED_OUT, + + /** + * The player's connection has entered an erroneous state. + *
+ * Reasons for this may include invalid packets, invalid data, and uncaught exceptions in the packet handler, + * among others. + */ + ERRONEOUS_STATE, + } + // Paper end }