From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 15 May 2021 20:30:45 -0700 Subject: [PATCH] Add PlayerKickEvent causes diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java index dbcf183483766f39334d7f7e8336033906625f3f..300929a406905f5ff1ede664d5b99fb0938d4d2e 100644 --- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java @@ -40,14 +40,14 @@ public class SignedMessageChain { if (signature == null) { throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.MISSING_PROFILE_KEY); } else if (playerPublicKey.data().hasExpired()) { - throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.EXPIRED_PROFILE_KEY); + throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.EXPIRED_PROFILE_KEY, org.bukkit.event.player.PlayerKickEvent.Cause.EXPIRED_PROFILE_PUBLIC_KEY); // Paper - kick event causes } else { SignedMessageLink signedMessageLink = SignedMessageChain.this.nextLink; if (signedMessageLink == null) { throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN); } else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { this.setChainBroken(); - throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT); + throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes } else { SignedMessageChain.this.lastTimeStamp = body.timeStamp(); PlayerChatMessage playerChatMessage = new PlayerChatMessage(signedMessageLink, signature, body, null, FilterMask.PASS_THROUGH); @@ -80,8 +80,15 @@ public class SignedMessageChain { static final Component INVALID_SIGNATURE = Component.translatable("chat.disabled.invalid_signature"); static final Component OUT_OF_ORDER_CHAT = Component.translatable("chat.disabled.out_of_order_chat"); - public DecodeException(Component message) { + // Paper start + public final org.bukkit.event.player.PlayerKickEvent.Cause kickCause; + public DecodeException(Component message, org.bukkit.event.player.PlayerKickEvent.Cause event) { super(message); + this.kickCause = event; + } + // Paper end + public DecodeException(Component message) { + this(message, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); // Paper } } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 42429684bd732d0094ad0db346d2a656871aabff..7e1b74547c691de5fa2fac6e515394e267c57036 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2368,7 +2368,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Component.translatable("commands.kick.success", serverPlayer.getDisplayName(), reason), true); i++; } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java index f8ae8c8eff73e4e87eb34d0f2635517f1688a6f1..59d20fd62e850a38380d877cef95ed69cb46ecbd 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java @@ -63,8 +63,8 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } @Override - public void kickPlayer(Component reason) { - this.disconnect(reason); + public void kickPlayer(Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause) { // Paper - kick event causes + this.disconnect(reason, cause); // Paper - kick event causes } // CraftBukkit end private static final Logger LOGGER = LogUtils.getLogger(); @@ -140,7 +140,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } else if (!this.isSingleplayerOwner()) { // Paper start - This needs to be handled on the main thread for plugins server.submit(() -> { - this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE); + this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause }); // Paper end - This needs to be handled on the main thread for plugins } @@ -176,7 +176,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex); - this.disconnect(Component.literal("Invalid payload REGISTER!")); + this.disconnect(Component.literal("Invalid payload REGISTER!"), PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { try { @@ -186,7 +186,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t unregister custom payload", ex); - this.disconnect(Component.literal("Invalid payload UNREGISTER!")); + this.disconnect(Component.literal("Invalid payload UNREGISTER!"), PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } } else { try { @@ -204,7 +204,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data); } catch (Exception ex) { ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex); - this.disconnect(Component.literal("Invalid custom payload!")); + this.disconnect(Component.literal("Invalid custom payload!"), PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause } } @@ -220,7 +220,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack PacketUtils.ensureRunningOnSameThread(packet, this, (BlockableEventLoop) this.server); if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) { ServerCommonPacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id()); - this.disconnect((Component) Component.translatable("multiplayer.requiredTexturePrompt.disconnect")); + this.disconnect((Component) Component.translatable("multiplayer.requiredTexturePrompt.disconnect"), PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION); // Paper - kick event cause } // Paper start - adventure pack callbacks // call the callbacks before the previously-existing event so the event has final say @@ -250,7 +250,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack return; } // CraftBukkit end - this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY); + this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY, PlayerKickEvent.Cause.INVALID_COOKIE); // Paper - kick event cause } protected void keepConnectionAlive() { @@ -262,7 +262,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // Paper - use vanilla's 15000L between keep alive packets if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // Paper - check keepalive limit, don't fire if already disconnected - this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE); + this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause } else if (this.checkIfClosed(currentTime)) { // Paper this.keepAlivePending = true; this.keepAliveTime = currentTime; @@ -278,7 +278,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack private boolean checkIfClosed(long time) { if (this.closed) { if (time - this.closedListenerTime >= 15000L) { - this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE); + this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE, PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause } return false; @@ -330,15 +330,25 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack // Paper start - adventure public void disconnect(final net.kyori.adventure.text.Component reason) { - this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(reason)); + this.disconnect(reason, PlayerKickEvent.Cause.UNKNOWN); + } + public void disconnect(final net.kyori.adventure.text.Component reason, PlayerKickEvent.Cause cause) { + this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(reason), cause); + // Paper end - kick event causes } // Paper end - adventure + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - kick event causes public void disconnect(Component reason) { - this.disconnect(new DisconnectionDetails(reason)); + // Paper start - kick event causes + this.disconnect(reason, PlayerKickEvent.Cause.UNKNOWN); + } + public void disconnect(final Component reason, PlayerKickEvent.Cause cause) { + this.disconnect(new DisconnectionDetails(reason), cause); + // Paper end - kick event causes } - public void disconnect(DisconnectionDetails disconnectionInfo) { + public void disconnect(DisconnectionDetails disconnectionInfo, PlayerKickEvent.Cause cause) { // Paper - kick event cause // CraftBukkit start - fire PlayerKickEvent if (this.processedDisconnect) { return; @@ -347,7 +357,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack Waitable waitable = new Waitable() { @Override protected Object evaluate() { - ServerCommonPacketListenerImpl.this.disconnect(disconnectionInfo); + ServerCommonPacketListenerImpl.this.disconnect(disconnectionInfo, cause); // Paper - kick event causes return null; } }; @@ -366,7 +376,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack net.kyori.adventure.text.Component leaveMessage = net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? this.player.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(this.player.getScoreboardName())); // Paper - Adventure - PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionInfo.reason()), leaveMessage); // Paper - adventure + PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionInfo.reason()), leaveMessage, cause); // Paper - adventure & kick event causes if (this.cserver.getServer().isRunning()) { this.cserver.getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 674149f3a392a600a506e55f20db044619328cd2..0fb16f3193c88c5f58d16aaf85129bbfd01fdfcd 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -359,7 +359,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString()); - this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer); // Paper - use configurable kick message + this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_PLAYER); // Paper - use configurable kick message & kick event cause return; } } else { @@ -378,7 +378,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString()); - this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle); // Paper - use configurable kick message + this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_VEHICLE); // Paper - use configurable kick message & kick event cause return; } } else { @@ -398,7 +398,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.dropSpamThrottler.tick(); if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) this.server.getPlayerIdleTimeout() * 1000L * 60L) { this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854 - this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause } } @@ -486,7 +486,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(), packet.getY(), packet.getZ(), packet.getYRot(), packet.getXRot())) { - this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_vehicle_movement")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause } else if (!this.updateAwaitingTeleport()) { Entity entity = this.player.getRootVehicle(); @@ -692,7 +692,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { - this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause return; } @@ -756,7 +756,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits - this.disconnect(Component.translatable("disconnect.spam")); + this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause return; } // CraftBukkit end @@ -921,7 +921,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - validate pick item position if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); - this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)")); + this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed @@ -1124,14 +1124,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (byteTotal > byteAllowed) { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size()); - this.disconnect(Component.literal("Book too large!")); + this.disconnect(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } } // Paper end - Book size limits // CraftBukkit start if (this.lastBookTick + 20 > MinecraftServer.currentTick) { - this.disconnect(Component.literal("Book edited too quickly!")); + this.disconnect(Component.literal("Book edited too quickly!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } this.lastBookTick = MinecraftServer.currentTick; @@ -1240,7 +1240,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl public void handleMovePlayer(ServerboundMovePlayerPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) { - this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause } else { ServerLevel worldserver = this.player.serverLevel(); @@ -1679,7 +1679,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.dropCount++; if (this.dropCount >= 20) { ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!"); - this.disconnect(Component.literal("You dropped your items too quickly (Hacking?)")); + this.disconnect(Component.literal("You dropped your items too quickly (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause return; } } @@ -1976,7 +1976,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.player.resetLastActionTime(); } else { ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); - this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)")); // CraftBukkit + this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // CraftBukkit // Paper - kick event cause } } @@ -2174,7 +2174,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private void tryHandleChat(String s, Runnable runnable, boolean sync) { // CraftBukkit if (ServerGamePacketListenerImpl.isChatMessageIllegal(s)) { - this.disconnect((Component) Component.translatable("multiplayer.disconnect.illegal_characters")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper } else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); } else { @@ -2197,7 +2197,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (optional.isEmpty()) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); - this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED); + this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes } return optional; @@ -2381,7 +2381,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // this.chatSpamThrottler.increment(); if (!this.chatSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // CraftBukkit end - this.disconnect((Component) Component.translatable("disconnect.spam")); + this.disconnect((Component) Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause } } @@ -2393,7 +2393,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl synchronized (this.lastSeenMessages) { if (!this.lastSeenMessages.applyOffset(packet.offset())) { ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); - this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED); + this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes } } @@ -2541,7 +2541,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } if (i > 4096) { - this.disconnect((Component) Component.translatable("multiplayer.disconnect.too_many_pending_chats")); + this.disconnect((Component) Component.translatable("multiplayer.disconnect.too_many_pending_chats"), org.bukkit.event.player.PlayerKickEvent.Cause.TOO_MANY_PENDING_CHATS); // Paper - kick event cause } } @@ -2599,7 +2599,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Spigot Start if ( entity == this.player && !this.player.isSpectator() ) { - this.disconnect( Component.literal( "Cannot interact with self!" ) ); + this.disconnect( Component.literal( "Cannot interact with self!" ), org.bukkit.event.player.PlayerKickEvent.Cause.SELF_INTERACTION ); // Paper - kick event cause return; } // Spigot End @@ -2715,7 +2715,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } } - ServerGamePacketListenerImpl.this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_entity_attacked")); + ServerGamePacketListenerImpl.this.disconnect((Component) Component.translatable("multiplayer.disconnect.invalid_entity_attacked"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_ENTITY_ATTACKED); // Paper - add cause ServerGamePacketListenerImpl.LOGGER.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } }); @@ -3114,7 +3114,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start - auto recipe limit if (!org.bukkit.Bukkit.isPrimaryThread()) { if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) { - this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam")); + this.disconnect(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause return; } } @@ -3385,7 +3385,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (!Objects.equals(profilepublickey_a, profilepublickey_a1)) { if (profilepublickey_a != null && profilepublickey_a1.expiresAt().isBefore(profilepublickey_a.expiresAt())) { - this.disconnect(ProfilePublicKey.EXPIRED_PROFILE_PUBLIC_KEY); + this.disconnect(ProfilePublicKey.EXPIRED_PROFILE_PUBLIC_KEY, org.bukkit.event.player.PlayerKickEvent.Cause.EXPIRED_PROFILE_PUBLIC_KEY); // Paper - kick event causes } else { try { SignatureValidator signaturevalidator = this.server.getProfileKeySignatureValidator(); @@ -3398,7 +3398,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl this.resetPlayerChatState(remotechatsession_a.validate(this.player.getGameProfile(), signaturevalidator)); } catch (ProfilePublicKey.ValidationException profilepublickey_b) { ServerGamePacketListenerImpl.LOGGER.error("Failed to validate profile key: {}", profilepublickey_b.getMessage()); - this.disconnect(profilepublickey_b.getComponent()); + this.disconnect(profilepublickey_b.getComponent(), profilepublickey_b.kickCause); // Paper - kick event causes } } diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java index 9d5723cdfdbf6257a71e57842aea9ba317fc049a..1e4b288f20153ce0c91fabf164c5c8320c90ba7d 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -70,7 +70,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, } @Override - public void kickPlayer(Component reason) { + public void kickPlayer(Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause) { // Paper - kick event causes - during login, no event can be called. this.disconnect(reason); } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java index 6f7807cc0da427485037b3a72a9c60c81a858294..3ec8d38ca514048d94d24424d2132a90c10f529f 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java @@ -633,7 +633,7 @@ public abstract class PlayerList { while (iterator.hasNext()) { entityplayer = (ServerPlayer) iterator.next(); this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved - entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login")); + entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login"), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause } // Instead of kicking then returning, we need to store the kick reason @@ -1238,7 +1238,7 @@ public abstract class PlayerList { // Paper end // CraftBukkit start - disconnect safely for (ServerPlayer player : this.players) { - if (isRestarting) player.connection.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.restartMessage)); else // Paper + if (isRestarting) player.connection.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.restartMessage), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); else // Paper - kick event cause (cause is never used here) player.connection.disconnect(java.util.Objects.requireNonNullElseGet(this.server.server.shutdownMessage(), net.kyori.adventure.text.Component::empty)); // CraftBukkit - add custom shutdown message // Paper - Adventure } // CraftBukkit end diff --git a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java index 9e2ad78b12cadbf0e2bda1e12fe844120529c347..6a7d7fad990fc44fdda6849d43dad141e61f7f37 100644 --- a/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java +++ b/src/main/java/net/minecraft/world/entity/player/ProfilePublicKey.java @@ -24,7 +24,7 @@ public record ProfilePublicKey(ProfilePublicKey.Data data) { public static ProfilePublicKey createValidated(SignatureValidator servicesSignatureVerifier, UUID playerUuid, ProfilePublicKey.Data publicKeyData) throws ProfilePublicKey.ValidationException { if (!publicKeyData.validateSignature(servicesSignatureVerifier, playerUuid)) { - throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE); + throw new ProfilePublicKey.ValidationException(INVALID_SIGNATURE, org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PUBLIC_KEY_SIGNATURE); // Paper - kick event causes } else { return new ProfilePublicKey(publicKeyData); } @@ -88,8 +88,16 @@ public record ProfilePublicKey(ProfilePublicKey.Data data) { } public static class ValidationException extends ThrowingComponent { + public final org.bukkit.event.player.PlayerKickEvent.Cause kickCause; // Paper + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper public ValidationException(Component messageText) { + // Paper start + this(messageText, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); + } + public ValidationException(Component messageText, org.bukkit.event.player.PlayerKickEvent.Cause kickCause) { + // Paper end super(messageText); + this.kickCause = kickCause; // Paper } } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 3cb6f46492a3441c09a452836d01c15d1837f6ea..4b28318dbdeb3fa5935949740343c996d30aa2dd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -280,7 +280,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { void sendPacket(Packet packet); - void kickPlayer(Component reason); + void kickPlayer(Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause); // Paper - kick event causes } public record CookieFuture(ResourceLocation key, CompletableFuture future) { @@ -652,7 +652,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot - this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true)); + this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true), org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); // Paper - kick event cause } // Paper start @@ -664,10 +664,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kick(final net.kyori.adventure.text.Component message) { + kick(message, org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); + } + + @Override + public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) { org.spigotmc.AsyncCatcher.catchOp("player kick"); final ServerGamePacketListenerImpl connection = this.getHandle().connection; if (connection != null) { - connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message); + connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause); } } @@ -726,7 +731,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - Improve chat handling if (ServerGamePacketListenerImpl.isChatMessageIllegal(msg)) { - this.getHandle().connection.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters")); + this.getHandle().connection.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - kick event causes } else { if (msg.startsWith("/")) { this.getHandle().connection.handleCommand(msg); diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java index 824c4ad135ea5177f416687c7042639ed126b70b..39e56b95aaafbcd8ebe68fdefaace83702e9510d 100644 --- a/src/main/java/org/spigotmc/RestartCommand.java +++ b/src/main/java/org/spigotmc/RestartCommand.java @@ -74,7 +74,7 @@ public class RestartCommand extends Command // Kick all players for ( ServerPlayer p : com.google.common.collect.ImmutableList.copyOf( MinecraftServer.getServer().getPlayerList().players ) ) { - p.connection.disconnect( CraftChatMessage.fromStringOrEmpty( SpigotConfig.restartMessage, true ) ); + p.connection.disconnect( CraftChatMessage.fromStringOrEmpty( SpigotConfig.restartMessage, true ), org.bukkit.event.player.PlayerKickEvent.Cause.RESTART_COMMAND); // Paper - kick event reason (cause is never used)) } // Give the socket a chance to send the packets try