9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-23 00:49:31 +00:00
Files
Leaf/patches/server/0045-Hearse-Add-base-codes.patch
2023-01-13 00:15:47 -05:00

395 lines
18 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Sun, 8 Jan 2023 22:12:06 +0800
Subject: [PATCH] Hearse: Add base codes
Original license: MIT
Original project: https://github.com/NaturalCodeClub/HearseRewrite
diff --git a/src/main/java/co/earthme/hearse/HearseConfig.java b/src/main/java/co/earthme/hearse/HearseConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..912da4787f83f656da67e9533b60183c17e6c345
--- /dev/null
+++ b/src/main/java/co/earthme/hearse/HearseConfig.java
@@ -0,0 +1,4 @@
+package co.earthme.hearse;
+
+public class HearseConfig {
+}
diff --git a/src/main/java/co/earthme/hearse/concurrent/ThreadPool.java b/src/main/java/co/earthme/hearse/concurrent/ThreadPool.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fbc81cb880cf6d38bb4c940b4cc1fa828c2ef17
--- /dev/null
+++ b/src/main/java/co/earthme/hearse/concurrent/ThreadPool.java
@@ -0,0 +1,76 @@
+package co.earthme.hearse.concurrent;
+
+import org.jetbrains.annotations.NotNull;
+
+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 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 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);
+ }
+
+ 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);
+ this.execute(wrapped);
+ }
+
+ public void runAllSubTasks(){
+ TaskEntry task;
+ while ((task = this.taskEntries.poll())!=null){
+ while (!task.allRunned()){
+ LockSupport.parkNanos(this,10000000);
+ }
+ }
+ }
+
+ private static class TaskEntry implements Runnable{
+ private final Runnable mainTask;
+ private final Runnable subTask;
+ private volatile boolean mainTaskFinished = false;
+
+ public TaskEntry(Runnable subTask,Runnable mainTask){
+ this.subTask = subTask;
+ this.mainTask = mainTask;
+ }
+
+ public boolean allRunned(){
+ if (!this.mainTaskFinished){
+ return false;
+ }
+ try {
+ this.subTask.run();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public void run() {
+ try {
+ this.mainTask.run();
+ }catch(Exception e){
+ e.printStackTrace();
+ }finally {
+ this.mainTaskFinished = true;
+ }
+ }
+ }
+}
diff --git a/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java b/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..06f55f26eb63e356b3558622bf68711f18cda1c6
--- /dev/null
+++ b/src/main/java/co/earthme/hearse/concurrent/WorkerThread.java
@@ -0,0 +1,13 @@
+package co.earthme.hearse.concurrent;
+
+import io.papermc.paper.util.TickThread;
+
+public class WorkerThread extends TickThread {
+ public WorkerThread(String name) {
+ super(name);
+ }
+
+ public static boolean isWorker(){
+ return Thread.currentThread() instanceof WorkerThread;
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 3d99330160a3ba0715394d0c88533bc4a79fe3a2..30cde5b9cd8d179f4b332563f2999f675851fbd1 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1,64 +1,33 @@
package net.minecraft.server.level;
+import co.aikar.timings.TimingHistory;
import com.google.common.annotations.VisibleForTesting;
-import co.aikar.timings.TimingHistory; // Paper
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mojang.datafixers.DataFixer;
import com.mojang.datafixers.util.Pair;
import com.mojang.logging.LogUtils;
+import io.papermc.paper.util.MCUtil;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.longs.LongSets;
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
-import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.*;
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.Executor;
-import java.util.function.BooleanSupplier;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import net.minecraft.CrashReport;
import net.minecraft.Util;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.RegistryAccess;
-import net.minecraft.core.SectionPos;
+import net.minecraft.core.*;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
-import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.protocol.Packet;
-import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
-import net.minecraft.network.protocol.game.ClientboundBlockEventPacket;
-import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
-import net.minecraft.network.protocol.game.ClientboundExplodePacket;
-import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
-import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
-import net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundEntityPacket;
-import net.minecraft.network.protocol.game.ClientboundSoundPacket;
-import net.minecraft.network.protocol.game.DebugPackets;
+import net.minecraft.network.protocol.game.*;
import net.minecraft.resources.ResourceKey;
-import io.papermc.paper.util.MCUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerScoreboard;
import net.minecraft.server.level.progress.ChunkProgressListener;
@@ -66,21 +35,10 @@ import net.minecraft.server.players.SleepStatus;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.TagKey;
-import net.minecraft.util.AbortableIterationConsumer;
-import net.minecraft.util.CsvOutput;
-import net.minecraft.util.Mth;
-import net.minecraft.util.ProgressListener;
-import net.minecraft.util.Unit;
-import net.minecraft.util.profiling.ProfilerFiller;
+import net.minecraft.util.*;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.damagesource.DamageSource;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.LightningBolt;
-import net.minecraft.world.entity.LivingEntity;
-import net.minecraft.world.entity.Mob;
-import net.minecraft.world.entity.MobCategory;
-import net.minecraft.world.entity.ReputationEventHandler;
+import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.ai.village.ReputationEventType;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
@@ -97,17 +55,7 @@ import net.minecraft.world.entity.raid.Raid;
import net.minecraft.world.entity.raid.Raids;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.crafting.RecipeManager;
-import net.minecraft.world.level.BlockEventData;
-import net.minecraft.world.level.ChunkPos;
-import net.minecraft.world.level.CustomSpawner;
-import net.minecraft.world.level.Explosion;
-import net.minecraft.world.level.ExplosionDamageCalculator;
-import net.minecraft.world.level.ForcedChunksSavedData;
-import net.minecraft.world.level.GameRules;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.NaturalSpawner;
-import net.minecraft.world.level.StructureManager;
-import net.minecraft.world.level.WorldGenLevel;
+import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.block.Block;
@@ -123,12 +71,10 @@ import net.minecraft.world.level.chunk.storage.EntityStorage;
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.dimension.end.EndDragonFight;
-import net.minecraft.world.level.entity.EntityPersistentStorage;
import net.minecraft.world.level.entity.EntityTickList;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.entity.LevelCallback;
import net.minecraft.world.level.entity.LevelEntityGetter;
-import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import net.minecraft.world.level.gameevent.DynamicGameEventListener;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEventDispatcher;
@@ -153,21 +99,32 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.LevelTicks;
-import org.slf4j.Logger;
import org.bukkit.Bukkit;
-import org.bukkit.Location;
import org.bukkit.WeatherType;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.generator.CustomWorldChunkManager;
-import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.util.WorldUUID;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.server.MapInitializeEvent;
import org.bukkit.event.weather.LightningStrikeEvent;
-import org.bukkit.event.world.GenericGameEvent;
import org.bukkit.event.world.TimeSkipEvent;
-// CraftBukkit end
-import it.unimi.dsi.fastutil.ints.IntArrayList; // Paper
+import org.slf4j.Logger;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.Executor;
+import java.util.function.BooleanSupplier;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class ServerLevel extends Level implements WorldGenLevel {
@@ -988,7 +945,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (this.canSleepThroughNights()) {
if (!this.getServer().isSingleplayer() || this.getServer().isPublished()) {
int i = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
- MutableComponent ichatmutablecomponent;
+ Component ichatmutablecomponent;
if (this.sleepStatus.areEnoughSleeping(i)) {
ichatmutablecomponent = Component.translatable("sleep.skipping_night");
@@ -1656,56 +1613,56 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {
- if (this.isUpdatingNavigations) {
- String s = "recursive call to sendBlockUpdated";
+ synchronized (this.navigatingMobs){
+ if (this.isUpdatingNavigations) {
+ return;
+ }
- Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated"));
- }
+ this.getChunkSource().blockChanged(pos);
+ if(this.paperConfig().misc.updatePathfindingOnBlockUpdate) { // Paper - option to disable pathfinding updates
+ VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
+ VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
- this.getChunkSource().blockChanged(pos);
- if(this.paperConfig().misc.updatePathfindingOnBlockUpdate) { // Paper - option to disable pathfinding updates
- VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
- VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
+ if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
+ List<PathNavigation> list = new ObjectArrayList();
+ Iterator iterator = this.navigatingMobs.iterator();
- if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
- List<PathNavigation> list = new ObjectArrayList();
- Iterator iterator = this.navigatingMobs.iterator();
+ while (iterator.hasNext()) {
+ // CraftBukkit start - fix SPIGOT-6362
+ Mob entityinsentient;
+ try {
+ entityinsentient = (Mob) iterator.next();
+ } catch (java.util.ConcurrentModificationException ex) {
+ // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
+ // In this case we just run the update again across all the iterators as the chunk will then be loaded
+ // As this is a relative edge case it is much faster than copying navigators (on either read or write)
+ this.sendBlockUpdated(pos, oldState, newState, flags);
+ return;
+ }
+ // CraftBukkit end
+ PathNavigation navigationabstract = entityinsentient.getNavigation();
- while (iterator.hasNext()) {
- // CraftBukkit start - fix SPIGOT-6362
- Mob entityinsentient;
- try {
- entityinsentient = (Mob) iterator.next();
- } catch (java.util.ConcurrentModificationException ex) {
- // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
- // In this case we just run the update again across all the iterators as the chunk will then be loaded
- // As this is a relative edge case it is much faster than copying navigators (on either read or write)
- this.sendBlockUpdated(pos, oldState, newState, flags);
- return;
- }
- // CraftBukkit end
- PathNavigation navigationabstract = entityinsentient.getNavigation();
+ if (navigationabstract.shouldRecomputePath(pos)) {
+ list.add(navigationabstract);
+ }
+ }
- if (navigationabstract.shouldRecomputePath(pos)) {
- list.add(navigationabstract);
- }
- }
+ try {
+ this.isUpdatingNavigations = true;
+ iterator = list.iterator();
- try {
- this.isUpdatingNavigations = true;
- iterator = list.iterator();
+ while (iterator.hasNext()) {
+ PathNavigation navigationabstract1 = (PathNavigation) iterator.next();
- while (iterator.hasNext()) {
- PathNavigation navigationabstract1 = (PathNavigation) iterator.next();
+ navigationabstract1.recomputePath();
+ }
+ } finally {
+ this.isUpdatingNavigations = false;
+ }
- navigationabstract1.recomputePath();
}
- } finally {
- this.isUpdatingNavigations = false;
- }
-
+ } // Paper
}
- } // Paper
}
@Override