From a24b5a38ec94a03907c3ef650eb9fb6e32f68b76 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 15 Mar 2014 14:34:03 +1100 Subject: [PATCH] Optimize Player Lookup Optimize player lookup and various player operations. We mainly do this by keeping a map instead of iterating through all players. We also speed up the duplicate login check and a few other checks by simply checking for one matching player. diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index d2a378e..8a48ec2 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -61,6 +61,25 @@ public abstract class PlayerList { private boolean s; private int t; + // Spigot Start + private final Map playerMap = new java.util.HashMap(); + + private void removePlayer(EntityPlayer player) + { + playerMap.remove( player.getName().toLowerCase() ); + } + + private void addPlayer(EntityPlayer player) + { + playerMap.put( player.getName().toLowerCase(), player ); + } + + private EntityPlayer getPlayerByName(String name) + { + return playerMap.get( name.toLowerCase() ); + } + // Spigot End + // CraftBukkit start private CraftServer cserver; @@ -244,6 +263,7 @@ public abstract class PlayerList { cserver.detectListNameConflict(entityplayer); // CraftBukkit // this.sendAll(new PacketPlayOutPlayerInfo(entityplayer.getName(), true, 1000)); // CraftBukkit - replaced with loop below this.players.add(entityplayer); + addPlayer( entityplayer ); // Spigot WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); // CraftBukkit start @@ -319,6 +339,7 @@ public abstract class PlayerList { worldserver.kill(entityplayer); worldserver.getPlayerChunkMap().removePlayer(entityplayer); this.players.remove(entityplayer); + removePlayer( entityplayer ); // Spigot this.n.remove(entityplayer.getUniqueID()); ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit @@ -394,24 +415,14 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig } public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) { // CraftBukkit - added EntityPlayer - UUID uuid = EntityHuman.a(gameprofile); - ArrayList arraylist = Lists.newArrayList(); - - EntityPlayer entityplayer; + // Spigot Start + EntityPlayer entityplayer = getPlayer( gameprofile.getName() ); - for (int i = 0; i < this.players.size(); ++i) { - entityplayer = (EntityPlayer) this.players.get(i); - if (entityplayer.getUniqueID().equals(uuid)) { - arraylist.add(entityplayer); - } - } - - Iterator iterator = arraylist.iterator(); - - while (iterator.hasNext()) { - entityplayer = (EntityPlayer) iterator.next(); - entityplayer.playerConnection.disconnect("You logged in from another location"); + if ( entityplayer != null ) + { + entityplayer.playerConnection.disconnect( "You logged in from another location" ); } + // Spigot End /* CraftBukkit start Object object; @@ -901,19 +912,7 @@ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig } public EntityPlayer getPlayer(String s) { - Iterator iterator = this.players.iterator(); - - EntityPlayer entityplayer; - - do { - if (!iterator.hasNext()) { - return null; - } - - entityplayer = (EntityPlayer) iterator.next(); - } while (!entityplayer.getName().equalsIgnoreCase(s)); - - return entityplayer; + return getPlayerByName( s ); // Spigot } public List a(ChunkCoordinates chunkcoordinates, int i, int j, int k, int l, int i1, int j1, Map map, String s, String s1, World world) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index bec4134..0430cc1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -131,14 +131,10 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } public Player getPlayer() { - for (Object obj : server.getHandle().players) { - EntityPlayer player = (EntityPlayer) obj; - if (player.getUniqueID().equals(getUniqueId())) { - return (player.playerConnection != null) ? player.playerConnection.getPlayer() : null; - } - } - - return null; + // Spigot Start + EntityPlayer player = server.getHandle().getPlayer( name ); + return ( player != null && player.playerConnection != null ) ? player.getBukkitEntity() : null; + // Spigot End } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 2645c97..ff13c51 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -502,6 +502,13 @@ public final class CraftServer implements Server { public Player getPlayer(final String name) { Validate.notNull(name, "Name cannot be null"); + // Spigot Start + Player directLookup = getPlayerExact( name ); + if ( directLookup != null ) + { + return directLookup; + } + // Spigot End Player[] players = getOnlinePlayers(); Player found = null; @@ -523,15 +530,10 @@ public final class CraftServer implements Server { public Player getPlayerExact(String name) { Validate.notNull(name, "Name cannot be null"); - String lname = name.toLowerCase(); - - for (Player player : getOnlinePlayers()) { - if (player.getName().equalsIgnoreCase(lname)) { - return player; - } - } - - return null; + // Spigot Start + EntityPlayer entityPlayer = playerList.getPlayer( name ); + return ( entityPlayer != null ) ? entityPlayer.getBukkitEntity() : null; + // Spigot End } // TODO: In 1.7.6+ this should use the server's UUID->EntityPlayer map diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 8af4bf7..8b1ffd6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -101,13 +101,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public boolean isOnline() { - for (Object obj : server.getHandle().players) { - EntityPlayer player = (EntityPlayer) obj; - if (player.getName().equalsIgnoreCase(getName())) { - return true; - } - } - return false; + return server.getHandle().getPlayer( getName() ) != null; // Spigot } public InetSocketAddress getAddress() { -- 1.8.3.2