more patches updated

This commit is contained in:
Jake Potrebic 2021-11-23 20:25:34 -08:00
parent 2b25404eca
commit f629237348
8 changed files with 50 additions and 85 deletions

View file

@ -53,15 +53,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@VisibleForTesting
protected final RegionBitmap usedSectors;
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
+ public final File regionFile; // Paper
+ public final Path regionFile; // Paper
public RegionFile(File file, File directory, boolean dsync) throws IOException {
this(file.toPath(), directory.toPath(), RegionFileVersion.VERSION_DEFLATE, dsync);
public RegionFile(Path path, Path path1, boolean dsync) throws IOException {
this(path, path1, RegionFileVersion.VERSION_DEFLATE, dsync);
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
public RegionFile(Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException {
this.header = ByteBuffer.allocateDirect(8192);
+ this.regionFile = file.toFile(); // Paper
+ this.regionFile = file; // Paper
+ initOversizedState(); // Paper
this.usedSectors = new RegionBitmap();
this.version = outputChunkStreamVersion;
@ -75,9 +75,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private int oversizedCount = 0;
+
+ private synchronized void initOversizedState() throws IOException {
+ File metaFile = getOversizedMetaFile();
+ if (metaFile.exists()) {
+ final byte[] read = java.nio.file.Files.readAllBytes(metaFile.toPath());
+ Path metaFile = getOversizedMetaFile();
+ if (Files.exists(metaFile)) {
+ final byte[] read = java.nio.file.Files.readAllBytes(metaFile);
+ System.arraycopy(read, 0, oversized, 0, oversized.length);
+ for (byte temp : oversized) {
+ oversizedCount += temp;
@ -101,9 +101,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ oversizedCount--;
+ }
+ if (previous && !oversized) {
+ File oversizedFile = getOversizedFile(x, z);
+ if (oversizedFile.exists()) {
+ oversizedFile.delete();
+ Path oversizedFile = getOversizedFile(x, z);
+ if (Files.exists(oversizedFile)) {
+ Files.delete(oversizedFile);
+ }
+ }
+ if (oversizedCount > 0) {
@ -111,28 +111,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ writeOversizedMeta();
+ }
+ } else if (previous) {
+ File oversizedMetaFile = getOversizedMetaFile();
+ if (oversizedMetaFile.exists()) {
+ oversizedMetaFile.delete();
+ Path oversizedMetaFile = getOversizedMetaFile();
+ if (Files.exists(oversizedMetaFile)) {
+ Files.delete(oversizedMetaFile);
+ }
+ }
+ }
+
+ private void writeOversizedMeta() throws IOException {
+ java.nio.file.Files.write(getOversizedMetaFile().toPath(), oversized);
+ java.nio.file.Files.write(getOversizedMetaFile(), oversized);
+ }
+
+ private File getOversizedMetaFile() {
+ return new File(this.regionFile.getParentFile(), this.regionFile.getName().replaceAll("\\.mca$", "") + ".oversized.nbt");
+ private Path getOversizedMetaFile() {
+ return this.regionFile.getParent().resolve(this.regionFile.getFileName().toString().replaceAll("\\.mca$", "") + ".oversized.nbt");
+ }
+
+ private File getOversizedFile(int x, int z) {
+ return new File(this.regionFile.getParentFile(), this.regionFile.getName().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
+ private Path getOversizedFile(int x, int z) {
+ return this.regionFile.getParent().resolve(this.regionFile.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt");
+ }
+
+ synchronized CompoundTag getOversizedData(int x, int z) throws IOException {
+ File file = getOversizedFile(x, z);
+ try (DataInputStream out = new DataInputStream(new BufferedInputStream(new InflaterInputStream(new java.io.FileInputStream(file))))) {
+ Path file = getOversizedFile(x, z);
+ try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) {
+ return NbtIo.read((java.io.DataInput) out);
+ }
+
@ -145,22 +145,23 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSto
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -0,0 +0,0 @@ import java.io.File;
import java.io.IOException;
@@ -0,0 +0,0 @@ import java.nio.file.Files;
import java.nio.file.Path;
import javax.annotation.Nullable;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.StreamTagVisitor;
+import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ExceptionCollector;
import net.minecraft.world.level.ChunkPos;
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
}
}
+ // Paper start
+ private static void printOversizedLog(String msg, File file, int x, int z) {
+ private static void printOversizedLog(String msg, Path file, int x, int z) {
+ org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
+ }
+

View file

@ -21,8 +21,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -0,0 +0,0 @@ public abstract class DistanceManager {
private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker();
private final DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter = new DistanceManager.FixedPlayerDistanceChunkTracker(8);
private final TickingTracker tickingTicketsTracker = new TickingTracker();
private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33);
- final Set<ChunkHolder> chunksToUpdateFutures = Sets.newHashSet();
+ // Paper start use a queue, but still keep unique requirement
@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- iter.remove();
- expectedSize--;
-
- playerchunk.updateFutures(playerchunkmap, this.mainThreadExecutor);
- playerchunk.updateFutures(chunkStorage, this.mainThreadExecutor);
-
- // Reset iterator if set was modified using add()
- if (this.chunksToUpdateFutures.size() != expectedSize) {
@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ while(!this.pendingChunkUpdates.isEmpty()) {
+ ChunkHolder remove = this.pendingChunkUpdates.remove();
+ remove.isUpdateQueued = false;
+ remove.updateFutures(playerchunkmap, this.mainThreadExecutor);
+ remove.updateFutures(chunkStorage, this.mainThreadExecutor);
+ }
+ // Paper end
return true;

View file

@ -29,13 +29,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start
public void loadSpawn(ChunkProgressListener worldloadlistener, ServerLevel worldserver) {
public void prepareLevels(ChunkProgressListener worldloadlistener, ServerLevel worldserver) {
- if (!worldserver.getWorld().getKeepSpawnInMemory()) {
- return;
- }
+ ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); // Paper
// WorldServer worldserver = this.E();
// WorldServer worldserver = this.overworld();
this.forceTicks = true;
// CraftBukkit end
+ if (worldserver.getWorld().getKeepSpawnInMemory()) { // Paper
@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- while (chunkproviderserver.getTickingGenerated() != 441) {
- // CraftBukkit start
- // this.nextTickTime = SystemUtils.getMonotonicMillis() + 10L;
- // this.nextTickTime = SystemUtils.getMillis() + 10L;
- this.executeModerately();
- // CraftBukkit end
- }
@ -68,22 +68,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
// CraftBukkit start
// this.nextTickTime = SystemUtils.getMonotonicMillis() + 10L;
// this.nextTickTime = SystemUtils.getMillis() + 10L;
this.executeModerately();
// Iterator iterator = this.worldServer.values().iterator();
// Iterator iterator = this.levels.values().iterator();
+ }
if (true) {
ServerLevel worldserver1 = worldserver;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// this.nextTick = SystemUtils.getMonotonicMillis() + 10L;
// this.nextTickTime = SystemUtils.getMillis() + 10L;
this.executeModerately();
// CraftBukkit end
- worldloadlistener.stop();
+ if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper
chunkproviderserver.getLightEngine().setTaskPerBatch(5);
// CraftBukkit start
// this.updateSpawnFlags();
// this.updateMobSpawningFlags();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java

View file

@ -7,30 +7,6 @@ Optimize World#loadChunk() too
This patch also adds a chunk status cache on region files (note that
its only purpose is to cache the status on DISK)
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -0,0 +0,0 @@ public class ChunkHolder {
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = (Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>) statusFuture.getNow(null);
return (either == null) ? null : (LevelChunk) either.left().orElse(null);
}
+
+ public ChunkAccess getAvailableChunkNow() {
+ // TODO can we just getStatusFuture(EMPTY)?
+ for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getParent(); curr != next; curr = next, next = next.getParent()) {
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = this.getFutureIfPresentUnchecked(curr);
+ Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = future.getNow(null);
+ if (either == null || !either.left().isPresent()) {
+ continue;
+ }
+ return either.left().get();
+ }
+ return null;
+ }
// CraftBukkit end
public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getFutureIfPresentUnchecked(ChunkStatus leastStatus) {
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
@ -41,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import net.minecraft.world.level.chunk.storage.ChunkStorage;
+import net.minecraft.world.level.chunk.storage.RegionFile;
import net.minecraft.world.level.entity.ChunkStatusUpdateListener;
import net.minecraft.world.level.levelgen.blending.BlendingData;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@Nullable
public CompoundTag readChunk(ChunkPos pos) throws IOException {
@ -52,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return null;
+ }
+
+ nbttagcompound = this.getChunkData(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, pos, level); // CraftBukkit
+ nbttagcompound = this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator.getTypeNameForDataFixer(), pos, level); // CraftBukkit
+ if (nbttagcompound == null) {
+ return null;
+ }
@ -67,12 +43,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) {
+ RegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos);
- return nbttagcompound == null ? null : this.getChunkData(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, pos, level); // CraftBukkit
- return nbttagcompound == null ? null : this.upgradeChunkTag(this.level.getTypeKey(), this.overworldDataStorage, nbttagcompound, this.generator.getTypeNameForDataFixer(), pos, level); // CraftBukkit
+ return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
}
+ public ChunkStatus getChunkStatusOnDisk(ChunkPos chunkPos) throws IOException {
+ RegionFile regionFile = regionFileCache.getFile(chunkPos, true);
+ RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true);
+
+ if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) {
+ return null;
@ -90,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException {
+ RegionFile regionFile = regionFileCache.getFile(chunkPos, false);
+ RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false);
+
+ regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound));
+ }
@ -101,21 +77,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end
+
boolean noPlayersCloseForSpawning(ChunkPos chunkPos) {
boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) {
// Spigot start
return this.isOutsideOfRange(chunkPos, false);
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
}
// Paper end
// Paper start - async chunk io
+ @Nullable
public ChunkAccess getChunkAtImmediately(int x, int z) {
ChunkHolder holder = this.chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
if (holder == null) {
return this.anyPlayerCloseEnoughForSpawning(pos, false);
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
@ -143,11 +107,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -0,0 +0,0 @@ public class ChunkSerializer {
return nbttagcompound;
}));
}
+ // Paper start
+ public static ChunkStatus getStatus(CompoundTag compound) {
+ public static @Nullable ChunkStatus getStatus(@Nullable CompoundTag compound) {
+ if (compound == null) {
+ return null;
+ }
@ -158,8 +122,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
+
public static ChunkStatus.ChunkType getChunkTypeFromTag(@Nullable CompoundTag nbt) {
if (nbt != null) {
ChunkStatus chunkstatus = ChunkStatus.byName(nbt.getCompound("Level").getString("Status"));
return nbt != null ? ChunkStatus.byName(nbt.getString("Status")).getChunkType() : ChunkStatus.ChunkType.PROTOCHUNK;
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@ -174,7 +138,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
public final File regionFile; // Paper
public final Path regionFile; // Paper
+ // Paper start - Cache chunk status
+ private final ChunkStatus[] statuses = new ChunkStatus[32 * 32];
@ -200,8 +164,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end
+
public RegionFile(File file, File directory, boolean dsync) throws IOException {
this(file.toPath(), directory.toPath(), RegionFileVersion.VERSION_DEFLATE, dsync);
public RegionFile(Path path, Path path1, boolean dsync) throws IOException {
this(path, path1, RegionFileVersion.VERSION_DEFLATE, dsync);
}
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
return this.getOffset(pos) != 0;
@ -299,7 +263,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return true;
+ net.minecraft.world.level.chunk.storage.RegionFile file;
+ try {
+ file = world.getChunkSource().chunkMap.regionFileCache.getFile(chunkPos, false);
+ file = world.getChunkSource().chunkMap.regionFileCache.getRegionFile(chunkPos, false);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }