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