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