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