--- a/net/minecraft/server/LoginListener.java +++ b/net/minecraft/server/LoginListener.java @@ -19,6 +19,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit start +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerPreLoginEvent; +// CraftBukkit end + public class LoginListener implements PacketLoginInListener, ITickable { private static final AtomicInteger b = new AtomicInteger(0); @@ -33,6 +39,7 @@ private final String j; private SecretKey loginKey; private EntityPlayer l; + public String hostname = ""; // CraftBukkit - add field public LoginListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { this.g = LoginListener.EnumProtocolState.HELLO; @@ -61,6 +68,20 @@ } + // CraftBukkit start + @Deprecated + public void disconnect(String s) { + try { + IChatBaseComponent ichatbasecomponent = new ChatComponentText(s); + LoginListener.c.info("Disconnecting {}: {}", this.c(), s); + this.networkManager.sendPacket(new PacketLoginOutDisconnect(ichatbasecomponent)); + this.networkManager.close(ichatbasecomponent); + } catch (Exception exception) { + LoginListener.c.error("Error whilst disconnecting player", exception); + } + } + // CraftBukkit end + public void disconnect(IChatBaseComponent ichatbasecomponent) { try { LoginListener.c.info("Disconnecting {}: {}", this.c(), ichatbasecomponent.getString()); @@ -77,10 +98,12 @@ this.i = this.a(this.i); } - IChatBaseComponent ichatbasecomponent = this.server.getPlayerList().attemptLogin(this.networkManager.getSocketAddress(), this.i); + // CraftBukkit start - fire PlayerLoginEvent + EntityPlayer s = this.server.getPlayerList().attemptLogin(this, this.i, hostname); - if (ichatbasecomponent != null) { - this.disconnect(ichatbasecomponent); + if (s == null) { + // this.disconnect(ichatbasecomponent); + // CraftBukkit end } else { this.g = LoginListener.EnumProtocolState.ACCEPTED; if (this.server.aw() >= 0 && !this.networkManager.isLocal()) { @@ -94,9 +117,9 @@ if (entityplayer != null) { this.g = LoginListener.EnumProtocolState.DELAY_ACCEPT; - this.l = this.server.getPlayerList().processLogin(this.i); + this.l = this.server.getPlayerList().processLogin(this.i, s); // CraftBukkit - add player reference } else { - this.server.getPlayerList().a(this.networkManager, this.server.getPlayerList().processLogin(this.i)); + this.server.getPlayerList().a(this.networkManager, this.server.getPlayerList().processLogin(this.i, s)); // CraftBukkit - add player reference } } @@ -141,6 +164,43 @@ LoginListener.this.i = LoginListener.this.server.ap().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s, this.a()); if (LoginListener.this.i != null) { + // CraftBukkit start - fire PlayerPreLoginEvent + if (!networkManager.isConnected()) { + return; + } + + String playerName = i.getName(); + java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress(); + java.util.UUID uniqueId = i.getId(); + final org.bukkit.craftbukkit.CraftServer server = LoginListener.this.server.server; + + AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); + server.getPluginManager().callEvent(asyncEvent); + + if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { + final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); + if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { + event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); + } + Waitable waitable = new Waitable() { + @Override + protected PlayerPreLoginEvent.Result evaluate() { + server.getPluginManager().callEvent(event); + return event.getResult(); + }}; + + LoginListener.this.server.processQueue.add(waitable); + if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) { + disconnect(event.getKickMessage()); + return; + } + } else { + if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { + disconnect(asyncEvent.getKickMessage()); + return; + } + } + // CraftBukkit end LoginListener.c.info("UUID of player {} is {}", LoginListener.this.i.getName(), LoginListener.this.i.getId()); LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; } else if (LoginListener.this.server.H()) { @@ -160,6 +220,11 @@ LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down", new Object[0])); LoginListener.c.error("Couldn't verify username because servers are unavailable"); } + // CraftBukkit start - catch all exceptions + } catch (Exception exception) { + disconnect("Failed to verify username!"); + server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + gameprofile.getName(), exception); + // CraftBukkit end } }