Commits

ORANG3I authored and md_5 committed 0f147ef56fa
SPIGOT-8020, #1540: Fix PlayerLoginEvent firing multiple times
No tags

nms-patches/net/minecraft/server/network/LoginListener.patch

Modified
68 68 + // CraftBukkit start
69 69 + @Deprecated
70 70 + public void disconnect(String s) {
71 71 + disconnect(IChatBaseComponent.literal(s));
72 72 + }
73 73 + // CraftBukkit end
74 74 +
75 75 @Override
76 76 public boolean isAcceptingMessages() {
77 77 return this.connection.isConnected();
78 -@@ -131,7 +175,27 @@
78 +@@ -93,6 +137,7 @@
79 +
80 + public void disconnect(IChatBaseComponent ichatbasecomponent) {
81 + try {
82 ++ this.state = EnumProtocolState.DISCONNECTED; // CraftBukkit - SPIGOT-8020: prevent repetition
83 + LoginListener.LOGGER.info("Disconnecting {}: {}", this.getUserName(), ichatbasecomponent.getString());
84 + this.connection.send(new PacketLoginOutDisconnect(ichatbasecomponent));
85 + this.connection.disconnect(ichatbasecomponent);
86 +@@ -131,7 +176,27 @@
79 87 this.state = LoginListener.EnumProtocolState.KEY;
80 88 this.connection.send(new PacketLoginOutEncryptionBegin("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
81 89 } else {
82 90 - this.startClientVerification(UUIDUtil.createOfflineProfile(this.requestedUsername));
83 91 + // CraftBukkit start
84 92 + Thread thread = new Thread("User Authenticator #" + LoginListener.UNIQUE_THREAD_ID.incrementAndGet()) {
85 93 +
86 94 + @Override
87 95 + public void run() {
88 96 + try {
97 105 + }
98 106 + }
99 107 + };
100 108 +
101 109 + thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LoginListener.LOGGER));
102 110 + thread.start();
103 111 + // CraftBukkit end
104 112 }
105 113
106 114 }
107 -@@ -144,10 +208,24 @@
115 +@@ -144,10 +209,24 @@
108 116
109 117 private void verifyLoginAndFinishConnectionSetup(GameProfile gameprofile) {
110 118 PlayerList playerlist = this.server.getPlayerList();
111 119 - IChatBaseComponent ichatbasecomponent = playerlist.canPlayerLogin(this.connection.getRemoteAddress(), gameprofile);
112 120 + // CraftBukkit start - fire PlayerLoginEvent
113 121 + this.player = playerlist.canPlayerLogin(this, gameprofile); // CraftBukkit
114 122
115 123 - if (ichatbasecomponent != null) {
116 124 - this.disconnect(ichatbasecomponent);
117 125 + if (this.player != null) {
125 133 +
126 134 + private void postCookies(GameProfile gameprofile) {
127 135 + PlayerList playerlist = this.server.getPlayerList();
128 136 +
129 137 + if (this.player == null) {
130 138 + // this.disconnect(ichatbasecomponent);
131 139 + // CraftBukkit end
132 140 } else {
133 141 if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) {
134 142 this.connection.send(new PacketLoginOutSetCompression(this.server.getCompressionThreshold()), PacketSendListener.thenRun(() -> {
135 -@@ -155,7 +233,7 @@
143 +@@ -155,7 +234,7 @@
136 144 }));
137 145 }
138 146
139 147 - boolean flag = playerlist.disconnectAllPlayersWithProfile(gameprofile);
140 148 + boolean flag = playerlist.disconnectAllPlayersWithProfile(gameprofile, this.player); // CraftBukkit - add player reference
141 149
142 150 if (flag) {
143 151 this.state = LoginListener.EnumProtocolState.WAITING_FOR_DUPE_DISCONNECT;
144 -@@ -205,6 +283,12 @@
152 +@@ -205,6 +284,12 @@
145 153 if (profileresult != null) {
146 154 GameProfile gameprofile = profileresult.profile();
147 155
148 156 + // CraftBukkit start - fire PlayerPreLoginEvent
149 157 + if (!connection.isConnected()) {
150 158 + return;
151 159 + }
152 160 + LoginListener.this.callPlayerPreLoginEvents(gameprofile);
153 161 + // CraftBukkit end
154 162 LoginListener.LOGGER.info("UUID of player {} is {}", gameprofile.getName(), gameprofile.getId());
155 163 LoginListener.this.startClientVerification(gameprofile);
156 164 } else if (LoginListener.this.server.isSingleplayer()) {
157 -@@ -222,6 +306,11 @@
165 +@@ -222,6 +307,11 @@
158 166 LoginListener.this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.authservers_down"));
159 167 LoginListener.LOGGER.error("Couldn't verify username because servers are unavailable");
160 168 }
161 169 + // CraftBukkit start - catch all exceptions
162 170 + } catch (Exception exception) {
163 171 + disconnect("Failed to verify username!");
164 172 + server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + s1, exception);
165 173 + // CraftBukkit end
166 174 }
167 175
168 176 }
169 -@@ -238,6 +327,43 @@
177 +@@ -238,6 +328,43 @@
170 178 thread.start();
171 179 }
172 180
173 181 + // CraftBukkit start
174 182 + private void callPlayerPreLoginEvents(GameProfile gameprofile) throws Exception {
175 183 + String playerName = gameprofile.getName();
176 184 + java.net.InetAddress address = ((java.net.InetSocketAddress) connection.getRemoteAddress()).getAddress();
177 185 + java.util.UUID uniqueId = gameprofile.getId();
178 186 + final org.bukkit.craftbukkit.CraftServer server = LoginListener.this.server.server;
179 187 +
203 211 + disconnect(asyncEvent.getKickMessage());
204 212 + return;
205 213 + }
206 214 + }
207 215 + }
208 216 + // CraftBukkit end
209 217 +
210 218 @Override
211 219 public void handleCustomQueryPacket(ServerboundCustomQueryAnswerPacket serverboundcustomqueryanswerpacket) {
212 220 this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY);
213 -@@ -245,10 +371,11 @@
221 +@@ -245,10 +372,11 @@
214 222
215 223 @Override
216 224 public void handleLoginAcknowledgement(ServerboundLoginAcknowledgedPacket serverboundloginacknowledgedpacket) {
217 225 + PlayerConnectionUtils.ensureRunningOnSameThread(serverboundloginacknowledgedpacket, this, this.server); // CraftBukkit
218 226 Validate.validState(this.state == LoginListener.EnumProtocolState.PROTOCOL_SWITCHING, "Unexpected login acknowledgement packet", new Object[0]);
219 227 this.connection.setupOutboundProtocol(ConfigurationProtocols.CLIENTBOUND);
220 228 CommonListenerCookie commonlistenercookie = CommonListenerCookie.createInitial((GameProfile) Objects.requireNonNull(this.authenticatedProfile), this.transferred);
221 229 - ServerConfigurationPacketListenerImpl serverconfigurationpacketlistenerimpl = new ServerConfigurationPacketListenerImpl(this.server, this.connection, commonlistenercookie);
222 230 + ServerConfigurationPacketListenerImpl serverconfigurationpacketlistenerimpl = new ServerConfigurationPacketListenerImpl(this.server, this.connection, commonlistenercookie, this.player); // CraftBukkit
223 231
224 232 this.connection.setupInboundProtocol(ConfigurationProtocols.SERVERBOUND, serverconfigurationpacketlistenerimpl);
225 233 serverconfigurationpacketlistenerimpl.startConfiguration();
226 -@@ -264,12 +391,18 @@
234 +@@ -264,12 +392,18 @@
227 235
228 236 @Override
229 237 public void handleCookieResponse(ServerboundCookieResponsePacket serverboundcookieresponsepacket) {
230 238 + // CraftBukkit start
231 239 + PlayerConnectionUtils.ensureRunningOnSameThread(serverboundcookieresponsepacket, this, this.server);
232 240 + if (this.player != null && this.player.getBukkitEntity().handleCookieResponse(serverboundcookieresponsepacket)) {
233 241 + return;
234 242 + }
235 243 + // CraftBukkit end
236 244 this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY);
237 245 }
238 246
239 247 private static enum EnumProtocolState {
240 248
241 249 - HELLO, KEY, AUTHENTICATING, NEGOTIATING, VERIFYING, WAITING_FOR_DUPE_DISCONNECT, PROTOCOL_SWITCHING, ACCEPTED;
242 -+ HELLO, KEY, AUTHENTICATING, NEGOTIATING, VERIFYING, WAITING_FOR_COOKIES, WAITING_FOR_DUPE_DISCONNECT, PROTOCOL_SWITCHING, ACCEPTED; // CraftBukkit
250 ++ HELLO, KEY, AUTHENTICATING, NEGOTIATING, VERIFYING, WAITING_FOR_DUPE_DISCONNECT, PROTOCOL_SWITCHING, ACCEPTED, WAITING_FOR_COOKIES, DISCONNECTED; // CraftBukkit
243 251
244 252 private EnumProtocolState() {}
245 253 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut