9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-23 17:09:29 +00:00
Files
Leaf/patches/server/0046-Hearse-Update-codes.patch
2023-01-13 00:15:47 -05:00

316 lines
17 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Mon, 9 Jan 2023 09:26:38 +0800
Subject: [PATCH] Hearse: Update codes
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java b/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java
index 06f55f26eb63e356b3558622bf68711f18cda1c6..2a43625d13d7aa253c15aba8092ac9361785a5f0 100644
--- a/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java
+++ b/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java
@@ -3,8 +3,11 @@ package co.earthme.hearse.concurrent;
import io.papermc.paper.util.TickThread;
public class WorkerThread extends TickThread {
+
public WorkerThread(String name) {
super(name);
+ this.setDaemon(true);
+ this.setPriority(Thread.NORM_PRIORITY - 2);
}
public static boolean isWorker(){
diff --git a/src/main/java/co/earthme/hearse/concurrent/WorkerThreadFactory.java b/src/main/java/co/earthme/hearse/concurrent/WorkerThreadFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e65b1eba68003a9f7ce5080d07a521817831ff48
--- /dev/null
+++ b/src/main/java/co/earthme/hearse/concurrent/WorkerThreadFactory.java
@@ -0,0 +1,5 @@
+package co.earthme.hearse.concurrent;
+
+public interface WorkerThreadFactory {
+ WorkerThread getNewThread(Runnable task);
+}
diff --git a/src/main/java/co/earthme/hearse/concurrent/ThreadPool.java b/src/main/java/co/earthme/hearse/concurrent/WorkerThreadPoolExecutor.java
similarity index 62%
rename from src/main/java/co/earthme/hearse/concurrent/ThreadPool.java
rename to src/main/java/co/earthme/hearse/concurrent/WorkerThreadPoolExecutor.java
index 3fbc81cb880cf6d38bb4c940b4cc1fa828c2ef17..f7ca6d650d9089b65137d61acca64c89e5b4db22 100644
--- a/src/main/java/co/earthme/hearse/concurrent/ThreadPool.java
+++ b/src/main/java/co/earthme/hearse/concurrent/WorkerThreadPoolExecutor.java
@@ -6,25 +6,17 @@ import java.util.Queue;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;
-public class ThreadPool extends ThreadPoolExecutor {
- public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
- }
-
- public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue, @NotNull ThreadFactory threadFactory) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
- }
+public class WorkerThreadPoolExecutor extends ThreadPoolExecutor {
+ private final Queue<TaskEntry> taskEntries = new ConcurrentLinkedQueue<>();
- public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue, @NotNull RejectedExecutionHandler handler) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
+ public WorkerThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue, @NotNull WorkerThreadFactory workerThreadFactory) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,r->workerThreadFactory.getNewThread(r));
}
- public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue, @NotNull ThreadFactory threadFactory, @NotNull RejectedExecutionHandler handler) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
+ public WorkerThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue<Runnable> workQueue, @NotNull WorkerThreadFactory workerThreadFactory, @NotNull RejectedExecutionHandler handler) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,r->workerThreadFactory.getNewThread(r), handler);
}
- private final Queue<TaskEntry> taskEntries = new ConcurrentLinkedQueue<>();
-
public void executeWithSubTask(Runnable mainTask,Runnable subTask){
final TaskEntry wrapped = new TaskEntry(subTask,mainTask);
this.taskEntries.offer(wrapped);
diff --git a/src/main/java/co/earthme/hearse/server/ServerHook.java b/src/main/java/co/earthme/hearse/server/ServerHook.java
new file mode 100644
index 0000000000000000000000000000000000000000..22260735664d986fed6bf82e4016b647417e1932
--- /dev/null
+++ b/src/main/java/co/earthme/hearse/server/ServerHook.java
@@ -0,0 +1,66 @@
+package co.earthme.hearse.server;
+
+import co.earthme.hearse.concurrent.WorkerThread;
+import co.earthme.hearse.concurrent.WorkerThreadPoolExecutor;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.entity.Entity;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ServerHook {
+ private static volatile boolean firstTick = false;
+ private static final AtomicInteger threadId = new AtomicInteger();
+ private static final WorkerThreadPoolExecutor worker = new WorkerThreadPoolExecutor(
+ Runtime.getRuntime().availableProcessors(),
+ Runtime.getRuntime().availableProcessors(),
+ 100,
+ TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<>(),
+ task -> {
+ WorkerThread workerThread = new WorkerThread("Hearse-Worker-Thread # "+threadId.getAndIncrement());
+ return workerThread;
+ }
+ );
+
+ public static void executeAsyncTask(Runnable task){
+ worker.execute(task);
+ }
+
+ public static void executeAsyncTaskWithMainThreadCallback(Runnable task,Runnable callBack){
+ worker.executeWithSubTask(task,callBack);
+ }
+
+ public static void callPostTick(){
+ if (!firstTick){
+ firstTick = true;
+ return;
+ }
+ worker.runAllSubTasks();
+ }
+
+ public static void callAsyncEntityTick(Entity entity, ServerLevel level){
+ MinecraftServer.getServer().executeMidTickTasks();
+ worker.execute(()->{
+ entity.activatedPriorityReset = false;
+ if (!entity.isRemoved()) {
+ entity.checkDespawn();
+ Entity entity1 = entity.getVehicle();
+ if (entity1 != null) {
+ if (!entity1.isRemoved() && entity1.hasPassenger(entity)) {
+ return;
+ }
+ entity.stopRiding();
+ }
+ try {
+ level.tickNonPassenger(entity);
+ } catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath) throw throwable;
+ level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(throwable.getMessage(), throwable)));
+ throwable.printStackTrace();
+ }
+ }
+ });
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3b7e4b724e86518ea57f5ed5ef0b8b3741d10f6f..e0e169a4403926ff6be004de1bf5ec2079acb440 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1,5 +1,6 @@
package net.minecraft.server;
+import co.earthme.hearse.server.ServerHook;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import co.aikar.timings.Timings;
@@ -1407,6 +1408,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
++this.tickCount;
this.tickChildren(shouldKeepTicking);
+ ServerHook.callPostTick();
if (i - this.lastServerStatus >= 5000000000L) {
this.lastServerStatus = i;
this.status.setPlayers(new ServerStatus.Players(this.getMaxPlayers(), this.getPlayerCount()));
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index a2935994edc279d880ff26dd5cc4e33f1105acc8..81697ea6d00967852556c3bb741317db030c24db 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -833,12 +833,10 @@ public class ServerChunkCache extends ChunkSource {
if (chunkMap.playerMobDistanceMap != null && _pufferfish_spawnCountsReady.getAndSet(false)) {
net.minecraft.server.MinecraftServer.getServer().mobSpawnExecutor.submit(() -> {
int mapped = distanceManager.getNaturalSpawnChunkCount();
- io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator<Entity> objectiterator =
- level.entityTickList.entities.iterator(io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.ITERATOR_FLAG_SEE_ADDITIONS);
+ Iterator<Entity> objectiterator = level.entityTickList.entities.iterator();
gg.pufferfish.pufferfish.util.IterableWrapper<Entity> wrappedIterator =
new gg.pufferfish.pufferfish.util.IterableWrapper<>(objectiterator);
lastSpawnState = NaturalSpawner.createState(mapped, wrappedIterator, this::getFullChunk, null, true);
- objectiterator.finishedIterating();
_pufferfish_spawnCountsReady.set(true);
});
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 6074956d677542a46066dc45ceda9d73a2e09d27..125e5fb54acb68d58ea9fb973894b02facb04edc 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1,6 +1,8 @@
package net.minecraft.server.level;
import co.aikar.timings.TimingHistory;
+import co.earthme.hearse.concurrent.WorkerThread;
+import co.earthme.hearse.server.ServerHook;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -221,7 +223,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority,
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
- if (Thread.currentThread() != this.thread) {
+ if (Thread.currentThread() != this.thread && !WorkerThread.isWorker()) {
this.getChunkSource().mainThreadProcessor.execute(() -> {
this.loadChunksForMoveAsync(axisalignedbb, priority, onLoad);
});
@@ -643,71 +645,15 @@ public class ServerLevel extends Level implements WorldGenLevel {
//timings.doSounds.stopTiming(); // Spigot // Purpur
this.handlingTick = false;
//gameprofilerfiller.pop(); // Purpur
- boolean flag = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
-
- if (flag) {
- this.resetEmptyTime();
- }
-
- if (flag || this.emptyTime++ < 300) {
- //gameprofilerfiller.push("entities"); // Purpur
- //timings.tickEntities.startTiming(); // Spigot // Purpur
- if (this.dragonFight != null) {
- //gameprofilerfiller.push("dragonFight"); // Purpur
- this.dragonFight.tick();
- //gameprofilerfiller.pop(); // Purpur
- }
-
- org.spigotmc.ActivationRange.activateEntities(this); // Spigot
- //timings.entityTick.startTiming(); // Spigot // Purpur
- this.entityTickList.forEach((entity) -> {
- entity.activatedPriorityReset = false; // Pufferfish - DAB
- if (!entity.isRemoved()) {
- if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed
- entity.discard();
- } else {
- //gameprofilerfiller.push("checkDespawn"); // Purpur
- entity.checkDespawn();
- //gameprofilerfiller.pop(); // Purpur
- if (true || this.chunkSource.chunkMap.getDistanceManager().inEntityTickingRange(entity.chunkPosition().toLong())) { // Paper - now always true if in the ticking list
- Entity entity1 = entity.getVehicle();
-
- if (entity1 != null) {
- if (!entity1.isRemoved() && entity1.hasPassenger(entity)) {
- return;
- }
-
- entity.stopRiding();
- }
-
- //gameprofilerfiller.push("tick"); // Purpur
- // Pufferfish start - copied from this.guardEntityTick
- try {
- this.tickNonPassenger(entity); // Pufferfish - changed
- MinecraftServer.getServer().executeMidTickTasks(); // Tuinity - execute chunk tasks mid tick
- } catch (Throwable throwable) {
- if (throwable instanceof ThreadDeath) throw throwable; // Paper
- // Paper start - Prevent tile entity and entity crashes
- final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
- MinecraftServer.LOGGER.error(msg, throwable);
- getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerInternalException(msg, throwable)));
- entity.discard();
- // Paper end
- }
- // Pufferfish end
- //gameprofilerfiller.pop(); // Purpur
- }
- }
- }
- });
- //timings.entityTick.stopTiming(); // Spigot // Purpur
- //timings.tickEntities.stopTiming(); // Spigot // Purpur
- //gameprofilerfiller.pop(); // Purpur
- this.tickBlockEntities();
+ this.resetEmptyTime();
+ if (this.dragonFight != null) {
+ this.dragonFight.tick();
}
-
- //gameprofilerfiller.push("entityManagement"); // Purpur
- //this.entityManager.tick(); // Paper - rewrite chunk system
+ org.spigotmc.ActivationRange.activateEntities(this); // Spigot
+ this.entityTickList.forEach((entity) -> {
+ ServerHook.callAsyncEntityTick(entity,this);
+ });
+ this.tickBlockEntities();
}
@Override
@@ -746,7 +692,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
- private boolean shouldDiscardEntity(Entity entity) {
+ public boolean shouldDiscardEntity(Entity entity) {
return !this.server.isSpawningAnimals() && (entity instanceof Animal || entity instanceof WaterAnimal) ? true : !this.server.areNpcsEnabled() && entity instanceof Npc;
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 958e0ee29915bddde2cb8ebfd578448b83e2b149..de78c5bdde53b4adfed9fda4d473560849bdb5aa 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -2,6 +2,7 @@ package net.minecraft.world.level;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
+import co.earthme.hearse.concurrent.WorkerThread;
import com.destroystokyo.paper.event.server.ServerExceptionEvent;
import com.destroystokyo.paper.exception.ServerInternalException;
import com.google.common.base.MoreObjects;
@@ -1116,7 +1117,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
// Paper end
// CraftBukkit end
- return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system
+ return this.isOutsideBuildHeight(blockposition) ? null : (!this.isClientSide && !io.papermc.paper.util.TickThread.isTickThread() && !WorkerThread.isWorker() ? null : this.getChunkAt(blockposition).getBlockEntity(blockposition, LevelChunk.EntityCreationType.IMMEDIATE)); // Paper - rewrite chunk system
}
public void setBlockEntity(BlockEntity blockEntity) {