From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: wangxyper 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 workQueue) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); + } + + public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue workQueue, @NotNull ThreadFactory threadFactory) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); + } + + public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue workQueue, @NotNull RejectedExecutionHandler handler) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); + } + + public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit, @NotNull BlockingQueue workQueue, @NotNull ThreadFactory threadFactory, @NotNull RejectedExecutionHandler handler) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); + } + + private final Queue 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 list = new ObjectArrayList(); + Iterator iterator = this.navigatingMobs.iterator(); - if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) { - List 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