diff --git a/patches/server/0018-Kaiiju-Don-t-pathfind-outside-region.patch b/patches/server/0017-Kaiiju-Don-t-pathfind-outside-region.patch similarity index 100% rename from patches/server/0018-Kaiiju-Don-t-pathfind-outside-region.patch rename to patches/server/0017-Kaiiju-Don-t-pathfind-outside-region.patch diff --git a/patches/server/0017-Kaiiju-linear-region-format-and-settings.patch b/patches/server/0017-Kaiiju-linear-region-format-and-settings.patch deleted file mode 100644 index 8fd9ca4..0000000 --- a/patches/server/0017-Kaiiju-linear-region-format-and-settings.patch +++ /dev/null @@ -1,1197 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrHua269 -Date: Wed, 7 Feb 2024 03:11:28 +0000 -Subject: [PATCH] Kaiiju linear region format and settings - - -diff --git a/build.gradle.kts b/build.gradle.kts -index 247598b6c73aca3743f4b16b47520f8ba16b2ed0..dd0a3477d69ab8f59f00ae930e983b57eaf322e2 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -20,6 +20,10 @@ dependencies { - } - // Folia end - implementation("com.electronwill.night-config:toml:3.6.6") //Luminol - Night config -+ // Kaiiju start - Linear format -+ implementation("com.github.luben:zstd-jni:1.5.4-1") -+ implementation("org.lz4:lz4-java:1.8.0") -+ // Kaiiju end - // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") - implementation("net.minecrell:terminalconsoleappender:1.3.0") -diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFile.java -new file mode 100644 -index 0000000000000000000000000000000000000000..249303116d3cfadd078ebf0ae6e44bf99eed6a47 ---- /dev/null -+++ b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFile.java -@@ -0,0 +1,31 @@ -+package dev.kaiijumc.kaiiju.region; -+ -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkStatus; -+ -+import java.io.DataInputStream; -+import java.io.DataOutputStream; -+import java.io.IOException; -+import java.nio.file.Path; -+import java.util.concurrent.locks.ReentrantLock; -+ -+public interface AbstractRegionFile { -+ void flush() throws IOException; -+ void clear(ChunkPos pos) throws IOException; -+ void close() throws IOException; -+ void setStatus(int x, int z, ChunkStatus status); -+ void setOversized(int x, int z, boolean b) throws IOException; -+ -+ boolean hasChunk(ChunkPos pos); -+ boolean doesChunkExist(ChunkPos pos) throws Exception; -+ boolean isOversized(int x, int z); -+ boolean recalculateHeader() throws IOException; -+ -+ DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException; -+ DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException; -+ CompoundTag getOversizedData(int x, int z) throws IOException; -+ ChunkStatus getStatusIfCached(int x, int z); -+ ReentrantLock getFileLock(); -+ Path getRegionFile(); -+} -diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java -new file mode 100644 -index 0000000000000000000000000000000000000000..dcfbabf54b19a4c29d5c95830242c5c26bf2f4aa ---- /dev/null -+++ b/src/main/java/dev/kaiijumc/kaiiju/region/AbstractRegionFileFactory.java -@@ -0,0 +1,29 @@ -+package dev.kaiijumc.kaiiju.region; -+ -+import net.minecraft.world.level.chunk.storage.RegionFile; -+import net.minecraft.world.level.chunk.storage.RegionFileVersion; -+ -+import java.io.IOException; -+import java.nio.file.Path; -+ -+public class AbstractRegionFileFactory { -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, boolean dsync) throws IOException { -+ return getAbstractRegionFile(linearCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync); -+ } -+ -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, boolean dsync, boolean canRecalcHeader) throws IOException { -+ return getAbstractRegionFile(linearCompression, file, directory, RegionFileVersion.VERSION_DEFLATE, dsync, canRecalcHeader); -+ } -+ -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync) throws IOException { -+ return getAbstractRegionFile(linearCompression, file, directory, outputChunkStreamVersion, dsync, false); -+ } -+ -+ public static AbstractRegionFile getAbstractRegionFile(int linearCompression, Path file, Path directory, RegionFileVersion outputChunkStreamVersion, boolean dsync, boolean canRecalcHeader) throws IOException { -+ if (file.toString().endsWith(".linear")) { -+ return new LinearRegionFile(file, linearCompression); -+ } else { -+ return new RegionFile(file, directory, outputChunkStreamVersion, dsync, canRecalcHeader); -+ } -+ } -+} -diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7e551a5fb7db6a0aa4f60b15587be2b716c54000 ---- /dev/null -+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java -@@ -0,0 +1,341 @@ -+package dev.kaiijumc.kaiiju.region; -+ -+import com.github.luben.zstd.ZstdInputStream; -+import com.github.luben.zstd.ZstdOutputStream; -+import com.mojang.logging.LogUtils; -+import net.jpountz.lz4.LZ4Compressor; -+import net.jpountz.lz4.LZ4Factory; -+import net.jpountz.lz4.LZ4FastDecompressor; -+import net.minecraft.nbt.CompoundTag; -+import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.ChunkStatus; -+import org.slf4j.Logger; -+ -+import javax.annotation.Nullable; -+import java.io.*; -+import java.nio.ByteBuffer; -+import java.nio.file.Files; -+import java.nio.file.Path; -+import java.nio.file.StandardCopyOption; -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.List; -+import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicInteger; -+import java.util.concurrent.locks.ReentrantLock; -+ -+public class LinearRegionFile implements AbstractRegionFile, AutoCloseable { -+ private static final long SUPERBLOCK = -4323716122432332390L; -+ private static final byte VERSION = 2; -+ private static final int HEADER_SIZE = 32; -+ private static final int FOOTER_SIZE = 8; -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ private static final List SUPPORTED_VERSIONS = Arrays.asList((byte) 1, (byte) 2); -+ public static final LinearRegionFileFlusher linearRegionFileFlusher = new LinearRegionFileFlusher(); -+ -+ private final byte[][] buffer = new byte[1024][]; -+ private final int[] bufferUncompressedSize = new int[1024]; -+ -+ private final int[] chunkTimestamps = new int[1024]; -+ private final ChunkStatus[] statuses = new ChunkStatus[1024]; -+ -+ private final LZ4Compressor compressor; -+ private final LZ4FastDecompressor decompressor; -+ -+ public final ReentrantLock fileLock = new ReentrantLock(true); -+ private final int compressionLevel; -+ -+ private AtomicBoolean markedToSave = new AtomicBoolean(false); -+ public boolean closed = false; -+ public Path path; -+ -+ public volatile boolean savingScheduled = true; -+ public final AtomicInteger dirtyChunkCount = new AtomicInteger(0); -+ -+ -+ public LinearRegionFile(Path file, int compression) throws IOException { -+ this.path = file; -+ this.compressionLevel = compression; -+ this.compressor = LZ4Factory.fastestInstance().fastCompressor(); -+ this.decompressor = LZ4Factory.fastestInstance().fastDecompressor(); -+ -+ File regionFile = new File(this.path.toString()); -+ -+ Arrays.fill(this.bufferUncompressedSize, 0); -+ -+ if (!regionFile.canRead()) return; -+ -+ try (FileInputStream fileStream = new FileInputStream(regionFile); -+ DataInputStream rawDataStream = new DataInputStream(fileStream)) { -+ -+ long superBlock = rawDataStream.readLong(); -+ if (superBlock != SUPERBLOCK) -+ throw new RuntimeException("Invalid superblock: " + superBlock + " in " + file); -+ -+ byte version = rawDataStream.readByte(); -+ if (!SUPPORTED_VERSIONS.contains(version)) -+ throw new RuntimeException("Invalid version: " + version + " in " + file); -+ -+ // Skip newestTimestamp (Long) + Compression level (Byte) + Chunk count (Short): Unused. -+ rawDataStream.skipBytes(11); -+ -+ int dataCount = rawDataStream.readInt(); -+ long fileLength = file.toFile().length(); -+ if (fileLength != HEADER_SIZE + dataCount + FOOTER_SIZE) -+ throw new IOException("Invalid file length: " + this.path + " " + fileLength + " " + (HEADER_SIZE + dataCount + FOOTER_SIZE)); -+ -+ rawDataStream.skipBytes(8); // Skip data hash (Long): Unused. -+ -+ byte[] rawCompressed = new byte[dataCount]; -+ rawDataStream.readFully(rawCompressed, 0, dataCount); -+ -+ superBlock = rawDataStream.readLong(); -+ if (superBlock != SUPERBLOCK) -+ throw new IOException("Footer superblock invalid " + this.path); -+ -+ try (DataInputStream dataStream = new DataInputStream(new ZstdInputStream(new ByteArrayInputStream(rawCompressed)))) { -+ -+ int[] starts = new int[1024]; -+ for (int i = 0; i < 1024; i++) { -+ starts[i] = dataStream.readInt(); -+ dataStream.skipBytes(4); // Skip timestamps (Int): Unused. -+ } -+ -+ for (int i = 0; i < 1024; i++) { -+ if (starts[i] > 0) { -+ int size = starts[i]; -+ byte[] b = new byte[size]; -+ dataStream.readFully(b, 0, size); -+ -+ int maxCompressedLength = this.compressor.maxCompressedLength(size); -+ byte[] compressed = new byte[maxCompressedLength]; -+ int compressedLength = this.compressor.compress(b, 0, size, compressed, 0, maxCompressedLength); -+ b = new byte[compressedLength]; -+ System.arraycopy(compressed, 0, b, 0, compressedLength); -+ -+ this.buffer[i] = b; -+ this.bufferUncompressedSize[i] = size; -+ } -+ } -+ } -+ } -+ } -+ -+ public Path getRegionFile() { -+ return this.path; -+ } -+ -+ public ReentrantLock getFileLock() { -+ return this.fileLock; -+ } -+ -+ public void flush() throws IOException { -+ if (getAndResetSaveMarker()) { -+ this.savingScheduled = false; //cancel async saving -+ flushWrapper(); // sync -+ } -+ } -+ -+ private void markToSave() { -+ markedToSave.set(true); -+ } -+ -+ private void signalToSave(){ -+ linearRegionFileFlusher.scheduleSave(this); -+ } -+ -+ public boolean getAndResetSaveMarker() { -+ return markedToSave.getAndSet(false); -+ } -+ -+ public boolean isMarkedToSave(){ -+ return this.markedToSave.get(); -+ } -+ -+ public void resetSaveMarker(){ -+ this.markedToSave.set(false); -+ } -+ -+ public void flushWrapper() { -+ try { -+ save(); -+ } catch (IOException e) { -+ LOGGER.error("Failed to flush region file " + path.toAbsolutePath(), e); -+ }finally { -+ this.dirtyChunkCount.set(0); //Reset dirty chunk count -+ } -+ } -+ -+ public boolean doesChunkExist(ChunkPos pos) throws Exception { -+ throw new Exception("doesChunkExist is a stub"); -+ } -+ -+ private synchronized void save() throws IOException { -+ long timestamp = getTimestamp(); -+ short chunkCount = 0; -+ -+ File tempFile = new File(path.toString() + ".tmp"); -+ -+ try (FileOutputStream fileStream = new FileOutputStream(tempFile); -+ ByteArrayOutputStream zstdByteArray = new ByteArrayOutputStream(); -+ ZstdOutputStream zstdStream = new ZstdOutputStream(zstdByteArray, this.compressionLevel); -+ DataOutputStream zstdDataStream = new DataOutputStream(zstdStream); -+ DataOutputStream dataStream = new DataOutputStream(fileStream)) { -+ -+ dataStream.writeLong(SUPERBLOCK); -+ dataStream.writeByte(VERSION); -+ dataStream.writeLong(timestamp); -+ dataStream.writeByte(this.compressionLevel); -+ -+ ArrayList byteBuffers = new ArrayList<>(); -+ for (int i = 0; i < 1024; i++) { -+ if (this.bufferUncompressedSize[i] != 0) { -+ chunkCount += 1; -+ byte[] content = new byte[bufferUncompressedSize[i]]; -+ this.decompressor.decompress(buffer[i], 0, content, 0, bufferUncompressedSize[i]); -+ -+ byteBuffers.add(content); -+ } else byteBuffers.add(null); -+ } -+ for (int i = 0; i < 1024; i++) { -+ zstdDataStream.writeInt(this.bufferUncompressedSize[i]); // Write uncompressed size -+ zstdDataStream.writeInt(this.chunkTimestamps[i]); // Write timestamp -+ } -+ for (int i = 0; i < 1024; i++) { -+ if (byteBuffers.get(i) != null) -+ zstdDataStream.write(byteBuffers.get(i), 0, byteBuffers.get(i).length); -+ } -+ zstdDataStream.close(); -+ -+ dataStream.writeShort(chunkCount); -+ -+ byte[] compressed = zstdByteArray.toByteArray(); -+ -+ dataStream.writeInt(compressed.length); -+ dataStream.writeLong(0); -+ -+ dataStream.write(compressed, 0, compressed.length); -+ dataStream.writeLong(SUPERBLOCK); -+ -+ dataStream.flush(); -+ fileStream.getFD().sync(); -+ fileStream.getChannel().force(true); // Ensure atomicity on Btrfs -+ } -+ Files.move(tempFile.toPath(), this.path, StandardCopyOption.REPLACE_EXISTING); -+ } -+ -+ -+ public void setStatus(int x, int z, ChunkStatus status) { -+ this.statuses[getChunkIndex(x, z)] = status; -+ } -+ -+ public synchronized void write(ChunkPos pos, ByteBuffer buffer) { -+ try { -+ byte[] b = toByteArray(new ByteArrayInputStream(buffer.array())); -+ int uncompressedSize = b.length; -+ -+ int maxCompressedLength = this.compressor.maxCompressedLength(b.length); -+ byte[] compressed = new byte[maxCompressedLength]; -+ int compressedLength = this.compressor.compress(b, 0, b.length, compressed, 0, maxCompressedLength); -+ b = new byte[compressedLength]; -+ System.arraycopy(compressed, 0, b, 0, compressedLength); -+ -+ int index = getChunkIndex(pos.x, pos.z); -+ this.buffer[index] = b; -+ this.chunkTimestamps[index] = getTimestamp(); -+ this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] = uncompressedSize; -+ } catch (IOException e) { -+ LOGGER.error("Chunk write IOException " + e + " " + this.path); -+ }finally { -+ this.dirtyChunkCount.getAndIncrement(); -+ } -+ markToSave(); -+ signalToSave(); -+ } -+ -+ public DataOutputStream getChunkDataOutputStream(ChunkPos pos) { -+ return new DataOutputStream(new BufferedOutputStream(new LinearRegionFile.ChunkBuffer(pos))); -+ } -+ -+ private class ChunkBuffer extends ByteArrayOutputStream { -+ private final ChunkPos pos; -+ -+ public ChunkBuffer(ChunkPos chunkcoordintpair) { -+ super(); -+ this.pos = chunkcoordintpair; -+ } -+ -+ public void close() throws IOException { -+ ByteBuffer bytebuffer = ByteBuffer.wrap(this.buf, 0, this.count); -+ LinearRegionFile.this.write(this.pos, bytebuffer); -+ } -+ } -+ -+ private byte[] toByteArray(InputStream in) throws IOException { -+ ByteArrayOutputStream out = new ByteArrayOutputStream(); -+ byte[] tempBuffer = new byte[4096]; -+ -+ int length; -+ while ((length = in.read(tempBuffer)) >= 0) { -+ out.write(tempBuffer, 0, length); -+ } -+ -+ return out.toByteArray(); -+ } -+ -+ @Nullable -+ public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) { -+ if(this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) { -+ byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]]; -+ this.decompressor.decompress(this.buffer[getChunkIndex(pos.x, pos.z)], 0, content, 0, bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]); -+ return new DataInputStream(new ByteArrayInputStream(content)); -+ } -+ return null; -+ } -+ -+ public ChunkStatus getStatusIfCached(int x, int z) { -+ return this.statuses[getChunkIndex(x, z)]; -+ } -+ -+ public void clear(ChunkPos pos) { -+ int i = getChunkIndex(pos.x, pos.z); -+ this.buffer[i] = null; -+ this.bufferUncompressedSize[i] = 0; -+ this.chunkTimestamps[i] = getTimestamp(); -+ this.dirtyChunkCount.getAndIncrement(); -+ markToSave(); -+ signalToSave(); -+ } -+ -+ public boolean hasChunk(ChunkPos pos) { -+ return this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] > 0; -+ } -+ -+ public void close() throws IOException { -+ if (closed) return; -+ closed = true; -+ flush(); // sync -+ } -+ -+ private static int getChunkIndex(int x, int z) { -+ return (x & 31) + ((z & 31) << 5); -+ } -+ -+ private static int getTimestamp() { -+ return (int) (System.currentTimeMillis() / 1000L); -+ } -+ -+ public boolean recalculateHeader() { -+ return false; -+ } -+ -+ public void setOversized(int x, int z, boolean something) {} -+ -+ public CompoundTag getOversizedData(int x, int z) throws IOException { -+ throw new IOException("getOversizedData is a stub " + this.path); -+ } -+ -+ public boolean isOversized(int x, int z) { -+ return false; -+ } -+} -diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java -new file mode 100644 -index 0000000000000000000000000000000000000000..dea4dffd67ee9881a224acf41367c6845acec832 ---- /dev/null -+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java -@@ -0,0 +1,63 @@ -+package dev.kaiijumc.kaiiju.region; -+ -+import com.google.common.util.concurrent.ThreadFactoryBuilder; -+ -+import java.util.concurrent.*; -+import org.bukkit.Bukkit; -+ -+public class LinearRegionFileFlusher { -+ private final ExecutorService ioExecutor = Executors.newFixedThreadPool( -+ me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushThreads, -+ new ThreadFactoryBuilder() -+ .setNameFormat("linear-flusher-%d") -+ .build() -+ ); -+ -+ private final Executor delayedFlusher = CompletableFuture.delayedExecutor( -+ me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushFrequency, -+ TimeUnit.SECONDS, -+ ioExecutor -+ ); -+ -+ public LinearRegionFileFlusher() { -+ Bukkit.getLogger().info("Using " + me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushThreads + " threads for linear region flushing."); -+ } -+ -+ public void scheduleSave(LinearRegionFile regionFile) { -+ if (regionFile.dirtyChunkCount.get() > me.earthme.luminol.config.modules.misc.RegionFormatConfig.flushImmediatelyIfDirtyChunkHigherThan){ -+ this.scheduleSaveInternal(regionFile,this.ioExecutor); -+ return; -+ } -+ -+ this.scheduleSaveInternal(regionFile,this.delayedFlusher); -+ } -+ -+ private void scheduleSaveInternal(LinearRegionFile regionFile,Executor scheduler){ -+ if (!regionFile.savingScheduled || !regionFile.isMarkedToSave()){ -+ return; -+ } -+ -+ regionFile.savingScheduled = true; -+ scheduler.execute(()->{ -+ try { -+ if (!regionFile.closed && regionFile.isMarkedToSave()){ -+ regionFile.flushWrapper(); -+ } -+ }finally { -+ regionFile.resetSaveMarker(); -+ regionFile.savingScheduled = false; -+ } -+ }); -+ } -+ -+ public void shutdown() { -+ this.ioExecutor.shutdown(); -+ for (;;) { -+ try { -+ if (this.ioExecutor.awaitTermination(5_00,TimeUnit.MILLISECONDS)) break; -+ } catch (InterruptedException e) { -+ e.printStackTrace(); -+ } -+ } -+ } -+} -diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java b/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7164d9cd03186f0657783f83de3d6435cda2b17e ---- /dev/null -+++ b/src/main/java/dev/kaiijumc/kaiiju/region/RegionFileFormat.java -@@ -0,0 +1,16 @@ -+package dev.kaiijumc.kaiiju.region; -+ -+public enum RegionFileFormat { -+ ANVIL, -+ LINEAR, -+ INVALID; -+ -+ public static RegionFileFormat fromString(String format) { -+ for (RegionFileFormat rff : values()) { -+ if (rff.name().equalsIgnoreCase(format)) { -+ return rff; -+ } -+ } -+ return RegionFileFormat.INVALID; -+ } -+} -diff --git a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -index 2934f0cf0ef09c84739312b00186c2ef0019a165..b46acbc078f3d3bfb0f3ede3f1cc172f4b48c5df 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -+++ b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -@@ -816,7 +816,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - final ChunkDataController taskController) { - final ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); - if (intendingToBlock) { -- return taskController.computeForRegionFile(chunkX, chunkZ, true, (final RegionFile file) -> { -+ return taskController.computeForRegionFile(chunkX, chunkZ, true, (final dev.kaiijumc.kaiiju.region.AbstractRegionFile file) -> { // Kaiiju - if (file == null) { // null if no regionfile exists - return Boolean.FALSE; - } -@@ -829,7 +829,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return Boolean.FALSE; - } // else: it either exists or is not known, fall back to checking the loaded region file - -- return taskController.computeForRegionFileIfLoaded(chunkX, chunkZ, (final RegionFile file) -> { -+ return taskController.computeForRegionFileIfLoaded(chunkX, chunkZ, (final dev.kaiijumc.kaiiju.region.AbstractRegionFile file) -> { // Kaiiju - if (file == null) { // null if not loaded - // not sure at this point, let the I/O thread figure it out - return Boolean.TRUE; -@@ -1131,9 +1131,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return this.getCache().doesRegionFileNotExistNoIO(new ChunkPos(chunkX, chunkZ)); - } - -- public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { -+ public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { // Kaiiju - final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -+ final dev.kaiijumc.kaiiju.region.AbstractRegionFile regionFile; // Kaiiju - synchronized (cache) { - try { - regionFile = cache.getRegionFile(new ChunkPos(chunkX, chunkZ), existingOnly, true); -@@ -1146,19 +1146,19 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.fileLock.unlock(); -+ regionFile.getFileLock().unlock(); // Kaiiju - } - } - } - -- public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { -+ public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { // Kaiiju - final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -+ final dev.kaiijumc.kaiiju.region.AbstractRegionFile regionFile; // Kaiiju - - synchronized (cache) { - regionFile = cache.getRegionFileIfLoaded(new ChunkPos(chunkX, chunkZ)); - if (regionFile != null) { -- regionFile.fileLock.lock(); -+ regionFile.getFileLock().lock(); // Kaiiju - } - } - -@@ -1166,7 +1166,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.fileLock.unlock(); -+ regionFile.getFileLock().unlock(); // Kaiiju - } - } - } -diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java -index 3f3fd8b1881106f893ffb677272e50d77cbb6626..338dfc1c87ac82df80b3b87148deb791110ce3cc 100644 ---- a/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java -+++ b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java -@@ -164,6 +164,7 @@ public final class RegionShutdownThread extends TickThread { - - this.saveLevelData(world); - } -+ dev.kaiijumc.kaiiju.region.LinearRegionFile.linearRegionFileFlusher.shutdown(); //Luminol - Kaiiju linear format fixes - // moved from stop part 1 - // we need this to be after saving level data, as that will complete any teleportations the player is in - LOGGER.info("Saving players"); -diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -index 9017907c0ec67a37a506f09b7e4499cef7885279..8b9ffcaab5d71660291d1c0454d2abd969d8c6ae 100644 ---- a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -+++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java -@@ -84,8 +84,13 @@ public class ThreadedWorldUpgrader { - LOGGER.info("Found " + regionFiles.length + " regionfiles to convert"); - LOGGER.info("Starting conversion now for world " + this.worldName); - -+ // Kaiiju start -+ dev.kaiijumc.kaiiju.region.RegionFileFormat formatName = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatName; -+ int linearCompression = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel; -+ LOGGER.info("Using format " + formatName + " (" + linearCompression + ")"); -+ // Kaiiju end - final WorldInfo info = new WorldInfo(() -> worldPersistentData, -- new ChunkStorage(regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); -+ new ChunkStorage(formatName, linearCompression, regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey); // Kaiiju - - long expectedChunks = (long)regionFiles.length * (32L * 32L); - -diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java -new file mode 100644 -index 0000000000000000000000000000000000000000..ab1c3e0276bbdbb32fd4155f7c596f3172c7f351 ---- /dev/null -+++ b/src/main/java/me/earthme/luminol/config/modules/misc/RegionFormatConfig.java -@@ -0,0 +1,60 @@ -+package me.earthme.luminol.config.modules.misc; -+ -+import com.electronwill.nightconfig.core.file.CommentedFileConfig; -+import dev.kaiijumc.kaiiju.region.RegionFileFormat; -+import me.earthme.luminol.config.*; -+ -+public class RegionFormatConfig implements IConfigModule { -+ @DoNotLoad -+ public static RegionFileFormat regionFormatName = RegionFileFormat.ANVIL; -+ -+ @HotReloadUnsupported -+ @ConfigInfo(baseName = "formatName") -+ private static String formatName = "ANVIL"; -+ @HotReloadUnsupported -+ @ConfigInfo(baseName = "linear_compression_level",comments = "WARNING: DO NOT USE TOO HIGH COMPRESSION LEVEL(Recommended is 1 which is default value if you are using linear) BECAUSE THAT WOULD MAKE YOUR DATA IN DANGER!") -+ public static int regionFormatLinearCompressionLevel = 1; -+ @HotReloadUnsupported -+ @ConfigInfo(baseName = "linear_flusher_thread_count") -+ public static int linearFlushThreads = 1; -+ @HotReloadUnsupported -+ @ConfigInfo(baseName = "linear_flush_frequency") -+ public static int linearFlushFrequency = 10; -+ @ConfigInfo(baseName = "flush_immediately_if_queued_higher_than") -+ public static int flushImmediatelyIfDirtyChunkHigherThan = 5; -+ -+ @Override -+ public EnumConfigCategory getCategory() { -+ return EnumConfigCategory.MISC; -+ } -+ -+ @Override -+ public String getBaseName() { -+ return "region_format"; -+ } -+ -+ @Override -+ public void onLoaded(CommentedFileConfig configInstance){ -+ if (LuminolConfig.alreadyInited){ -+ return; -+ } -+ -+ regionFormatName = RegionFileFormat.fromString(formatName); -+ if (regionFormatName.equals(RegionFileFormat.INVALID)) { -+ LuminolConfig.logger.error("Unknown region format in luminol global config: {}", formatName); -+ LuminolConfig.logger.error("Falling back to ANVIL region file format."); -+ regionFormatName = RegionFileFormat.ANVIL; -+ } -+ -+ if (regionFormatLinearCompressionLevel > 23 || regionFormatLinearCompressionLevel < 1) { -+ LuminolConfig.logger.error("Linear region compression level should be between 1 and 22 in luminol global config: {}", regionFormatLinearCompressionLevel); -+ LuminolConfig.logger.error("Falling back to compression level 1."); -+ regionFormatLinearCompressionLevel = 1; -+ } -+ -+ if (linearFlushThreads < 0) -+ linearFlushThreads = Math.max(Runtime.getRuntime().availableProcessors() + linearFlushThreads, 1); -+ else -+ linearFlushThreads = Math.max(linearFlushThreads, 1); -+ } -+} -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index d2e02ccdfbea138f8afe335a8b8c50f0696d7108..0e495628228543d55a101d7840acb9fd16e1937b 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -923,7 +923,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { -- super(session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); -+ super(me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatName, me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel, session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync); // Kaiiju - // Paper - rewrite chunk system - this.tickingGenerated = new AtomicInteger(); - //this.playerMap = new PlayerMap(); // Folia - region threading -@@ -256,7 +256,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - this.lightEngine = new ThreadedLevelLightEngine(chunkProvider, this, this.level.dimensionType().hasSkyLight(), null, null); // Paper - rewrite chunk system - this.distanceManager = new ChunkMap.ChunkDistanceManager(executor, mainThreadExecutor); - this.overworldDataStorage = persistentStateManagerFactory; -- this.poiManager = new PoiManager(path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); -+ this.poiManager = new PoiManager(me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatName, me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel, path.resolve("poi"), dataFixer, dsync, iregistrycustom, world); // Kaiiju - this.setServerViewDistance(viewDistance); - // Paper start - this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new); -@@ -808,13 +808,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos); // Kaiiju - - return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); - } - - public ChunkStatus getChunkStatusOnDisk(ChunkPos chunkPos) throws IOException { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true); // Kaiiju - - if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) { - return null; -@@ -832,7 +832,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - } - - public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException { -- net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false); // Kaiiju - - regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound)); - } -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 43b8f64d7c14e6dd0975b24a3205806c4433f26f..eefc98c82c9eb7316f195e306cceb5c9bdcbead8 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -446,8 +446,8 @@ public class ServerLevel extends Level implements WorldGenLevel { - - private static final class EntityRegionFileStorage extends net.minecraft.world.level.chunk.storage.RegionFileStorage { - -- public EntityRegionFileStorage(Path directory, boolean dsync) { -- super(directory, dsync); -+ public EntityRegionFileStorage(dev.kaiijumc.kaiiju.region.RegionFileFormat format, int linearCompression, Path directory, boolean dsync) { // Kaiiju -+ super(format, linearCompression, directory, dsync); // Kaiiju - } - - protected void write(ChunkPos pos, net.minecraft.nbt.CompoundTag nbt) throws IOException { -@@ -808,7 +808,7 @@ public class ServerLevel extends Level implements WorldGenLevel { - // CraftBukkit end - boolean flag2 = minecraftserver.forceSynchronousWrites(); - DataFixer datafixer = minecraftserver.getFixerUpper(); -- this.entityStorage = new EntityRegionFileStorage(convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); -+ this.entityStorage = new EntityRegionFileStorage(me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatName, me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver); // Kaiiju - - // this.entityManager = new PersistentEntitySectionManager<>(Entity.class, new ServerLevel.EntityCallbacks(), entitypersistentstorage, this.entitySliceManager); // Paper // Paper - rewrite chunk system - StructureTemplateManager structuretemplatemanager = minecraftserver.getStructureManager(); -diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index 77dd632a266f4abed30b87b7909d77857c01e316..97007462c7f3d7231fff18ecf295f2574684bf9f 100644 ---- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -61,7 +61,7 @@ public class WorldUpgrader { - private volatile int skipped; - private final Reference2FloatMap> progressMap = Reference2FloatMaps.synchronize(new Reference2FloatOpenHashMap()); - private volatile Component status = Component.translatable("optimizeWorld.stage.counting"); -- public static final Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); -+ public static Pattern REGEX = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.(linear | mca)$"); // Kaiiju - private final DimensionDataStorage overworldDataStorage; - - public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, Registry dimensionOptionsRegistry, boolean eraseCache) { -@@ -116,7 +116,12 @@ public class WorldUpgrader { - ResourceKey resourcekey1 = (ResourceKey) iterator1.next(); - Path path = this.levelStorage.getDimensionPath(resourcekey1); - -- builder1.put(resourcekey1, new ChunkStorage(path.resolve("region"), this.dataFixer, true)); -+ // Kaiiju start -+ String worldName = this.levelStorage.getLevelId(); -+ dev.kaiijumc.kaiiju.region.RegionFileFormat formatName = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatName; -+ int linearCompression = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel; -+ builder1.put(resourcekey1, new ChunkStorage(formatName, linearCompression, path.resolve("region"), this.dataFixer, true)); -+ // Kaiiju end - } - - ImmutableMap, ChunkStorage> immutablemap1 = builder1.build(); -@@ -241,7 +246,7 @@ public class WorldUpgrader { - File file = this.levelStorage.getDimensionPath(world).toFile(); - File file1 = new File(file, "region"); - File[] afile = file1.listFiles((file2, s) -> { -- return s.endsWith(".mca"); -+ return s.endsWith(".mca") || s.endsWith(".linear"); // Kaiiju - }); - - if (afile == null) { -@@ -260,7 +265,11 @@ public class WorldUpgrader { - int l = Integer.parseInt(matcher.group(2)) << 5; - - try { -- RegionFile regionfile = new RegionFile(file2.toPath(), file1.toPath(), true); -+ // Kaiiju start -+ String worldName = this.levelStorage.getLevelId(); -+ int linearCompression = me.earthme.luminol.config.modules.misc.RegionFormatConfig.regionFormatLinearCompressionLevel; -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(linearCompression, file2.toPath(), file1.toPath(), true); -+ // Kaiiju end - - try { - for (int i1 = 0; i1 < 32; ++i1) { -diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -index 5150d447c9dc2f539446749c8bee102050bab4ed..187ff795192c7eb56dffafa1ff6fa3068ac341c3 100644 ---- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java -@@ -59,8 +59,8 @@ public class PoiManager extends SectionStorage { - // Paper end - rewrite chunk system - - -- public PoiManager(Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) { -- super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world); -+ public PoiManager(dev.kaiijumc.kaiiju.region.RegionFileFormat formatName, int linearCompression, Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) { // Kaiiju -+ super(formatName, linearCompression, path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world); // Kaiiju - this.world = (net.minecraft.server.level.ServerLevel)world; // Paper - rewrite chunk system - } - -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index d16d7c2fed89fb1347df7ddd95856e7f08c22e8a..e4200692f6a33a12d00120f7a661de3e57a671dd 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java -@@ -36,9 +36,9 @@ public class ChunkStorage implements AutoCloseable { - @Nullable - private volatile LegacyStructureDataHandler legacyStructureHandler; - -- public ChunkStorage(Path directory, DataFixer dataFixer, boolean dsync) { -+ public ChunkStorage(dev.kaiijumc.kaiiju.region.RegionFileFormat format, int linearCompression, Path directory, DataFixer dataFixer, boolean dsync) { // Kaiiju - this.fixerUpper = dataFixer; -- this.regionFileCache = new RegionFileStorage(directory, dsync, true); // Paper - rewrite chunk system; async chunk IO & Attempt to recalculate regionfile header if it is corrupt -+ this.regionFileCache = new RegionFileStorage(format,linearCompression,directory, dsync, true); // Paper - rewrite chunk system; async chunk IO & Attempt to recalculate regionfile header if it is corrupt //Kaiiju - } - - public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) { -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 6cf83502a954cce9c562ec036bfeddb477d38b73..a450533cd01dab4ae165dc93f6c57553fee831c8 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java -@@ -26,7 +26,7 @@ import net.minecraft.nbt.NbtIo; // Paper - import net.minecraft.world.level.ChunkPos; - import org.slf4j.Logger; - --public class RegionFile implements AutoCloseable { -+public class RegionFile implements AutoCloseable, dev.kaiijumc.kaiiju.region.AbstractRegionFile { // Kaiiju - - private static final Logger LOGGER = LogUtils.getLogger(); - private static final int SECTOR_BYTES = 4096; -@@ -50,6 +50,17 @@ public class RegionFile implements AutoCloseable { - public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(); // Paper - public final Path regionFile; // Paper - -+ // Kaiiju start - Abstract getters -+ public Path getRegionFile() { -+ return this.regionFile; -+ } -+ -+ public java.util.concurrent.locks.ReentrantLock getFileLock() { -+ return this.fileLock; -+ } -+ // Kaiiju end -+ -+ - // Paper start - Attempt to recalculate regionfile header if it is corrupt - private static long roundToSectors(long bytes) { - long sectors = bytes >>> 12; // 4096 = 2^12 -@@ -128,7 +139,7 @@ public class RegionFile implements AutoCloseable { - } - - // note: only call for CHUNK regionfiles -- boolean recalculateHeader() throws IOException { -+ public boolean recalculateHeader() throws IOException { // Kaiiju - if (!this.canRecalcHeader) { - return false; - } -@@ -955,10 +966,10 @@ public class RegionFile implements AutoCloseable { - private static int getChunkIndex(int x, int z) { - return (x & 31) + (z & 31) * 32; - } -- synchronized boolean isOversized(int x, int z) { -+ public synchronized boolean isOversized(int x, int z) { // Kaiiju - return this.oversized[getChunkIndex(x, z)] == 1; - } -- synchronized void setOversized(int x, int z, boolean oversized) throws IOException { -+ public synchronized void setOversized(int x, int z, boolean oversized) throws IOException { // Kaiiju - final int offset = getChunkIndex(x, z); - boolean previous = this.oversized[offset] == 1; - this.oversized[offset] = (byte) (oversized ? 1 : 0); -@@ -997,7 +1008,7 @@ public class RegionFile implements AutoCloseable { - return this.regionFile.getParent().resolve(this.regionFile.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); - } - -- synchronized CompoundTag getOversizedData(int x, int z) throws IOException { -+ public synchronized CompoundTag getOversizedData(int x, int z) throws IOException { // Kaiiju - 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); -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -index fe312b1aef579cb4bf81bdd967cf72ff880d7505..db9e4386ca95bdaba0a4a4e13e3a90d2bcfbae91 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 -@@ -21,9 +21,13 @@ public class RegionFileStorage implements AutoCloseable { - - public static final String ANVIL_EXTENSION = ".mca"; - private static final int MAX_CACHE_SIZE = 256; -- public final Long2ObjectLinkedOpenHashMap regionCache = new Long2ObjectLinkedOpenHashMap(); -+ public final Long2ObjectLinkedOpenHashMap regionCache = new Long2ObjectLinkedOpenHashMap(); // Kaiiju - private final Path folder; - private final boolean sync; -+ // Kaiiju start - Per world chunk format -+ public final dev.kaiijumc.kaiiju.region.RegionFileFormat format; -+ public final int linearCompression; -+ // Kaiiju end - private final boolean isChunkData; // Paper - - // Paper start - cache regionfile does not exist state -@@ -55,11 +59,15 @@ public class RegionFileStorage implements AutoCloseable { - } - // Paper end - cache regionfile does not exist state - -- protected RegionFileStorage(Path directory, boolean dsync) { // Paper - protected constructor -+ protected RegionFileStorage(dev.kaiijumc.kaiiju.region.RegionFileFormat format, int linearCompression, Path directory, boolean dsync) { // Paper - protected constructor - // Paper start - add isChunkData param -- this(directory, dsync, false); -+ this(format, linearCompression, directory, dsync, false); - } -- RegionFileStorage(Path directory, boolean dsync, boolean isChunkData) { -+ RegionFileStorage(dev.kaiijumc.kaiiju.region.RegionFileFormat format, int linearCompression, Path directory, boolean dsync, boolean isChunkData) { // Kaiiju -+ // Kaiiju start -+ this.format = format; -+ this.linearCompression = linearCompression; -+ // Kaiiju end - this.isChunkData = isChunkData; - // Paper end - add isChunkData param - this.folder = directory; -@@ -70,7 +78,7 @@ public class RegionFileStorage implements AutoCloseable { - @Nullable - public static ChunkPos getRegionFileCoordinates(Path file) { - String fileName = file.getFileName().toString(); -- if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) { -+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca") || !fileName.endsWith(".linear")) { // Kaiiju - return null; - } - -@@ -90,29 +98,29 @@ public class RegionFileStorage implements AutoCloseable { - } - } - -- public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { -+ public synchronized dev.kaiijumc.kaiiju.region.AbstractRegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) { // Kaiiju - return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ())); - } - - public synchronized boolean chunkExists(ChunkPos pos) throws IOException { -- RegionFile regionfile = getRegionFile(pos, true); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = getRegionFile(pos, true); // Kaiiju - - return regionfile != null ? regionfile.hasChunk(pos) : false; - } - -- public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit -+ public synchronized dev.kaiijumc.kaiiju.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Kaiiju - return this.getRegionFile(chunkcoordintpair, existingOnly, false); - } -- public synchronized RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly, boolean lock) throws IOException { -+ public synchronized dev.kaiijumc.kaiiju.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly, boolean lock) throws IOException { // Kaiiju - // Paper end - long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); final long regionPos = i; // Paper - OBFHELPER -- RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = this.regionCache.getAndMoveToFirst(i); // Kaiiju - - if (regionfile != null) { - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile.fileLock.lock(); -+ regionfile.getFileLock().lock(); // Kaiiju - } - // Paper end - return regionfile; -@@ -123,28 +131,45 @@ public class RegionFileStorage implements AutoCloseable { - } - // Paper end - cache regionfile does not exist state - if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - Sanitise RegionFileCache and make configurable -- ((RegionFile) this.regionCache.removeLast()).close(); -+ this.regionCache.removeLast().close(); // Kaiiju - } - - // Paper - only create directory if not existing only - moved down - Path path = this.folder; - int j = chunkcoordintpair.getRegionX(); -- Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Paper - diff on change -- if (existingOnly && !java.nio.file.Files.exists(path1)) { // Paper start - cache regionfile does not exist state -- this.markNonExisting(regionPos); -- return null; // CraftBukkit -+ // Kaiiju start - Polyglot -+ //Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); // Paper - diff on change -+ Path path1; -+ if (existingOnly) { -+ Path anvil = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); -+ Path linear = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".linear"); -+ if (java.nio.file.Files.exists(anvil)) path1 = anvil; -+ else if (java.nio.file.Files.exists(linear)) path1 = linear; -+ else { -+ this.markNonExisting(regionPos); -+ return null; -+ } -+ // Kaiiju end - } else { -+ // Kaiiju start - Polyglot -+ String extension = switch (this.format) { -+ case LINEAR -> "linear"; -+ default -> "mca"; -+ }; -+ path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + "." + extension); -+ // Kaiiju end - this.createRegionFile(regionPos); - } -+ - // Paper end - cache regionfile does not exist state - FileUtil.createDirectoriesSafe(this.folder); // Paper - only create directory if not existing only - moved from above -- RegionFile regionfile1 = new RegionFile(path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile1 = dev.kaiijumc.kaiiju.region.AbstractRegionFileFactory.getAbstractRegionFile(this.linearCompression, path1, this.folder, this.sync, this.isChunkData); // Paper - allow for chunk regionfiles to regen header // Kaiiju - - this.regionCache.putAndMoveToFirst(i, regionfile1); - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile1.fileLock.lock(); -+ regionfile1.getFileLock().lock(); // Kaiiju - } - // Paper end - return regionfile1; -@@ -156,7 +181,7 @@ public class RegionFileStorage implements AutoCloseable { - 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."); - } - -- private static CompoundTag readOversizedChunk(RegionFile regionfile, ChunkPos chunkCoordinate) throws IOException { -+ private static CompoundTag readOversizedChunk(dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile, ChunkPos chunkCoordinate) throws IOException { // Kaiiju - synchronized (regionfile) { - try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) { - CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); -@@ -191,14 +216,14 @@ public class RegionFileStorage implements AutoCloseable { - @Nullable - public CompoundTag read(ChunkPos pos) throws IOException { - // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing -- RegionFile regionfile = this.getRegionFile(pos, true, true); // Paper -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = this.getRegionFile(pos, true, true); // Paper // Kaiiju - if (regionfile == null) { - return null; - } - // Paper start - Add regionfile parameter - return this.read(pos, regionfile); - } -- public CompoundTag read(ChunkPos pos, RegionFile regionfile) throws IOException { -+ public CompoundTag read(ChunkPos pos, dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile) throws IOException { // Kaiiju - // We add the regionfile parameter to avoid the potential deadlock (on fileLock) if we went back to obtain a regionfile - // if we decide to re-read - // Paper end -@@ -208,7 +233,7 @@ public class RegionFileStorage implements AutoCloseable { - - // Paper start - if (regionfile.isOversized(pos.x, pos.z)) { -- printOversizedLog("Loading Oversized Chunk!", regionfile.regionFile, pos.x, pos.z); -+ printOversizedLog("Loading Oversized Chunk!", regionfile.getRegionFile(), pos.x, pos.z); // Kaiiju - return readOversizedChunk(regionfile, pos); - } - // Paper end -@@ -222,12 +247,12 @@ public class RegionFileStorage implements AutoCloseable { - if (this.isChunkData) { - ChunkPos chunkPos = ChunkSerializer.getChunkCoordinate(nbttagcompound); - if (!chunkPos.equals(pos)) { -- net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.regionFile.toAbsolutePath()); -+ net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.getRegionFile().toAbsolutePath()); // Kaiiju - if (regionfile.recalculateHeader()) { -- regionfile.fileLock.lock(); // otherwise we will unlock twice and only lock once. -+ regionfile.getFileLock().lock(); // otherwise we will unlock twice and only lock once. // Kaiiju - return this.read(pos, regionfile); - } -- net.minecraft.server.MinecraftServer.LOGGER.error("Can't recalculate regionfile header, regenerating chunk " + pos + " for " + regionfile.regionFile.toAbsolutePath()); -+ net.minecraft.server.MinecraftServer.LOGGER.error("Can't recalculate regionfile header, regenerating chunk " + pos + " for " + regionfile.getRegionFile().toAbsolutePath()); // Kaiiju - return null; - } - } -@@ -261,13 +286,13 @@ public class RegionFileStorage implements AutoCloseable { - - return nbttagcompound; - } finally { // Paper start -- regionfile.fileLock.unlock(); -+ regionfile.getFileLock().unlock(); // Kaiiju - } // Paper end - } - - public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException { - // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing -- RegionFile regionfile = this.getRegionFile(chunkPos, true); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = this.getRegionFile(chunkPos, true); // Kaiiju - if (regionfile == null) { - return; - } -@@ -298,7 +323,7 @@ public class RegionFileStorage implements AutoCloseable { - - protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { - // Paper start - rewrite chunk system -- RegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = this.getRegionFile(pos, nbt == null, true); // CraftBukkit // Kaiiju - if (nbt == null && regionfile == null) { - return; - } -@@ -353,7 +378,7 @@ public class RegionFileStorage implements AutoCloseable { - // Paper end - Chunk save reattempt - // Paper start - rewrite chunk system - } finally { -- regionfile.fileLock.unlock(); -+ regionfile.getFileLock().unlock(); // Kaiiju - } - // Paper end - rewrite chunk system - } -@@ -363,7 +388,7 @@ public class RegionFileStorage implements AutoCloseable { - ObjectIterator objectiterator = this.regionCache.values().iterator(); - - while (objectiterator.hasNext()) { -- RegionFile regionfile = (RegionFile) objectiterator.next(); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = (dev.kaiijumc.kaiiju.region.AbstractRegionFile) objectiterator.next(); // Kaiiju - - try { - regionfile.close(); -@@ -379,7 +404,7 @@ public class RegionFileStorage implements AutoCloseable { - ObjectIterator objectiterator = this.regionCache.values().iterator(); - - while (objectiterator.hasNext()) { -- RegionFile regionfile = (RegionFile) objectiterator.next(); -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile regionfile = (dev.kaiijumc.kaiiju.region.AbstractRegionFile) objectiterator.next(); // Kaiiju - - regionfile.flush(); - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -index 4aac1979cf57300825a999c876fcf24d3170e68e..3b96582f15d0985b670b5b5a1548800dee2154f4 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -47,8 +47,8 @@ public class SectionStorage extends RegionFileStorage implements AutoCloseabl - public final RegistryAccess registryAccess; // Paper - rewrite chunk system - protected final LevelHeightAccessor levelHeightAccessor; - -- public SectionStorage(Path path, Function> codecFactory, Function factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { -- super(path, dsync); // Paper - remove mojang I/O thread -+ public SectionStorage(dev.kaiijumc.kaiiju.region.RegionFileFormat format, int linearCompression, Path path, Function> codecFactory, Function factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) { // Kaiiju -+ super(format, linearCompression, path, dsync); // Paper - remove mojang I/O thread // Kaiiju - this.codec = codecFactory; - this.factory = factory; - this.fixerUpper = dataFixer; -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index becb3b07876715d7c39ba4e7289cc5ac85f84412..6763ebef045f856dac9d25113b7824699934ca44 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -576,7 +576,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { - world.getChunk(x, z); // make sure we're at ticket level 32 or lower - return true; - } -- net.minecraft.world.level.chunk.storage.RegionFile file; -+ dev.kaiijumc.kaiiju.region.AbstractRegionFile file; // Kaiiju - try { - file = world.getChunkSource().chunkMap.regionFileCache.getRegionFile(chunkPos, false); - } catch (java.io.IOException ex) { diff --git a/patches/server/0019-Kaiiju-Vanilla-end-portal-teleportation.patch b/patches/server/0018-Kaiiju-Vanilla-end-portal-teleportation.patch similarity index 97% rename from patches/server/0019-Kaiiju-Vanilla-end-portal-teleportation.patch rename to patches/server/0018-Kaiiju-Vanilla-end-portal-teleportation.patch index dd402f2..3df4eb3 100644 --- a/patches/server/0019-Kaiiju-Vanilla-end-portal-teleportation.patch +++ b/patches/server/0018-Kaiiju-Vanilla-end-portal-teleportation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Kaiiju Vanilla end portal teleportation diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index ad15df5dfe34e20a6b5dafaf01e8a7306b158109..1e1086ea561d8a57a33e57fc310493120530c5cf 100644 +index 8749e1d7109b751ec69e771b43014c085c0802cd..b676200cb54afa7aebe23eee4e7aef7c9a6e0712 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -4193,12 +4193,17 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0020-Kaiiju-Async-path-processing.patch b/patches/server/0019-Kaiiju-Async-path-processing.patch similarity index 100% rename from patches/server/0020-Kaiiju-Async-path-processing.patch rename to patches/server/0019-Kaiiju-Async-path-processing.patch diff --git a/patches/server/0021-Petal-Reduce-sensor-work.patch b/patches/server/0020-Petal-Reduce-sensor-work.patch similarity index 100% rename from patches/server/0021-Petal-Reduce-sensor-work.patch rename to patches/server/0020-Petal-Reduce-sensor-work.patch diff --git a/patches/server/0022-Pufferfish-Optimize-entity-coordinate-key.patch b/patches/server/0021-Pufferfish-Optimize-entity-coordinate-key.patch similarity index 100% rename from patches/server/0022-Pufferfish-Optimize-entity-coordinate-key.patch rename to patches/server/0021-Pufferfish-Optimize-entity-coordinate-key.patch diff --git a/patches/server/0023-Pufferfish-Cache-climbing-check-for-activation.patch b/patches/server/0022-Pufferfish-Cache-climbing-check-for-activation.patch similarity index 96% rename from patches/server/0023-Pufferfish-Cache-climbing-check-for-activation.patch rename to patches/server/0022-Pufferfish-Cache-climbing-check-for-activation.patch index b89071f..a2f9c0e 100644 --- a/patches/server/0023-Pufferfish-Cache-climbing-check-for-activation.patch +++ b/patches/server/0022-Pufferfish-Cache-climbing-check-for-activation.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Pufferfish Cache climbing check for activation diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1e1086ea561d8a57a33e57fc310493120530c5cf..165c680dd36d75c3b595004ed9605b4429a7193b 100644 +index b676200cb54afa7aebe23eee4e7aef7c9a6e0712..2fb2df4922a1b5b3acf732e68d8db7bb15ecc789 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -309,7 +309,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0024-Pufferfish-Improve-fluid-direction-caching.patch b/patches/server/0023-Pufferfish-Improve-fluid-direction-caching.patch similarity index 100% rename from patches/server/0024-Pufferfish-Improve-fluid-direction-caching.patch rename to patches/server/0023-Pufferfish-Improve-fluid-direction-caching.patch diff --git a/patches/server/0025-Pufferfish-Optimize-suffocation.patch b/patches/server/0024-Pufferfish-Optimize-suffocation.patch similarity index 100% rename from patches/server/0025-Pufferfish-Optimize-suffocation.patch rename to patches/server/0024-Pufferfish-Optimize-suffocation.patch diff --git a/patches/server/0026-Pufferfish-Early-return-optimization-for-target-find.patch b/patches/server/0025-Pufferfish-Early-return-optimization-for-target-find.patch similarity index 100% rename from patches/server/0026-Pufferfish-Early-return-optimization-for-target-find.patch rename to patches/server/0025-Pufferfish-Early-return-optimization-for-target-find.patch diff --git a/patches/server/0027-Pufferfish-Reduce-chunk-loading-lookups.patch b/patches/server/0026-Pufferfish-Reduce-chunk-loading-lookups.patch similarity index 100% rename from patches/server/0027-Pufferfish-Reduce-chunk-loading-lookups.patch rename to patches/server/0026-Pufferfish-Reduce-chunk-loading-lookups.patch diff --git a/patches/server/0028-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch b/patches/server/0027-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch similarity index 100% rename from patches/server/0028-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch rename to patches/server/0027-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch diff --git a/patches/server/0029-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch b/patches/server/0028-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch similarity index 98% rename from patches/server/0029-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch rename to patches/server/0028-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch index 4b19a5e..903ef93 100644 --- a/patches/server/0029-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch +++ b/patches/server/0028-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Pufferfish Reduce entity fluid lookups if no fluids diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 165c680dd36d75c3b595004ed9605b4429a7193b..e7919e78110d2213d081be2b2f169ef48d6bf364 100644 +index 2fb2df4922a1b5b3acf732e68d8db7bb15ecc789..9b4a9025f9b30834a07a83cc02e7ee7f665dcbd9 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -5260,16 +5260,18 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0030-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch b/patches/server/0029-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch similarity index 100% rename from patches/server/0030-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch rename to patches/server/0029-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch diff --git a/patches/server/0031-Pufferfish-Entity-TTL.patch b/patches/server/0030-Pufferfish-Entity-TTL.patch similarity index 97% rename from patches/server/0031-Pufferfish-Entity-TTL.patch rename to patches/server/0030-Pufferfish-Entity-TTL.patch index 2c5b282..cbadd13 100644 --- a/patches/server/0031-Pufferfish-Entity-TTL.patch +++ b/patches/server/0030-Pufferfish-Entity-TTL.patch @@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..15697d69659b6e1e776acf5094684b5f + } +} diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index e7919e78110d2213d081be2b2f169ef48d6bf364..253057e0e339b1db05d98a17b92bda45ae210039 100644 +index 9b4a9025f9b30834a07a83cc02e7ee7f665dcbd9..835a6e73a340375e30e4822df45a1c99d36ac009 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -812,6 +812,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0032-Pufferfish-Reduce-projectile-chunk-loading.patch b/patches/server/0031-Pufferfish-Reduce-projectile-chunk-loading.patch similarity index 100% rename from patches/server/0032-Pufferfish-Reduce-projectile-chunk-loading.patch rename to patches/server/0031-Pufferfish-Reduce-projectile-chunk-loading.patch diff --git a/patches/server/0033-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0032-Pufferfish-Dynamic-Activation-of-Brain.patch similarity index 99% rename from patches/server/0033-Pufferfish-Dynamic-Activation-of-Brain.patch rename to patches/server/0032-Pufferfish-Dynamic-Activation-of-Brain.patch index cb74dc1..8fc3054 100644 --- a/patches/server/0033-Pufferfish-Dynamic-Activation-of-Brain.patch +++ b/patches/server/0032-Pufferfish-Dynamic-Activation-of-Brain.patch @@ -71,7 +71,7 @@ index 0000000000000000000000000000000000000000..af5893ba1f738ec9827d7b714682c314 + } +} diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index eefc98c82c9eb7316f195e306cceb5c9bdcbead8..7be323f6dc960bef4a258dacc6840f7074e42473 100644 +index 43b8f64d7c14e6dd0975b24a3205806c4433f26f..3f394934e64df09e65b86d61a1dcabd3c6031a38 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -987,6 +987,7 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -83,7 +83,7 @@ index eefc98c82c9eb7316f195e306cceb5c9bdcbead8..7be323f6dc960bef4a258dacc6840f70 if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 253057e0e339b1db05d98a17b92bda45ae210039..b0373fd5f5c2d8c5aa51cfbd6e016ec11f63d0cc 100644 +index 835a6e73a340375e30e4822df45a1c99d36ac009..c7c0f6e399e472792ecad75fc402a64785fae818 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -481,6 +481,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0034-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch b/patches/server/0033-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch similarity index 100% rename from patches/server/0034-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch rename to patches/server/0033-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch diff --git a/patches/server/0035-Pufferfish-Reduce-entity-allocations.patch b/patches/server/0034-Pufferfish-Reduce-entity-allocations.patch similarity index 100% rename from patches/server/0035-Pufferfish-Reduce-entity-allocations.patch rename to patches/server/0034-Pufferfish-Reduce-entity-allocations.patch diff --git a/patches/server/0036-Pufferfish-Improve-container-checking-with-a-bitset.patch b/patches/server/0035-Pufferfish-Improve-container-checking-with-a-bitset.patch similarity index 100% rename from patches/server/0036-Pufferfish-Improve-container-checking-with-a-bitset.patch rename to patches/server/0035-Pufferfish-Improve-container-checking-with-a-bitset.patch diff --git a/patches/server/0037-Gale-Variable-entity-wake-up-duration.patch b/patches/server/0036-Gale-Variable-entity-wake-up-duration.patch similarity index 100% rename from patches/server/0037-Gale-Variable-entity-wake-up-duration.patch rename to patches/server/0036-Gale-Variable-entity-wake-up-duration.patch diff --git a/patches/server/0038-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch b/patches/server/0037-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch similarity index 97% rename from patches/server/0038-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch rename to patches/server/0037-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch index 1425537..a352a95 100644 --- a/patches/server/0038-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch +++ b/patches/server/0037-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch @@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..ed62d25d6cd6dfcf8c5db20ced36eb3d + } +} diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b0373fd5f5c2d8c5aa51cfbd6e016ec11f63d0cc..8db82ab42fdc5adc65f84f69f276638ca0fce208 100644 +index c7c0f6e399e472792ecad75fc402a64785fae818..31f80438e82da6de1cd1ec35a2f77c45f0127722 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -5458,6 +5458,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0039-Gale-Optimize-sun-burn-tick.patch b/patches/server/0038-Gale-Optimize-sun-burn-tick.patch similarity index 97% rename from patches/server/0039-Gale-Optimize-sun-burn-tick.patch rename to patches/server/0038-Gale-Optimize-sun-burn-tick.patch index 5154acb..9abc3ea 100644 --- a/patches/server/0039-Gale-Optimize-sun-burn-tick.patch +++ b/patches/server/0038-Gale-Optimize-sun-burn-tick.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Gale Optimize sun burn tick diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8db82ab42fdc5adc65f84f69f276638ca0fce208..52f9511cf11eb59ca817b6d3fc3d2ef152fa5719 100644 +index 31f80438e82da6de1cd1ec35a2f77c45f0127722..6948342ef9fa4af0e13707e85cd788c815e34544 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -308,7 +308,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0040-Gale-Check-frozen-ticks-before-landing-block.patch b/patches/server/0039-Gale-Check-frozen-ticks-before-landing-block.patch similarity index 100% rename from patches/server/0040-Gale-Check-frozen-ticks-before-landing-block.patch rename to patches/server/0039-Gale-Check-frozen-ticks-before-landing-block.patch diff --git a/patches/server/0041-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch b/patches/server/0040-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch similarity index 100% rename from patches/server/0041-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch rename to patches/server/0040-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch diff --git a/patches/server/0042-Gale-Use-platform-math-functions.patch b/patches/server/0041-Gale-Use-platform-math-functions.patch similarity index 100% rename from patches/server/0042-Gale-Use-platform-math-functions.patch rename to patches/server/0041-Gale-Use-platform-math-functions.patch diff --git a/patches/server/0043-Gale-Skip-entity-move-if-movement-is-zero.patch b/patches/server/0042-Gale-Skip-entity-move-if-movement-is-zero.patch similarity index 95% rename from patches/server/0043-Gale-Skip-entity-move-if-movement-is-zero.patch rename to patches/server/0042-Gale-Skip-entity-move-if-movement-is-zero.patch index e453500..76b84f6 100644 --- a/patches/server/0043-Gale-Skip-entity-move-if-movement-is-zero.patch +++ b/patches/server/0042-Gale-Skip-entity-move-if-movement-is-zero.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Gale Skip entity move if movement is zero diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 52f9511cf11eb59ca817b6d3fc3d2ef152fa5719..c47ee80b1959e5edac0b74c6545bde493455e75a 100644 +index 6948342ef9fa4af0e13707e85cd788c815e34544..29cbafa048f61f7eb7d35dd103faff8c2b4a77f5 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -317,6 +317,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S diff --git a/patches/server/0044-Gale-Optimize-world-generation-chunk-and-block-acces.patch b/patches/server/0043-Gale-Optimize-world-generation-chunk-and-block-acces.patch similarity index 100% rename from patches/server/0044-Gale-Optimize-world-generation-chunk-and-block-acces.patch rename to patches/server/0043-Gale-Optimize-world-generation-chunk-and-block-acces.patch diff --git a/patches/server/0045-Gale-Optimize-noise-generation.patch b/patches/server/0044-Gale-Optimize-noise-generation.patch similarity index 100% rename from patches/server/0045-Gale-Optimize-noise-generation.patch rename to patches/server/0044-Gale-Optimize-noise-generation.patch diff --git a/patches/server/0046-Gale-Faster-chunk-serialization.patch b/patches/server/0045-Gale-Faster-chunk-serialization.patch similarity index 100% rename from patches/server/0046-Gale-Faster-chunk-serialization.patch rename to patches/server/0045-Gale-Faster-chunk-serialization.patch diff --git a/patches/server/0047-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch b/patches/server/0046-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch similarity index 100% rename from patches/server/0047-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch rename to patches/server/0046-Gale-Reduce-lambda-and-Optional-allocation-in-Entity.patch diff --git a/patches/server/0048-Gale-Replace-AI-goal-set-with-optimized-collection.patch b/patches/server/0047-Gale-Replace-AI-goal-set-with-optimized-collection.patch similarity index 100% rename from patches/server/0048-Gale-Replace-AI-goal-set-with-optimized-collection.patch rename to patches/server/0047-Gale-Replace-AI-goal-set-with-optimized-collection.patch diff --git a/patches/server/0049-Gale-Replace-AI-attributes-with-optimized-collection.patch b/patches/server/0048-Gale-Replace-AI-attributes-with-optimized-collection.patch similarity index 100% rename from patches/server/0049-Gale-Replace-AI-attributes-with-optimized-collection.patch rename to patches/server/0048-Gale-Replace-AI-attributes-with-optimized-collection.patch diff --git a/patches/server/0050-Gale-Replace-throttle-tracker-map-with-optimized-col.patch b/patches/server/0049-Gale-Replace-throttle-tracker-map-with-optimized-col.patch similarity index 100% rename from patches/server/0050-Gale-Replace-throttle-tracker-map-with-optimized-col.patch rename to patches/server/0049-Gale-Replace-throttle-tracker-map-with-optimized-col.patch diff --git a/patches/server/0052-Sparkly-Paper-Optimize-canSee-checks.patch b/patches/server/0050-Sparkly-Paper-Optimize-canSee-checks.patch similarity index 97% rename from patches/server/0052-Sparkly-Paper-Optimize-canSee-checks.patch rename to patches/server/0050-Sparkly-Paper-Optimize-canSee-checks.patch index 7b03206..3592d87 100644 --- a/patches/server/0052-Sparkly-Paper-Optimize-canSee-checks.patch +++ b/patches/server/0050-Sparkly-Paper-Optimize-canSee-checks.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Sparkly Paper Optimize canSee checks diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 76ad4d8bce1611ead6f1596b2ba78267e3718655..d1dc02b3e4f775c9bd79073a8e96243aa5ab6c24 100644 +index 6ab9f83786dcfbd3156d2f2bd6da57baed1399f4..09b72783bab881a42d94b77c453c638f5b7aaf40 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1408,7 +1408,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider diff --git a/patches/server/0051-LinearPaper-Remove-all-locks-on-region-files.patch b/patches/server/0051-LinearPaper-Remove-all-locks-on-region-files.patch deleted file mode 100644 index 90a2c99..0000000 --- a/patches/server/0051-LinearPaper-Remove-all-locks-on-region-files.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrHua269 -Date: Wed, 7 Feb 2024 06:30:38 +0000 -Subject: [PATCH] LinearPaper Remove all locks on region files - - -diff --git a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -index b46acbc078f3d3bfb0f3ede3f1cc172f4b48c5df..812d8504c6abd16b34ee4abd976563f345f00d18 100644 ---- a/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -+++ b/src/main/java/io/papermc/paper/chunk/system/io/RegionFileIOThread.java -@@ -835,7 +835,8 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return Boolean.TRUE; - } - -- return file.hasChunk(chunkPos) ? Boolean.TRUE : Boolean.FALSE; -+ //return file.hasChunk(chunkPos) ? Boolean.TRUE : Boolean.FALSE; -+ return Boolean.TRUE; - }); - } - } -@@ -1146,7 +1147,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.getFileLock().unlock(); // Kaiiju -+// regionFile.getFileLock().unlock(); // Kaiiju - } - } - } -@@ -1158,7 +1159,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - synchronized (cache) { - regionFile = cache.getRegionFileIfLoaded(new ChunkPos(chunkX, chunkZ)); - if (regionFile != null) { -- regionFile.getFileLock().lock(); // Kaiiju -+// regionFile.getFileLock().lock(); // Kaiiju - } - } - -@@ -1166,7 +1167,7 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return function.apply(regionFile); - } finally { - if (regionFile != null) { -- regionFile.getFileLock().unlock(); // Kaiiju -+// regionFile.getFileLock().unlock(); // Kaiiju - } - } - } -diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java -index db9e4386ca95bdaba0a4a4e13e3a90d2bcfbae91..73fc6d393cb338fee7d866b99a4e25684d47e79b 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 -@@ -120,7 +120,7 @@ public class RegionFileStorage implements AutoCloseable { - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile.getFileLock().lock(); // Kaiiju -+// regionfile.getFileLock().lock(); // Kaiiju - } - // Paper end - return regionfile; -@@ -169,7 +169,7 @@ public class RegionFileStorage implements AutoCloseable { - // Paper start - if (lock) { - // must be in this synchronized block -- regionfile1.getFileLock().lock(); // Kaiiju -+// regionfile1.getFileLock().lock(); // Kaiiju - } - // Paper end - return regionfile1; -@@ -249,7 +249,7 @@ public class RegionFileStorage implements AutoCloseable { - if (!chunkPos.equals(pos)) { - net.minecraft.server.MinecraftServer.LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + chunkPos + " instead! Attempting regionfile recalculation for regionfile " + regionfile.getRegionFile().toAbsolutePath()); // Kaiiju - if (regionfile.recalculateHeader()) { -- regionfile.getFileLock().lock(); // otherwise we will unlock twice and only lock once. // Kaiiju -+// regionfile.getFileLock().lock(); // otherwise we will unlock twice and only lock once. // Kaiiju - return this.read(pos, regionfile); - } - net.minecraft.server.MinecraftServer.LOGGER.error("Can't recalculate regionfile header, regenerating chunk " + pos + " for " + regionfile.getRegionFile().toAbsolutePath()); // Kaiiju -@@ -286,7 +286,7 @@ public class RegionFileStorage implements AutoCloseable { - - return nbttagcompound; - } finally { // Paper start -- regionfile.getFileLock().unlock(); // Kaiiju -+// regionfile.getFileLock().unlock(); // Kaiiju - } // Paper end - } - -@@ -378,7 +378,7 @@ public class RegionFileStorage implements AutoCloseable { - // Paper end - Chunk save reattempt - // Paper start - rewrite chunk system - } finally { -- regionfile.getFileLock().unlock(); // Kaiiju -+ //regionfile.getFileLock().unlock(); // Kaiiju - } - // Paper end - rewrite chunk system - } diff --git a/patches/server/0053-Purpur-use-alternative-keep-alive.patch b/patches/server/0051-Purpur-use-alternative-keep-alive.patch similarity index 100% rename from patches/server/0053-Purpur-use-alternative-keep-alive.patch rename to patches/server/0051-Purpur-use-alternative-keep-alive.patch diff --git a/patches/server/0054-Leaves-Protocol-Core.patch b/patches/server/0052-Leaves-Protocol-Core.patch similarity index 100% rename from patches/server/0054-Leaves-Protocol-Core.patch rename to patches/server/0052-Leaves-Protocol-Core.patch diff --git a/patches/server/0055-Leaves-Bladeren-Protocol.patch b/patches/server/0053-Leaves-Bladeren-Protocol.patch similarity index 100% rename from patches/server/0055-Leaves-Bladeren-Protocol.patch rename to patches/server/0053-Leaves-Bladeren-Protocol.patch diff --git a/patches/server/0056-Leaves-Fix-Bladeren-Protocol.patch b/patches/server/0054-Leaves-Fix-Bladeren-Protocol.patch similarity index 100% rename from patches/server/0056-Leaves-Fix-Bladeren-Protocol.patch rename to patches/server/0054-Leaves-Fix-Bladeren-Protocol.patch diff --git a/patches/server/0057-Leaves-carpet-protocol-support.patch b/patches/server/0055-Leaves-carpet-protocol-support.patch similarity index 100% rename from patches/server/0057-Leaves-carpet-protocol-support.patch rename to patches/server/0055-Leaves-carpet-protocol-support.patch diff --git a/patches/server/0058-Threaded-region-start-tick-and-finished-tick-event.patch b/patches/server/0056-Threaded-region-start-tick-and-finished-tick-event.patch similarity index 100% rename from patches/server/0058-Threaded-region-start-tick-and-finished-tick-event.patch rename to patches/server/0056-Threaded-region-start-tick-and-finished-tick-event.patch diff --git a/patches/server/0059-Leaves-Replay-Mod-API.patch b/patches/server/0057-Leaves-Replay-Mod-API.patch similarity index 99% rename from patches/server/0059-Leaves-Replay-Mod-API.patch rename to patches/server/0057-Leaves-Replay-Mod-API.patch index 1add2f8..a12b61c 100644 --- a/patches/server/0059-Leaves-Replay-Mod-API.patch +++ b/patches/server/0057-Leaves-Replay-Mod-API.patch @@ -168,7 +168,7 @@ index 18b8651147dedcf80d9baf04e87fb25cfbf9b89f..e9a49eb00c64d864ebf4b24d6fe84aba super.channelActive(channelhandlercontext); this.channel = channelhandlercontext.channel(); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0e495628228543d55a101d7840acb9fd16e1937b..ea4ee9aa6f9cf28c8b06e2c0546a8a92e44e2620 100644 +index d2e02ccdfbea138f8afe335a8b8c50f0696d7108..f03f01e6a3a0d0c1e99dde1d102178d57f9c342b 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1727,7 +1727,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop