mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-23 00:49:31 +00:00
395 lines
18 KiB
Diff
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
|