Fix loadChunk(x, z, false)
I was not correctly checking if the status was even cached. Actually fix it this time Do not forget about the async chunk placeholder Actually fix it this time I hope No plugin tickets for getChunkAtGen(x, z, boolean) Change ChunkStatus ABI This is required for asynchronous IO. async io will require calls to getChunkStatusIfCached to return the chunk status for a chunk currently queued to save - this cannot be reasonably done with current ABI
This commit is contained in:
		
					parent
					
						
							
								ff085b8e8e
							
						
					
				
			
			
				commit
				
					
						36c4831619
					
				
			
		
					 4 changed files with 115 additions and 58 deletions
				
			
		|  | @ -1,4 +1,4 @@ | ||||||
| From f652935fc9f95af75b49dc0e665ed32fe7eb74e0 Mon Sep 17 00:00:00 2001 | From 56ad1b929e7dcae4e58f7d68c31c749ace2e2b1e Mon Sep 17 00:00:00 2001 | ||||||
| From: Spottedleaf <Spottedleaf@users.noreply.github.com> | From: Spottedleaf <Spottedleaf@users.noreply.github.com> | ||||||
| Date: Sat, 15 Jun 2019 08:54:33 -0700 | Date: Sat, 15 Jun 2019 08:54:33 -0700 | ||||||
| Subject: [PATCH] Fix World#isChunkGenerated calls | Subject: [PATCH] Fix World#isChunkGenerated calls | ||||||
|  | @ -8,7 +8,7 @@ This patch also adds a chunk status cache on region files (note that | ||||||
| its only purpose is to cache the status on DISK) | its only purpose is to cache the status on DISK) | ||||||
| 
 | 
 | ||||||
| diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | ||||||
| index bff81bdb8..dab86960a 100644
 | index fef44094b..539c65f85 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 | ||||||
| @@ -27,7 +27,7 @@ public class ChunkProviderServer extends IChunkProvider {
 | @@ -27,7 +27,7 @@ public class ChunkProviderServer extends IChunkProvider {
 | ||||||
|  | @ -134,10 +134,10 @@ index 0daf5f99e..761cd1355 100644 | ||||||
|   |   | ||||||
|      public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) { |      public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> getStatusFutureUnchecked(ChunkStatus chunkstatus) { | ||||||
| diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| index 884c8a908..e0798c1c8 100644
 | index 884c8a908..e2f8b18d9 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| @@ -807,10 +807,23 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | @@ -807,11 +807,56 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | ||||||
|      } |      } | ||||||
|   |   | ||||||
|      @Nullable |      @Nullable | ||||||
|  | @ -156,18 +156,51 @@ index 884c8a908..e0798c1c8 100644 | ||||||
| +            return null;
 | +            return null;
 | ||||||
| +        }
 | +        }
 | ||||||
| +
 | +
 | ||||||
| +        this.getRegionFile(chunkcoordintpair, false).setStatus(chunkcoordintpair.x, chunkcoordintpair.z, ChunkRegionLoader.getStatus(nbttagcompound));
 | +        this.updateChunkStatusOnDisk(chunkcoordintpair, nbttagcompound);
 | ||||||
| +
 | +
 | ||||||
| +        return nbttagcompound;
 | +        return nbttagcompound;
 | ||||||
| +        // Paper end
 | +        // Paper end
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +    // Paper start - chunk status cache "api"
 | ||||||
|  | +    public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) {
 | ||||||
|  | +        RegionFile regionFile = this.getRegionFileIfLoaded(chunkPos);
 | ||||||
|  | +
 | ||||||
|  | +        return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +    public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
 | ||||||
|  | +        RegionFile regionFile = this.getRegionFile(chunkPos, false);
 | ||||||
|  | +
 | ||||||
|  | +        if (!regionFile.chunkExists(chunkPos)) {
 | ||||||
|  | +            return null;
 | ||||||
|  | +        }
 | ||||||
|  | +
 | ||||||
|  | +        ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
 | ||||||
|  | +
 | ||||||
|  | +        if (status != null) {
 | ||||||
|  | +            return status;
 | ||||||
|  | +        }
 | ||||||
|  | +
 | ||||||
|  | +        this.readChunkData(chunkPos);
 | ||||||
|  | +
 | ||||||
|  | +        return regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
 | ||||||
|  | +    }
 | ||||||
