001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.io.File;
006    import java.net.SocketAddress;
007    import java.text.SimpleDateFormat;
008    import java.util.ArrayList;
009    import java.util.Collections;
010    import java.util.HashSet;
011    import java.util.Iterator;
012    import java.util.List;
013    import java.util.Set;
014    import java.util.logging.Logger;
015    
016    import cpw.mods.fml.common.network.FMLNetworkHandler;
017    import cpw.mods.fml.common.network.NetworkRegistry;
018    import cpw.mods.fml.common.registry.GameRegistry;
019    import net.minecraft.server.MinecraftServer;
020    import net.minecraftforge.common.DimensionManager;
021    
022    public abstract class ServerConfigurationManager
023    {
024        private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z");
025    
026        /** Reference to the logger. */
027        public static final Logger logger = Logger.getLogger("Minecraft");
028    
029        /** Reference to the MinecraftServer object. */
030        private final MinecraftServer mcServer;
031    
032        /** A list of player entities that exist on this server. */
033        public final List playerEntityList = new ArrayList();
034        private final BanList bannedPlayers = new BanList(new File("banned-players.txt"));
035        private final BanList bannedIPs = new BanList(new File("banned-ips.txt"));
036    
037        /** A set containing the OPs. */
038        private Set ops = new HashSet();
039    
040        /** The Set of all whitelisted players. */
041        private Set whiteListedPlayers = new HashSet();
042    
043        /** Reference to the PlayerNBTManager object. */
044        private IPlayerFileData playerNBTManagerObj;
045    
046        /**
047         * Server setting to only allow OPs and whitelisted players to join the server.
048         */
049        private boolean whiteListEnforced;
050    
051        /** The maximum number of players that can be connected at a time. */
052        protected int maxPlayers;
053        protected int viewDistance;
054        private EnumGameType gameType;
055    
056        /** True if all players are allowed to use commands (cheats). */
057        private boolean commandsAllowedForAll;
058    
059        /**
060         * index into playerEntities of player to ping, updated every tick; currently hardcoded to max at 200 players
061         */
062        private int playerPingIndex = 0;
063    
064        public ServerConfigurationManager(MinecraftServer par1MinecraftServer)
065        {
066            this.mcServer = par1MinecraftServer;
067            this.bannedPlayers.setListActive(false);
068            this.bannedIPs.setListActive(false);
069            this.maxPlayers = 8;
070        }
071    
072        public void initializeConnectionToPlayer(INetworkManager par1INetworkManager, EntityPlayerMP par2EntityPlayerMP)
073        {
074            this.readPlayerDataFromFile(par2EntityPlayerMP);
075            par2EntityPlayerMP.setWorld(this.mcServer.worldServerForDimension(par2EntityPlayerMP.dimension));
076            par2EntityPlayerMP.theItemInWorldManager.setWorld((WorldServer)par2EntityPlayerMP.worldObj);
077            String var3 = "local";
078    
079            if (par1INetworkManager.getSocketAddress() != null)
080            {
081                var3 = par1INetworkManager.getSocketAddress().toString();
082            }
083    
084            logger.info(par2EntityPlayerMP.username + "[" + var3 + "] logged in with entity id " + par2EntityPlayerMP.entityId + " at (" + par2EntityPlayerMP.posX + ", " + par2EntityPlayerMP.posY + ", " + par2EntityPlayerMP.posZ + ")");
085            WorldServer var4 = this.mcServer.worldServerForDimension(par2EntityPlayerMP.dimension);
086            ChunkCoordinates var5 = var4.getSpawnPoint();
087            this.func_72381_a(par2EntityPlayerMP, (EntityPlayerMP)null, var4);
088            NetServerHandler var6 = new NetServerHandler(this.mcServer, par1INetworkManager, par2EntityPlayerMP);
089            var6.sendPacketToPlayer(new Packet1Login(par2EntityPlayerMP.entityId, var4.getWorldInfo().getTerrainType(), par2EntityPlayerMP.theItemInWorldManager.getGameType(), var4.getWorldInfo().isHardcoreModeEnabled(), var4.provider.dimensionId, var4.difficultySetting, var4.getHeight(), this.getMaxPlayers()));
090            var6.sendPacketToPlayer(new Packet6SpawnPosition(var5.posX, var5.posY, var5.posZ));
091            var6.sendPacketToPlayer(new Packet202PlayerAbilities(par2EntityPlayerMP.capabilities));
092            this.updateTimeAndWeatherForPlayer(par2EntityPlayerMP, var4);
093            this.sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + par2EntityPlayerMP.username + " joined the game."));
094            this.playerLoggedIn(par2EntityPlayerMP);
095            var6.setPlayerLocation(par2EntityPlayerMP.posX, par2EntityPlayerMP.posY, par2EntityPlayerMP.posZ, par2EntityPlayerMP.rotationYaw, par2EntityPlayerMP.rotationPitch);
096            this.mcServer.getNetworkThread().addPlayer(var6);
097            var6.sendPacketToPlayer(new Packet4UpdateTime(var4.getTotalWorldTime(), var4.getWorldTime()));
098    
099            if (this.mcServer.getTexturePack().length() > 0)
100            {
101                par2EntityPlayerMP.requestTexturePackLoad(this.mcServer.getTexturePack(), this.mcServer.textureSize());
102            }
103    
104            Iterator var7 = par2EntityPlayerMP.getActivePotionEffects().iterator();
105    
106            while (var7.hasNext())
107            {
108                PotionEffect var8 = (PotionEffect)var7.next();
109                var6.sendPacketToPlayer(new Packet41EntityEffect(par2EntityPlayerMP.entityId, var8));
110            }
111    
112            par2EntityPlayerMP.addSelfToInternalCraftingInventory();
113            FMLNetworkHandler.handlePlayerLogin(par2EntityPlayerMP, var6, par1INetworkManager);
114        }
115    
116        /**
117         * Sets the NBT manager to the one for the WorldServer given.
118         */
119        public void setPlayerManager(WorldServer[] par1ArrayOfWorldServer)
120        {
121            this.playerNBTManagerObj = par1ArrayOfWorldServer[0].getSaveHandler().getSaveHandler();
122        }
123    
124        public void func_72375_a(EntityPlayerMP par1EntityPlayerMP, WorldServer par2WorldServer)
125        {
126            WorldServer var3 = par1EntityPlayerMP.getServerForPlayer();
127    
128            if (par2WorldServer != null)
129            {
130                par2WorldServer.getPlayerManager().removePlayer(par1EntityPlayerMP);
131            }
132    
133            var3.getPlayerManager().addPlayer(par1EntityPlayerMP);
134            var3.theChunkProviderServer.loadChunk((int)par1EntityPlayerMP.posX >> 4, (int)par1EntityPlayerMP.posZ >> 4);
135        }
136    
137        public int getEntityViewDistance()
138        {
139            return PlayerManager.func_72686_a(this.getViewDistance());
140        }
141    
142        /**
143         * called during player login. reads the player information from disk.
144         */
145        public void readPlayerDataFromFile(EntityPlayerMP par1EntityPlayerMP)
146        {
147            NBTTagCompound var2 = this.mcServer.worldServers[0].getWorldInfo().getPlayerNBTTagCompound();
148    
149            if (par1EntityPlayerMP.getCommandSenderName().equals(this.mcServer.getServerOwner()) && var2 != null)
150            {
151                par1EntityPlayerMP.readFromNBT(var2);
152            }
153            else
154            {
155                this.playerNBTManagerObj.readPlayerData(par1EntityPlayerMP);
156            }
157        }
158    
159        /**
160         * also stores the NBTTags if this is an intergratedPlayerList
161         */
162        protected void writePlayerData(EntityPlayerMP par1EntityPlayerMP)
163        {
164            this.playerNBTManagerObj.writePlayerData(par1EntityPlayerMP);
165        }
166    
167        /**
168         * Called when a player successfully logs in. Reads player data from disk and inserts the player into the world.
169         */
170        public void playerLoggedIn(EntityPlayerMP par1EntityPlayerMP)
171        {
172            this.sendPacketToAllPlayers(new Packet201PlayerInfo(par1EntityPlayerMP.username, true, 1000));
173            this.playerEntityList.add(par1EntityPlayerMP);
174            WorldServer var2 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
175            var2.spawnEntityInWorld(par1EntityPlayerMP);
176            this.func_72375_a(par1EntityPlayerMP, (WorldServer)null);
177    
178            for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3)
179            {
180                EntityPlayerMP var4 = (EntityPlayerMP)this.playerEntityList.get(var3);
181                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet201PlayerInfo(var4.username, true, var4.ping));
182            }
183        }
184    
185        /**
186         * using player's dimension, update their movement when in a vehicle (e.g. cart, boat)
187         */
188        public void serverUpdateMountedMovingPlayer(EntityPlayerMP par1EntityPlayerMP)
189        {
190            par1EntityPlayerMP.getServerForPlayer().getPlayerManager().updateMountedMovingPlayer(par1EntityPlayerMP);
191        }
192    
193        /**
194         * Called when a player disconnects from the game. Writes player data to disk and removes them from the world.
195         */
196        public void playerLoggedOut(EntityPlayerMP par1EntityPlayerMP)
197        {
198            GameRegistry.onPlayerLogout(par1EntityPlayerMP);
199            this.writePlayerData(par1EntityPlayerMP);
200            WorldServer var2 = par1EntityPlayerMP.getServerForPlayer();
201            var2.setEntityDead(par1EntityPlayerMP);
202            var2.getPlayerManager().removePlayer(par1EntityPlayerMP);
203            this.playerEntityList.remove(par1EntityPlayerMP);
204            this.sendPacketToAllPlayers(new Packet201PlayerInfo(par1EntityPlayerMP.username, false, 9999));
205        }
206    
207        /**
208         * checks ban-lists, then white-lists, then space for the server. Returns null on success, or an error message
209         */
210        public String allowUserToConnect(SocketAddress par1SocketAddress, String par2Str)
211        {
212            if (this.bannedPlayers.isBanned(par2Str))
213            {
214                BanEntry var6 = (BanEntry)this.bannedPlayers.getBannedList().get(par2Str);
215                String var7 = "You are banned from this server!\nReason: " + var6.getBanReason();
216    
217                if (var6.getBanEndDate() != null)
218                {
219                    var7 = var7 + "\nYour ban will be removed on " + dateFormat.format(var6.getBanEndDate());
220                }
221    
222                return var7;
223            }
224            else if (!this.isAllowedToLogin(par2Str))
225            {
226                return "You are not white-listed on this server!";
227            }
228            else
229            {
230                String var3 = par1SocketAddress.toString();
231                var3 = var3.substring(var3.indexOf("/") + 1);
232                var3 = var3.substring(0, var3.indexOf(":"));
233    
234                if (this.bannedIPs.isBanned(var3))
235                {
236                    BanEntry var4 = (BanEntry)this.bannedIPs.getBannedList().get(var3);
237                    String var5 = "Your IP address is banned from this server!\nReason: " + var4.getBanReason();
238    
239                    if (var4.getBanEndDate() != null)
240                    {
241                        var5 = var5 + "\nYour ban will be removed on " + dateFormat.format(var4.getBanEndDate());
242                    }
243    
244                    return var5;
245                }
246                else
247                {
248                    return this.playerEntityList.size() >= this.maxPlayers ? "The server is full!" : null;
249                }
250            }
251        }
252    
253        /**
254         * also checks for multiple logins
255         */
256        public EntityPlayerMP createPlayerForUser(String par1Str)
257        {
258            ArrayList var2 = new ArrayList();
259            EntityPlayerMP var4;
260    
261            for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3)
262            {
263                var4 = (EntityPlayerMP)this.playerEntityList.get(var3);
264    
265                if (var4.username.equalsIgnoreCase(par1Str))
266                {
267                    var2.add(var4);
268                }
269            }
270    
271            Iterator var5 = var2.iterator();
272    
273            while (var5.hasNext())
274            {
275                var4 = (EntityPlayerMP)var5.next();
276                var4.playerNetServerHandler.kickPlayerFromServer("You logged in from another location");
277            }
278    
279            Object var6;
280    
281            if (this.mcServer.isDemo())
282            {
283                var6 = new DemoWorldManager(this.mcServer.worldServerForDimension(0));
284            }
285            else
286            {
287                var6 = new ItemInWorldManager(this.mcServer.worldServerForDimension(0));
288            }
289    
290            return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), par1Str, (ItemInWorldManager)var6);
291        }
292    
293        /**
294         * creates and returns a respawned player based on the provided PlayerEntity. Args are the PlayerEntityMP to
295         * respawn, an INT for the dimension to respawn into (usually 0), and a boolean value that is true if the player
296         * beat the game rather than dying
297         */
298        public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int par2, boolean par3)
299        {
300            World world = mcServer.worldServerForDimension(par2);
301            if (world == null)
302            {
303                par2 = 0;
304            }
305            else if (!world.provider.canRespawnHere())
306            {
307                par2 = world.provider.getRespawnDimension(par1EntityPlayerMP);
308            }
309    
310            par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeAllTrackingPlayers(par1EntityPlayerMP);
311            par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeEntityFromAllTrackingPlayers(par1EntityPlayerMP);
312            par1EntityPlayerMP.getServerForPlayer().getPlayerManager().removePlayer(par1EntityPlayerMP);
313            this.playerEntityList.remove(par1EntityPlayerMP);
314            this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension).removeEntity(par1EntityPlayerMP);
315            ChunkCoordinates var4 = par1EntityPlayerMP.getBedLocation();
316            boolean var5 = par1EntityPlayerMP.isSpawnForced();
317            par1EntityPlayerMP.dimension = par2;
318            Object var6;
319    
320            if (this.mcServer.isDemo())
321            {
322                var6 = new DemoWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension));
323            }
324            else
325            {
326                var6 = new ItemInWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension));
327            }
328    
329            EntityPlayerMP var7 = new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), par1EntityPlayerMP.username, (ItemInWorldManager)var6);
330            var7.playerNetServerHandler = par1EntityPlayerMP.playerNetServerHandler;
331            var7.clonePlayer(par1EntityPlayerMP, par3);
332            var7.dimension = par2;
333            var7.entityId = par1EntityPlayerMP.entityId;
334            WorldServer var8 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
335            this.func_72381_a(var7, par1EntityPlayerMP, var8);
336            ChunkCoordinates var9;
337    
338            if (var4 != null)
339            {
340                var9 = EntityPlayer.verifyRespawnCoordinates(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), var4, var5);
341    
342                if (var9 != null)
343                {
344                    var7.setLocationAndAngles((double)((float)var9.posX + 0.5F), (double)((float)var9.posY + 0.1F), (double)((float)var9.posZ + 0.5F), 0.0F, 0.0F);
345                    var7.setSpawnChunk(var4, var5);
346                }
347                else
348                {
349                    var7.playerNetServerHandler.sendPacketToPlayer(new Packet70GameEvent(0, 0));
350                }
351            }
352    
353            var8.theChunkProviderServer.loadChunk((int)var7.posX >> 4, (int)var7.posZ >> 4);
354    
355            while (!var8.getCollidingBoundingBoxes(var7, var7.boundingBox).isEmpty())
356            {
357                var7.setPosition(var7.posX, var7.posY + 1.0D, var7.posZ);
358            }
359    
360            var7.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(var7.dimension, (byte)var7.worldObj.difficultySetting, var7.worldObj.getWorldInfo().getTerrainType(), var7.worldObj.getHeight(), var7.theItemInWorldManager.getGameType()));
361            var9 = var8.getSpawnPoint();
362            var7.playerNetServerHandler.setPlayerLocation(var7.posX, var7.posY, var7.posZ, var7.rotationYaw, var7.rotationPitch);
363            var7.playerNetServerHandler.sendPacketToPlayer(new Packet6SpawnPosition(var9.posX, var9.posY, var9.posZ));
364            var7.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(var7.experience, var7.experienceTotal, var7.experienceLevel));
365            this.updateTimeAndWeatherForPlayer(var7, var8);
366            var8.getPlayerManager().addPlayer(var7);
367            var8.spawnEntityInWorld(var7);
368            this.playerEntityList.add(var7);
369            var7.addSelfToInternalCraftingInventory();
370            GameRegistry.onPlayerRespawn(var7);
371            return var7;
372        }
373    
374        public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2)
375        {
376            transferPlayerToDimension(par1EntityPlayerMP, par2, mcServer.worldServerForDimension(par2).func_85176_s());
377        }
378    
379        public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2, Teleporter teleporter)
380        {
381            int var3 = par1EntityPlayerMP.dimension;
382            WorldServer var4 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
383            par1EntityPlayerMP.dimension = par2;
384            WorldServer var5 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
385    
386            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(par1EntityPlayerMP.dimension, (byte)par1EntityPlayerMP.worldObj.difficultySetting, var5.getWorldInfo().getTerrainType(), var5.getHeight(), par1EntityPlayerMP.theItemInWorldManager.getGameType()));
387            var4.removeEntity(par1EntityPlayerMP);
388            par1EntityPlayerMP.isDead = false;
389            this.transferEntityToWorld(par1EntityPlayerMP, var3, var4, var5, teleporter);
390            this.func_72375_a(par1EntityPlayerMP, var4);
391            par1EntityPlayerMP.playerNetServerHandler.setPlayerLocation(par1EntityPlayerMP.posX, par1EntityPlayerMP.posY, par1EntityPlayerMP.posZ, par1EntityPlayerMP.rotationYaw, par1EntityPlayerMP.rotationPitch);
392            par1EntityPlayerMP.theItemInWorldManager.setWorld(var5);
393            this.updateTimeAndWeatherForPlayer(par1EntityPlayerMP, var5);
394            this.syncPlayerInventory(par1EntityPlayerMP);
395            Iterator var6 = par1EntityPlayerMP.getActivePotionEffects().iterator();
396    
397            while (var6.hasNext())
398            {
399                PotionEffect var7 = (PotionEffect)var6.next();
400                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(par1EntityPlayerMP.entityId, var7));
401            }
402            GameRegistry.onPlayerChangedDimension(par1EntityPlayerMP);
403        }
404    
405        /**
406         * Transfers an entity from a world to another world.
407         */
408        public void transferEntityToWorld(Entity par1Entity, int par2, WorldServer par3WorldServer, WorldServer par4WorldServer)
409        {
410            transferEntityToWorld(par1Entity, par2, par3WorldServer, par4WorldServer, par4WorldServer.func_85176_s());
411        }
412    
413        public void transferEntityToWorld(Entity par1Entity, int par2, WorldServer par3WorldServer, WorldServer par4WorldServer, Teleporter teleporter)
414        {
415            WorldProvider pOld = par3WorldServer.provider;
416            WorldProvider pNew = par4WorldServer.provider;
417            double moveFactor = pOld.getMovementFactor() / pNew.getMovementFactor();
418            double var5 = par1Entity.posX * moveFactor;
419            double var7 = par1Entity.posZ * moveFactor;
420            double var11 = par1Entity.posX;
421            double var13 = par1Entity.posY;
422            double var15 = par1Entity.posZ;
423            float var17 = par1Entity.rotationYaw;
424            par3WorldServer.theProfiler.startSection("moving");
425    
426            if (par1Entity.dimension == 1)
427            {
428                ChunkCoordinates var18;
429    
430                if (par2 == 1)
431                {
432                    var18 = par4WorldServer.getSpawnPoint();
433                }
434                else
435                {
436                    var18 = par4WorldServer.getEntrancePortalLocation();
437                }
438    
439                var5 = (double)var18.posX;
440                par1Entity.posY = (double)var18.posY;
441                var7 = (double)var18.posZ;
442                par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, 90.0F, 0.0F);
443    
444                if (par1Entity.isEntityAlive())
445                {
446                    par3WorldServer.updateEntityWithOptionalForce(par1Entity, false);
447                }
448            }
449    
450            par3WorldServer.theProfiler.endSection();
451    
452            if (par2 != 1)
453            {
454                par3WorldServer.theProfiler.startSection("placing");
455                var5 = (double)MathHelper.clamp_int((int)var5, -29999872, 29999872);
456                var7 = (double)MathHelper.clamp_int((int)var7, -29999872, 29999872);
457    
458                if (par1Entity.isEntityAlive())
459                {
460                    par4WorldServer.spawnEntityInWorld(par1Entity);
461                    par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, par1Entity.rotationYaw, par1Entity.rotationPitch);
462                    par4WorldServer.updateEntityWithOptionalForce(par1Entity, false);
463                    teleporter.placeInPortal(par1Entity, var11, var13, var15, var17);
464                }
465    
466                par3WorldServer.theProfiler.endSection();
467            }
468    
469            par1Entity.setWorld(par4WorldServer);
470        }
471    
472        /**
473         * sends 1 player per tick, but only sends a player once every 600 ticks
474         */
475        public void sendPlayerInfoToAllPlayers()
476        {
477            if (++this.playerPingIndex > 600)
478            {
479                this.playerPingIndex = 0;
480            }
481    
482            if (this.playerPingIndex < this.playerEntityList.size())
483            {
484                EntityPlayerMP var1 = (EntityPlayerMP)this.playerEntityList.get(this.playerPingIndex);
485                this.sendPacketToAllPlayers(new Packet201PlayerInfo(var1.username, true, var1.ping));
486            }
487        }
488    
489        /**
490         * sends a packet to all players
491         */
492        public void sendPacketToAllPlayers(Packet par1Packet)
493        {
494            for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2)
495            {
496                ((EntityPlayerMP)this.playerEntityList.get(var2)).playerNetServerHandler.sendPacketToPlayer(par1Packet);
497            }
498        }
499    
500        /**
501         * Sends a packet to all players in the specified Dimension
502         */
503        public void sendPacketToAllPlayersInDimension(Packet par1Packet, int par2)
504        {
505            for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3)
506            {
507                EntityPlayerMP var4 = (EntityPlayerMP)this.playerEntityList.get(var3);
508    
509                if (var4.dimension == par2)
510                {
511                    var4.playerNetServerHandler.sendPacketToPlayer(par1Packet);
512                }
513            }
514        }
515    
516        /**
517         * returns a string containing a comma-seperated list of player names
518         */
519        public String getPlayerListAsString()
520        {
521            String var1 = "";
522    
523            for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2)
524            {
525                if (var2 > 0)
526                {
527                    var1 = var1 + ", ";
528                }
529    
530                var1 = var1 + ((EntityPlayerMP)this.playerEntityList.get(var2)).username;
531            }
532    
533            return var1;
534        }
535    
536        /**
537         * Returns an array of the usernames of all the connected players.
538         */
539        public String[] getAllUsernames()
540        {
541            String[] var1 = new String[this.playerEntityList.size()];
542    
543            for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2)
544            {
545                var1[var2] = ((EntityPlayerMP)this.playerEntityList.get(var2)).username;
546            }
547    
548            return var1;
549        }
550    
551        public BanList getBannedPlayers()
552        {
553            return this.bannedPlayers;
554        }
555    
556        public BanList getBannedIPs()
557        {
558            return this.bannedIPs;
559        }
560    
561        /**
562         * This adds a username to the ops list, then saves the op list
563         */
564        public void addOp(String par1Str)
565        {
566            this.ops.add(par1Str.toLowerCase());
567        }
568    
569        /**
570         * This removes a username from the ops list, then saves the op list
571         */
572        public void removeOp(String par1Str)
573        {
574            this.ops.remove(par1Str.toLowerCase());
575        }
576    
577        /**
578         * Determine if the player is allowed to connect based on current server settings.
579         */
580        public boolean isAllowedToLogin(String par1Str)
581        {
582            par1Str = par1Str.trim().toLowerCase();
583            return !this.whiteListEnforced || this.ops.contains(par1Str) || this.whiteListedPlayers.contains(par1Str);
584        }
585    
586        /**
587         * Returns true if the specific player is allowed to use commands.
588         */
589        public boolean areCommandsAllowed(String par1Str)
590        {
591            return this.ops.contains(par1Str.trim().toLowerCase()) || this.mcServer.isSinglePlayer() && this.mcServer.worldServers[0].getWorldInfo().areCommandsAllowed() && this.mcServer.getServerOwner().equalsIgnoreCase(par1Str) || this.commandsAllowedForAll;
592        }
593    
594        public EntityPlayerMP getPlayerForUsername(String par1Str)
595        {
596            Iterator var2 = this.playerEntityList.iterator();
597            EntityPlayerMP var3;
598    
599            do
600            {
601                if (!var2.hasNext())
602                {
603                    return null;
604                }
605    
606                var3 = (EntityPlayerMP)var2.next();
607            }
608            while (!var3.username.equalsIgnoreCase(par1Str));
609    
610            return var3;
611        }
612    
613        /**
614         * Find all players in a specified range and narrowing down by other parameters
615         */
616        public List findPlayers(ChunkCoordinates par1ChunkCoordinates, int par2, int par3, int par4, int par5, int par6, int par7)
617        {
618            if (this.playerEntityList.isEmpty())
619            {
620                return null;
621            }
622            else
623            {
624                Object var8 = new ArrayList();
625                boolean var9 = par4 < 0;
626                int var10 = par2 * par2;
627                int var11 = par3 * par3;
628                par4 = MathHelper.abs_int(par4);
629    
630                for (int var12 = 0; var12 < this.playerEntityList.size(); ++var12)
631                {
632                    EntityPlayerMP var13 = (EntityPlayerMP)this.playerEntityList.get(var12);
633    
634                    if (par1ChunkCoordinates != null && (par2 > 0 || par3 > 0))
635                    {
636                        float var14 = par1ChunkCoordinates.getDistanceSquaredToChunkCoordinates(var13.getPlayerCoordinates());
637    
638                        if (par2 > 0 && var14 < (float)var10 || par3 > 0 && var14 > (float)var11)
639                        {
640                            continue;
641                        }
642                    }
643    
644                    if ((par5 == EnumGameType.NOT_SET.getID() || par5 == var13.theItemInWorldManager.getGameType().getID()) && (par6 <= 0 || var13.experienceLevel >= par6) && var13.experienceLevel <= par7)
645                    {
646                        ((List)var8).add(var13);
647                    }
648                }
649    
650                if (par1ChunkCoordinates != null)
651                {
652                    Collections.sort((List)var8, new PlayerPositionComparator(par1ChunkCoordinates));
653                }
654    
655                if (var9)
656                {
657                    Collections.reverse((List)var8);
658                }
659    
660                if (par4 > 0)
661                {
662                    var8 = ((List)var8).subList(0, Math.min(par4, ((List)var8).size()));
663                }
664    
665                return (List)var8;
666            }
667        }
668    
669        /**
670         * params: x,y,z,d,dimension. The packet is sent to all players within d distance of x,y,z (d^2<x^2+y^2+z^2)
671         */
672        public void sendToAllNear(double par1, double par3, double par5, double par7, int par9, Packet par10Packet)
673        {
674            this.sendToAllNearExcept((EntityPlayer)null, par1, par3, par5, par7, par9, par10Packet);
675        }
676    
677        /**
678         * params: srcPlayer,x,y,z,d,dimension. The packet is not sent to the srcPlayer, but all other players where
679         * dx*dx+dy*dy+dz*dz<d*d
680         */
681        public void sendToAllNearExcept(EntityPlayer par1EntityPlayer, double par2, double par4, double par6, double par8, int par10, Packet par11Packet)
682        {
683            for (int var12 = 0; var12 < this.playerEntityList.size(); ++var12)
684            {
685                EntityPlayerMP var13 = (EntityPlayerMP)this.playerEntityList.get(var12);
686    
687                if (var13 != par1EntityPlayer && var13.dimension == par10)
688                {
689                    double var14 = par2 - var13.posX;
690                    double var16 = par4 - var13.posY;
691                    double var18 = par6 - var13.posZ;
692    
693                    if (var14 * var14 + var16 * var16 + var18 * var18 < par8 * par8)
694                    {
695                        var13.playerNetServerHandler.sendPacketToPlayer(par11Packet);
696                    }
697                }
698            }
699        }
700    
701        /**
702         * Saves all of the players' current states.
703         */
704        public void saveAllPlayerData()
705        {
706            for (int var1 = 0; var1 < this.playerEntityList.size(); ++var1)
707            {
708                this.writePlayerData((EntityPlayerMP)this.playerEntityList.get(var1));
709            }
710        }
711    
712        /**
713         * Add the specified player to the white list.
714         */
715        public void addToWhiteList(String par1Str)
716        {
717            this.whiteListedPlayers.add(par1Str);
718        }
719    
720        /**
721         * Remove the specified player from the whitelist.
722         */
723        public void removeFromWhitelist(String par1Str)
724        {
725            this.whiteListedPlayers.remove(par1Str);
726        }
727    
728        /**
729         * Returns the whitelisted players.
730         */
731        public Set getWhiteListedPlayers()
732        {
733            return this.whiteListedPlayers;
734        }
735    
736        public Set getOps()
737        {
738            return this.ops;
739        }
740    
741        /**
742         * Either does nothing, or calls readWhiteList.
743         */
744        public void loadWhiteList() {}
745    
746        /**
747         * Updates the time and weather for the given player to those of the given world
748         */
749        public void updateTimeAndWeatherForPlayer(EntityPlayerMP par1EntityPlayerMP, WorldServer par2WorldServer)
750        {
751            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet4UpdateTime(par2WorldServer.getTotalWorldTime(), par2WorldServer.getWorldTime()));
752    
753            if (par2WorldServer.isRaining())
754            {
755                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet70GameEvent(1, 0));
756            }
757        }
758    
759        /**
760         * sends the players inventory to himself
761         */
762        public void syncPlayerInventory(EntityPlayerMP par1EntityPlayerMP)
763        {
764            par1EntityPlayerMP.sendContainerToPlayer(par1EntityPlayerMP.inventoryContainer);
765            par1EntityPlayerMP.setPlayerHealthUpdated();
766        }
767    
768        /**
769         * Returns the number of players currently on the server.
770         */
771        public int getCurrentPlayerCount()
772        {
773            return this.playerEntityList.size();
774        }
775    
776        /**
777         * Returns the maximum number of players allowed on the server.
778         */
779        public int getMaxPlayers()
780        {
781            return this.maxPlayers;
782        }
783    
784        /**
785         * Returns an array of usernames for which player.dat exists for.
786         */
787        public String[] getAvailablePlayerDat()
788        {
789            return this.mcServer.worldServers[0].getSaveHandler().getSaveHandler().getAvailablePlayerDat();
790        }
791    
792        public boolean isWhiteListEnabled()
793        {
794            return this.whiteListEnforced;
795        }
796    
797        public void setWhiteListEnabled(boolean par1)
798        {
799            this.whiteListEnforced = par1;
800        }
801    
802        public List getPlayerList(String par1Str)
803        {
804            ArrayList var2 = new ArrayList();
805            Iterator var3 = this.playerEntityList.iterator();
806    
807            while (var3.hasNext())
808            {
809                EntityPlayerMP var4 = (EntityPlayerMP)var3.next();
810    
811                if (var4.func_71114_r().equals(par1Str))
812                {
813                    var2.add(var4);
814                }
815            }
816    
817            return var2;
818        }
819    
820        /**
821         * Gets the View Distance.
822         */
823        public int getViewDistance()
824        {
825            return this.viewDistance;
826        }
827    
828        public MinecraftServer getServerInstance()
829        {
830            return this.mcServer;
831        }
832    
833        /**
834         * gets the tags created in the last writePlayerData call
835         */
836        public NBTTagCompound getTagsFromLastWrite()
837        {
838            return null;
839        }
840    
841        @SideOnly(Side.CLIENT)
842        public void setGameType(EnumGameType par1EnumGameType)
843        {
844            this.gameType = par1EnumGameType;
845        }
846    
847        private void func_72381_a(EntityPlayerMP par1EntityPlayerMP, EntityPlayerMP par2EntityPlayerMP, World par3World)
848        {
849            if (par2EntityPlayerMP != null)
850            {
851                par1EntityPlayerMP.theItemInWorldManager.setGameType(par2EntityPlayerMP.theItemInWorldManager.getGameType());
852            }
853            else if (this.gameType != null)
854            {
855                par1EntityPlayerMP.theItemInWorldManager.setGameType(this.gameType);
856            }
857    
858            par1EntityPlayerMP.theItemInWorldManager.initializeGameType(par3World.getWorldInfo().getGameType());
859        }
860    
861        @SideOnly(Side.CLIENT)
862    
863        /**
864         * Sets whether all players are allowed to use commands (cheats) on the server.
865         */
866        public void setCommandsAllowedForAll(boolean par1)
867        {
868            this.commandsAllowedForAll = par1;
869        }
870    
871        /**
872         * Kicks everyone with "Server closed" as reason.
873         */
874        public void removeAllPlayers()
875        {
876            while (!this.playerEntityList.isEmpty())
877            {
878                ((EntityPlayerMP)this.playerEntityList.get(0)).playerNetServerHandler.kickPlayerFromServer("Server closed");
879            }
880        }
881    }