2021-07-09 21:03:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:19:41 -0700
2024-01-19 13:22:30 +01:00
Subject: [PATCH] Fix kick event leave message not being sent
2021-07-09 21:03:28 +02:00
2022-03-16 16:57:51 +01:00
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
index 09798fc2d2d847f3ec705a2640f25ac08ca69f92..87652ea4f3950c2161b3405dcfef03bd196f1237 100644
2022-03-16 16:57:51 +01:00
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
2024-10-23 20:50:46 +02:00
@@ -318,7 +318,6 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
2023-09-22 09:24:44 +02:00
public boolean joining = true;
2022-12-19 11:46:55 +01:00
public boolean sentListPacket = false;
2024-01-21 12:11:43 +01:00
public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
2022-03-16 16:57:51 +01:00
- public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
2022-12-07 21:16:54 +01:00
public boolean isRealPlayer; // Paper
2024-07-17 19:24:53 +02:00
public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
2023-09-22 13:39:00 +02:00
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
2024-10-23 20:50:46 +02:00
index 59d20fd62e850a38380d877cef95ed69cb46ecbd..fc242acade3ff06c9213428cde103cf078216382 100644
2023-09-22 13:39:00 +02:00
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
2024-10-23 20:50:46 +02:00
@@ -116,6 +116,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
2023-09-22 13:39:00 +02:00
@Override
2024-06-14 01:32:45 +02:00
public void onDisconnect(DisconnectionDetails info) {
2024-01-19 13:22:30 +01:00
+ // Paper start - Fix kick event leave message not being sent
2024-06-14 01:32:45 +02:00
+ this.onDisconnect(info, null);
2023-09-22 13:39:00 +02:00
+ }
2024-06-14 01:32:45 +02:00
+ public void onDisconnect(DisconnectionDetails info, @Nullable net.kyori.adventure.text.Component quitMessage) {
2024-01-19 13:22:30 +01:00
+ // Paper end - Fix kick event leave message not being sent
2023-09-22 13:39:00 +02:00
if (this.isSingleplayerOwner()) {
ServerCommonPacketListenerImpl.LOGGER.info("Stopping singleplayer server as player logged out");
this.server.halt(false);
2024-10-23 20:50:46 +02:00
@@ -386,18 +391,17 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
2023-09-22 13:39:00 +02:00
// Do not kick the player
return;
}
- this.player.kickLeaveMessage = event.getLeaveMessage(); // CraftBukkit - SPIGOT-3034: Forward leave message to PlayerQuitEvent
// Send the possibly modified leave message
2024-06-14 14:11:52 +02:00
- this.disconnect0(new DisconnectionDetails(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()), disconnectionInfo.report(), disconnectionInfo.bugReportLink())); // Paper - Adventure
+ this.disconnect0(new DisconnectionDetails(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.reason()), disconnectionInfo.report(), disconnectionInfo.bugReportLink()), event.leaveMessage()); // Paper - Adventure & use kick event leave message
2024-06-14 01:32:45 +02:00
}
2024-06-14 14:11:52 +02:00
- private void disconnect0(DisconnectionDetails disconnectiondetails) {
+ private void disconnect0(DisconnectionDetails disconnectiondetails, @Nullable net.kyori.adventure.text.Component leaveMessage) { // Paper - use kick event leave message
// CraftBukkit end
this.player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.KICKED; // Paper - Add API for quit reason
2024-06-14 01:32:45 +02:00
this.connection.send(new ClientboundDisconnectPacket(disconnectiondetails.reason()), PacketSendListener.thenRun(() -> {
this.connection.disconnect(disconnectiondetails);
2023-09-22 13:39:00 +02:00
}));
2024-06-14 01:32:45 +02:00
- this.onDisconnect(disconnectiondetails); // CraftBukkit - fire quit instantly
2024-06-14 14:11:52 +02:00
+ this.onDisconnect(disconnectiondetails, leaveMessage); // CraftBukkit - fire quit instantly // Paper - use kick event leave message
2023-09-22 13:39:00 +02:00
this.connection.setReadOnly();
MinecraftServer minecraftserver = this.server;
Connection networkmanager = this.connection;
2021-07-09 21:03:28 +02:00
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2024-10-27 18:11:15 +01:00
index e48c6f37ba0ebe698e28042e9331ab2ec0c39e7c..0229b3e6c27b142ff726de8e2e15104a6acbc1f0 100644
2021-07-09 21:03:28 +02:00
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
2024-10-24 19:29:35 +02:00
@@ -1915,6 +1915,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
2021-07-09 21:03:28 +02:00
@Override
2024-06-14 01:32:45 +02:00
public void onDisconnect(DisconnectionDetails info) {
2024-01-19 13:22:30 +01:00
+ // Paper start - Fix kick event leave message not being sent
2024-06-14 01:32:45 +02:00
+ this.onDisconnect(info, null);
2021-07-09 21:03:28 +02:00
+ }
2023-09-22 13:39:00 +02:00
+ @Override
2024-06-14 01:32:45 +02:00
+ public void onDisconnect(DisconnectionDetails info, @Nullable net.kyori.adventure.text.Component quitMessage) {
2024-01-19 13:22:30 +01:00
+ // Paper end - Fix kick event leave message not being sent
2021-07-09 21:03:28 +02:00
// CraftBukkit start - Rarely it would send a disconnect line twice
if (this.processedDisconnect) {
return;
2024-10-24 19:29:35 +02:00
@@ -1923,11 +1929,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
2023-09-22 09:24:44 +02:00
}
// CraftBukkit end
2024-06-14 01:32:45 +02:00
ServerGamePacketListenerImpl.LOGGER.info("{} lost connection: {}", this.player.getName().getString(), info.reason().getString());
2023-09-22 09:24:44 +02:00
- this.removePlayerFromWorld();
2024-06-14 01:32:45 +02:00
- super.onDisconnect(info);
2024-01-19 13:22:30 +01:00
+ this.removePlayerFromWorld(quitMessage); // Paper - Fix kick event leave message not being sent
2024-06-14 01:32:45 +02:00
+ super.onDisconnect(info, quitMessage); // Paper - Fix kick event leave message not being sent
2023-09-22 09:24:44 +02:00
}
2024-01-19 13:22:30 +01:00
+ // Paper start - Fix kick event leave message not being sent
2023-09-22 09:24:44 +02:00
private void removePlayerFromWorld() {
+ this.removePlayerFromWorld(null);
+ }
+
+ private void removePlayerFromWorld(@Nullable net.kyori.adventure.text.Component quitMessage) {
2024-01-19 13:22:30 +01:00
+ // Paper end - Fix kick event leave message not being sent
2023-09-22 09:24:44 +02:00
this.chatMessageChain.close();
// CraftBukkit start - Replace vanilla quit message handling with our own.
/*
2024-10-24 19:29:35 +02:00
@@ -1937,7 +1949,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
2021-07-09 21:03:28 +02:00
this.player.disconnect();
// Paper start - Adventure
2021-11-25 00:46:26 +01:00
- net.kyori.adventure.text.Component quitMessage = this.server.getPlayerList().remove(this.player);
+ quitMessage = quitMessage == null ? this.server.getPlayerList().remove(this.player) : this.server.getPlayerList().remove(this.player, quitMessage); // Paper - pass in quitMessage to fix kick message not being used
2021-07-09 21:03:28 +02:00
if ((quitMessage != null) && !quitMessage.equals(net.kyori.adventure.text.Component.empty())) {
2022-07-27 23:19:52 +02:00
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false);
2021-07-09 21:03:28 +02:00
// Paper end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
index 26ba0cec3a8492d91df894a69cc1fc8076eeda0d..85bd61bd45690c5532f56d8f11b81f7a11f3e284 100644
2021-07-09 21:03:28 +02:00
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
2024-10-27 18:11:15 +01:00
@@ -510,6 +510,11 @@ public abstract class PlayerList {
2021-07-09 21:03:28 +02:00
}
2023-06-08 04:04:01 +02:00
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component
2024-01-19 13:22:30 +01:00
+ // Paper start - Fix kick event leave message not being sent
2023-09-22 19:31:02 +02:00
+ return this.remove(entityplayer, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())));
2021-07-09 21:03:28 +02:00
+ }
2021-11-25 00:46:26 +01:00
+ public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
2024-01-19 13:22:30 +01:00
+ // Paper end - Fix kick event leave message not being sent
2023-06-08 04:04:01 +02:00
ServerLevel worldserver = entityplayer.serverLevel();
2021-07-09 21:03:28 +02:00
entityplayer.awardStat(Stats.LEAVE_GAME);
2024-10-27 20:09:27 +01:00
@@ -520,7 +525,7 @@ public abstract class PlayerList {
entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason
}
- PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & Add API for quit reason
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), leaveMessage, entityplayer.quitReason); // Paper - Adventure & Add API for quit reason
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());