    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            Iterator var3 = this.playerEntityList.iterator();
    178
    179            while (var3.hasNext())
    180            {
    181                EntityPlayerMP var4 = (EntityPlayerMP)var3.next();
    182                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet201PlayerInfo(var4.username, true, var4.ping));
    183            }
    184        }
    185
    186        /**
    187         * using player's dimension, update their movement when in a vehicle (e.g. cart, boat)
    188         */
    189        public void serverUpdateMountedMovingPlayer(EntityPlayerMP par1EntityPlayerMP)
    190        {
    191            par1EntityPlayerMP.getServerForPlayer().getPlayerManager().updateMountedMovingPlayer(par1EntityPlayerMP);
    192        }
    193
    194        /**
    195         * Called when a player disconnects from the game. Writes player data to disk and removes them from the world.
    196         */
    197        public void playerLoggedOut(EntityPlayerMP par1EntityPlayerMP)
    198        {
    199            GameRegistry.onPlayerLogout(par1EntityPlayerMP);
    200            this.writePlayerData(par1EntityPlayerMP);
    201            WorldServer var2 = par1EntityPlayerMP.getServerForPlayer();
    202            var2.setEntityDead(par1EntityPlayerMP);
    203            var2.getPlayerManager().removePlayer(par1EntityPlayerMP);
    204            this.playerEntityList.remove(par1EntityPlayerMP);
    205            this.sendPacketToAllPlayers(new Packet201PlayerInfo(par1EntityPlayerMP.username, false, 9999));
    206        }
    207
    208        /**
    209         * checks ban-lists, then white-lists, then space for the server. Returns null on success, or an error message
    210         */
    211        public String allowUserToConnect(SocketAddress par1SocketAddress, String par2Str)
    212        {
    213            if (this.bannedPlayers.isBanned(par2Str))
    214            {
    215                BanEntry var6 = (BanEntry)this.bannedPlayers.getBannedList().get(par2Str);
    216                String var7 = "You are banned from this server!\nReason: " + var6.getBanReason();
    217
    218                if (var6.getBanEndDate() != null)
    219                {
    220                    var7 = var7 + "\nYour ban will be removed on " + dateFormat.format(var6.getBanEndDate());
    221                }
    222
    223                return var7;
    224            }
    225            else if (!this.isAllowedToLogin(par2Str))
    226            {
    227                return "You are not white-listed on this server!";
    228            }
    229            else
    230            {
    231                String var3 = par1SocketAddress.toString();
    232                var3 = var3.substring(var3.indexOf("/") + 1);
    233                var3 = var3.substring(0, var3.indexOf(":"));
    234
    235                if (this.bannedIPs.isBanned(var3))
    236                {
    237                    BanEntry var4 = (BanEntry)this.bannedIPs.getBannedList().get(var3);
    238                    String var5 = "Your IP address is banned from this server!\nReason: " + var4.getBanReason();
    239
    240                    if (var4.getBanEndDate() != null)
    241                    {
    242                        var5 = var5 + "\nYour ban will be removed on " + dateFormat.format(var4.getBanEndDate());
    243                    }
    244
    245                    return var5;
    246                }
    247                else
    248                {
    249                    return this.playerEntityList.size() >= this.maxPlayers ? "The server is full!" : null;
    250                }
    251            }
    252        }
    253
    254        /**
    255         * also checks for multiple logins
    256         */
    257        public EntityPlayerMP createPlayerForUser(String par1Str)
    258        {
    259            ArrayList var2 = new ArrayList();
    260            Iterator var3 = this.playerEntityList.iterator();
    261            EntityPlayerMP var4;
    262
    263            while (var3.hasNext())
    264            {
    265                var4 = (EntityPlayerMP)var3.next();
    266
    267                if (var4.username.equalsIgnoreCase(par1Str))
    268                {
    269                    var2.add(var4);
    270                }
    271            }
    272
    273            var3 = var2.iterator();
    274
    275            while (var3.hasNext())
    276            {
    277                var4 = (EntityPlayerMP)var3.next();
    278                var4.playerNetServerHandler.kickPlayerFromServer("You logged in from another location");
    279            }
    280
    281            Object var5;
    282
    283            if (this.mcServer.isDemo())
    284            {
    285                var5 = new DemoWorldManager(this.mcServer.worldServerForDimension(0));
    286            }
    287            else
    288            {
    289                var5 = new ItemInWorldManager(this.mcServer.worldServerForDimension(0));
    290            }
    291
    292            return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), par1Str, (ItemInWorldManager)var5);
    293        }
    294
    295        /**
    296         * creates and returns a respawned player based on the provided PlayerEntity. Args are the PlayerEntityMP to
    297         * respawn, an INT for the dimension to respawn into (usually 0), and a boolean value that is true if the player
    298         * beat the game rather than dying
    299         */
    300        public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int par2, boolean par3)
    301        {
    302            World world = mcServer.worldServerForDimension(par2);
    303            if (world == null || !world.provider.canRespawnHere())
    304            {
    305                par2 = 0;
    306            }
    307
    308            par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeAllTrackingPlayers(par1EntityPlayerMP);
    309            par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeEntityFromAllTrackingPlayers(par1EntityPlayerMP);
    310            par1EntityPlayerMP.getServerForPlayer().getPlayerManager().removePlayer(par1EntityPlayerMP);
    311            this.playerEntityList.remove(par1EntityPlayerMP);
    312            this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension).removeEntity(par1EntityPlayerMP);
    313            ChunkCoordinates var4 = par1EntityPlayerMP.getSpawnChunk();
    314            boolean var5 = par1EntityPlayerMP.func_82245_bX();
    315            par1EntityPlayerMP.dimension = par2;
    316            Object var6;
    317
    318            if (this.mcServer.isDemo())
    319            {
    320                var6 = new DemoWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension));
    321            }
    322            else
    323            {
    324                var6 = new ItemInWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension));
    325            }
    326
    327            EntityPlayerMP var7 = new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), par1EntityPlayerMP.username, (ItemInWorldManager)var6);
    328            var7.playerNetServerHandler = par1EntityPlayerMP.playerNetServerHandler;
    329            var7.clonePlayer(par1EntityPlayerMP, par3);
    330            var7.dimension = par2;
    331            var7.entityId = par1EntityPlayerMP.entityId;
    332            WorldServer var8 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
    333            this.func_72381_a(var7, par1EntityPlayerMP, var8);
    334            ChunkCoordinates var9;
    335
    336            if (var4 != null)
    337            {
    338                var9 = EntityPlayer.verifyRespawnCoordinates(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), var4, var5);
    339
    340                if (var9 != null)
    341                {
    342                    var7.setLocationAndAngles((double)((float)var9.posX + 0.5F), (double)((float)var9.posY + 0.1F), (double)((float)var9.posZ + 0.5F), 0.0F, 0.0F);
    343                    var7.setSpawnChunk(var4, var5);
    344                }
    345                else
    346                {
    347                    var7.playerNetServerHandler.sendPacketToPlayer(new Packet70GameEvent(0, 0));
    348                }
    349            }
    350
    351            var8.theChunkProviderServer.loadChunk((int)var7.posX >> 4, (int)var7.posZ >> 4);
    352
    353            while (!var8.getCollidingBoundingBoxes(var7, var7.boundingBox).isEmpty())
    354            {
    355                var7.setPosition(var7.posX, var7.posY + 1.0D, var7.posZ);
    356            }
    357
    358            var7.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(var7.dimension, (byte)var7.worldObj.difficultySetting, var7.worldObj.getWorldInfo().getTerrainType(), var7.worldObj.getHeight(), var7.theItemInWorldManager.getGameType()));
    359            var9 = var8.getSpawnPoint();
    360            var7.playerNetServerHandler.setPlayerLocation(var7.posX, var7.posY, var7.posZ, var7.rotationYaw, var7.rotationPitch);
    361            var7.playerNetServerHandler.sendPacketToPlayer(new Packet6SpawnPosition(var9.posX, var9.posY, var9.posZ));
    362            var7.playerNetServerHandler.sendPacketToPlayer(new Packet43Experience(var7.experience, var7.experienceTotal, var7.experienceLevel));
    363            this.updateTimeAndWeatherForPlayer(var7, var8);
    364            var8.getPlayerManager().addPlayer(var7);
    365            var8.spawnEntityInWorld(var7);
    366            this.playerEntityList.add(var7);
    367            var7.addSelfToInternalCraftingInventory();
    368            GameRegistry.onPlayerRespawn(var7);
    369            return var7;
    370        }
    371
    372        public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2)
    373        {
    374            transferPlayerToDimension(par1EntityPlayerMP, par2, mcServer.worldServerForDimension(par2).func_85176_s());
    375        }
    376
    377        public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2, Teleporter teleporter)
    378        {
    379            int var3 = par1EntityPlayerMP.dimension;
    380            WorldServer var4 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
    381            par1EntityPlayerMP.dimension = par2;
    382            WorldServer var5 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension);
    383
    384            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet9Respawn(par1EntityPlayerMP.dimension, (byte)par1EntityPlayerMP.worldObj.difficultySetting, var5.getWorldInfo().getTerrainType(), var5.getHeight(), par1EntityPlayerMP.theItemInWorldManager.getGameType()));
    385            var4.removeEntity(par1EntityPlayerMP);
    386            par1EntityPlayerMP.isDead = false;
    387            this.transferEntityToWorld(par1EntityPlayerMP, var3, var4, var5, teleporter);
    388            this.func_72375_a(par1EntityPlayerMP, var4);
    389            par1EntityPlayerMP.playerNetServerHandler.setPlayerLocation(par1EntityPlayerMP.posX, par1EntityPlayerMP.posY, par1EntityPlayerMP.posZ, par1EntityPlayerMP.rotationYaw, par1EntityPlayerMP.rotationPitch);
    390            par1EntityPlayerMP.theItemInWorldManager.setWorld(var5);
    391            this.updateTimeAndWeatherForPlayer(par1EntityPlayerMP, var5);
    392            this.syncPlayerInventory(par1EntityPlayerMP);
    393            Iterator var6 = par1EntityPlayerMP.getActivePotionEffects().iterator();
    394
    395            while (var6.hasNext())
    396            {
    397                PotionEffect var7 = (PotionEffect)var6.next();
    398                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet41EntityEffect(par1EntityPlayerMP.entityId, var7));
    399            }
    400            GameRegistry.onPlayerChangedDimension(par1EntityPlayerMP);
    401        }
    402
    403        /**
    404         * Transfers an entity from a world to another world.
    405         */
    406        public void transferEntityToWorld(Entity par1Entity, int par2, WorldServer par3WorldServer, WorldServer par4WorldServer)
    407        {
    408            transferEntityToWorld(par1Entity, par2, par3WorldServer, par4WorldServer, par4WorldServer.func_85176_s());
    409        }
    410
    411        public void transferEntityToWorld(Entity par1Entity, int par2, WorldServer par3WorldServer, WorldServer par4WorldServer, Teleporter teleporter)
    412        {
    413            WorldProvider pOld = par3WorldServer.provider;
    414            WorldProvider pNew = par4WorldServer.provider;
    415            double moveFactor = pOld.getMovementFactor() / pNew.getMovementFactor();
    416            double var5 = par1Entity.posX * moveFactor;
    417            double var7 = par1Entity.posZ * moveFactor;
    418            double var11 = par1Entity.posX;
    419            double var13 = par1Entity.posY;
    420            double var15 = par1Entity.posZ;
    421            float var17 = par1Entity.rotationYaw;
    422            par3WorldServer.theProfiler.startSection("moving");
    423
    424            if (par1Entity.dimension == 1)
    425            {
    426                ChunkCoordinates var18;
    427
    428                if (par2 == 1)
    429                {
    430                    var18 = par4WorldServer.getSpawnPoint();
    431                }
    432                else
    433                {
    434                    var18 = par4WorldServer.getEntrancePortalLocation();
    435                }
    436
    437                var5 = (double)var18.posX;
    438                par1Entity.posY = (double)var18.posY;
    439                var7 = (double)var18.posZ;
    440                par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, 90.0F, 0.0F);
    441
    442                if (par1Entity.isEntityAlive())
    443                {
    444                    par3WorldServer.updateEntityWithOptionalForce(par1Entity, false);
    445                }
    446            }
    447
    448            par3WorldServer.theProfiler.endSection();
    449
    450            if (par2 != 1)
    451            {
    452                par3WorldServer.theProfiler.startSection("placing");
    453                var5 = (double)MathHelper.clamp_int((int)var5, -29999872, 29999872);
    454                var7 = (double)MathHelper.clamp_int((int)var7, -29999872, 29999872);
    455
    456                if (par1Entity.isEntityAlive())
    457                {
    458                    par4WorldServer.spawnEntityInWorld(par1Entity);
    459                    par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, par1Entity.rotationYaw, par1Entity.rotationPitch);
    460                    par4WorldServer.updateEntityWithOptionalForce(par1Entity, false);
    461                    teleporter.placeInPortal(par1Entity, var11, var13, var15, var17);
    462                }
    463
    464                par3WorldServer.theProfiler.endSection();
    465            }
    466
    467            par1Entity.setWorld(par4WorldServer);
    468        }
    469
    470        /**
    471         * sends 1 player per tick, but only sends a player once every 600 ticks
    472         */
    473        public void sendPlayerInfoToAllPlayers()
    474        {
    475            if (++this.playerPingIndex > 600)
    476            {
    477                this.playerPingIndex = 0;
    478            }
    479
    480            if (this.playerPingIndex < this.playerEntityList.size())
    481            {
    482                EntityPlayerMP var1 = (EntityPlayerMP)this.playerEntityList.get(this.playerPingIndex);
    483                this.sendPacketToAllPlayers(new Packet201PlayerInfo(var1.username, true, var1.ping));
    484            }
    485        }
    486
    487        /**
    488         * sends a packet to all players
    489         */
    490        public void sendPacketToAllPlayers(Packet par1Packet)
    491        {
    492            for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2)
    493            {
    494                ((EntityPlayerMP)this.playerEntityList.get(var2)).playerNetServerHandler.sendPacketToPlayer(par1Packet);
    495            }
    496        }
    497
    498        /**
    499         * Sends a packet to all players in the specified Dimension
    500         */
    501        public void sendPacketToAllPlayersInDimension(Packet par1Packet, int par2)
    502        {
    503            Iterator var3 = this.playerEntityList.iterator();
    504
    505            while (var3.hasNext())
    506            {
    507                EntityPlayerMP var4 = (EntityPlayerMP)var3.next();
    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            Iterator var12 = this.playerEntityList.iterator();
    684
    685            while (var12.hasNext())
    686            {
    687                EntityPlayerMP var13 = (EntityPlayerMP)var12.next();
    688
    689                if (var13 != par1EntityPlayer && var13.dimension == par10)
    690                {
    691                    double var14 = par2 - var13.posX;
    692                    double var16 = par4 - var13.posY;
    693                    double var18 = par6 - var13.posZ;
    694
    695                    if (var14 * var14 + var16 * var16 + var18 * var18 < par8 * par8)
    696                    {
    697                        var13.playerNetServerHandler.sendPacketToPlayer(par11Packet);
    698                    }
    699                }
    700            }
    701        }
    702
    703        /**
    704         * Saves all of the players' current states.
    705         */
    706        public void saveAllPlayerData()
    707        {
    708            Iterator var1 = this.playerEntityList.iterator();
    709
    710            while (var1.hasNext())
    711            {
    712                EntityPlayerMP var2 = (EntityPlayerMP)var1.next();
    713                this.writePlayerData(var2);
    714            }
    715        }
    716
    717        /**
    718         * Add the specified player to the white list.
    719         */
    720        public void addToWhiteList(String par1Str)
    721        {
    722            this.whiteListedPlayers.add(par1Str);
    723        }
    724
    725        /**
    726         * Remove the specified player from the whitelist.
    727         */
    728        public void removeFromWhitelist(String par1Str)
    729        {
    730            this.whiteListedPlayers.remove(par1Str);
    731        }
    732
    733        /**
    734         * Returns the whitelisted players.
    735         */
    736        public Set getWhiteListedPlayers()
    737        {
    738            return this.whiteListedPlayers;
    739        }
    740
    741        public Set getOps()
    742        {
    743            return this.ops;
    744        }
    745
    746        /**
    747         * Either does nothing, or calls readWhiteList.
    748         */
    749        public void loadWhiteList() {}
    750
    751        /**
    752         * Updates the time and weather for the given player to those of the given world
    753         */
    754        public void updateTimeAndWeatherForPlayer(EntityPlayerMP par1EntityPlayerMP, WorldServer par2WorldServer)
    755        {
    756            par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet4UpdateTime(par2WorldServer.getTotalWorldTime(), par2WorldServer.getWorldTime()));
    757
    758            if (par2WorldServer.isRaining())
    759            {
    760                par1EntityPlayerMP.playerNetServerHandler.sendPacketToPlayer(new Packet70GameEvent(1, 0));
    761            }
    762        }
    763
    764        /**
    765         * sends the players inventory to himself
    766         */
    767        public void syncPlayerInventory(EntityPlayerMP par1EntityPlayerMP)
    768        {
    769            par1EntityPlayerMP.sendContainerToPlayer(par1EntityPlayerMP.inventorySlots);
    770            par1EntityPlayerMP.setPlayerHealthUpdated();
    771        }
    772
    773        /**
    774         * Returns the number of players currently on the server.
    775         */
    776        public int getCurrentPlayerCount()
    777        {
    778            return this.playerEntityList.size();
    779        }
    780
    781        /**
    782         * Returns the maximum number of players allowed on the server.
    783         */
    784        public int getMaxPlayers()
    785        {
    786            return this.maxPlayers;
    787        }
    788
    789        /**
    790         * Returns an array of usernames for which player.dat exists for.
    791         */
    792        public String[] getAvailablePlayerDat()
    793        {
    794            return this.mcServer.worldServers[0].getSaveHandler().getSaveHandler().getAvailablePlayerDat();
    795        }
    796
    797        public boolean isWhiteListEnabled()
    798        {
    799            return this.whiteListEnforced;
    800        }
    801
    802        public void setWhiteListEnabled(boolean par1)
    803        {
    804            this.whiteListEnforced = par1;
    805        }
    806
    807        public List getPlayerList(String par1Str)
    808        {
    809            ArrayList var2 = new ArrayList();
    810            Iterator var3 = this.playerEntityList.iterator();
    811
    812            while (var3.hasNext())
    813            {
    814                EntityPlayerMP var4 = (EntityPlayerMP)var3.next();
    815
    816                if (var4.func_71114_r().equals(par1Str))
    817                {
    818                    var2.add(var4);
    819                }
    820            }
    821
    822            return var2;
    823        }
    824
    825        /**
    826         * Gets the View Distance.
    827         */
    828        public int getViewDistance()
    829        {
    830            return this.viewDistance;
    831        }
    832
    833        public MinecraftServer getServerInstance()
    834        {
    835            return this.mcServer;
    836        }
    837
    838        /**
    839         * gets the tags created in the last writePlayerData call
    840         */
    841        public NBTTagCompound getTagsFromLastWrite()
    842        {
    843            return null;
    844        }
    845
    846        @SideOnly(Side.CLIENT)
    847        public void setGameType(EnumGameType par1EnumGameType)
    848        {
    849            this.gameType = par1EnumGameType;
    850        }
    851
    852        private void func_72381_a(EntityPlayerMP par1EntityPlayerMP, EntityPlayerMP par2EntityPlayerMP, World par3World)
    853        {
    854            if (par2EntityPlayerMP != null)
    855            {
    856                par1EntityPlayerMP.theItemInWorldManager.setGameType(par2EntityPlayerMP.theItemInWorldManager.getGameType());
    857            }
    858            else if (this.gameType != null)
    859            {
    860                par1EntityPlayerMP.theItemInWorldManager.setGameType(this.gameType);
    861            }
    862
    863            par1EntityPlayerMP.theItemInWorldManager.initializeGameType(par3World.getWorldInfo().getGameType());
    864        }
    865
    866        @SideOnly(Side.CLIENT)
    867
    868        /**
    869         * Sets whether all players are allowed to use commands (cheats) on the server.
    870         */
    871        public void setCommandsAllowedForAll(boolean par1)
    872        {
    873            this.commandsAllowedForAll = par1;
    874        }
    875
    876        /**
    877         * Kicks everyone with "Server closed" as reason.
    878         */
    879        public void removeAllPlayers()
    880        {
    881            while (!this.playerEntityList.isEmpty())
    882            {
    883                ((EntityPlayerMP)this.playerEntityList.get(0)).playerNetServerHandler.kickPlayerFromServer("Server closed");
    884            }
    885        }
    886    }