mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2025-01-07 08:58:04 +01:00
rebase c2me port
This commit is contained in:
parent
fd74d8f1ad
commit
2372955f66
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ '8', '11', '15', '16' ]
|
||||
java: [ '11', '15', '16' ]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
11
Jenkinsfile
vendored
11
Jenkinsfile
vendored
@ -9,7 +9,7 @@ pipeline {
|
||||
stages {
|
||||
stage('Cleanup') {
|
||||
tools {
|
||||
jdk "OpenJDK 8"
|
||||
jdk "OpenJDK 11"
|
||||
}
|
||||
steps {
|
||||
scmSkip(deleteBuild: true, skipPattern:'.*\\[CI-SKIP\\].*')
|
||||
@ -29,7 +29,7 @@ pipeline {
|
||||
}
|
||||
stage('Init project & submodules') {
|
||||
tools {
|
||||
jdk "OpenJDK 8"
|
||||
jdk "OpenJDK 11"
|
||||
}
|
||||
steps {
|
||||
withMaven(
|
||||
@ -43,7 +43,7 @@ pipeline {
|
||||
}
|
||||
stage('Decompile & apply patches') {
|
||||
tools {
|
||||
jdk "OpenJDK 8"
|
||||
jdk "OpenJDK 11"
|
||||
}
|
||||
steps {
|
||||
withMaven(
|
||||
@ -60,7 +60,7 @@ pipeline {
|
||||
}
|
||||
stage('Build') {
|
||||
tools {
|
||||
jdk "OpenJDK 8"
|
||||
jdk "OpenJDK 11"
|
||||
}
|
||||
steps {
|
||||
withMaven(
|
||||
@ -76,7 +76,8 @@ pipeline {
|
||||
paperworkdir="$basedir/Paper/work"
|
||||
mcver=$(cat "$paperworkdir/BuildData/info.json" | grep minecraftVersion | cut -d '"' -f 4)
|
||||
|
||||
patchedJarPath="$basedir/Yatopia-Server/build/libs/yatopia-server-$mcver-R0.1-SNAPSHOT.jar"
|
||||
patchedJarPath=$(find "$basedir/Yatopia-Server/build/libs/" -type f -name "*.jar" | grep -v '\\-sources.jar$')
|
||||
|
||||
vanillaJarPath="$paperworkdir/Minecraft/$mcver/$mcver.jar"
|
||||
|
||||
cd "$paperworkdir/Paperclip"
|
||||
|
@ -105,6 +105,7 @@ # Patches
|
||||
| server | Breedable Polar Bears | William Blake Galbreath | |
|
||||
| api | Bring back server name | William Blake Galbreath | |
|
||||
| server | Bring back server name | William Blake Galbreath | |
|
||||
| server | C2ME Port | ishland | Simon Gardling |
|
||||
| server | Cache climbing check for activation | Paul Sauve | |
|
||||
| server | Cache coordinate key for micro opt | Paul Sauve | |
|
||||
| server | Cache entityhuman display name | Paul Sauve | |
|
||||
@ -229,6 +230,7 @@ # Patches
|
||||
| server | Fix the dead lagging the server | William Blake Galbreath | |
|
||||
| server | Fix vanilla command permission handler | William Blake Galbreath | |
|
||||
| server | Flying squids! Oh my! | William Blake Galbreath | |
|
||||
| server | Force world save | ishland | |
|
||||
| api | Full netherite armor grants fire resistance | BillyGalbreath | |
|
||||
| server | Full netherite armor grants fire resistance | BillyGalbreath | |
|
||||
| server | Gamemode extra permissions | BillyGalbreath | |
|
||||
@ -293,6 +295,7 @@ # Patches
|
||||
| server | Movement options for armor stands | Mariell Hoversholm | |
|
||||
| server | Multi-Threaded Server Ticking Vanilla | Spottedleaf | |
|
||||
| server | Multi-Threaded ticking CraftBukkit | Spottedleaf | |
|
||||
| server | Multi-threaded World Upgrade | ishland | |
|
||||
| server | Name craft scheduler threads according to the plugin using | Spottedleaf | |
|
||||
| server | New nbt cache | Hugo Planque | ishland |
|
||||
| server | Nuke streams off BlockPosition | Ivan Pekov | |
|
||||
@ -439,11 +442,14 @@ # Patches
|
||||
| server | Zombie horse naturally spawn | William Blake Galbreath | |
|
||||
| server | add config for logging login location | Simon Gardling | |
|
||||
| server | dont load chunks for physics | Aikar | |
|
||||
| api | java 11 | Simon Gardling | |
|
||||
| server | java 11 | Simon Gardling | |
|
||||
| server | lithium DataTrackerMixin | JellySquid | tr7zw |
|
||||
| server | lithium HashedList | JellySquid | |
|
||||
| server | lithium MixinBox | JellySquid | |
|
||||
| server | lithium MixinDirection | JellySquid | |
|
||||
| server | lithium MixinGoalSelector | JellySquid | |
|
||||
| server | lithium MultiNoiseBiomeSourceMixin | ishland | |
|
||||
| server | lithium NoiseChunkGeneratorMixin | JellySquid | |
|
||||
| server | lithium PerlinNoiseSamplerMixin | JellySquid | Bud Gidiere |
|
||||
| server | lithium VoronoiBiomeAccessTypeMixin | JellySquid | |
|
||||
|
@ -59,10 +59,10 @@ subprojects {
|
||||
}
|
||||
|
||||
java {
|
||||
if(JavaVersion.VERSION_1_8 > JavaVersion.current()){
|
||||
error("This build must be run with Java 8 or better")
|
||||
if(JavaVersion.VERSION_11 > JavaVersion.current()){
|
||||
error("This build must be run with Java 11 or later")
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.current()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
21
patches/api/0009-java-11.patch
Normal file
21
patches/api/0009-java-11.patch
Normal file
@ -0,0 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Gardling <titaniumtown@gmail.com>
|
||||
Date: Fri, 23 Apr 2021 11:11:13 -0400
|
||||
Subject: [PATCH] java 11
|
||||
|
||||
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
index cc3149a51f5780b73c11492e13dbe7eb86d83e6c..6143478e7e4bfb12208b290b64eee0f95a84f445 100644
|
||||
--- a/pom.xml
|
||||
+++ b/pom.xml
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
<properties>
|
||||
<!-- <skipTests>true</skipTests> Paper - This [was] not going to end well -->
|
||||
- <maven.compiler.source>1.8</maven.compiler.source>
|
||||
- <maven.compiler.target>1.8</maven.compiler.target>
|
||||
+ <maven.compiler.source>11</maven.compiler.source>
|
||||
+ <maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<adventure.version>4.7.0</adventure.version> <!-- Paper - When updating this make sure to update the linked JavaDocs on the homepage as well! -->
|
||||
</properties>
|
307
patches/removed/server/0072-Multi-threaded-RegionFile-IO.patch
Normal file
307
patches/removed/server/0072-Multi-threaded-RegionFile-IO.patch
Normal file
@ -0,0 +1,307 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ishland <ishlandmc@yeah.net>
|
||||
Date: Sun, 15 Nov 2020 10:42:27 +0800
|
||||
Subject: [PATCH] Multi-threaded RegionFile IO
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java
|
||||
index 9fe91f9512ee8c2589fc8da76bda5f6d70c9fac4..8b81119cfdef81665a302d96cfada5bb43bc1077 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java
|
||||
@@ -35,7 +35,7 @@ import java.util.function.Function;
|
||||
* @see #scheduleSave(WorldServer, int, int, NBTTagCompound, NBTTagCompound, int)
|
||||
* @see #loadChunkDataAsync(WorldServer, int, int, int, Consumer, boolean, boolean, boolean)
|
||||
*/
|
||||
-public final class PaperFileIOThread extends QueueExecutorThread {
|
||||
+public final class PaperFileIOThread { // Yatopia
|
||||
|
||||
public static final Logger LOGGER = MinecraftServer.LOGGER;
|
||||
public static final NBTTagCompound FAILURE_VALUE = new NBTTagCompound();
|
||||
@@ -44,23 +44,84 @@ public final class PaperFileIOThread extends QueueExecutorThread {
|
||||
|
||||
public static final PaperFileIOThread INSTANCE = new PaperFileIOThread();
|
||||
|
||||
+ /* Yatopia
|
||||
static {
|
||||
INSTANCE.start();
|
||||
}
|
||||
+ */
|
||||
}
|
||||
|
||||
private final AtomicLong writeCounter = new AtomicLong();
|
||||
+ // Yatopia start - multi-threaded RegionFile IO
|
||||
+ private final com.ibm.asyncutil.locks.AsyncNamedLock<RegionFileCoord> regionFileLock = com.ibm.asyncutil.locks.AsyncNamedLock.createFair();
|
||||
+ private final PrioritizedTaskQueue<PrioritizedTaskQueue.PrioritizedTask> queue;
|
||||
+ private final PaperFileIOThread.FileIOExecutorThread receiver;
|
||||
+ private final java.util.Set<Thread> executorThreads = com.google.common.collect.Sets.newConcurrentHashSet();
|
||||
+ private final java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newFixedThreadPool(
|
||||
+ org.yatopiamc.yatopia.server.YatopiaConfig.regionFileIOThreadPoolSize == -1 ? Math.min(Runtime.getRuntime().availableProcessors(), Integer.getInteger("paper.maxChunkThreads", 8)) : org.yatopiamc.yatopia.server.YatopiaConfig.regionFileIOThreadPoolSize,
|
||||
+ new com.google.common.util.concurrent.ThreadFactoryBuilder()
|
||||
+ .setNameFormat("Paper RegionFile IO Worker #%d")
|
||||
+ .setPriority(Thread.NORM_PRIORITY - 1)
|
||||
+ .setDaemon(true)
|
||||
+ .setThreadFactory(r -> {
|
||||
+ Thread thr = new Thread(r);
|
||||
+ executorThreads.add(thr);
|
||||
+ return thr;
|
||||
+ })
|
||||
+ .setUncaughtExceptionHandler((t, e) -> {
|
||||
+ LOGGER.fatal("Uncaught exception thrown from " + t.getName() + ", report this!", e);
|
||||
+ executorThreads.remove(t);
|
||||
+ })
|
||||
+ .build()
|
||||
+ );
|
||||
|
||||
private PaperFileIOThread() {
|
||||
- super(new PrioritizedTaskQueue<>(), (int)(1.0e6)); // 1.0ms spinwait time
|
||||
- this.setName("Paper RegionFile IO Thread");
|
||||
- this.setPriority(Thread.NORM_PRIORITY - 1); // we keep priority close to normal because threads can wait on us
|
||||
- this.setUncaughtExceptionHandler((final Thread unused, final Throwable thr) -> {
|
||||
- LOGGER.fatal("Uncaught exception thrown from IO thread, report this!", thr);
|
||||
+ queue = new PrioritizedTaskQueue<>();
|
||||
+ receiver = new PaperFileIOThread.FileIOExecutorThread(queue, (int) (1.0e6)); // 1.0ms spinwait time
|
||||
+ receiver.setName("Paper RegionFile IO Task Receiver");
|
||||
+ receiver.setPriority(Thread.NORM_PRIORITY - 1); // we keep priority close to normal because threads can wait on us
|
||||
+ receiver.setUncaughtExceptionHandler((final Thread thread, final Throwable thr) -> {
|
||||
+ LOGGER.fatal("Uncaught exception thrown from " + thread.getName() + ", report this!", thr);
|
||||
});
|
||||
+ receiver.start();
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ public void flush() {
|
||||
+ receiver.flush();
|
||||
+ final java.util.Set<CompletableFuture<?>> runningTasks = new java.util.HashSet<>(receiver.runningTasks);
|
||||
+ LOGGER.debug("Flushing Chunk IO: Waiting for {} futures", runningTasks.size());
|
||||
+ for(CompletableFuture<?> future: runningTasks) {
|
||||
+ try {
|
||||
+ future.join();
|
||||
+ } catch (Throwable ignored) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void queueTask(PrioritizedTaskQueue.PrioritizedTask newTask) {
|
||||
+ queue.add(newTask);
|
||||
+ receiver.notifyTasks();
|
||||
+ }
|
||||
+
|
||||
+ public void close(final boolean wait) {
|
||||
+ receiver.close(wait, true);
|
||||
+ this.flush();
|
||||
+ executor.shutdown();
|
||||
+ while (wait && !executor.isTerminated()) {
|
||||
+ try {
|
||||
+ executor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS);
|
||||
+ } catch (InterruptedException e) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
+ public boolean isOnWorkerThread() {
|
||||
+ return executorThreads.contains(Thread.currentThread());
|
||||
}
|
||||
|
||||
- /* run() is implemented by superclass */
|
||||
+ // Yatopia end
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -394,6 +455,85 @@ public final class PaperFileIOThread extends QueueExecutorThread {
|
||||
this.queueTask(new GeneralTask(priority, runnable));
|
||||
}
|
||||
|
||||
+ // Yatopia start
|
||||
+ public static final class RegionFileCoord {
|
||||
+
|
||||
+ public final int x;
|
||||
+ public final int z;
|
||||
+
|
||||
+ public RegionFileCoord(int x, int z) {
|
||||
+ this.x = x;
|
||||
+ this.z = z;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (o == null || getClass() != o.getClass()) return false;
|
||||
+ RegionFileCoord that = (RegionFileCoord) o;
|
||||
+ return x == that.x && z == that.z;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return java.util.Objects.hash(x, z);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final class FileIOExecutorThread<T extends PrioritizedTaskQueue.PrioritizedTask & Runnable> extends QueueExecutorThread<T> {
|
||||
+ private final java.util.Set<CompletableFuture<?>> runningTasks = com.google.common.collect.Sets.newConcurrentHashSet();
|
||||
+
|
||||
+ public FileIOExecutorThread(PrioritizedTaskQueue<T> queue, long spinWaitTime) {
|
||||
+ super(queue, spinWaitTime);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void preMainLoop() {
|
||||
+ runningTasks.removeIf(CompletableFuture::isDone);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected boolean pollTasks(boolean flushTasks) {
|
||||
+ Runnable task;
|
||||
+ boolean ret = false;
|
||||
+
|
||||
+ while ((task = this.queue.poll()) != null) {
|
||||
+ ret = true;
|
||||
+ if (task instanceof ChunkDataTask) {
|
||||
+ ChunkDataTask chunkDataTask = (ChunkDataTask) task;
|
||||
+ runningTasks.add(regionFileLock.acquireLock(new RegionFileCoord(chunkDataTask.x >> 5, chunkDataTask.z >> 5))
|
||||
+ .thenApplyAsync(lockToken -> {
|
||||
+ try {
|
||||
+ chunkDataTask.run();
|
||||
+ } finally {
|
||||
+ lockToken.releaseLock();
|
||||
+ }
|
||||
+ return null;
|
||||
+ }, executor)
|
||||
+ .exceptionally(throwable -> {
|
||||
+ LOGGER.fatal("Exception thrown from prioritized runnable task in thread '" + Thread.currentThread().getName() + "': " + IOUtil.genericToString(chunkDataTask), throwable);
|
||||
+ return null;
|
||||
+ }).toCompletableFuture());
|
||||
+ } else {
|
||||
+ Runnable finalTask = task;
|
||||
+ runningTasks.add(CompletableFuture.supplyAsync(() -> {
|
||||
+ finalTask.run();
|
||||
+ return null;
|
||||
+ }).exceptionally(throwable -> {
|
||||
+ LOGGER.fatal("Exception thrown from prioritized runnable task in thread '" + Thread.currentThread().getName() + "': " + IOUtil.genericToString(finalTask), throwable);
|
||||
+ return null;
|
||||
+ }));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (flushTasks) {
|
||||
+ this.handleFlushThreads(false);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
static final class GeneralTask extends PrioritizedTaskQueue.PrioritizedTask implements Runnable {
|
||||
|
||||
private final Runnable run;
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java
|
||||
index ee906b594b306906c170180a29a8b61997d05168..7e348fcb813707fee830082b826932e0bbba1c49 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java
|
||||
@@ -35,6 +35,7 @@ public class QueueExecutorThread<T extends PrioritizedTaskQueue.PrioritizedTask
|
||||
final long spinWaitTime = this.spinWaitTime;
|
||||
main_loop:
|
||||
for (;;) {
|
||||
+ preMainLoop(); // Yatopia
|
||||
this.pollTasks(true);
|
||||
|
||||
// spinwait
|
||||
@@ -81,11 +82,17 @@ public class QueueExecutorThread<T extends PrioritizedTaskQueue.PrioritizedTask
|
||||
// LockSupport.park() can fail for any reason
|
||||
do {
|
||||
Thread.interrupted();
|
||||
- LockSupport.park("Waiting on tasks");
|
||||
+ LockSupport.parkNanos("Waiting on tasks", 1_000_000_000); // Yatopia - prevent dead lock
|
||||
} while (this.parked.get());
|
||||
}
|
||||
}
|
||||
|
||||
+ // Yatopia start
|
||||
+ protected void preMainLoop() {
|
||||
+ // Used for PaperFileIOThread
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
+
|
||||
protected boolean handleClose() {
|
||||
if (this.closed) {
|
||||
this.pollTasks(true); // this ensures we've emptied the queue
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 6fd059412e07e1b3b2597b693df5a4f439ebe382..d42d5c7153a655da65d1847541b9f15137b53dbb 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -962,7 +962,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
// Spigot end
|
||||
// Paper start - move final shutdown items here
|
||||
LOGGER.info("Flushing Chunk IO");
|
||||
- com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
|
||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true); // Paper // Yatopia
|
||||
LOGGER.info("Closing Thread Pool");
|
||||
SystemUtils.shutdownServerThreadPool(); // Paper
|
||||
LOGGER.info("Closing Server");
|
||||
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
index 9b3aa025069f45bf94949cbf626ccfa69a646845..aa4b548dbf3366e5bb0df3763be9bdc1c4e9d34d 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
@@ -1725,7 +1725,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
@Nullable
|
||||
@Override
|
||||
public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
- if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) {
|
||||
+ if (!com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.isOnWorkerThread()) { // Yatopia
|
||||
NBTTagCompound ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE
|
||||
.loadChunkDataAsyncFuture(this.world, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(),
|
||||
false, true, true).join().chunkData;
|
||||
@@ -1740,7 +1740,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
||||
@Override
|
||||
public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException {
|
||||
- if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) {
|
||||
+ if (!com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.isOnWorkerThread()) { // Yatopia
|
||||
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(
|
||||
this.world, chunkcoordintpair.x, chunkcoordintpair.z, null, nbttagcompound,
|
||||
com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); // Tuinity - writes are async, no need for priority
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
index 29cd71efe86eea2227f373c15c39dc530e9e8199..55d497f4305de50e58c7e0788724576f81128138 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
@@ -504,7 +504,7 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
|
||||
@javax.annotation.Nullable
|
||||
@Override
|
||||
public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws java.io.IOException {
|
||||
- if (this.world != null && Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) {
|
||||
+ if (this.world != null && !com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.isOnWorkerThread()) { // Yatopia
|
||||
NBTTagCompound ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE
|
||||
.loadChunkDataAsyncFuture(this.world, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(),
|
||||
true, false, true).join().poiData;
|
||||
@@ -519,7 +519,7 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
|
||||
|
||||
@Override
|
||||
public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws java.io.IOException {
|
||||
- if (this.world != null && Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) {
|
||||
+ if (this.world != null && !com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.isOnWorkerThread()) { // Yatopia
|
||||
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(
|
||||
this.world, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, null,
|
||||
com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY); // Tuinity - writes are async, no need for priority
|
||||
diff --git a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
index 545bf94bf47f0c6e9da1a4c162e081cbb2cd8390..e8e8e1fed06f0c17631a134e3673a25549d7c86c 100644
|
||||
--- a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
+++ b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
@@ -16,6 +16,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
+import com.google.common.base.Preconditions;
|
||||
|
||||
public class YatopiaConfig {
|
||||
|
||||
@@ -282,4 +283,10 @@ public class YatopiaConfig {
|
||||
allowThreadedFeatures = getBoolean("settings.c2me.allow-threaded-features", allowThreadedFeatures);
|
||||
c2meThreads = getInt("settings.c2me.parallelism", c2meThreads);
|
||||
}
|
||||
+
|
||||
+ public static int regionFileIOThreadPoolSize = -1;
|
||||
+ private static void multiThreadedRegionFile() {
|
||||
+ regionFileIOThreadPoolSize = getInt("settings.threads.regionfile", -1);
|
||||
+ Preconditions.checkArgument(regionFileIOThreadPoolSize == -1 || regionFileIOThreadPoolSize > 0, "Invalid settings.threads.regionfile in yatopia.yml");
|
||||
+ }
|
||||
}
|
653
patches/server/0068-C2ME-Port.patch
Normal file
653
patches/server/0068-C2ME-Port.patch
Normal file
@ -0,0 +1,653 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ishland <ishlandmc@yeah.net>
|
||||
Date: Thu, 22 Apr 2021 17:56:12 -0400
|
||||
Subject: [PATCH] C2ME Port
|
||||
|
||||
Port of https://github.com/YatopiaMC/C2ME-fabric
|
||||
|
||||
Co-authored-by: Simon Gardling <titaniumtown@gmail.com>
|
||||
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
index d0259f18488e1ecf0276865e0ff7958726a40033..f0a73238612327d71cf78801df816823d80893a0 100644
|
||||
--- a/pom.xml
|
||||
+++ b/pom.xml
|
||||
@@ -203,6 +203,12 @@
|
||||
<artifactId>commons-rng-core</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
+ <!-- https://mvnrepository.com/artifact/com.ibm.async/asyncutil -->
|
||||
+ <dependency>
|
||||
+ <groupId>com.ibm.async</groupId>
|
||||
+ <artifactId>asyncutil</artifactId>
|
||||
+ <version>0.1.0</version>
|
||||
+ </dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunk.java b/src/main/java/net/minecraft/server/level/PlayerChunk.java
|
||||
index 06157bb07cce3ba24087ceaca7138b5609b37b5b..47f0604a891d46f688abd5daa6fb4de8b56305e3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/PlayerChunk.java
|
||||
@@ -374,6 +374,7 @@ public class PlayerChunk {
|
||||
return either == null ? null : (Chunk) either.left().orElse(null); // CraftBukkit - decompile error
|
||||
}
|
||||
|
||||
+ @Nullable public IChunkAccess getCurrentChunk() { return this.f(); } // Yatopia - OBFHELPER
|
||||
@Nullable
|
||||
public IChunkAccess f() {
|
||||
for (int i = PlayerChunk.CHUNK_STATUSES.size() - 1; i >= 0; --i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
index e25476f6a9477447cc06f24ed05679326e83cd95..b77793771e8e264e90e09399e10246308ba1cb52 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
|
||||
@@ -154,8 +154,9 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
public final LongSet unloadQueue;
|
||||
private boolean updatingChunksModified;
|
||||
private final ChunkTaskQueueSorter p;
|
||||
- private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxWorldGen;
|
||||
+ // private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxWorldGen; // Yatopia
|
||||
public final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxMain; // Paper - private -> public
|
||||
+ private final ThreadLocal<ChunkStatus> capturedRequiredStatus = new ThreadLocal<>(); // Yatopia
|
||||
// Paper start
|
||||
final Mailbox<ChunkTaskQueueSorter.a<Runnable>> mailboxLight;
|
||||
public void addLightTask(PlayerChunk playerchunk, Runnable run) {
|
||||
@@ -461,7 +462,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
// Paper end
|
||||
|
||||
this.p = new ChunkTaskQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE);
|
||||
- this.mailboxWorldGen = this.p.a(threadedmailbox, false);
|
||||
+ // this.mailboxWorldGen = this.p.a(threadedmailbox, false); // Yatopia
|
||||
this.mailboxMain = this.p.a(mailbox, false);
|
||||
this.mailboxLight = this.p.a(lightthreaded, false);// Paper
|
||||
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
|
||||
@@ -1334,7 +1335,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
return this.z.put(chunkcoordintpair.pair(), (byte) (chunkstatus_type == ChunkStatus.Type.PROTOCHUNK ? -1 : 1));
|
||||
}
|
||||
|
||||
- private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) {
|
||||
+ private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) { // Yarn: upgradeChunk
|
||||
+ this.capturedRequiredStatus.set(chunkstatus); // Yatopia - C2ME port
|
||||
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
|
||||
CompletableFuture<Either<List<IChunkAccess>, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, chunkstatus.f(), (i) -> {
|
||||
return this.a(chunkstatus, i);
|
||||
@@ -1372,7 +1374,11 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
return;
|
||||
}
|
||||
// Paper end
|
||||
- this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable));
|
||||
+
|
||||
+ // Yatopia start - C2ME port
|
||||
+ org.yatopiamc.c2me.common.threading.GlobalExecutors.scheduler.execute(runnable);
|
||||
+ // this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // Yatopia
|
||||
+ // Yatopia end
|
||||
}).thenComposeAsync((either) -> { // Tuinity start - force competion on the main thread
|
||||
return CompletableFuture.completedFuture(either);
|
||||
}, this.mainInvokingExecutor);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
index 3068b307b7ad64f5add188e956d59a52126f332a..8892b54c85db83e3f5ad1ae26d3f23de754564f2 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
|
||||
@@ -178,7 +178,17 @@ import org.bukkit.event.world.TimeSkipEvent;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList; // Tuinity
|
||||
import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
|
||||
|
||||
-public class WorldServer extends World implements GeneratorAccessSeed, NonBlockingWorldAccess { // Yatopia
|
||||
+// Yatopia start
|
||||
+import org.yatopiamc.c2me.common.threading.worldgen.IWorldGenLockable;
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.ibm.asyncutil.locks.AsyncNamedLock;
|
||||
+// Yatopia end
|
||||
+
|
||||
+public class WorldServer extends World implements GeneratorAccessSeed, NonBlockingWorldAccess, IWorldGenLockable { // Yatopia // Yatopia - port C2ME
|
||||
+
|
||||
+ private volatile AsyncLock worldGenSingleThreadedLock = null; // Yatopia - port C2ME
|
||||
+ private volatile AsyncNamedLock<ChunkCoordIntPair> worldGenChunkLock = null;
|
||||
+ // Yatopia - port C2ME
|
||||
|
||||
public static final BlockPosition a = new BlockPosition(100, 50, 0);
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@@ -608,7 +618,23 @@ public class WorldServer extends World implements GeneratorAccessSeed, NonBlocki
|
||||
|
||||
this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper
|
||||
this.fakeTime = this.worldDataServer.getDayTime(); // Purpur
|
||||
+ // Yatopia start - port C2ME
|
||||
+ this.worldGenSingleThreadedLock = AsyncLock.createFair();
|
||||
+ this.worldGenChunkLock = AsyncNamedLock.createFair();
|
||||
+ // Yatopia end - port C2ME
|
||||
+ }
|
||||
+
|
||||
+ // Yatopia start - port C2ME
|
||||
+ @Override
|
||||
+ public AsyncLock getWorldGenSingleThreadedLock() {
|
||||
+ return this.worldGenSingleThreadedLock;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public AsyncNamedLock<ChunkCoordIntPair> getWorldGenChunkLock() {
|
||||
+ return this.worldGenChunkLock;
|
||||
}
|
||||
+ // Yatopia end - port C2ME
|
||||
|
||||
// Tuinity start - optimise collision
|
||||
public boolean collidesWithAnyBlockOrWorldBorder(@Nullable Entity entity, AxisAlignedBB axisalignedbb, boolean loadChunks,
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WeightedList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WeightedList.java
|
||||
index e2b5d6155bebdbf99b0850de7f9e1f5d342f9e2f..30db0ba3674a85c8dd866fab94c5374ba203c5cd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/WeightedList.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/WeightedList.java
|
||||
@@ -14,7 +14,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class WeightedList<U> {
|
||||
|
||||
- protected final List<WeightedList.a<U>> list; public final List<WeightedList.a<U>> getList() { return this.list; } // Paper - decompile conflict // Tuinity - OBFHELPER
|
||||
+ public final List<WeightedList.a<U>> list; public final List<WeightedList.a<U>> getList() { return this.list; } // Paper - decompile conflict // Tuinity - OBFHELPER // Yatopia - protected -> public
|
||||
private final Random b;
|
||||
private final boolean isUnsafe; // Paper
|
||||
|
||||
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 f4a4d63a2e21b08580023cf0dcd15a68d192cf14..1802498d48493d3e63c999a067c71e65ea29a890 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
|
||||
@@ -22,6 +22,9 @@ import net.minecraft.world.level.levelgen.HeightMap;
|
||||
import net.minecraft.world.level.levelgen.WorldGenStage;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructureManager;
|
||||
import net.minecraft.world.level.lighting.LightEngine;
|
||||
+import org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusUtils; // Yatopia
|
||||
+import org.yatopiamc.c2me.common.threading.worldgen.IWorldGenLockable; // Yatopia
|
||||
+import java.util.function.Supplier; // Yatopia
|
||||
|
||||
public class ChunkStatus {
|
||||
|
||||
@@ -162,6 +165,7 @@ public class ChunkStatus {
|
||||
return ichunkaccess.getChunkStatus().b(chunkstatus) && ichunkaccess.r();
|
||||
}
|
||||
|
||||
+ public static ChunkStatus byDistanceFromFull(int level) { return a(level); } // Yatopia - OBFHELPER
|
||||
public static ChunkStatus a(int i) {
|
||||
return i >= ChunkStatus.q.size() ? ChunkStatus.EMPTY : (i < 0 ? ChunkStatus.FULL : (ChunkStatus) ChunkStatus.q.get(i));
|
||||
}
|
||||
@@ -186,6 +190,14 @@ public class ChunkStatus {
|
||||
this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1;
|
||||
}
|
||||
|
||||
+ static {
|
||||
+ // Yatopia start - C2ME port
|
||||
+ for (ChunkStatus chunkStatus : IRegistry.CHUNK_STATUS) {
|
||||
+ chunkStatus.calculateReducedTaskRadius();
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
+ }
|
||||
+
|
||||
public final int getStatusIndex() { return c(); } // Paper - OBFHELPER
|
||||
public int c() {
|
||||
return this.t;
|
||||
@@ -200,8 +212,44 @@ public class ChunkStatus {
|
||||
return this.u;
|
||||
}
|
||||
|
||||
+ // Yatopia start - C2ME port
|
||||
+ private int reducedTaskRadius = -1;
|
||||
+
|
||||
+ public void calculateReducedTaskRadius() {
|
||||
+ if (this.getNeighborRadius() == 0) {
|
||||
+ this.reducedTaskRadius = 0;
|
||||
+ } else {
|
||||
+ for (int i = 0; i <= this.getNeighborRadius(); i++) {
|
||||
+ final ChunkStatus status = ChunkStatus.byDistanceFromFull(ChunkStatus.getTicketLevelOffset(this) + i); // TODO [VanillaCopy] from TACS getRequiredStatusForGeneration
|
||||
+ if (status == ChunkStatus.STRUCTURE_STARTS) {
|
||||
+ this.reducedTaskRadius = Math.min(this.getNeighborRadius(), i);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ //noinspection ConstantConditions
|
||||
+ if ((Object) this == ChunkStatus.LIGHT) {
|
||||
+ this.reducedTaskRadius = 1;
|
||||
+ }
|
||||
+ System.out.println(String.format("%s task radius: %d -> %d", this, this.getNeighborRadius(), this.reducedTaskRadius));
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
+
|
||||
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> a(WorldServer worldserver, ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function<IChunkAccess, CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> function, List<IChunkAccess> list) {
|
||||
- return this.v.doWork(this, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, (IChunkAccess) list.get(list.size() / 2));
|
||||
+ // Yatopia start - port C2ME
|
||||
+ final IChunkAccess targetChunk = (IChunkAccess) list.get(list.size() / 2);
|
||||
+ final Supplier<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> generationTask = () ->
|
||||
+ this.v.doWork(this, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, targetChunk);
|
||||
+
|
||||
+ if (targetChunk.getChunkStatus().isAtLeastStatus((ChunkStatus) (Object) this)) {
|
||||
+ return generationTask.get();
|
||||
+ } else {
|
||||
+ int lockRadius = org.yatopiamc.yatopia.server.YatopiaConfig.reduceLockRadius && this.reducedTaskRadius != -1 ? this.reducedTaskRadius : this.getNeighborRadius();
|
||||
+ //noinspection ConstantConditions
|
||||
+ return ChunkStatusUtils.runChunkGenWithLock(targetChunk.getPos(), lockRadius, ((IWorldGenLockable) worldserver).getWorldGenChunkLock(), () ->
|
||||
+ ChunkStatusUtils.getThreadingType((ChunkStatus) (Object) this).runTask(((IWorldGenLockable) worldserver).getWorldGenSingleThreadedLock(), generationTask));
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
}
|
||||
|
||||
public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> a(WorldServer worldserver, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function<IChunkAccess, CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> function, IChunkAccess ichunkaccess) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java
|
||||
index 13983f3271d33ab6e4c7030de5865edbd7b0cd8a..7460f5c85800f0d3c6076bc944b10b5931ba22bf 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/DefinedStructure.java
|
||||
@@ -843,7 +843,7 @@ public class DefinedStructure {
|
||||
private final Map<Block, List<DefinedStructure.BlockInfo>> b;
|
||||
|
||||
private a(List<DefinedStructure.BlockInfo> list) {
|
||||
- this.b = Maps.newHashMap();
|
||||
+ this.b = new java.util.concurrent.ConcurrentHashMap<>(); // Yatopia - port C2ME
|
||||
this.a = list;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayers.java b/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayers.java
|
||||
index 5bbd71f2cf6db34dd01e8e209809a4661505aaf1..76995e812492d3fd0f9180525727174bf3d8c409 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayers.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayers.java
|
||||
@@ -13,7 +13,7 @@ import net.minecraft.world.level.newbiome.layer.traits.AreaTransformer2;
|
||||
|
||||
public class GenLayers {
|
||||
|
||||
- private static final Int2IntMap a = (Int2IntMap) SystemUtils.a((Object) (new Int2IntOpenHashMap()), (int2intopenhashmap) -> {
|
||||
+ private static final Int2IntMap a = (Int2IntMap) SystemUtils.a((new Int2IntOpenHashMap()), (int2intopenhashmap) -> { // Yatopia - decompile fixes
|
||||
a(int2intopenhashmap, GenLayers.Type.BEACH, 16);
|
||||
a(int2intopenhashmap, GenLayers.Type.BEACH, 26);
|
||||
a(int2intopenhashmap, GenLayers.Type.DESERT, 2);
|
||||
@@ -154,9 +154,9 @@ public class GenLayers {
|
||||
|
||||
public static GenLayer a(long i, boolean flag, int j, int k) {
|
||||
boolean flag1 = true;
|
||||
- AreaFactory<AreaLazy> areafactory = a(flag, j, k, (l) -> {
|
||||
+ AreaFactory<AreaLazy> areafactory = () -> a(flag, j, k, (l) -> { // Yatopia
|
||||
return new WorldGenContextArea(25, i, l);
|
||||
- });
|
||||
+ }).make(); // Yatopia
|
||||
|
||||
return new GenLayer(areafactory);
|
||||
}
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/threading/GlobalExecutors.java b/src/main/java/org/yatopiamc/c2me/common/threading/GlobalExecutors.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..dcf55bc98818f98c1a7b6869306a40c11b842cdf
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/threading/GlobalExecutors.java
|
||||
@@ -0,0 +1,25 @@
|
||||
+package org.yatopiamc.c2me.common.threading;
|
||||
+
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+
|
||||
+import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
+import java.util.concurrent.atomic.AtomicReference;
|
||||
+
|
||||
+public class GlobalExecutors {
|
||||
+
|
||||
+ public static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
|
||||
+ 1,
|
||||
+ new ThreadFactoryBuilder().setNameFormat("C2ME scheduler").setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).setThreadFactory(r -> {
|
||||
+ final Thread thread = new Thread(r);
|
||||
+ GlobalExecutors.schedulerThread.set(thread);
|
||||
+ return thread;
|
||||
+ }).build()
|
||||
+ );
|
||||
+ private static final AtomicReference<Thread> schedulerThread = new AtomicReference<>();
|
||||
+
|
||||
+ public static void ensureSchedulerThread() {
|
||||
+ if (Thread.currentThread() != schedulerThread.get())
|
||||
+ throw new IllegalStateException("Not on scheduler thread");
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusThreadingType.java b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusThreadingType.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5af95799cb4cd380f25a31f50f67a2bcb9c1bec5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusThreadingType.java
|
||||
@@ -0,0 +1,45 @@
|
||||
+
|
||||
+package org.yatopiamc.c2me.common.threading.worldgen;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.mojang.datafixers.util.Either;
|
||||
+
|
||||
+import net.minecraft.world.level.chunk.IChunkAccess;
|
||||
+import net.minecraft.server.level.PlayerChunk;
|
||||
+
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.function.Function;
|
||||
+import java.util.function.Supplier;
|
||||
+
|
||||
+public enum ChunkStatusThreadingType {
|
||||
+
|
||||
+ PARALLELIZED() {
|
||||
+ @Override
|
||||
+ public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> runTask(AsyncLock lock, Supplier<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> completableFuture) {
|
||||
+ return CompletableFuture.supplyAsync(completableFuture, WorldGenThreadingExecutorUtils.mainExecutor).thenCompose(Function.identity());
|
||||
+ }
|
||||
+ },
|
||||
+ SINGLE_THREADED() {
|
||||
+ @Override
|
||||
+ public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> runTask(AsyncLock lock, Supplier<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> completableFuture) {
|
||||
+ Preconditions.checkNotNull(lock);
|
||||
+ return lock.acquireLock().toCompletableFuture().thenComposeAsync(lockToken -> {
|
||||
+ try {
|
||||
+ return completableFuture.get();
|
||||
+ } finally {
|
||||
+ lockToken.releaseLock();
|
||||
+ }
|
||||
+ }, WorldGenThreadingExecutorUtils.mainExecutor);
|
||||
+ }
|
||||
+ },
|
||||
+ AS_IS() {
|
||||
+ @Override
|
||||
+ public CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> runTask(AsyncLock lock, Supplier<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> completableFuture) {
|
||||
+ return completableFuture.get();
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ public abstract CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> runTask(AsyncLock lock, Supplier<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> completableFuture);
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusUtils.java b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusUtils.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0c28024cf9a50f35e1a867188b2a3f8fbbccb3ce
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusUtils.java
|
||||
@@ -0,0 +1,59 @@
|
||||
+package org.yatopiamc.c2me.common.threading.worldgen;
|
||||
+
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.ibm.asyncutil.locks.AsyncNamedLock;
|
||||
+import org.yatopiamc.c2me.common.threading.GlobalExecutors;
|
||||
+import org.yatopiamc.c2me.common.util.AsyncCombinedLock;
|
||||
+import org.yatopiamc.c2me.common.util.AsyncNamedLockDelegateAsyncLock;
|
||||
+
|
||||
+import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
+import net.minecraft.world.level.ChunkCoordIntPair;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.function.Function;
|
||||
+import java.util.function.Supplier;
|
||||
+
|
||||
+import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.AS_IS;
|
||||
+import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.PARALLELIZED;
|
||||
+import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.SINGLE_THREADED;
|
||||
+import org.yatopiamc.yatopia.server.YatopiaConfig;
|
||||
+
|
||||
+public class ChunkStatusUtils {
|
||||
+
|
||||
+ public static ChunkStatusThreadingType getThreadingType(final ChunkStatus status) {
|
||||
+ if (status.equals(ChunkStatus.STRUCTURE_STARTS)
|
||||
+ || status.equals(ChunkStatus.STRUCTURE_REFERENCES)
|
||||
+ || status.equals(ChunkStatus.BIOMES)
|
||||
+ || status.equals(ChunkStatus.NOISE)
|
||||
+ || status.equals(ChunkStatus.SURFACE)
|
||||
+ || status.equals(ChunkStatus.CARVERS)
|
||||
+ || status.equals(ChunkStatus.LIQUID_CARVERS)
|
||||
+ || status.equals(ChunkStatus.HEIGHTMAPS)) {
|
||||
+ return PARALLELIZED;
|
||||
+ } else if (status.equals(ChunkStatus.SPAWN)) {
|
||||
+ return SINGLE_THREADED;
|
||||
+ } else if (status.equals(ChunkStatus.FEATURES)) {
|
||||
+ return YatopiaConfig.allowThreadedFeatures ? PARALLELIZED : SINGLE_THREADED;
|
||||
+ }
|
||||
+ return AS_IS;
|
||||
+ }
|
||||
+
|
||||
+ public static <T> CompletableFuture<T> runChunkGenWithLock(ChunkCoordIntPair target, int radius, AsyncNamedLock<ChunkCoordIntPair> chunkLock, Supplier<CompletableFuture<T>> action) {
|
||||
+ return CompletableFuture.supplyAsync(() -> {
|
||||
+ ArrayList<ChunkCoordIntPair> fetchedLocks = new ArrayList<>((2 * radius + 1) * (2 * radius + 1));
|
||||
+ for (int x = target.x - radius; x <= target.x + radius; x++)
|
||||
+ for (int z = target.z - radius; z <= target.z + radius; z++)
|
||||
+ fetchedLocks.add(new ChunkCoordIntPair(x, z));
|
||||
+
|
||||
+ return new AsyncCombinedLock(chunkLock, new HashSet<>(fetchedLocks)).getFuture().thenComposeAsync(lockToken -> {
|
||||
+ final CompletableFuture<T> future = action.get();
|
||||
+ future.thenRun(lockToken::releaseLock);
|
||||
+ return future;
|
||||
+ }, GlobalExecutors.scheduler);
|
||||
+ }, AsyncCombinedLock.lockWorker).thenCompose(Function.identity());
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/IWorldGenLockable.java b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/IWorldGenLockable.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b80923bcda9045968e0fad39f2e40b99dba135dc
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/IWorldGenLockable.java
|
||||
@@ -0,0 +1,13 @@
|
||||
+package org.yatopiamc.c2me.common.threading.worldgen;
|
||||
+
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.ibm.asyncutil.locks.AsyncNamedLock;
|
||||
+import net.minecraft.world.level.ChunkCoordIntPair;
|
||||
+
|
||||
+public interface IWorldGenLockable {
|
||||
+
|
||||
+ AsyncLock getWorldGenSingleThreadedLock();
|
||||
+
|
||||
+ AsyncNamedLock<ChunkCoordIntPair> getWorldGenChunkLock();
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/WorldGenThreadingExecutorUtils.java b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/WorldGenThreadingExecutorUtils.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..215010825a18881f84d94ead66314b946d46d75b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/threading/worldgen/WorldGenThreadingExecutorUtils.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package org.yatopiamc.c2me.common.threading.worldgen;
|
||||
+
|
||||
+import org.yatopiamc.c2me.common.util.C2MEForkJoinWorkerThreadFactory;
|
||||
+
|
||||
+import java.util.concurrent.ForkJoinPool;
|
||||
+import org.yatopiamc.yatopia.server.YatopiaConfig;
|
||||
+
|
||||
+public class WorldGenThreadingExecutorUtils {
|
||||
+
|
||||
+ public static final ForkJoinPool mainExecutor = new ForkJoinPool(
|
||||
+ YatopiaConfig.c2meThreads,
|
||||
+ new C2MEForkJoinWorkerThreadFactory("C2ME worldgen worker #%d", Thread.NORM_PRIORITY - 1),
|
||||
+ null,
|
||||
+ true
|
||||
+ );
|
||||
+
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/util/AsyncCombinedLock.java b/src/main/java/org/yatopiamc/c2me/common/util/AsyncCombinedLock.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9e34b74d9abecae4b386d49514ceb0d1f333e271
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/util/AsyncCombinedLock.java
|
||||
@@ -0,0 +1,88 @@
|
||||
+package org.yatopiamc.c2me.common.util;
|
||||
+
|
||||
+import com.google.common.collect.Sets;
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.ibm.asyncutil.locks.AsyncNamedLock;
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
+import net.minecraft.world.level.ChunkCoordIntPair;
|
||||
+
|
||||
+import java.util.Optional;
|
||||
+import java.util.Set;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.concurrent.ForkJoinPool;
|
||||
+import java.util.function.Function;
|
||||
+import java.util.stream.Collectors;
|
||||
+
|
||||
+public class AsyncCombinedLock {
|
||||
+
|
||||
+ public static final ForkJoinPool lockWorker = new ForkJoinPool(
|
||||
+ 2,
|
||||
+ new C2MEForkJoinWorkerThreadFactory("C2ME lock worker #%d", Thread.NORM_PRIORITY - 1),
|
||||
+ null,
|
||||
+ true
|
||||
+ );
|
||||
+
|
||||
+ private final AsyncNamedLock<ChunkCoordIntPair> lock;
|
||||
+ private final ChunkCoordIntPair[] names;
|
||||
+ private final CompletableFuture<AsyncLock.LockToken> future = new CompletableFuture<>();
|
||||
+
|
||||
+ public AsyncCombinedLock(AsyncNamedLock<ChunkCoordIntPair> lock, Set<ChunkCoordIntPair> names) {
|
||||
+ this.lock = lock;
|
||||
+ this.names = names.toArray(ChunkCoordIntPair[]::new);
|
||||
+ lockWorker.execute(this::tryAcquire);
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void tryAcquire() { // TODO optimize logic further
|
||||
+ final LockEntry[] tryLocks = new LockEntry[names.length];
|
||||
+ boolean allAcquired = true;
|
||||
+ for (int i = 0, namesLength = names.length; i < namesLength; i++) {
|
||||
+ ChunkCoordIntPair name = names[i];
|
||||
+ final LockEntry entry = new LockEntry(name, this.lock.tryLock(name));
|
||||
+ tryLocks[i] = entry;
|
||||
+ if (entry.lockToken.isEmpty()) {
|
||||
+ allAcquired = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (allAcquired) {
|
||||
+ future.complete(() -> {
|
||||
+ for (LockEntry entry : tryLocks) {
|
||||
+ //noinspection OptionalGetWithoutIsPresent
|
||||
+ entry.lockToken.get().releaseLock(); // if it isn't present then something is really wrong
|
||||
+ }
|
||||
+ });
|
||||
+ } else {
|
||||
+ boolean triedRelock = false;
|
||||
+ for (LockEntry entry : tryLocks) {
|
||||
+ if (entry == null) continue;
|
||||
+ entry.lockToken.ifPresent(AsyncLock.LockToken::releaseLock);
|
||||
+ if (!triedRelock && entry.lockToken.isEmpty()) {
|
||||
+ this.lock.acquireLock(entry.name).thenCompose(lockToken -> {
|
||||
+ lockToken.releaseLock();
|
||||
+ return CompletableFuture.runAsync(this::tryAcquire, lockWorker);
|
||||
+ });
|
||||
+ triedRelock = true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!triedRelock) {
|
||||
+ // shouldn't happen at all...
|
||||
+ lockWorker.execute(this::tryAcquire);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public CompletableFuture<AsyncLock.LockToken> getFuture() {
|
||||
+ return future.thenApply(Function.identity());
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
+ private static class LockEntry {
|
||||
+ public final ChunkCoordIntPair name;
|
||||
+ public final Optional<AsyncLock.LockToken> lockToken;
|
||||
+
|
||||
+ private LockEntry(ChunkCoordIntPair name, Optional<AsyncLock.LockToken> lockToken) {
|
||||
+ this.name = name;
|
||||
+ this.lockToken = lockToken;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/util/AsyncNamedLockDelegateAsyncLock.java b/src/main/java/org/yatopiamc/c2me/common/util/AsyncNamedLockDelegateAsyncLock.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..119421953de58fbc928e14bf618b340ee6b2fe94
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/util/AsyncNamedLockDelegateAsyncLock.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+package org.yatopiamc.c2me.common.util;
|
||||
+
|
||||
+import com.ibm.asyncutil.locks.AsyncLock;
|
||||
+import com.ibm.asyncutil.locks.AsyncNamedLock;
|
||||
+
|
||||
+import java.util.Objects;
|
||||
+import java.util.Optional;
|
||||
+import java.util.concurrent.CompletionStage;
|
||||
+
|
||||
+public class AsyncNamedLockDelegateAsyncLock<T> implements AsyncLock {
|
||||
+
|
||||
+ private final AsyncNamedLock<T> delegate;
|
||||
+ private final T name;
|
||||
+
|
||||
+ public AsyncNamedLockDelegateAsyncLock(AsyncNamedLock<T> delegate, T name) {
|
||||
+ this.delegate = Objects.requireNonNull(delegate);
|
||||
+ this.name = name;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public CompletionStage<LockToken> acquireLock() {
|
||||
+ return delegate.acquireLock(name);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Optional<LockToken> tryLock() {
|
||||
+ return delegate.tryLock(name);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/c2me/common/util/C2MEForkJoinWorkerThreadFactory.java b/src/main/java/org/yatopiamc/c2me/common/util/C2MEForkJoinWorkerThreadFactory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ab5b9be9dcf67bdd9237fb7d21574155c2d52306
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/yatopiamc/c2me/common/util/C2MEForkJoinWorkerThreadFactory.java
|
||||
@@ -0,0 +1,39 @@
|
||||
+package org.yatopiamc.c2me.common.util;
|
||||
+
|
||||
+import java.util.concurrent.ForkJoinPool;
|
||||
+import java.util.concurrent.ForkJoinWorkerThread;
|
||||
+import java.util.concurrent.atomic.AtomicLong;
|
||||
+
|
||||
+public class C2MEForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
|
||||
+ private final AtomicLong serial = new AtomicLong(0);
|
||||
+ private final String namePattern;
|
||||
+ private final int priority;
|
||||
+
|
||||
+ public C2MEForkJoinWorkerThreadFactory(String namePattern, int priority) {
|
||||
+ this.namePattern = namePattern;
|
||||
+ this.priority = priority;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||
+ final C2MEForkJoinWorkerThread C2MEForkJoinWorkerThread = new C2MEForkJoinWorkerThread(pool);
|
||||
+ C2MEForkJoinWorkerThread.setName(String.format(namePattern, serial.incrementAndGet()));
|
||||
+ C2MEForkJoinWorkerThread.setPriority(priority);
|
||||
+ C2MEForkJoinWorkerThread.setDaemon(true);
|
||||
+ return C2MEForkJoinWorkerThread;
|
||||
+ }
|
||||
+
|
||||
+ private static class C2MEForkJoinWorkerThread extends ForkJoinWorkerThread {
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a ForkJoinWorkerThread operating in the given pool.
|
||||
+ *
|
||||
+ * @param pool the pool this thread works in
|
||||
+ * @throws NullPointerException if pool is null
|
||||
+ */
|
||||
+ protected C2MEForkJoinWorkerThread(ForkJoinPool pool) {
|
||||
+ super(pool);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
index fce7ce0efca340cf5820cdcbe010c9fdeae7cafc..1d1717d72ceb56594bc29f8a14437b61f911f817 100644
|
||||
--- a/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
+++ b/src/main/java/org/yatopiamc/yatopia/server/YatopiaConfig.java
|
||||
@@ -271,4 +271,12 @@ public class YatopiaConfig {
|
||||
fixProtocolLib = getBoolean("settings.fix-protocollib", fixProtocolLib);
|
||||
}
|
||||
|
||||
+ public static boolean allowThreadedFeatures = false;
|
||||
+ public static int c2meThreads = Math.min(6, Runtime.getRuntime().availableProcessors());
|
||||
+ public static boolean reduceLockRadius = false;
|
||||
+ private static void c2me() {
|
||||
+ allowThreadedFeatures = getBoolean("settings.c2me.allow-threaded-features", allowThreadedFeatures);
|
||||
+ c2meThreads = getInt("settings.c2me.parallelism", c2meThreads);
|
||||
+ reduceLockRadius = getBoolean("settings.c2me.reduce-lock-radius", reduceLockRadius);
|
||||
+ }
|
||||
}
|
144
patches/server/0069-Multi-threaded-World-Upgrade.patch
Normal file
144
patches/server/0069-Multi-threaded-World-Upgrade.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ishland <ishlandmc@yeah.net>
|
||||
Date: Fri, 5 Feb 2021 19:34:00 +0800
|
||||
Subject: [PATCH] Multi-threaded World Upgrade
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index 6818f8496ab76ee6ffc747bd6848b43830ec8914..1fe2610ed0ddab1e203e273914c9325aec74e7c2 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -281,6 +281,8 @@ public class Main {
|
||||
WorldUpgrader worldupgrader = new WorldUpgrader(convertable_conversionsession, datafixer, immutableset, flag);
|
||||
IChatBaseComponent ichatbasecomponent = null;
|
||||
|
||||
+ long lastLocation = 0L; // Yatopia
|
||||
+ long lastTime = System.nanoTime(); // Yatopia
|
||||
while (!worldupgrader.b()) {
|
||||
IChatBaseComponent ichatbasecomponent1 = worldupgrader.h();
|
||||
|
||||
@@ -289,13 +291,16 @@ public class Main {
|
||||
Main.LOGGER.info(worldupgrader.h().getString());
|
||||
}
|
||||
|
||||
- int i = worldupgrader.e();
|
||||
-
|
||||
- if (i > 0) {
|
||||
- int j = worldupgrader.f() + worldupgrader.g();
|
||||
-
|
||||
- Main.LOGGER.info("{}% completed ({} / {} chunks)...", MathHelper.d((float) j / (float) i * 100.0F), j, i);
|
||||
- }
|
||||
+ // Yatopia start
|
||||
+ long totalChunkCount = worldupgrader.getTotalChunkCount();
|
||||
+ if (totalChunkCount > 0) {
|
||||
+ long processedCount = worldupgrader.getUpgradedChunkCount() + worldupgrader.getSkippedChunkCount();
|
||||
+ long currentTime = System.nanoTime();
|
||||
+ String speedRate = String.format("%.1f", (processedCount - lastLocation) / ((currentTime - lastTime) / 1_000_000_000.0));
|
||||
+ Main.LOGGER.info("{}% completed ({} / {} chunks) at {}cps...", MathHelper.d((float) processedCount / (float) totalChunkCount * 100.0F), processedCount, totalChunkCount, speedRate);
|
||||
+ lastLocation = processedCount;
|
||||
+ lastTime = currentTime;
|
||||
+ } // Yatopia end
|
||||
|
||||
if (!booleansupplier.getAsBoolean()) {
|
||||
worldupgrader.a();
|
||||
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
index 6725b31a5183d5af7f8f7566ed21eb61797ef4c9..f13e16aca89f5013ef316e7dbf3d4c67885e6f3e 100644
|
||||
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
||||
@@ -33,6 +33,13 @@ import net.minecraft.world.level.storage.Convertable;
|
||||
import net.minecraft.world.level.storage.WorldPersistentData;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
+// Yatopia start
|
||||
+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
+import java.util.Set;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+import java.util.concurrent.ExecutorService;
|
||||
+import java.util.concurrent.Executors;
|
||||
+// Yatopia end
|
||||
|
||||
// CraftBukkit start
|
||||
import net.minecraft.world.level.dimension.DimensionManager;
|
||||
@@ -50,9 +57,9 @@ public class WorldUpgrader {
|
||||
private volatile boolean h = true;
|
||||
private volatile boolean i;
|
||||
private volatile float j;
|
||||
- private volatile int k;
|
||||
- private volatile int l;
|
||||
- private volatile int m;
|
||||
+ private volatile long k; // Yatopia - int -> long
|
||||
+ private volatile long l; // Yatopia - int -> long
|
||||
+ private volatile long m; // Yatopia - int -> long
|
||||
private final Object2FloatMap<ResourceKey<DimensionManager>> n = Object2FloatMaps.synchronize(new Object2FloatOpenCustomHashMap(SystemUtils.k())); // CraftBukkit
|
||||
private volatile IChatBaseComponent o = new ChatMessage("optimizeWorld.stage.counting");
|
||||
private static final Pattern p = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$");
|
||||
@@ -117,6 +124,11 @@ public class WorldUpgrader {
|
||||
|
||||
this.o = new ChatMessage("optimizeWorld.stage.upgrading");
|
||||
|
||||
+ // Yatopia start
|
||||
+ final ExecutorService upgradeExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).setNameFormat("WorldUpgrader Worker #%d").build());
|
||||
+ final Set<CompletableFuture<Void>> futures = new ObjectOpenHashSet<>();
|
||||
+ final com.ibm.asyncutil.locks.AsyncNamedLock<Integer> regionFileLocks = com.ibm.asyncutil.locks.AsyncNamedLock.createFair();
|
||||
+ // Yatopia end
|
||||
while (this.h) {
|
||||
boolean flag = false;
|
||||
float f1 = 0.0F;
|
||||
@@ -130,6 +142,11 @@ public class WorldUpgrader {
|
||||
|
||||
if (listiterator.hasNext()) {
|
||||
ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) listiterator.next();
|
||||
+ // Yatopia start
|
||||
+ flag = true;
|
||||
+ futures.add(regionFileLocks.acquireLock(String.format("%d %d", chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()).hashCode()).toCompletableFuture().thenAcceptAsync(lockToken -> {
|
||||
+ try {
|
||||
+ // Yatopia end
|
||||
boolean flag1 = false;
|
||||
|
||||
try {
|
||||
@@ -179,7 +196,12 @@ public class WorldUpgrader {
|
||||
++this.m;
|
||||
}
|
||||
|
||||
- flag = true;
|
||||
+ // Yatopia start
|
||||
+ } finally {
|
||||
+ lockToken.releaseLock();
|
||||
+ }
|
||||
+ }, upgradeExecutor));
|
||||
+ // Yatopia end
|
||||
}
|
||||
|
||||
f2 = (float) listiterator.nextIndex() / f;
|
||||
@@ -192,6 +214,8 @@ public class WorldUpgrader {
|
||||
}
|
||||
}
|
||||
|
||||
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); // Yatopia
|
||||
+ upgradeExecutor.shutdown(); // Yatopia
|
||||
this.o = new ChatMessage("optimizeWorld.stage.finished");
|
||||
UnmodifiableIterator unmodifiableiterator3 = immutablemap1.values().iterator();
|
||||
|
||||
@@ -280,16 +304,19 @@ public class WorldUpgrader {
|
||||
}
|
||||
|
||||
public int e() {
|
||||
- return this.k;
|
||||
+ return (int) this.k; // Yatopia
|
||||
}
|
||||
+ public long getTotalChunkCount() { return this.k; } // Yatopia
|
||||
|
||||
public int f() {
|
||||
- return this.l;
|
||||
+ return (int) this.l; // Yatopia
|
||||
}
|
||||
+ public long getUpgradedChunkCount() { return this.l; } // Yatopia
|
||||
|
||||
public int g() {
|
||||
- return this.m;
|
||||
+ return (int) this.m; // Yatopia
|
||||
}
|
||||
+ public long getSkippedChunkCount() { return this.m; } // Yatopia
|
||||
|
||||
public IChatBaseComponent h() {
|
||||
return this.o;
|
195
patches/server/0070-lithium-MultiNoiseBiomeSourceMixin.patch
Normal file
195
patches/server/0070-lithium-MultiNoiseBiomeSourceMixin.patch
Normal file
@ -0,0 +1,195 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ishland <ishlandmc@yeah.net>
|
||||
Date: Wed, 3 Feb 2021 23:00:18 +0800
|
||||
Subject: [PATCH] lithium MultiNoiseBiomeSourceMixin
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/biome/BiomeBase.java b/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
|
||||
index c4fb051739c1c186c1574185e0653f513755987d..e9993fa0f3af9e3ecd01f91ef5c14e528bdb33b5 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/biome/BiomeBase.java
|
||||
@@ -52,6 +52,13 @@ import org.apache.logging.log4j.Logger;
|
||||
public final class BiomeBase {
|
||||
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
+ // Yatopia start
|
||||
+ static class cProxy extends BiomeBase.c {
|
||||
+ public cProxy(float f, float f1, float f2, float f3, float f4) {
|
||||
+ super(f, f1, f2, f3, f4);
|
||||
+ }
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
// Paper start
|
||||
private static class dProxy extends BiomeBase.d {
|
||||
private dProxy(Precipitation biomebase_precipitation, float f, TemperatureModifier biomebase_temperaturemodifier, float f1) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/biome/WorldChunkManagerMultiNoise.java b/src/main/java/net/minecraft/world/level/biome/WorldChunkManagerMultiNoise.java
|
||||
index 5287aec4c384c6cea76334ae1d8dc99070e8f43e..23637d9be9f9973266c1bba699c40cdc6c5d9e6d 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/biome/WorldChunkManagerMultiNoise.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/biome/WorldChunkManagerMultiNoise.java
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.datafixers.util.Function3;
|
||||
+import com.mojang.datafixers.util.Function6; // Yatopia - decompile fix
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
@@ -27,26 +28,43 @@ import net.minecraft.world.level.levelgen.synth.NoiseGeneratorNormal;
|
||||
|
||||
public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
|
||||
+ // Yatopia start - decompile fix
|
||||
+ private static class aProxy extends WorldChunkManagerMultiNoise.a {
|
||||
+ public aProxy(int i, List<Double> list) {
|
||||
+ super(i, list);
|
||||
+ }
|
||||
+ }
|
||||
+ private static class bProxy extends WorldChunkManagerMultiNoise.b {
|
||||
+ public bProxy(MinecraftKey minecraftkey, Function3<WorldChunkManagerMultiNoise.b, IRegistry<BiomeBase>, Long, WorldChunkManagerMultiNoise> function3) {
|
||||
+ super(minecraftkey, function3);
|
||||
+ }
|
||||
+ }
|
||||
+ private static class cProxy extends WorldChunkManagerMultiNoise.c {
|
||||
+ private cProxy(WorldChunkManagerMultiNoise.b worldchunkmanagermultinoise_b, IRegistry<BiomeBase> iregistry, long i) {
|
||||
+ super(worldchunkmanagermultinoise_b, iregistry, i);
|
||||
+ }
|
||||
+ }
|
||||
+ // Yatopia end
|
||||
private static final WorldChunkManagerMultiNoise.a g = new WorldChunkManagerMultiNoise.a(-7, ImmutableList.of(1.0D, 1.0D));
|
||||
public static final MapCodec<WorldChunkManagerMultiNoise> e = RecordCodecBuilder.mapCodec((instance) -> {
|
||||
return instance.group(Codec.LONG.fieldOf("seed").forGetter((worldchunkmanagermultinoise) -> {
|
||||
return worldchunkmanagermultinoise.r;
|
||||
}), RecordCodecBuilder.create((instance1) -> {
|
||||
- return instance1.group(BiomeBase.c.a.fieldOf("parameters").forGetter(Pair::getFirst), BiomeBase.d.fieldOf("biome").forGetter(Pair::getSecond)).apply(instance1, Pair::of);
|
||||
- }).listOf().fieldOf("biomes").forGetter((worldchunkmanagermultinoise) -> {
|
||||
- return worldchunkmanagermultinoise.p;
|
||||
- }), WorldChunkManagerMultiNoise.a.a.fieldOf("temperature_noise").forGetter((worldchunkmanagermultinoise) -> {
|
||||
+ return instance1.group(BiomeBase.cProxy.a.fieldOf("parameters").forGetter((java.util.function.Function) t -> ((Pair) t).getFirst()), BiomeBase.d.fieldOf("biome").forGetter(t1 -> (Supplier<BiomeBase>) ((Pair) t1).getSecond())).apply(instance1, Pair::of); // Yatopia - decompile fix
|
||||
+ }).listOf().fieldOf("biomes").forGetter((Function) worldchunkmanagermultinoise -> { // Yatopia - decompile fix
|
||||
+ return ((WorldChunkManagerMultiNoise) worldchunkmanagermultinoise).p; // Yatopia - decompile fix
|
||||
+ }), WorldChunkManagerMultiNoise.aProxy.a.fieldOf("temperature_noise").forGetter((worldchunkmanagermultinoise) -> { // Yatopia - decompile fix
|
||||
return worldchunkmanagermultinoise.h;
|
||||
- }), WorldChunkManagerMultiNoise.a.a.fieldOf("humidity_noise").forGetter((worldchunkmanagermultinoise) -> {
|
||||
+ }), WorldChunkManagerMultiNoise.aProxy.a.fieldOf("humidity_noise").forGetter((worldchunkmanagermultinoise) -> { // Yatopia - decompile fix
|
||||
return worldchunkmanagermultinoise.i;
|
||||
- }), WorldChunkManagerMultiNoise.a.a.fieldOf("altitude_noise").forGetter((worldchunkmanagermultinoise) -> {
|
||||
+ }), WorldChunkManagerMultiNoise.aProxy.a.fieldOf("altitude_noise").forGetter((worldchunkmanagermultinoise) -> { // Yatopia - decompile fix
|
||||
return worldchunkmanagermultinoise.j;
|
||||
- }), WorldChunkManagerMultiNoise.a.a.fieldOf("weirdness_noise").forGetter((worldchunkmanagermultinoise) -> {
|
||||
+ }), WorldChunkManagerMultiNoise.aProxy.a.fieldOf("weirdness_noise").forGetter((worldchunkmanagermultinoise) -> { // Yatopia - decompile fix
|
||||
return worldchunkmanagermultinoise.k;
|
||||
- })).apply(instance, WorldChunkManagerMultiNoise::new);
|
||||
+ })).apply(instance, (Function6<Long, List<Pair<BiomeBase.c, Supplier<BiomeBase>>>, WorldChunkManagerMultiNoise.a, WorldChunkManagerMultiNoise.a, WorldChunkManagerMultiNoise.a, WorldChunkManagerMultiNoise.a, WorldChunkManagerMultiNoise>) WorldChunkManagerMultiNoise::new); // Yatopia - decompile fix
|
||||
});
|
||||
- public static final Codec<WorldChunkManagerMultiNoise> f = Codec.mapEither(WorldChunkManagerMultiNoise.c.a, WorldChunkManagerMultiNoise.e).xmap((either) -> {
|
||||
- return (WorldChunkManagerMultiNoise) either.map(WorldChunkManagerMultiNoise.c::d, Function.identity());
|
||||
+ public static final Codec<WorldChunkManagerMultiNoise> f = Codec.mapEither(WorldChunkManagerMultiNoise.cProxy.a, WorldChunkManagerMultiNoise.e).xmap((either) -> { // Yatopia - decompile fix
|
||||
+ return (WorldChunkManagerMultiNoise) either.map(c -> c.d(), Function.identity()); // Yatopia - decompile fix
|
||||
}, (worldchunkmanagermultinoise) -> {
|
||||
return (Either) worldchunkmanagermultinoise.d().map(Either::left).orElseGet(() -> {
|
||||
return Either.right(worldchunkmanagermultinoise);
|
||||
@@ -100,8 +118,44 @@ public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
});
|
||||
}
|
||||
|
||||
+ //Yatopia - Faster Method
|
||||
+ /**
|
||||
+ * @reason Remove stream based code in favor of regular collections.
|
||||
+ * @author SuperCoder79
|
||||
+ */
|
||||
@Override
|
||||
public BiomeBase getBiome(int i, int j, int k) {
|
||||
+ // [VanillaCopy] MultiNoiseBiomeSource#getBiomeForNoiseGen
|
||||
+
|
||||
+ // Get the y value for perlin noise sampling. This field is always set to false in vanilla code.
|
||||
+ int l = this.q ? j : 0;
|
||||
+
|
||||
+ // Calculate the noise point based using 4 perlin noise samplers.
|
||||
+ BiomeBase.c biomebase_c = new BiomeBase.c(
|
||||
+ (float) this.l.a(i, l, k),
|
||||
+ (float) this.m.a(i, l, k),
|
||||
+ (float) this.n.a(i, l, k),
|
||||
+ (float) this.o.a(i, l, k),
|
||||
+ 0.0F);
|
||||
+
|
||||
+ int idx = -1;
|
||||
+ float min = Float.POSITIVE_INFINITY;
|
||||
+
|
||||
+ // Iterate through the biome points and calculate the distance to the current noise point.
|
||||
+ for (int itterator = 0; itterator < this.p.size(); itterator++) {
|
||||
+ float distance = this.p.get(itterator).getFirst().a(biomebase_c);
|
||||
+
|
||||
+ // If the distance is less than the recorded minimum, update the minimum and set the current index.
|
||||
+ if (min > distance) {
|
||||
+ idx = itterator;
|
||||
+ min = distance;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Return the biome with the noise point closest to the evaluated one.
|
||||
+ return this.p.get(idx).getSecond().get() == null ? BiomeRegistry.b : this.p.get(idx).getSecond().get();
|
||||
+ }
|
||||
+ /* //Yatopia - Replace Method
|
||||
int l = this.q ? j : 0;
|
||||
BiomeBase.c biomebase_c = new BiomeBase.c((float) this.l.a((double) i, (double) l, (double) k), (float) this.m.a((double) i, (double) l, (double) k), (float) this.n.a((double) i, (double) l, (double) k), (float) this.o.a((double) i, (double) l, (double) k), 0.0F);
|
||||
|
||||
@@ -109,15 +163,17 @@ public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
return ((BiomeBase.c) pair.getFirst()).a(biomebase_c);
|
||||
})).map(Pair::getSecond).map(Supplier::get).orElse(BiomeRegistry.b);
|
||||
}
|
||||
+ */ //Yatopia End
|
||||
+
|
||||
|
||||
public boolean b(long i) {
|
||||
- return this.r == i && this.s.isPresent() && Objects.equals(((Pair) this.s.get()).getSecond(), WorldChunkManagerMultiNoise.b.a);
|
||||
+ return this.r == i && this.s.isPresent() && Objects.equals(((Pair) this.s.get()).getSecond(), WorldChunkManagerMultiNoise.bProxy.a); // Yatopia - decompile fix
|
||||
}
|
||||
|
||||
public static class b {
|
||||
|
||||
- private static final Map<MinecraftKey, WorldChunkManagerMultiNoise.b> b = Maps.newHashMap();
|
||||
- public static final WorldChunkManagerMultiNoise.b a = new WorldChunkManagerMultiNoise.b(new MinecraftKey("nether"), (worldchunkmanagermultinoise_b, iregistry, olong) -> {
|
||||
+ protected static final Map<MinecraftKey, WorldChunkManagerMultiNoise.b> b = Maps.newHashMap(); // Yatopia - decompile fix
|
||||
+ public static final WorldChunkManagerMultiNoise.b a = new WorldChunkManagerMultiNoise.b(new MinecraftKey("nether"), (worldchunkmanagermultinoise_b, iregistry, olong) -> { // Yatopia - decompile fix
|
||||
return new WorldChunkManagerMultiNoise(olong, ImmutableList.of(Pair.of(new BiomeBase.c(0.0F, 0.0F, 0.0F, 0.0F, 0.0F), () -> {
|
||||
return (BiomeBase) iregistry.d(Biomes.NETHER_WASTES);
|
||||
}), Pair.of(new BiomeBase.c(0.0F, -0.5F, 0.0F, 0.0F, 0.0F), () -> {
|
||||
@@ -136,7 +192,7 @@ public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
public b(MinecraftKey minecraftkey, Function3<WorldChunkManagerMultiNoise.b, IRegistry<BiomeBase>, Long, WorldChunkManagerMultiNoise> function3) {
|
||||
this.c = minecraftkey;
|
||||
this.d = function3;
|
||||
- WorldChunkManagerMultiNoise.b.b.put(minecraftkey, this);
|
||||
+ WorldChunkManagerMultiNoise.bProxy.b.put(minecraftkey, this); // Yatopia - decompile fix
|
||||
}
|
||||
|
||||
public WorldChunkManagerMultiNoise a(IRegistry<BiomeBase> iregistry, long i) {
|
||||
@@ -144,16 +200,16 @@ public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
}
|
||||
}
|
||||
|
||||
- static final class c {
|
||||
+ static class c { // Yatopia - decompile fix
|
||||
|
||||
public static final MapCodec<WorldChunkManagerMultiNoise.c> a = RecordCodecBuilder.mapCodec((instance) -> {
|
||||
return instance.group(MinecraftKey.a.flatXmap((minecraftkey) -> {
|
||||
- return (DataResult) Optional.ofNullable(WorldChunkManagerMultiNoise.b.b.get(minecraftkey)).map(DataResult::success).orElseGet(() -> {
|
||||
+ return (DataResult) Optional.ofNullable(bProxy.b.get(minecraftkey)).map(DataResult::success).orElseGet(() -> { // Yatopia - decompile fix
|
||||
return DataResult.error("Unknown preset: " + minecraftkey);
|
||||
});
|
||||
}, (worldchunkmanagermultinoise_b) -> {
|
||||
- return DataResult.success(worldchunkmanagermultinoise_b.c);
|
||||
- }).fieldOf("preset").stable().forGetter(WorldChunkManagerMultiNoise.c::a), RegistryLookupCodec.a(IRegistry.ay).forGetter(WorldChunkManagerMultiNoise.c::b), Codec.LONG.fieldOf("seed").stable().forGetter(WorldChunkManagerMultiNoise.c::c)).apply(instance, instance.stable(WorldChunkManagerMultiNoise.c::new));
|
||||
+ return DataResult.success(((WorldChunkManagerMultiNoise.b) worldchunkmanagermultinoise_b).c); // Yatopia - decompile fix
|
||||
+ }).fieldOf("preset").stable().forGetter(o -> ((WorldChunkManagerMultiNoise.c) o).a()), (RecordCodecBuilder) RegistryLookupCodec.a(IRegistry.ay).forGetter((Function<WorldChunkManagerMultiNoise.c, IRegistry<BiomeBase>>) c -> c.b()), (RecordCodecBuilder) Codec.LONG.fieldOf("seed").stable().forGetter((Function<WorldChunkManagerMultiNoise.c, Long>) c -> c.c())).apply(instance, instance.stable((Function3<WorldChunkManagerMultiNoise.b, IRegistry<BiomeBase>, Long, WorldChunkManagerMultiNoise.c>) WorldChunkManagerMultiNoise.c::new)); // Yatopia - decompile fix
|
||||
});
|
||||
private final WorldChunkManagerMultiNoise.b b;
|
||||
private final IRegistry<BiomeBase> c;
|
||||
@@ -187,7 +243,7 @@ public class WorldChunkManagerMultiNoise extends WorldChunkManager {
|
||||
private final int b;
|
||||
private final DoubleList c;
|
||||
public static final Codec<WorldChunkManagerMultiNoise.a> a = RecordCodecBuilder.create((instance) -> {
|
||||
- return instance.group(Codec.INT.fieldOf("firstOctave").forGetter(WorldChunkManagerMultiNoise.a::a), Codec.DOUBLE.listOf().fieldOf("amplitudes").forGetter(WorldChunkManagerMultiNoise.a::b)).apply(instance, WorldChunkManagerMultiNoise.a::new);
|
||||
+ return instance.group(Codec.INT.fieldOf("firstOctave").forGetter((Function<WorldChunkManagerMultiNoise.a, Integer>) a -> a.a()), Codec.DOUBLE.listOf().fieldOf("amplitudes").forGetter(a -> a.b())).apply(instance, WorldChunkManagerMultiNoise.a::new); // Yatopia - decompile fix
|
||||
});
|
||||
|
||||
public a(int i, List<Double> list) {
|
42
patches/server/0071-Force-world-save.patch
Normal file
42
patches/server/0071-Force-world-save.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: ishland <ishlandmc@yeah.net>
|
||||
Date: Tue, 9 Feb 2021 21:42:09 +0800
|
||||
Subject: [PATCH] Force world save
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
index 29cd71efe86eea2227f373c15c39dc530e9e8199..4028526166fe528d772729e9334289df460f3b1e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/VillagePlace.java
|
||||
@@ -366,6 +366,7 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
|
||||
}).orElse(false);
|
||||
}
|
||||
|
||||
+ private final java.util.concurrent.atomic.AtomicBoolean hasWorked = new java.util.concurrent.atomic.AtomicBoolean(false); // Yatopia - enforce one chunk unload per tick
|
||||
@Override
|
||||
public void a(BooleanSupplier booleansupplier) {
|
||||
// Paper start - async chunk io
|
||||
@@ -373,7 +374,7 @@ public class VillagePlace extends RegionFileSection<VillagePlaceSection> {
|
||||
super.a(booleansupplier);
|
||||
} else {
|
||||
//super.a(booleansupplier); // re-implement below
|
||||
- while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean() && !this.world.isSavingDisabled()) { // Tuinity - unload POI data - don't write to disk if saving is disabled
|
||||
+ hasWorked.set(false); while (!((RegionFileSection)this).d.isEmpty() && (hasWorked.compareAndSet(false, true) || booleansupplier.getAsBoolean()) && !this.world.isSavingDisabled()) { // Tuinity - unload POI data - don't write to disk if saving is disabled // Yatopia - enforce one chunk unload per tick
|
||||
ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).r();
|
||||
|
||||
NBTTagCompound data;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSection.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSection.java
|
||||
index f70c14385c95763b5f270a6e2ce372cf047ba7bb..4454489153f7932deaaebe8aa32ecb603764f42b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileSection.java
|
||||
@@ -50,8 +50,9 @@ public class RegionFileSection<R> extends RegionFileCache implements AutoCloseab
|
||||
//this.b = new IOWorker(file, flag, file.getName()); // Paper - nuke IOWorker
|
||||
}
|
||||
|
||||
+ private final java.util.concurrent.atomic.AtomicBoolean hasWorked = new java.util.concurrent.atomic.AtomicBoolean(false); // Yatopia - enforce one chunk unload per tick
|
||||
protected void a(BooleanSupplier booleansupplier) {
|
||||
- while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) {
|
||||
+ hasWorked.set(false); while (!this.d.isEmpty() && (hasWorked.compareAndSet(false, true) || booleansupplier.getAsBoolean())) { // Yatopia - enforce one chunk unload per tick
|
||||
ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r(); // Paper - conflict here to avoid obfhelpers
|
||||
|
||||
this.d(chunkcoordintpair);
|
58
patches/server/0072-java-11.patch
Normal file
58
patches/server/0072-java-11.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Gardling <titaniumtown@gmail.com>
|
||||
Date: Fri, 23 Apr 2021 11:11:20 -0400
|
||||
Subject: [PATCH] java 11
|
||||
|
||||
|
||||
diff --git a/pom.xml b/pom.xml
|
||||
index f0a73238612327d71cf78801df816823d80893a0..57a87372c039fb410c97eaa00227b429b90da2b1 100644
|
||||
--- a/pom.xml
|
||||
+++ b/pom.xml
|
||||
@@ -14,8 +14,8 @@
|
||||
<bt.name>git</bt.name>
|
||||
<minecraft.version>1.16.5</minecraft.version>
|
||||
<minecraft_version>1_16_R3</minecraft_version>
|
||||
- <maven.compiler.source>1.8</maven.compiler.source>
|
||||
- <maven.compiler.target>1.8</maven.compiler.target>
|
||||
+ <maven.compiler.source>11</maven.compiler.source>
|
||||
+ <maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
diff --git a/src/main/java/io/papermc/paper/util/PaperJvmChecker.java b/src/main/java/io/papermc/paper/util/PaperJvmChecker.java
|
||||
index c6ea429819c07e7f4bc257cad73463a030767825..3fdca3afeefdb7f850934f9b1b5312f8979b50f3 100644
|
||||
--- a/src/main/java/io/papermc/paper/util/PaperJvmChecker.java
|
||||
+++ b/src/main/java/io/papermc/paper/util/PaperJvmChecker.java
|
||||
@@ -28,21 +28,17 @@ public class PaperJvmChecker {
|
||||
public static void checkJvm() {
|
||||
if (getJvmVersion() < 11) {
|
||||
final Logger logger = LogManager.getLogger();
|
||||
- logger.warn("************************************************************");
|
||||
- logger.warn("* WARNING - YOU ARE RUNNING AN OUTDATED VERSION OF JAVA.");
|
||||
- logger.warn("* PAPER WILL STOP BEING COMPATIBLE WITH THIS VERSION OF");
|
||||
- logger.warn("* JAVA WHEN MINECRAFT 1.17 IS RELEASED.");
|
||||
- logger.warn("*");
|
||||
- logger.warn("* Please update the version of Java you use to run Paper");
|
||||
- logger.warn("* to at least Java 11. When Paper for Minecraft 1.17 is");
|
||||
- logger.warn("* released support for versions of Java before 11 will");
|
||||
- logger.warn("* be dropped.");
|
||||
- logger.warn("*");
|
||||
- logger.warn("* Current Java version: {}", System.getProperty("java.version"));
|
||||
- logger.warn("*");
|
||||
- logger.warn("* Check this forum post for more information: ");
|
||||
- logger.warn("* https://papermc.io/java11");
|
||||
- logger.warn("************************************************************");
|
||||
+ // Yatopia start - require java 11+
|
||||
+ // Note - no clue how someone would run a jar built for java 11 on a java version lower than 11, but doesn't hurt to update this warning I guess.
|
||||
+ logger.fatal("************************************************************");
|
||||
+ logger.fatal("* ERROR - YOU ARE RUNNING AN OUTDATED VERSION OF JAVA.");
|
||||
+ logger.fatal("* YOU NEED TO BE RUNNING JAVA 11 OR HIGHER");
|
||||
+ logger.fatal("* In order to achieve Yatopia's high performance,");
|
||||
+ logger.fatal("* Yatopia uses features only found in Java 11 or higher.");
|
||||
+ logger.fatal("* If you do not know how to install Java 11 or have any other questions,");
|
||||
+ logger.fatal("* Join our discord server (https://discord.io/YatopiaMC) and ask for support in #yatopia-help");
|
||||
+ logger.fatal("************************************************************");
|
||||
+ // Yatopia end
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user