|  | +
 | ||||||
|  | +    public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException {
 | ||||||
|  | +        RegionFile regionFile = this.getRegionFile(chunkPos, false);
 | ||||||
|  | +
 | ||||||
|  | +        regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
 | ||||||
|      } |      } | ||||||
|  | +    // Paper end
 | ||||||
|   |   | ||||||
|      // Spigot Start |      // Spigot Start | ||||||
|  |      boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair, boolean reducedRange) { | ||||||
| diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
 | diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java
 | ||||||
| index 2e14d8465..d610253b9 100644
 | index 2e14d8465..66c8b0307 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/RegionFile.java
 | --- a/src/main/java/net/minecraft/server/RegionFile.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/RegionFile.java
 | +++ b/src/main/java/net/minecraft/server/RegionFile.java
 | ||||||
| @@ -31,6 +31,47 @@ public class RegionFile implements AutoCloseable {
 | @@ -31,6 +31,30 @@ public class RegionFile implements AutoCloseable {
 | ||||||
|      private final int[] d = new int[1024];private int[] timestamps = d; // Paper - OBFHELPER |      private final int[] d = new int[1024];private int[] timestamps = d; // Paper - OBFHELPER | ||||||
|      private final List<Boolean> e; private List<Boolean> getFreeSectors() { return this.e; } // Paper - OBFHELPER |      private final List<Boolean> e; private List<Boolean> getFreeSectors() { return this.e; } // Paper - OBFHELPER | ||||||
|   |   | ||||||
|  | @ -193,29 +226,20 @@ index 2e14d8465..d610253b9 100644 | ||||||
| +        final int location = this.getChunkLocation(new ChunkCoordIntPair(x, z));
 | +        final int location = this.getChunkLocation(new ChunkCoordIntPair(x, z));
 | ||||||
| +        return this.statuses[location];
 | +        return this.statuses[location];
 | ||||||
| +    }
 | +    }
 | ||||||
| +
 |  | ||||||
| +    public ChunkStatus getStatus(int x, int z, PlayerChunkMap playerChunkMap) throws IOException {
 |  | ||||||
| +        if (this.closed) {
 |  | ||||||
| +            // We've used an invalid region file.
 |  | ||||||
| +            throw new java.io.EOFException("RegionFile is closed");
 |  | ||||||
| +        }
 |  | ||||||
| +        ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z);
 |  | ||||||
| +        int location = this.getChunkLocation(chunkPos);
 |  | ||||||
| +        ChunkStatus cached = this.statuses[location];
 |  | ||||||
| +        if (cached != null) {
 |  | ||||||
| +            return cached;
 |  | ||||||
| +        }
 |  | ||||||
| +
 |  | ||||||
| +        playerChunkMap.readChunkData(chunkPos); // This will set our status (yes it's disgusting)
 |  | ||||||
| +
 |  | ||||||
| +        return this.statuses[location];
 |  | ||||||
| +    }
 |  | ||||||
| +    // Paper end
 | +    // Paper end
 | ||||||
| +
 | +
 | ||||||
