mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-07 19:12:22 +01:00
f5226d3739
This event is invoked when a player has disconnected. It is guaranteed that, if the server is in online-mode, that the provided uuid and username have been validated. The event is invoked for players who have not yet logged into the world, whereas PlayerQuitEvent is only invoked on players who have logged into the world. The event is invoked for players who have already logged into the world, although whether or not the player exists in the world at the time of firing is undefined. (That is, whether the plugin can retrieve a Player object using the event parameters is undefined). However, it is guaranteed that this event is invoked AFTER PlayerQuitEvent, if the player has already logged into the world. This event is guaranteed to never fire unless AsyncPlayerPreLoginEvent has been called beforehand, and this event may not be called in parallel with AsyncPlayerPreLoginEvent for the same connection. Cancelling the AsyncPlayerPreLoginEvent guarantees the corresponding PlayerConnectionCloseEvent is never called. The event may be invoked asynchronously or synchronously. As it stands, it is never invoked asynchronously. However, plugins should check Event#isAsynchronous to be future-proof. On purpose, the deprecated PlayerPreLoginEvent event is left out of the API spec for this event. Plugins should not be using that event, and how PlayerPreLoginEvent interacts with PlayerConnectionCloseEvent is undefined. == AT == public net.minecraft.server.network.ServerLoginPacketListenerImpl$State public net.minecraft.server.network.ServerLoginPacketListenerImpl state
148 lines
7.6 KiB
Diff
148 lines
7.6 KiB
Diff
--- a/net/minecraft/network/Connection.java
|
|
+++ b/net/minecraft/network/Connection.java
|
|
@@ -82,13 +82,13 @@
|
|
marker.add(Connection.PACKET_MARKER);
|
|
});
|
|
public static final Supplier<NioEventLoopGroup> NETWORK_WORKER_GROUP = Suppliers.memoize(() -> {
|
|
- return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build());
|
|
+ return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()); // Paper
|
|
});
|
|
public static final Supplier<EpollEventLoopGroup> NETWORK_EPOLL_WORKER_GROUP = Suppliers.memoize(() -> {
|
|
- return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).build());
|
|
+ return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()); // Paper
|
|
});
|
|
public static final Supplier<DefaultEventLoopGroup> LOCAL_WORKER_GROUP = Suppliers.memoize(() -> {
|
|
- return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
|
|
+ return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(LOGGER)).build()); // Paper
|
|
});
|
|
private static final ProtocolInfo<ServerHandshakePacketListener> INITIAL_PROTOCOL = HandshakeProtocols.SERVERBOUND;
|
|
private final PacketFlow receiving;
|
|
@@ -96,6 +96,11 @@
|
|
private final Queue<Consumer<Connection>> pendingActions = Queues.newConcurrentLinkedQueue();
|
|
public Channel channel;
|
|
public SocketAddress address;
|
|
+ // Spigot Start
|
|
+ public java.util.UUID spoofedUUID;
|
|
+ public com.mojang.authlib.properties.Property[] spoofedProfile;
|
|
+ public boolean preparing = true;
|
|
+ // Spigot End
|
|
@Nullable
|
|
private volatile PacketListener disconnectListener;
|
|
@Nullable
|
|
@@ -114,7 +119,25 @@
|
|
private volatile DisconnectionDetails delayedDisconnect;
|
|
@Nullable
|
|
BandwidthDebugMonitor bandwidthDebugMonitor;
|
|
+ public String hostname = ""; // CraftBukkit - add field
|
|
+ // Paper start - NetworkClient implementation
|
|
+ public int protocolVersion;
|
|
+ public java.net.InetSocketAddress virtualHost;
|
|
+ private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush"); // Paper - Disable explicit network manager flushing
|
|
+ // Paper end
|
|
|
|
+ // Paper start - add utility methods
|
|
+ public final net.minecraft.server.level.ServerPlayer getPlayer() {
|
|
+ if (this.packetListener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl impl) {
|
|
+ return impl.player;
|
|
+ } else if (this.packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl impl) {
|
|
+ org.bukkit.craftbukkit.entity.CraftPlayer player = impl.getCraftPlayer();
|
|
+ return player == null ? null : player.getHandle();
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+ // Paper end - add utility methods
|
|
+
|
|
public Connection(PacketFlow side) {
|
|
this.receiving = side;
|
|
}
|
|
@@ -123,6 +146,9 @@
|
|
super.channelActive(channelhandlercontext);
|
|
this.channel = channelhandlercontext.channel();
|
|
this.address = this.channel.remoteAddress();
|
|
+ // Spigot Start
|
|
+ this.preparing = false;
|
|
+ // Spigot End
|
|
if (this.delayedDisconnect != null) {
|
|
this.disconnect(this.delayedDisconnect);
|
|
}
|
|
@@ -176,6 +202,7 @@
|
|
|
|
}
|
|
}
|
|
+ if (net.minecraft.server.MinecraftServer.getServer().isDebugging()) io.papermc.paper.util.TraceUtil.printStackTrace(throwable); // Spigot // Paper
|
|
}
|
|
|
|
protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet<?> packet) {
|
|
@@ -205,7 +232,7 @@
|
|
}
|
|
|
|
private static <T extends PacketListener> void genericsFtw(Packet<T> packet, PacketListener listener) {
|
|
- packet.handle(listener);
|
|
+ packet.handle((T) listener); // CraftBukkit - decompile error
|
|
}
|
|
|
|
private void validateListener(ProtocolInfo<?> state, PacketListener listener) {
|
|
@@ -431,7 +458,7 @@
|
|
}
|
|
|
|
if (this.channel != null) {
|
|
- this.channel.flush();
|
|
+ if (enableExplicitFlush) this.channel.eventLoop().execute(() -> this.channel.flush()); // Paper - Disable explicit network manager flushing; we don't need to explicit flush here, but allow opt in incase issues are found to a better version
|
|
}
|
|
|
|
if (this.tickCount++ % 20 == 0) {
|
|
@@ -464,12 +491,15 @@
|
|
}
|
|
|
|
public void disconnect(DisconnectionDetails disconnectionInfo) {
|
|
+ // Spigot Start
|
|
+ this.preparing = false;
|
|
+ // Spigot End
|
|
if (this.channel == null) {
|
|
this.delayedDisconnect = disconnectionInfo;
|
|
}
|
|
|
|
if (this.isConnected()) {
|
|
- this.channel.close().awaitUninterruptibly();
|
|
+ this.channel.close(); // We can't wait as this may be called from an event loop.
|
|
this.disconnectionDetails = disconnectionInfo;
|
|
}
|
|
|
|
@@ -537,7 +567,7 @@
|
|
}
|
|
|
|
public void configurePacketHandler(ChannelPipeline pipeline) {
|
|
- pipeline.addLast("hackfix", new ChannelOutboundHandlerAdapter(this) {
|
|
+ pipeline.addLast("hackfix", new ChannelOutboundHandlerAdapter() { // CraftBukkit - decompile error
|
|
public void write(ChannelHandlerContext channelhandlercontext, Object object, ChannelPromise channelpromise) throws Exception {
|
|
super.write(channelhandlercontext, object, channelpromise);
|
|
}
|
|
@@ -660,7 +690,28 @@
|
|
});
|
|
|
|
packetlistener1.onDisconnect(disconnectiondetails);
|
|
+ }
|
|
+ this.pendingActions.clear(); // Free up packet queue.
|
|
+ // Paper start - Add PlayerConnectionCloseEvent
|
|
+ final PacketListener packetListener = this.getPacketListener();
|
|
+ if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
|
+ /* Player was logged in, either game listener or configuration listener */
|
|
+ final com.mojang.authlib.GameProfile profile = commonPacketListener.getOwner();
|
|
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(),
|
|
+ profile.getName(), ((InetSocketAddress) this.address).getAddress(), false).callEvent();
|
|
+ } else if (packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginListener) {
|
|
+ /* Player is login stage */
|
|
+ switch (loginListener.state) {
|
|
+ case VERIFYING:
|
|
+ case WAITING_FOR_DUPE_DISCONNECT:
|
|
+ case PROTOCOL_SWITCHING:
|
|
+ case ACCEPTED:
|
|
+ final com.mojang.authlib.GameProfile profile = loginListener.authenticatedProfile; /* Should be non-null at this stage */
|
|
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(), profile.getName(),
|
|
+ ((InetSocketAddress) this.address).getAddress(), false).callEvent();
|
|
+ }
|
|
}
|
|
+ // Paper end - Add PlayerConnectionCloseEvent
|
|
|
|
}
|
|
}
|