-
Bug
-
Resolution: Fixed
-
Minecraft 1.9.1
-
Unconfirmed
This affects 1.9
The bug
A client connecting to a server without notifying the session service first causes a NullPointerException for the server. This cannot be reproduced with a unmodded client, because the vanilla client cannot connect to a server with invalid session data.
The reason
The following is based on decompiled version of Minecraft 1.9 using MCP 9.24 beta. All method and class names are the names used in the decompiled version.
The reason why this happens is because the method net.minecraft.server.network.NetHandlerLoginServer.processEncryptionResponse(...).new Thread() {...}.run() calls the getName() method of the net.minecraft.server.network.NetHandlerLoginServer.loginGameProfile field, which is null. Instead it should call the method of the local variable net.minecraft.server.network.NetHandlerLoginServer.processEncryptionResponse(...).new Thread() {...}.run().gameprofile.
public void processEncryptionResponse(CPacketEncryptionResponse packetIn) { Validate.validState(this.currentLoginState == NetHandlerLoginServer.LoginState.KEY, "Unexpected key packet", new Object[0]); PrivateKey privatekey = this.server.getKeyPair().getPrivate(); if (!Arrays.equals(this.verifyToken, packetIn.getVerifyToken(privatekey))) { throw new IllegalStateException("Invalid nonce!"); } else { this.secretKey = packetIn.getSecretKey(privatekey); this.currentLoginState = NetHandlerLoginServer.LoginState.AUTHENTICATING; this.networkManager.enableEncryption(this.secretKey); (new Thread("User Authenticator #" + AUTHENTICATOR_THREAD_ID.incrementAndGet()) { public void run() { GameProfile gameprofile = NetHandlerLoginServer.this.loginGameProfile; try { String s = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.this.serverId, NetHandlerLoginServer.this.server.getKeyPair().getPublic(), NetHandlerLoginServer.this.secretKey))).toString(16); NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.server.getMinecraftSessionService().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s); if (NetHandlerLoginServer.this.loginGameProfile != null) { NetHandlerLoginServer.logger.info("UUID of player " + NetHandlerLoginServer.this.loginGameProfile.getName() + " is " + NetHandlerLoginServer.this.loginGameProfile.getId()); NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; } else if (NetHandlerLoginServer.this.server.isSinglePlayer()) { NetHandlerLoginServer.logger.warn("Failed to verify username but will let them in anyway!"); NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.getOfflineProfile(gameprofile); NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; } else { NetHandlerLoginServer.this.closeConnection("Failed to verify username!"); // Replaced this //NetHandlerLoginServer.logger.error("Username \'" + NetHandlerLoginServer.this.loginGameProfile.getName() + "\' tried to join with an invalid session"); NetHandlerLoginServer.logger.error("Username \'" + gameprofile.getName() + "\' tried to join with an invalid session"); } } catch (AuthenticationUnavailableException var3) { if (NetHandlerLoginServer.this.server.isSinglePlayer()) { NetHandlerLoginServer.logger.warn("Authentication servers are down but will let them in anyway!"); NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.getOfflineProfile(gameprofile); NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; } else { NetHandlerLoginServer.this.closeConnection("Authentication servers are down. Please try again later, sorry!"); NetHandlerLoginServer.logger.error("Couldn\'t verify username because servers are unavailable"); } } } }).start(); } }