|      public RegionFile(File file) throws IOException { |      public RegionFile(File file) throws IOException { | ||||||
|          this.b = new RandomAccessFile(file, "rw"); |          this.b = new RandomAccessFile(file, "rw"); | ||||||
|          this.file = file; // Spigot // Paper - We need this earlier |          this.file = file; // Spigot // Paper - We need this earlier | ||||||
| @@ -299,6 +340,7 @@ public class RegionFile implements AutoCloseable {
 | @@ -286,6 +310,7 @@ public class RegionFile implements AutoCloseable {
 | ||||||
|  |          return this.c[this.f(chunkcoordintpair)]; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | +    public final boolean chunkExists(ChunkCoordIntPair chunkPos) { return this.d(chunkPos); } // Paper - OBFHELPER
 | ||||||
|  |      public boolean d(ChunkCoordIntPair chunkcoordintpair) { | ||||||
|  |          return this.getOffset(chunkcoordintpair) != 0; | ||||||
|  |      } | ||||||
|  | @@ -299,6 +324,7 @@ public class RegionFile implements AutoCloseable {
 | ||||||
|          this.writeInt(i); // Paper - Avoid 3 io write calls |          this.writeInt(i); // Paper - Avoid 3 io write calls | ||||||
|      } |      } | ||||||
|   |   | ||||||
|  | @ -223,7 +247,7 @@ index 2e14d8465..d610253b9 100644 | ||||||
|      private int f(ChunkCoordIntPair chunkcoordintpair) { |      private int f(ChunkCoordIntPair chunkcoordintpair) { | ||||||
|          return chunkcoordintpair.j() + chunkcoordintpair.k() * 32; |          return chunkcoordintpair.j() + chunkcoordintpair.k() * 32; | ||||||
|      } |      } | ||||||
| @@ -312,6 +354,7 @@ public class RegionFile implements AutoCloseable {
 | @@ -312,6 +338,7 @@ public class RegionFile implements AutoCloseable {
 | ||||||
|      } |      } | ||||||
|   |   | ||||||
|      public void close() throws IOException { |      public void close() throws IOException { | ||||||
|  | @ -265,10 +289,10 @@ index 6f34d8aea..d2b328945 100644 | ||||||
|                      printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ); |                      printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ); | ||||||
|                      // Eek, major fail. We have retry logic, so reduce threshholds and fall back |                      // Eek, major fail. We have retry logic, so reduce threshholds and fall back | ||||||
| diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | ||||||
| index bb0f75f52..ece1a68c1 100644
 | index bb0f75f52..f01e8a87e 100644
 | ||||||
| --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | ||||||
| +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
 | ||||||
| @@ -393,8 +393,20 @@ public class CraftWorld implements World {
 | @@ -393,8 +393,19 @@ public class CraftWorld implements World {
 | ||||||
|   |   | ||||||
|      @Override |      @Override | ||||||
|      public boolean isChunkGenerated(int x, int z) { |      public boolean isChunkGenerated(int x, int z) { | ||||||
|  | @ -284,81 +308,114 @@ index bb0f75f52..ece1a68c1 100644 | ||||||
| +        }
 | +        }
 | ||||||
|          try { |          try { | ||||||
| -            return world.getChunkProvider().getChunkAtIfCachedImmediately(x, z) != null || world.getChunkProvider().playerChunkMap.chunkExists(new ChunkCoordIntPair(x, z)); // Paper
 | -            return world.getChunkProvider().getChunkAtIfCachedImmediately(x, z) != null || world.getChunkProvider().playerChunkMap.chunkExists(new ChunkCoordIntPair(x, z)); // Paper
 | ||||||
| +            return world.getChunkProvider().playerChunkMap.getRegionFile(new ChunkCoordIntPair(x, z), false)
 | +            return world.getChunkProvider().playerChunkMap.getChunkStatusOnDisk(new ChunkCoordIntPair(x, z)) == ChunkStatus.FULL;
 | ||||||
| +                .getStatus(x, z, world.getChunkProvider().playerChunkMap) == ChunkStatus.FULL;
 |  | ||||||
| +            // Paper end
 | +            // Paper end
 | ||||||
|          } catch (IOException ex) { |          } catch (IOException ex) { | ||||||
|              throw new RuntimeException(ex); |              throw new RuntimeException(ex); | ||||||
|          } |          } | ||||||
| @@ -506,20 +518,24 @@ public class CraftWorld implements World {
 | @@ -506,20 +517,45 @@ public class CraftWorld implements World {
 | ||||||
|      @Override |      @Override | ||||||
|      public boolean loadChunk(int x, int z, boolean generate) { |      public boolean loadChunk(int x, int z, boolean generate) { | ||||||
|          org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot |          org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot | ||||||
| -        IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
 | -        IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
 | ||||||
| -
 | +        // Paper start - Optimize this method
 | ||||||
|  | +        ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z);
 | ||||||
|  |   | ||||||
| -        // If generate = false, but the chunk already exists, we will get this back.
 | -        // If generate = false, but the chunk already exists, we will get this back.
 | ||||||
| -        if (chunk instanceof ProtoChunkExtension) {
 | -        if (chunk instanceof ProtoChunkExtension) {
 | ||||||
| -            // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
 | -            // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
 | ||||||
| -            chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | -            chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | ||||||
| -        }
 | +        IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
 | ||||||
| +        // Paper - Optimize this method
 | +        if (immediate != null) {
 | ||||||
| +        if (!generate) {
 | +            if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
 | ||||||
| +            net.minecraft.server.RegionFile file = world.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(x, z));
 | +                return false; // not full status
 | ||||||
| +            if (file != null && file.getStatusIfCached(x, z) != ChunkStatus.FULL) {
 |  | ||||||
| +                return false;
 |  | ||||||
| +            }
 | +            }
 | ||||||
|  | +            world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
 | ||||||
|  | +            world.getChunkAt(x, z); // make sure we're at ticket level 32 or lower
 | ||||||
|  | +            return true;
 | ||||||
|  |          } | ||||||
|   |   | ||||||
| -        if (chunk instanceof net.minecraft.server.Chunk) {
 | -        if (chunk instanceof net.minecraft.server.Chunk) {
 | ||||||
| -            world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
 | -            world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
 | ||||||
| -            return true;
 | -            return true;
 | ||||||
|  | +        if (!generate) {
 | ||||||
|  | +            net.minecraft.server.RegionFile file;
 | ||||||
|  | +            try {
 | ||||||
|  | +                file = world.getChunkProvider().playerChunkMap.getRegionFile(chunkPos, false);
 | ||||||
|  | +            } catch (IOException ex) {
 | ||||||
|  | +                throw new RuntimeException(ex);
 | ||||||
|  | +            }
 | ||||||
|  | +
 | ||||||
|  | +            ChunkStatus status = file.getStatusIfCached(x, z);
 | ||||||
|  | +            if (!file.chunkExists(chunkPos) || (status != null && status != ChunkStatus.FULL)) {
 | ||||||
|  | +                return false;
 | ||||||
|  | +            }
 | ||||||
|  | +
 | ||||||
| +            IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
 | +            IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
 | ||||||
| +            if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
 | +            if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
 | ||||||
| +                return false;
 | +                return false;
 | ||||||
| +            }
 | +            }
 | ||||||
|  | +
 | ||||||
| +            // fall through to load
 | +            // fall through to load
 | ||||||
| +            // we do this so we do not re-read the chunk data on disk
 | +            // we do this so we do not re-read the chunk data on disk
 | ||||||
|          } |          } | ||||||
| -
 |   | ||||||
| -        return false;
 | -        return false;
 | ||||||
| +        world.getChunkProvider().addTicket(TicketType.PLUGIN, new ChunkCoordIntPair(x, z), 1, Unit.INSTANCE);
 | +        world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE);
 | ||||||
| +        world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | +        world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | ||||||
| +        return true;
 | +        return true;
 | ||||||
| +        // Paper end
 | +        // Paper end
 | ||||||
|      } |      } | ||||||
|   |   | ||||||
|      @Override |      @Override | ||||||
| @@ -2249,21 +2265,20 @@ public class CraftWorld implements World {
 | @@ -2249,21 +2285,40 @@ public class CraftWorld implements World {
 | ||||||
|   |   | ||||||
|      // Paper start |      // Paper start | ||||||
|      private Chunk getChunkAtGen(int x, int z, boolean gen) { |      private Chunk getChunkAtGen(int x, int z, boolean gen) { | ||||||
| -        // copied from loadChunk()
 | -        // copied from loadChunk()
 | ||||||
| -        // this function is identical except we do not add a plugin ticket
 | -        // this function is identical except we do not add a plugin ticket
 | ||||||
| -        IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, gen || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
 | -        IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, gen || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
 | ||||||
| -
 | +        // Note: Copied from loadChunk()
 | ||||||
|  | +        ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z);
 | ||||||
|  |   | ||||||
| -        // If generate = false, but the chunk already exists, we will get this back.
 | -        // If generate = false, but the chunk already exists, we will get this back.
 | ||||||
| -        if (chunk instanceof ProtoChunkExtension) {
 | -        if (chunk instanceof ProtoChunkExtension) {
 | ||||||
| -            // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
 | -            // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
 | ||||||
| -            chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | -            chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true);
 | ||||||
| -        }
 | +        IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z);
 | ||||||
| -
 | +        if (immediate != null) {
 | ||||||
|  | +            if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) {
 | ||||||
|  | +                return null; // not full status
 | ||||||
|  | +            }
 | ||||||
|  | +            return world.getChunkAt(x, z).bukkitChunk; // make sure we're at ticket level 32 or lower
 | ||||||
|  |          } | ||||||
|  |   | ||||||
| -        if (chunk instanceof net.minecraft.server.Chunk) {
 | -        if (chunk instanceof net.minecraft.server.Chunk) {
 | ||||||
| -            return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
 | -            return ((net.minecraft.server.Chunk)chunk).bukkitChunk;
 | ||||||
| +        // Note: Copied from loadChunk()
 |  | ||||||
| +        if (!gen) {
 | +        if (!gen) {
 | ||||||
| +            net.minecraft.server.RegionFile file = world.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(x, z));
 | +            net.minecraft.server.RegionFile file;
 | ||||||
| +            if (file != null && file.getStatusIfCached(x, z) != ChunkStatus.FULL) {
 | +            try {
 | ||||||
|  | +                file = world.getChunkProvider().playerChunkMap.getRegionFile(chunkPos, false);
 | ||||||
|  | +            } catch (IOException ex) {
 | ||||||
|  | +                throw new RuntimeException(ex);
 | ||||||
|  | +            }
 | ||||||
|  | +
 | ||||||
|  | +            ChunkStatus status = file.getStatusIfCached(x, z);
 | ||||||
|  | +            if (!file.chunkExists(chunkPos) || (status != null && status != ChunkStatus.FULL)) {
 | ||||||
| +                return null;
 | +                return null;
 | ||||||
| +            }
 | +            }
 | ||||||
|  | +
 | ||||||
| +            IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
 | +            IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true);
 | ||||||
| +            if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
 | +            if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) {
 | ||||||
| +                return null;
 | +                return null;
 | ||||||
| +            }
 | +            }
 | ||||||
|  | +
 | ||||||
| +            // fall through to load
 | +            // fall through to load
 | ||||||
| +            // we do this so we do not re-read the chunk data on disk
 | +            // we load at empty so we don't double-load chunk data in this case
 | ||||||
|          } |          } | ||||||
| -
 |   | ||||||
| -        return null;
 | -        return null;
 | ||||||
| +        return ((net.minecraft.server.Chunk)world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true)).bukkitChunk;
 | +        return world.getChunkAt(x, z).bukkitChunk;
 | ||||||
|      } |      } | ||||||
|   |   | ||||||
|      @Override |      @Override | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| From 258e62129db2aeb3cdabadfeaf0baf682ab9d983 Mon Sep 17 00:00:00 2001 | From af0d14664907ee01ca8462ecf282c3c46d8941ef Mon Sep 17 00:00:00 2001 | ||||||
| From: Spottedleaf <Spottedleaf@users.noreply.github.com> | From: Spottedleaf <Spottedleaf@users.noreply.github.com> | ||||||
| Date: Sun, 16 Jun 2019 23:30:25 -0700 | Date: Sun, 16 Jun 2019 23:30:25 -0700 | ||||||
| Subject: [PATCH] Fix MC-154214 | Subject: [PATCH] Fix MC-154214 | ||||||
|  | @ -6,7 +6,7 @@ Subject: [PATCH] Fix MC-154214 | ||||||
| Avoid adding player tickets when they're out of range of the closest player | Avoid adding player tickets when they're out of range of the closest player | ||||||
| 
 | 
 | ||||||
| diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | ||||||
| index 99c7537ef..757b505ea 100644
 | index 99c7537ef2..757b505eaf 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | --- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
 | ||||||
| @@ -359,12 +359,18 @@ public abstract class ChunkMapDistance {
 | @@ -359,12 +359,18 @@ public abstract class ChunkMapDistance {
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| From 3423bf44d5532a8e2d8a7b2fdf6aa278aa1702b1 Mon Sep 17 00:00:00 2001 | From ba7006117301143d6877b70bfd4f0043feb4fa5d Mon Sep 17 00:00:00 2001 | ||||||
| From: Spottedleaf <Spottedleaf@users.noreply.github.com> | From: Spottedleaf <Spottedleaf@users.noreply.github.com> | ||||||
| Date: Sat, 22 Jun 2019 04:20:47 -0700 | Date: Sat, 22 Jun 2019 04:20:47 -0700 | ||||||
| Subject: [PATCH] Use ChunkStatus cache when saving protochunks | Subject: [PATCH] Use ChunkStatus cache when saving protochunks | ||||||
|  | @ -7,7 +7,7 @@ The cache should contain the chunk status when saving. If not it | ||||||
| will load it. | will load it. | ||||||
| 
 | 
 | ||||||
| diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| index e0798c1c8..f21961d3a 100644
 | index e2f8b18d9..7cb5438e4 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| @@ -723,8 +723,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | @@ -723,8 +723,10 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | ||||||
|  | @ -17,7 +17,7 @@ index e0798c1c8..f21961d3a 100644 | ||||||
| -                    nbttagcompound = this.readChunkData(chunkcoordintpair);
 | -                    nbttagcompound = this.readChunkData(chunkcoordintpair);
 | ||||||
| -                    if (nbttagcompound != null && ChunkRegionLoader.a(nbttagcompound) == ChunkStatus.Type.LEVELCHUNK) {
 | -                    if (nbttagcompound != null && ChunkRegionLoader.a(nbttagcompound) == ChunkStatus.Type.LEVELCHUNK) {
 | ||||||
| +                    // Paper start - Optimize save by using status cache
 | +                    // Paper start - Optimize save by using status cache
 | ||||||
| +                    ChunkStatus statusOnDisk = this.getRegionFile(ichunkaccess.getPos(), false).getStatus(ichunkaccess.getPos().x, ichunkaccess.getPos().z, this);
 | +                    ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair);
 | ||||||
| +                    if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
 | +                    if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
 | ||||||
| +                        // Paper end
 | +                        // Paper end
 | ||||||
|                          return false; |                          return false; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| From ff5ffde5a598d484afed73de5c1e35743cb184bf Mon Sep 17 00:00:00 2001 | From 3db1a7a3ad9eac4b9e25423bad3a4281d2cdcba5 Mon Sep 17 00:00:00 2001 | ||||||
| From: stonar96 <minecraft.stonar96@gmail.com> | From: stonar96 <minecraft.stonar96@gmail.com> | ||||||
| Date: Mon, 20 Aug 2018 03:03:58 +0200 | Date: Mon, 20 Aug 2018 03:03:58 +0200 | ||||||
| Subject: [PATCH] Anti-Xray | Subject: [PATCH] Anti-Xray | ||||||
|  | @ -1565,7 +1565,7 @@ index 761cd1355..956a47132 100644 | ||||||
|                  this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false); |                  this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false); | ||||||
|   |   | ||||||
| diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| index f21961d3a..f5b35b95b 100644
 | index 7cb5438e4..a43927781 100644
 | ||||||
| --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
 | ||||||
| @@ -494,7 +494,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | @@ -494,7 +494,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | ||||||
|  | @ -1577,7 +1577,7 @@ index f21961d3a..f5b35b95b 100644 | ||||||
|          }, this.executor); |          }, this.executor); | ||||||
|      } |      } | ||||||
|   |   | ||||||
| @@ -1116,7 +1116,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | @@ -1148,7 +1148,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
 | ||||||
|   |   | ||||||
|      private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) { |      private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) { | ||||||
|          if (apacket[0] == null) { |          if (apacket[0] == null) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Spottedleaf
				Spottedleaf