Paper/patch-remap/mache-spigotflower-stripped/net/minecraft/server/network/ServerCommonPacketListenerI...

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() {