--- a/net/minecraft/server/ChunkRegionLoader.java +++ b/net/minecraft/server/ChunkRegionLoader.java @@ -34,7 +34,7 @@ private final File c; private final DataFixer d; private PersistentStructureLegacy e; - private boolean f; + // private boolean f; // CraftBukkit public ChunkRegionLoader(File file, DataFixer datafixer) { this.c = file; @@ -50,12 +50,13 @@ @Nullable private NBTTagCompound b(GeneratorAccess generatoraccess, int i, int j) throws IOException { - DataInputStream datainputstream = RegionFileCache.d(this.c, i, j); + // CraftBukkit start + NBTTagCompound nbttagcompound = RegionFileCache.d(this.c, i, j); - if (datainputstream == null) { + if (nbttagcompound == null) { return null; } else { - NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(datainputstream); + // CraftBukkit end int k = nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : -1; if (k < 1493) { @@ -78,13 +79,29 @@ } } + // CraftBukkit start - Add async variant, provide compatibility @Nullable public synchronized Chunk a(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException { + Object[] data = loadChunk(generatoraccess, i, j, consumer); + if (data != null) { + Chunk chunk = (Chunk) data[0]; + NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; + consumer.accept(chunk); + this.loadEntities(nbttagcompound.getCompound("Level"), chunk); + return chunk; + } + + return null; + } + + public synchronized Object[] loadChunk(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException { + // CraftBukkit end NBTTagCompound nbttagcompound = this.a(generatoraccess, i, j); if (nbttagcompound == null) { return null; } else { + /* Chunk chunk = this.a(generatoraccess, i, j, nbttagcompound); if (chunk != null) { @@ -93,6 +110,9 @@ } return chunk; + */ + + return this.a(generatoraccess, i, j, nbttagcompound); } } @@ -121,7 +141,7 @@ } @Nullable - protected Chunk a(GeneratorAccess generatoraccess, int i, int j, NBTTagCompound nbttagcompound) { + protected Object[] a(GeneratorAccess generatoraccess, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[] if (nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8)) { ChunkStatus.Type chunkstatus_type = this.a(nbttagcompound); @@ -140,10 +160,28 @@ ChunkRegionLoader.a.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", Integer.valueOf(i), Integer.valueOf(j), Integer.valueOf(i), Integer.valueOf(j), Integer.valueOf(chunk.locX), Integer.valueOf(chunk.locZ)); nbttagcompound1.setInt("xPos", i); nbttagcompound1.setInt("zPos", j); + + // CraftBukkit start - Have to move tile entities since we don't load them at this stage + NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10); + if (tileEntities != null) { + for (int te = 0; te < tileEntities.size(); te++) { + NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te); + int x = tileEntity.getInt("x") - chunk.locX * 16; + int z = tileEntity.getInt("z") - chunk.locZ * 16; + tileEntity.setInt("x", i * 16 + x); + tileEntity.setInt("z", j * 16 + z); + } + } + // CraftBukkit end chunk = this.a(generatoraccess, nbttagcompound1); } - return chunk; + // CraftBukkit start + Object[] data = new Object[2]; + data[0] = chunk; + data[1] = nbttagcompound; + return data; + // CraftBukkit end } } } else { @@ -158,7 +196,7 @@ ChunkStatus.Type chunkstatus_type = this.a(nbttagcompound); if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) { - return new ProtoChunkExtension(this.a(generatoraccess, i, j, nbttagcompound)); + return new ProtoChunkExtension((IChunkAccess) this.a(generatoraccess, i, j, nbttagcompound)[0]); // CraftBukkit - fix up access } else { NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); @@ -204,19 +242,30 @@ } public synchronized boolean a() { - if (this.b.isEmpty()) { - if (this.f) { + // CraftBukkit start + return this.processSaveQueueEntry(false); + } + + private synchronized boolean processSaveQueueEntry(boolean logCompletion) { + Iterator> iter = this.b.entrySet().iterator(); + if (!iter.hasNext()) { + if (logCompletion) { + // CraftBukkit end ChunkRegionLoader.a.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.c.getName()); } return false; } else { - ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.b.keySet().iterator().next(); + // CraftBukkit start + Map.Entry entry = iter.next(); + ChunkCoordIntPair chunkcoordintpair = entry.getKey(); + NBTTagCompound nbttagcompound = entry.getValue(); + // CraftBukkit end boolean flag; try { - NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair); + // NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair); // CraftBukkit if (nbttagcompound != null) { try { @@ -228,7 +277,7 @@ flag = true; } finally { - this.b.remove(chunkcoordintpair); + this.b.remove(chunkcoordintpair, nbttagcompound); // CraftBukkit } return flag; @@ -248,10 +297,14 @@ } private void b(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { - DataOutputStream dataoutputstream = RegionFileCache.e(this.c, chunkcoordintpair.x, chunkcoordintpair.z); + // CraftBukkit start + RegionFileCache.e(this.c, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound); + /* NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); dataoutputstream.close(); + */ + // CraftBukkit end if (this.e != null) { this.e.a(chunkcoordintpair.a()); } @@ -264,15 +317,16 @@ public void c() { try { - this.f = true; + // this.f = true; // CraftBukkit while (true) { - if (this.a()) { + if (this.processSaveQueueEntry(true)) { // CraftBukkit continue; } + break; // CraftBukkit - Fix infinite loop when saving chunks } } finally { - this.f = false; + // this.f = false; // CraftBukkit } } @@ -301,7 +355,7 @@ if (abiomebase != null) { for (int k = 0; k < abiomebase.length; ++k) { - aint[k] = BiomeBase.REGISTRY_ID.a((Object) abiomebase[k]); + aint[k] = BiomeBase.REGISTRY_ID.a(abiomebase[k]); // CraftBukkit - decompile error } } @@ -383,7 +437,7 @@ int[] aint = new int[abiomebase.length]; for (int i = 0; i < abiomebase.length; ++i) { - aint[i] = BiomeBase.REGISTRY_ID.a((Object) abiomebase[i]); + aint[i] = BiomeBase.REGISTRY_ID.a(abiomebase[i]); // CraftBukkit - decompile error } nbttagcompound.setIntArray("Biomes", aint); @@ -485,7 +539,7 @@ } ChunkConverter chunkconverter = nbttagcompound.hasKeyOfType("UpgradeData", 10) ? new ChunkConverter(nbttagcompound.getCompound("UpgradeData")) : ChunkConverter.a; - Predicate predicate = (block) -> { + Predicate predicate = (block) -> { // CraftBukkit - decompile error return block.getBlockData().isAir(); }; RegistryBlocks registryblocks = Block.REGISTRY; @@ -497,7 +551,7 @@ Block.REGISTRY.getClass(); ProtoChunkTickList protochunkticklist = new ProtoChunkTickList(predicate, function, registryblocks1::get, new ChunkCoordIntPair(i, j)); - predicate = (fluidtype) -> { + Predicate predicate1 = (fluidtype) -> { // CraftBukkit - decompile error return fluidtype == FluidTypes.a; }; registryblocks = FluidType.c; @@ -505,7 +559,7 @@ function = registryblocks::b; registryblocks1 = FluidType.c; FluidType.c.getClass(); - ProtoChunkTickList protochunkticklist1 = new ProtoChunkTickList(predicate, function, registryblocks1::get, new ChunkCoordIntPair(i, j)); + ProtoChunkTickList protochunkticklist1 = new ProtoChunkTickList(predicate1, function, registryblocks1::get, new ChunkCoordIntPair(i, j)); // CraftBukkit - decompile error long i1 = nbttagcompound.getLong("InhabitedTime"); Chunk chunk = new Chunk(generatoraccess.getMinecraftWorld(), i, j, abiomebase, chunkconverter, protochunkticklist, protochunkticklist1, i1); @@ -852,17 +906,29 @@ } @Nullable + // CraftBukkit start public static Entity a(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag) { + return spawnEntity(nbttagcompound, world, d0, d1, d2, flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + public static Entity spawnEntity(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + // CraftBukkit end return a(nbttagcompound, world, (entity) -> { entity.setPositionRotation(d0, d1, d2, entity.yaw, entity.pitch); - return flag && !world.addEntity(entity) ? null : entity; + return flag && !world.addEntity(entity, spawnReason) ? null : entity; }); } @Nullable + // CraftBukkit start public static Entity a(NBTTagCompound nbttagcompound, World world, boolean flag) { + return spawnEntity(nbttagcompound, world, flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + public static Entity spawnEntity(NBTTagCompound nbttagcompound, World world, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + // CraftBukkit end return a(nbttagcompound, world, (entity) -> { - return flag && !world.addEntity(entity) ? null : entity; + return flag && !world.addEntity(entity, spawnReason) ? null : entity; // CraftBukkit }); } @@ -876,8 +942,14 @@ } } + // CraftBukkit start public static void a(Entity entity, GeneratorAccess generatoraccess) { - if (generatoraccess.addEntity(entity) && entity.isVehicle()) { + a(entity, generatoraccess, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + public static void a(Entity entity, GeneratorAccess generatoraccess, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { + if (generatoraccess.addEntity(entity, reason) && entity.isVehicle()) { + // CraftBukkit end Iterator iterator = entity.bP().iterator(); while (iterator.hasNext()) {