package net.minecraft.server; import java.util.ArrayList; import java.util.List; // CraftBukkit start import org.bukkit.BlockChangeDelegate; import org.bukkit.generator.ChunkGenerator; import org.bukkit.craftbukkit.generator.CustomChunkGenerator; import org.bukkit.craftbukkit.generator.InternalChunkGenerator; import org.bukkit.craftbukkit.generator.NetherChunkGenerator; import org.bukkit.craftbukkit.generator.NormalChunkGenerator; import org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator; import org.bukkit.event.weather.LightningStrikeEvent; public class WorldServer extends World implements BlockChangeDelegate { // CraftBukkit end public ChunkProviderServer chunkProviderServer; public boolean weirdIsOpCache = false; public boolean savingDisabled; public final MinecraftServer server; // CraftBukkit - private -> public final private IntHashMap entitiesById; // CraftBukkit start - change signature public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, String s, int i, WorldSettings worldsettings, org.bukkit.World.Environment env, ChunkGenerator gen) { super(idatamanager, s, worldsettings, WorldProvider.byDimension(env.getId()), gen, env); this.server = minecraftserver; if (this.entitiesById == null) { this.entitiesById = new IntHashMap(); } this.dimension = i; this.pvpMode = minecraftserver.pvpMode; this.manager = new PlayerManager(minecraftserver, this.dimension, minecraftserver.propertyManager.getInt("view-distance", 10)); } @Override public TileEntity getTileEntity(int i, int j, int k) { TileEntity result = super.getTileEntity(i, j, k); int type = getTypeId(i, j, k); if (type == Block.CHEST.id) { if (!(result instanceof TileEntityChest)) { result = fixTileEntity(i, j, k, type, result); } } else if (type == Block.FURNACE.id) { if (!(result instanceof TileEntityFurnace)) { result = fixTileEntity(i, j, k, type, result); } } else if (type == Block.DISPENSER.id) { if (!(result instanceof TileEntityDispenser)) { result = fixTileEntity(i, j, k, type, result); } } else if (type == Block.JUKEBOX.id) { if (!(result instanceof TileEntityRecordPlayer)) { result = fixTileEntity(i, j, k, type, result); } } else if (type == Block.NOTE_BLOCK.id) { if (!(result instanceof TileEntityNote)) { result = fixTileEntity(i, j, k, type, result); } } else if (type == Block.MOB_SPAWNER.id) { if (!(result instanceof TileEntityMobSpawner)) { result = fixTileEntity(i, j, k, type, result); } } else if ((type == Block.SIGN_POST.id) || (type == Block.WALL_SIGN.id)) { if (!(result instanceof TileEntitySign)) { result = fixTileEntity(i, j, k, type, result); } } return result; } private TileEntity fixTileEntity(int x, int y, int z, int type, TileEntity found) { getServer().getLogger().severe("Block at " + x + "," + y + "," + z + " is " + org.bukkit.Material.getMaterial(type).toString() + " but has " + found + ". " + "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover."); if (Block.byId[type] instanceof BlockContainer) { TileEntity replacement = ((BlockContainer) Block.byId[type]).a_(); setTileEntity(x, y, z, replacement); return replacement; } else { getServer().getLogger().severe("Don't know how to fix for this type... Can't do anything! :("); return found; } } public final int dimension; public EntityTracker tracker; public PlayerManager manager; // CraftBukkit end public void entityJoinedWorld(Entity entity, boolean flag) { /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed if (!this.server.spawnAnimals && (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal)) { entity.die(); } // CraftBukkit end */ if (!this.server.spawnNPCs && entity instanceof NPC) { entity.die(); } if (entity.passenger == null || !(entity.passenger instanceof EntityHuman)) { super.entityJoinedWorld(entity, flag); } } public void vehicleEnteredWorld(Entity entity, boolean flag) { super.entityJoinedWorld(entity, flag); } protected IChunkProvider b() { IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider); // CraftBukkit start InternalChunkGenerator gen; if (this.generator != null) { gen = new CustomChunkGenerator(this, this.getSeed(), this.generator); } else if (this.worldProvider instanceof WorldProviderHell) { gen = new NetherChunkGenerator(this, this.getSeed()); } else if (this.worldProvider instanceof WorldProviderTheEnd) { gen = new SkyLandsChunkGenerator(this, this.getSeed()); } else { gen = new NormalChunkGenerator(this, this.getSeed()); } this.chunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen); // CraftBukkit end return this.chunkProviderServer; } public List getTileEntities(int i, int j, int k, int l, int i1, int j1) { ArrayList arraylist = new ArrayList(); for (int k1 = 0; k1 < this.tileEntityList.size(); ++k1) { TileEntity tileentity = (TileEntity) this.tileEntityList.get(k1); if (tileentity.x >= i && tileentity.y >= j && tileentity.z >= k && tileentity.x < l && tileentity.y < i1 && tileentity.z < j1) { arraylist.add(tileentity); } } return arraylist; } public boolean a(EntityHuman entityhuman, int i, int j, int k) { int l = MathHelper.a(i - this.worldData.c()); int i1 = MathHelper.a(k - this.worldData.e()); if (l > i1) { i1 = l; } // CraftBukkit - Configurable spawn protection return i1 > this.getServer().getSpawnRadius() || this.server.serverConfigurationManager.isOp(entityhuman.name); } protected void c() { if (this.entitiesById == null) { this.entitiesById = new IntHashMap(); } super.c(); } protected void c(Entity entity) { super.c(entity); this.entitiesById.a(entity.id, entity); Entity[] aentity = entity.bb(); if (aentity != null) { for (int i = 0; i < aentity.length; ++i) { this.entitiesById.a(aentity[i].id, aentity[i]); } } } protected void d(Entity entity) { super.d(entity); this.entitiesById.d(entity.id); Entity[] aentity = entity.bb(); if (aentity != null) { for (int i = 0; i < aentity.length; ++i) { this.entitiesById.d(aentity[i].id); } } } public Entity getEntity(int i) { return (Entity) this.entitiesById.get(i); } public boolean strikeLightning(Entity entity) { // CraftBukkit start LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entity.getBukkitEntity()); this.getServer().getPluginManager().callEvent(lightning); if (lightning.isCancelled()) { return false; } if (super.strikeLightning(entity)) { this.server.serverConfigurationManager.sendPacketNearby(entity.locX, entity.locY, entity.locZ, 512.0D, this.dimension, new Packet71Weather(entity)); // CraftBukkit end return true; } else { return false; } } public void broadcastEntityEffect(Entity entity, byte b0) { Packet38EntityStatus packet38entitystatus = new Packet38EntityStatus(entity.id, b0); // CraftBukkit this.server.getTracker(this.dimension).sendPacketToEntity(entity, packet38entitystatus); } public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag) { // CraftBukkit start Explosion explosion = super.createExplosion(entity, d0, d1, d2, f, flag); if (explosion.wasCanceled) { return explosion; } /* Remove explosion.a = flag; explosion.a(); explosion.a(false); */ this.server.serverConfigurationManager.sendPacketNearby(d0, d1, d2, 64.0D, this.dimension, new Packet60Explosion(d0, d1, d2, f, explosion.blocks)); // CraftBukkit end return explosion; } public void playNote(int i, int j, int k, int l, int i1) { super.playNote(i, j, k, l, i1); // CraftBukkit this.server.serverConfigurationManager.sendPacketNearby((double) i, (double) j, (double) k, 64.0D, this.dimension, new Packet54PlayNoteBlock(i, j, k, l, i1)); } public void saveLevel() { this.dataManager.e(); } protected void i() { boolean flag = this.x(); super.i(); if (flag != this.x()) { // CraftBukkit start - only sending weather packets to those affected for (int i = 0; i < this.players.size(); ++i) { if (((EntityPlayer) this.players.get(i)).world == this) { ((EntityPlayer) this.players.get(i)).netServerHandler.sendPacket(new Packet70Bed(flag ? 2 : 1, 0)); } } // CraftBukkit end } } }