mirror of https://github.com/PaperMC/Paper.git
209 lines
8.8 KiB
Diff
209 lines
8.8 KiB
Diff
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
|
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
|
@@ -26,6 +30,17 @@
|
|
import net.minecraft.util.thread.BlockableEventLoop;
|
|
import org.slf4j.Logger;
|
|
|
|
+// CraftBukkit start
|
|
+import io.netty.buffer.ByteBuf;
|
|
+import java.util.concurrent.ExecutionException;
|
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
+import org.bukkit.craftbukkit.util.CraftChatMessage;
|
|
+import org.bukkit.craftbukkit.util.CraftLocation;
|
|
+import org.bukkit.craftbukkit.util.Waitable;
|
|
+import org.bukkit.event.player.PlayerKickEvent;
|
|
+import org.bukkit.event.player.PlayerResourcePackStatusEvent;
|
|
+// CraftBukkit end
|
|
+
|
|
public abstract class ServerCommonPacketListenerImpl implements ServerCommonPacketListener {
|
|
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
@@ -39,13 +54,21 @@
|
|
private int latency;
|
|
private volatile boolean suspendFlushingOnServerThread = false;
|
|
|
|
- public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection connection, CommonListenerCookie commonlistenercookie) {
|
|
+ public ServerCommonPacketListenerImpl(MinecraftServer minecraftserver, Connection networkmanager, CommonListenerCookie commonlistenercookie, ServerPlayer player) { // CraftBukkit
|
|
this.server = minecraftserver;
|
|
this.connection = connection;
|
|
this.keepAliveTime = Util.getMillis();
|
|
this.latency = commonlistenercookie.latency();
|
|
+ // CraftBukkit start - add fields and methods
|
|
+ this.player = player;
|
|
+ this.cserver = minecraftserver.server;
|
|
}
|
|
|
|
+ public CraftPlayer getCraftPlayer() {
|
|
+ return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
|
|
+ // CraftBukkit end
|
|
+ }
|
|
+
|
|
@Override
|
|
@Override
|
|
public void onDisconnect(Component component) {
|
|
@@ -59,6 +83,7 @@
|
|
@Override
|
|
@Override
|
|
public void handleKeepAlive(ServerboundKeepAlivePacket serverboundkeepalivepacket) {
|
|
+ PacketUtils.ensureRunningOnSameThread(serverboundkeepalivepacket, this, this.player.serverLevel()); // CraftBukkit
|
|
if (this.keepAlivePending && serverboundkeepalivepacket.getId() == this.keepAliveChallenge) {
|
|
int i = (int) (Util.getMillis() - this.keepAliveTime);
|
|
|
|
@@ -74,10 +98,52 @@
|
|
@Override
|
|
public void handlePong(ServerboundPongPacket serverboundpongpacket) {}
|
|
|
|
+ // CraftBukkit start
|
|
+ private static final ResourceLocation CUSTOM_REGISTER = new ResourceLocation("register");
|
|
+ private static final ResourceLocation CUSTOM_UNREGISTER = new ResourceLocation("unregister");
|
|
+
|
|
@Override
|
|
@Override
|
|
public void handleCustomPayload(ServerboundCustomPayloadPacket serverboundcustompayloadpacket) {}
|
|
|
|
+ if (identifier.equals(CUSTOM_REGISTER)) {
|
|
+ try {
|
|
+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
|
|
+ for (String channel : channels.split("\0")) {
|
|
+ getCraftPlayer().addChannel(channel);
|
|
+ }
|
|
+ } catch (Exception ex) {
|
|
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex);
|
|
+ this.disconnect("Invalid payload REGISTER!");
|
|
+ }
|
|
+ } else if (identifier.equals(CUSTOM_UNREGISTER)) {
|
|
+ try {
|
|
+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8);
|
|
+ for (String channel : channels.split("\0")) {
|
|
+ getCraftPlayer().removeChannel(channel);
|
|
+ }
|
|
+ } catch (Exception ex) {
|
|
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t unregister custom payload", ex);
|
|
+ this.disconnect("Invalid payload UNREGISTER!");
|
|
+ }
|
|
+ } else {
|
|
+ try {
|
|
+ byte[] data = new byte[payload.readableBytes()];
|
|
+ payload.readBytes(data);
|
|
+ cserver.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), identifier.toString(), data);
|
|
+ } catch (Exception ex) {
|
|
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
|
|
+ this.disconnect("Invalid custom payload!");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ public final boolean isDisconnected() {
|
|
+ return !this.player.joining && !this.connection.isConnected();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
@Override
|
|
@Override
|
|
public void handleResourcePackResponse(ServerboundResourcePackPacket serverboundresourcepackpacket) {
|
|
@@ -86,6 +156,7 @@
|
|
ServerCommonPacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), serverboundresourcepackpacket.id());
|
|
this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"));
|
|
}
|
|
+ this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getCraftPlayer(), serverboundresourcepackpacket.id(), PlayerResourcePackStatusEvent.Status.values()[serverboundresourcepackpacket.action().ordinal()])); // CraftBukkit
|
|
|
|
}
|
|
|
|
@@ -93,7 +164,7 @@
|
|
this.server.getProfiler().push("keepAlive");
|
|
long i = Util.getMillis();
|
|
|
|
- if (i - this.keepAliveTime >= 15000L) {
|
|
+ if (i - this.keepAliveTime >= 25000L) { // CraftBukkit
|
|
if (this.keepAlivePending) {
|
|
this.disconnect(ServerCommonPacketListenerImpl.TIMEOUT_DISCONNECTION_MESSAGE);
|
|
} else {
|
|
@@ -121,6 +192,14 @@
|
|
}
|
|
|
|
public void send(Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
|
|
+ // CraftBukkit start
|
|
+ if (packet == null) {
|
|
+ return;
|
|
+ } else if (packet instanceof ClientboundSetDefaultSpawnPositionPacket) {
|
|
+ ClientboundSetDefaultSpawnPositionPacket packet6 = (ClientboundSetDefaultSpawnPositionPacket) packet;
|
|
+ this.player.compassTarget = CraftLocation.toBukkit(packet6.pos, this.getCraftPlayer().getWorld());
|
|
+ }
|
|
+ // CraftBukkit end
|
|
boolean flag = !this.suspendFlushingOnServerThread || !this.server.isSameThread();
|
|
|
|
try {
|
|
@@ -136,16 +215,67 @@
|
|
}
|
|
}
|
|
|
|
- public void disconnect(Component component) {
|
|
- this.connection.send(new ClientboundDisconnectPacket(component), PacketSendListener.thenRun(() -> {
|
|
- this.connection.disconnect(component);
|
|
+ // CraftBukkit start
|
|
+ @Deprecated
|
|
+ public void disconnect(Component ichatbasecomponent) {
|
|
+ disconnect(CraftChatMessage.fromComponent(ichatbasecomponent));
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
+ public void disconnect(String s) {
|
|
+ // CraftBukkit start - fire PlayerKickEvent
|
|
+ if (this.processedDisconnect) {
|
|
+ return;
|
|
+ }
|
|
+ if (!this.cserver.isPrimaryThread()) {
|
|
+ Waitable waitable = new Waitable() {
|
|
+ @Override
|
|
+ protected Object evaluate() {
|
|
+ ServerCommonPacketListenerImpl.this.disconnect(s);
|
|
+ return null;
|
|
+ }
|
|
+ };
|
|
+
|
|
+ this.server.processQueue.add(waitable);
|
|
+
|
|
+ try {
|
|
+ waitable.get();
|
|
+ } catch (InterruptedException e) {
|
|
+ Thread.currentThread().interrupt();
|
|
+ } catch (ExecutionException e) {
|
|
+ throw new RuntimeException(e);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ String leaveMessage = ChatFormatting.YELLOW + this.player.getScoreboardName() + " left the game.";
|
|
+
|
|
+ PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), s, leaveMessage);
|
|
+
|
|
+ if (this.cserver.getServer().isRunning()) {
|
|
+ this.cserver.getPluginManager().callEvent(event);
|
|
+ }
|
|
+
|
|
+ if (event.isCancelled()) {
|
|
+ // 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
|
|
+ final Component ichatbasecomponent = CraftChatMessage.fromString(event.getReason(), true)[0];
|
|
+ // CraftBukkit end
|
|
+
|
|
+ this.connection.send(new ClientboundDisconnectPacket(ichatbasecomponent), PacketSendListener.thenRun(() -> {
|
|
+ this.connection.disconnect(ichatbasecomponent);
|
|
}));
|
|
+ this.onDisconnect(ichatbasecomponent); // CraftBukkit - fire quit instantly
|
|
this.connection.setReadOnly();
|
|
MinecraftServer minecraftserver = this.server;
|
|
Connection connection = this.connection;
|
|
|
|
Objects.requireNonNull(this.connection);
|
|
- minecraftserver.executeBlocking(connection::handleDisconnection);
|
|
+ // CraftBukkit - Don't wait
|
|
+ minecraftserver.wrapRunnable(networkmanager::handleDisconnection);
|
|
}
|
|
|
|
protected boolean isSingleplayerOwner() {
|