Fix build
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: peaches94 <peachescu94@gmail.com>
|
From: peaches94 <peachescu94@gmail.com>
|
||||||
Date: Sun, 26 Jun 2022 16:51:37 -0500
|
Date: Sun, 26 Jun 2022 16:51:37 -0500
|
||||||
Subject: [PATCH] Petal patches
|
Subject: [PATCH] Async path processing
|
||||||
|
|
||||||
Original code by Bloom-host, licensed under GPL-3.0.
|
Original code by Bloom-host, licensed under GNU General Public License v3.0
|
||||||
You can find the original code on https://github.com/Bloom-host/Petal
|
You can find the original code on https://github.com/Bloom-host/Petal
|
||||||
|
|
||||||
diff --git a/src/main/java/host/bloom/pathfinding/AsyncPath.java b/src/main/java/host/bloom/pathfinding/AsyncPath.java
|
diff --git a/src/main/java/host/bloom/pathfinding/AsyncPath.java b/src/main/java/host/bloom/pathfinding/AsyncPath.java
|
||||||
@@ -411,408 +411,6 @@ index 0000000000000000000000000000000000000000..d5327cb257d63291adc8b5c60cffb4e4
|
|||||||
+ @NotNull NodeEvaluator generate();
|
+ @NotNull NodeEvaluator generate();
|
||||||
+
|
+
|
||||||
+}
|
+}
|
||||||
diff --git a/src/main/java/host/bloom/tracker/MultithreadedTracker.java b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..d27b7224ed2bcc63386dc46c33bfb8b272d91f92
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
|
|
||||||
@@ -0,0 +1,154 @@
|
|
||||||
+package host.bloom.tracker;
|
|
||||||
+
|
|
||||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
||||||
+import io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
|
|
||||||
+import io.papermc.paper.world.ChunkEntitySlices;
|
|
||||||
+import net.minecraft.server.MinecraftServer;
|
|
||||||
+import net.minecraft.server.level.ChunkMap;
|
|
||||||
+import net.minecraft.world.entity.Entity;
|
|
||||||
+import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
+
|
|
||||||
+import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
+import java.util.concurrent.Executor;
|
|
||||||
+import java.util.concurrent.Executors;
|
|
||||||
+import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
+
|
|
||||||
+public class MultithreadedTracker {
|
|
||||||
+
|
|
||||||
+ private enum TrackerStage {
|
|
||||||
+ UPDATE_PLAYERS,
|
|
||||||
+ SEND_CHANGES
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static final int parallelism = Math.max(4, Runtime.getRuntime().availableProcessors());
|
|
||||||
+ private static final Executor trackerExecutor = Executors.newFixedThreadPool(parallelism, new ThreadFactoryBuilder()
|
|
||||||
+ .setNameFormat("petal-tracker-%d")
|
|
||||||
+ .setPriority(Thread.NORM_PRIORITY - 2)
|
|
||||||
+ .build());
|
|
||||||
+
|
|
||||||
+ private final IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks;
|
|
||||||
+ private final AtomicInteger taskIndex = new AtomicInteger();
|
|
||||||
+
|
|
||||||
+ private final ConcurrentLinkedQueue<Runnable> mainThreadTasks;
|
|
||||||
+ private final AtomicInteger finishedTasks = new AtomicInteger();
|
|
||||||
+
|
|
||||||
+ public MultithreadedTracker(IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks, ConcurrentLinkedQueue<Runnable> mainThreadTasks) {
|
|
||||||
+ this.entityTickingChunks = entityTickingChunks;
|
|
||||||
+ this.mainThreadTasks = mainThreadTasks;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public void tick() {
|
|
||||||
+ int iterator = this.entityTickingChunks.createRawIterator();
|
|
||||||
+
|
|
||||||
+ if (iterator == -1) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // start with updating players
|
|
||||||
+ try {
|
|
||||||
+ this.taskIndex.set(iterator);
|
|
||||||
+ this.finishedTasks.set(0);
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < parallelism; i++) {
|
|
||||||
+ trackerExecutor.execute(this::runUpdatePlayers);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while (this.taskIndex.get() < this.entityTickingChunks.getListSize()) {
|
|
||||||
+ this.runMainThreadTasks();
|
|
||||||
+ this.handleChunkUpdates(5); // assist
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while (this.finishedTasks.get() != parallelism) {
|
|
||||||
+ this.runMainThreadTasks();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ this.runMainThreadTasks(); // finish any remaining tasks
|
|
||||||
+ } finally {
|
|
||||||
+ this.entityTickingChunks.finishRawIterator();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // then send changes
|
|
||||||
+ iterator = this.entityTickingChunks.createRawIterator();
|
|
||||||
+
|
|
||||||
+ if (iterator == -1) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ try {
|
|
||||||
+ do {
|
|
||||||
+ LevelChunk chunk = this.entityTickingChunks.rawGet(iterator);
|
|
||||||
+
|
|
||||||
+ if (chunk != null) {
|
|
||||||
+ this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
|
|
||||||
+ }
|
|
||||||
+ } while (++iterator < this.entityTickingChunks.getListSize());
|
|
||||||
+ } finally {
|
|
||||||
+ this.entityTickingChunks.finishRawIterator();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void runMainThreadTasks() {
|
|
||||||
+ try {
|
|
||||||
+ Runnable task;
|
|
||||||
+ while ((task = this.mainThreadTasks.poll()) != null) {
|
|
||||||
+ task.run();
|
|
||||||
+ }
|
|
||||||
+ } catch (Throwable throwable) {
|
|
||||||
+ MinecraftServer.LOGGER.warn("Tasks failed while ticking track queue", throwable);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void runUpdatePlayers() {
|
|
||||||
+ try {
|
|
||||||
+ while (handleChunkUpdates(10));
|
|
||||||
+ } finally {
|
|
||||||
+ this.finishedTasks.incrementAndGet();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private boolean handleChunkUpdates(int tasks) {
|
|
||||||
+ int index;
|
|
||||||
+ while ((index = this.taskIndex.getAndAdd(tasks)) < this.entityTickingChunks.getListSize()) {
|
|
||||||
+ for (int i = index; i < index + tasks && i < this.entityTickingChunks.getListSize(); i++) {
|
|
||||||
+ LevelChunk chunk = this.entityTickingChunks.rawGet(i);
|
|
||||||
+ if (chunk != null) {
|
|
||||||
+ try {
|
|
||||||
+ this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
|
|
||||||
+ } catch (Throwable throwable) {
|
|
||||||
+ MinecraftServer.LOGGER.warn("Ticking tracker failed", throwable);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
|
|
||||||
+ final ChunkEntitySlices entitySlices = chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ);
|
|
||||||
+ if (entitySlices == null) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ final Entity[] rawEntities = entitySlices.entities.getRawData();
|
|
||||||
+ final ChunkMap chunkMap = chunk.level.chunkSource.chunkMap;
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < rawEntities.length; i++) {
|
|
||||||
+ Entity entity = rawEntities[i];
|
|
||||||
+ if (entity != null) {
|
|
||||||
+ ChunkMap.TrackedEntity entityTracker = chunkMap.entityMap.get(entity.getId());
|
|
||||||
+ if (entityTracker != null) {
|
|
||||||
+ if (trackerStage == TrackerStage.SEND_CHANGES) {
|
|
||||||
+ entityTracker.serverEntity.sendChanges();
|
|
||||||
+ } else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
|
|
||||||
+ entityTracker.updatePlayers(entityTracker.entity.getPlayersInTrackRange());
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
|
||||||
index 0fd814f1d65c111266a2b20f86561839a4cef755..169ac3ad1b1e8e3e1874ada2471e478233c6ada7 100644
|
|
||||||
--- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
|
||||||
+++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
|
||||||
@@ -15,7 +15,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
||||||
|
|
||||||
/* list impl */
|
|
||||||
protected E[] listElements;
|
|
||||||
- protected int listSize;
|
|
||||||
+ protected int listSize; public int getListSize() { return this.listSize; } // petal - expose listSize
|
|
||||||
|
|
||||||
protected final double maxFragFactor;
|
|
||||||
|
|
||||||
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
||||||
index f597d65d56964297eeeed6c7e77703764178fee0..665c377e2d0d342f4dcc89c4cbdfcc9e4b96e95c 100644
|
|
||||||
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
||||||
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
||||||
@@ -35,7 +35,7 @@ public final class ChunkEntitySlices {
|
|
||||||
protected final EntityCollectionBySection allEntities;
|
|
||||||
protected final EntityCollectionBySection hardCollidingEntities;
|
|
||||||
protected final Reference2ObjectOpenHashMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
|
|
||||||
- protected final EntityList entities = new EntityList();
|
|
||||||
+ public final EntityList entities = new EntityList();
|
|
||||||
|
|
||||||
public ChunkHolder.FullChunkStatus status;
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
||||||
index 3203b953709ca7cb9172f5912a922131ad7ec9eb..3c99de7bc5b3c5159ad76f63d67877756f152385 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
||||||
@@ -1237,8 +1237,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
entity.tracker = null; // Paper - We're no longer tracked
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // petal start - multithreaded tracker
|
|
||||||
+ private @Nullable host.bloom.tracker.MultithreadedTracker multithreadedTracker;
|
|
||||||
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
|
||||||
+ private boolean tracking = false;
|
|
||||||
+
|
|
||||||
+ public void runOnTrackerMainThread(final Runnable runnable) {
|
|
||||||
+ if (this.tracking) {
|
|
||||||
+ this.trackerMainThreadTasks.add(runnable);
|
|
||||||
+ } else {
|
|
||||||
+ runnable.run();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Paper start - optimised tracker
|
|
||||||
private final void processTrackQueue() {
|
|
||||||
+ if (true) {
|
|
||||||
+ if (this.multithreadedTracker == null) {
|
|
||||||
+ this.multithreadedTracker = new host.bloom.tracker.MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.trackerMainThreadTasks);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ this.tracking = true;
|
|
||||||
+ try {
|
|
||||||
+ this.multithreadedTracker.tick();
|
|
||||||
+ } finally {
|
|
||||||
+ this.tracking = false;
|
|
||||||
+ }
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ // petal end
|
|
||||||
+
|
|
||||||
+ this.level.timings.tracker1.startTiming();
|
|
||||||
//this.level.timings.tracker1.startTiming(); // Purpur
|
|
||||||
try {
|
|
||||||
for (TrackedEntity tracker : this.entityMap.values()) {
|
|
||||||
@@ -1462,11 +1491,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
|
|
||||||
public class TrackedEntity {
|
|
||||||
|
|
||||||
- final ServerEntity serverEntity;
|
|
||||||
- final Entity entity;
|
|
||||||
+ public final ServerEntity serverEntity; // petal -> public
|
|
||||||
+ public final Entity entity; // petal -> public
|
|
||||||
private final int range;
|
|
||||||
SectionPos lastSectionPos;
|
|
||||||
- public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
|
|
||||||
+ public final Set<ServerPlayerConnection> seenBy = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new ReferenceOpenHashSet<>()); // Paper - optimise map impl // petal - sync
|
|
||||||
|
|
||||||
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
|
|
||||||
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
|
|
||||||
@@ -1478,7 +1507,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
// Paper start - use distance map to optimise tracker
|
|
||||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;
|
|
||||||
|
|
||||||
- final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) {
|
|
||||||
+ public final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) { // petal -> public
|
|
||||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
|
|
||||||
this.lastTrackerCandidates = newTrackerCandidates;
|
|
||||||
|
|
||||||
@@ -1550,7 +1579,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePlayer(ServerPlayer player) {
|
|
||||||
- org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
|
||||||
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot // petal - we can remove async too
|
|
||||||
if (this.seenBy.remove(player.connection)) {
|
|
||||||
this.serverEntity.removePairing(player);
|
|
||||||
}
|
|
||||||
@@ -1558,7 +1587,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePlayer(ServerPlayer player) {
|
|
||||||
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
|
||||||
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot // petal - we can update async
|
|
||||||
if (player != this.entity) {
|
|
||||||
// Paper start - remove allocation of Vec3D here
|
|
||||||
// Vec3 vec3d = player.position().subtract(this.entity.position());
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerBossEvent.java b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
|
||||||
index ca42c2642a729b90d22b968af7258f3aee72e14b..40261b80d947a6be43465013fae5532197cfe721 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
|
||||||
@@ -13,7 +13,7 @@ import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.BossEvent;
|
|
||||||
|
|
||||||
public class ServerBossEvent extends BossEvent {
|
|
||||||
- private final Set<ServerPlayer> players = Sets.newHashSet();
|
|
||||||
+ private final Set<ServerPlayer> players = Sets.newConcurrentHashSet(); // petal - players can be removed in async tracking
|
|
||||||
private final Set<ServerPlayer> unmodifiablePlayers = Collections.unmodifiableSet(this.players);
|
|
||||||
public boolean visible = true;
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
||||||
index 3441339e1ba5efb0e25c16fa13cb65d2fbdafc42..555336cf6700566e8a99e0f0cd6f0cc41b6c5ba0 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
|
||||||
@@ -249,14 +249,18 @@ public class ServerEntity {
|
|
||||||
|
|
||||||
public void removePairing(ServerPlayer player) {
|
|
||||||
this.entity.stopSeenByPlayer(player);
|
|
||||||
- player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
|
|
||||||
+ // petal start - ensure main thread
|
|
||||||
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
|
||||||
+ player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}))
|
|
||||||
+ );
|
|
||||||
+ // petal end
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPairing(ServerPlayer player) {
|
|
||||||
ServerGamePacketListenerImpl playerconnection = player.connection;
|
|
||||||
|
|
||||||
Objects.requireNonNull(player.connection);
|
|
||||||
- this.sendPairingData(playerconnection::send, player); // CraftBukkit - add player
|
|
||||||
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() -> this.sendPairingData(playerconnection::send, player)); // CraftBukkit - add player // petal - main thread
|
|
||||||
this.entity.startSeenByPlayer(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -362,19 +366,30 @@ public class ServerEntity {
|
|
||||||
SynchedEntityData datawatcher = this.entity.getEntityData();
|
|
||||||
|
|
||||||
if (datawatcher.isDirty()) {
|
|
||||||
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false));
|
|
||||||
+ // Petal start - sync
|
|
||||||
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
|
||||||
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false))
|
|
||||||
+ );
|
|
||||||
+ // Petal end
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.entity instanceof LivingEntity) {
|
|
||||||
Set<AttributeInstance> set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes();
|
|
||||||
|
|
||||||
if (!set.isEmpty()) {
|
|
||||||
+ // Petal start - sync
|
|
||||||
+ final var copy = Lists.newArrayList(set);
|
|
||||||
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
|
|
||||||
+
|
|
||||||
// CraftBukkit start - Send scaled max health
|
|
||||||
if (this.entity instanceof ServerPlayer) {
|
|
||||||
- ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(set, false);
|
|
||||||
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(copy, false);
|
|
||||||
}
|
|
||||||
// CraftBukkit end
|
|
||||||
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set));
|
|
||||||
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
|
|
||||||
+
|
|
||||||
+ });
|
|
||||||
+ // Petal end
|
|
||||||
}
|
|
||||||
|
|
||||||
set.clear();
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
||||||
index 571a1cbee376032b6b9f36c9fe3f9199a3ad3197..92e7ba78e18efb8263475ecc076bc49e88b85e84 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
||||||
@@ -1703,6 +1703,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
||||||
if (chunk != null) {
|
|
||||||
for (int j2 = k; j2 <= j1; ++j2) {
|
|
||||||
flag |= chunk.getEventDispatcher(j2).walkListeners(event, emitterPos, emitter, (gameeventlistener, vec3d1) -> {
|
|
||||||
+ if (!gameeventlistener.listensToEvent(event, emitter)) return; // petal - if they don't listen, ignore
|
|
||||||
(gameeventlistener.handleEventsImmediately() ? list : this.gameEventMessages).add(new GameEvent.Message(event, emitterPos, emitter, gameeventlistener, vec3d1));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
index 1fc877194950ee754e9ffdbe3ff9b80bb316560f..9fe6d0700f8f4d4cc018bcb4f33fffaa5f51a1d9 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
||||||
@@ -1012,20 +1012,22 @@ public abstract class LivingEntity extends Entity {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity != null) {
|
|
||||||
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
|
||||||
+ // petal start - only do itemstack lookup if we need to
|
|
||||||
+ //ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
|
||||||
EntityType<?> entitytypes = entity.getType();
|
|
||||||
|
|
||||||
// Purpur start
|
|
||||||
- if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) {
|
|
||||||
+ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) {
|
|
||||||
d0 *= entity.level.purpurConfig.skeletonHeadVisibilityPercent;
|
|
||||||
}
|
|
||||||
- else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) {
|
|
||||||
+ else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) {
|
|
||||||
d0 *= entity.level.purpurConfig.zombieHeadVisibilityPercent;
|
|
||||||
}
|
|
||||||
- else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) {
|
|
||||||
+ else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) {
|
|
||||||
d0 *= entity.level.purpurConfig.creeperHeadVisibilityPercent;
|
|
||||||
}
|
|
||||||
// Purpur end
|
|
||||||
+ // petal end
|
|
||||||
|
|
||||||
// Purpur start
|
|
||||||
if (entity instanceof LivingEntity entityliving) {
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
|
||||||
index d5e3bd662da349fc2ee58c7800d79c60300f33b3..0981873ee37fc839035b8398bac03d15adecb301 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
|
||||||
@@ -884,10 +884,10 @@ public abstract class Mob extends LivingEntity {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Paper end
|
|
||||||
+ int i = this.level.getServer().getTickCount() + this.getId(); // petal - move up
|
|
||||||
//this.level.getProfiler().push("sensing"); // Purpur
|
|
||||||
- this.sensing.tick();
|
|
||||||
+ if (i % 10 == 0) this.sensing.tick(); // petal - only refresh line of sight cache every half second
|
|
||||||
//this.level.getProfiler().pop(); // Purpur
|
|
||||||
- int i = this.level.getServer().getTickCount() + this.getId();
|
|
||||||
|
|
||||||
if (i % 2 != 0 && this.tickCount > 1) {
|
|
||||||
//this.level.getProfiler().push("targetSelector"); // Purpur
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||||
index bf3b8ccb3e031e0ad24cd51e28ea8cbd4f8a8030..e0453df8c0fcdb40ef0ed5ae8865d45df3325e46 100644
|
index bf3b8ccb3e031e0ad24cd51e28ea8cbd4f8a8030..e0453df8c0fcdb40ef0ed5ae8865d45df3325e46 100644
|
||||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
|
||||||
@@ -1335,186 +933,6 @@ index 68e31cf561f3d76bce6fa4324a75594c776f8964..6ce824a1f74163f60fc3b222f3aaf59c
|
|||||||
BlockPos blockposition = pathentity.getTarget();
|
BlockPos blockposition = pathentity.getTarget();
|
||||||
|
|
||||||
if (blockposition != null) {
|
if (blockposition != null) {
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
|
||||||
index 22c309343299e60ed8028229b7f134109001ff35..d5947d29295ddc93ba8ac1c0fc61f7badad582c4 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
|
||||||
@@ -85,6 +85,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // petal start
|
|
||||||
+ @Override
|
|
||||||
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
|
|
||||||
+ return !this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE && context.sourceEntity() instanceof LivingEntity;
|
|
||||||
+ }
|
|
||||||
+ // petal end
|
|
||||||
+
|
|
||||||
public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) {
|
|
||||||
org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
|
||||||
blockEntity.sculkSpreader.updateCursors(world, pos, world.getRandom(), true);
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
||||||
index 620173eef4c2f30a97a4c2f8049ea01fcc60d0b2..bdf67c916fe435f3bd04a61cce6db93c606515ce 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
|
||||||
@@ -84,7 +84,18 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
private Supplier<ChunkHolder.FullChunkStatus> fullStatus;
|
|
||||||
@Nullable
|
|
||||||
private LevelChunk.PostLoadProcessor postLoad;
|
|
||||||
- private final Int2ObjectMap<GameEventDispatcher> gameEventDispatcherSections;
|
|
||||||
+ // petal start
|
|
||||||
+ private final GameEventDispatcher[] gameEventDispatcherSections;
|
|
||||||
+ private static final int GAME_EVENT_DISPATCHER_RADIUS = 2;
|
|
||||||
+
|
|
||||||
+ private static int getGameEventSectionIndex(int sectionIndex) {
|
|
||||||
+ return sectionIndex + GAME_EVENT_DISPATCHER_RADIUS;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static int getGameEventSectionLength(int sectionCount) {
|
|
||||||
+ return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
|
|
||||||
+ }
|
|
||||||
+ // petal end
|
|
||||||
private final LevelChunkTicks<Block> blockTicks;
|
|
||||||
private final LevelChunkTicks<Fluid> fluidTicks;
|
|
||||||
|
|
||||||
@@ -113,7 +124,7 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
this.tickersInLevel = Maps.newHashMap();
|
|
||||||
this.clientLightReady = false;
|
|
||||||
this.level = (ServerLevel) world; // CraftBukkit - type
|
|
||||||
- this.gameEventDispatcherSections = new Int2ObjectOpenHashMap();
|
|
||||||
+ this.gameEventDispatcherSections = new GameEventDispatcher[getGameEventSectionLength(this.getSectionsCount())]; // petal
|
|
||||||
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
|
|
||||||
int j = aheightmap_type.length;
|
|
||||||
|
|
||||||
@@ -446,9 +457,23 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
if (world instanceof ServerLevel) {
|
|
||||||
ServerLevel worldserver = (ServerLevel) world;
|
|
||||||
|
|
||||||
- return (GameEventDispatcher) this.gameEventDispatcherSections.computeIfAbsent(ySectionCoord, (j) -> {
|
|
||||||
- return new EuclideanGameEventDispatcher(worldserver);
|
|
||||||
- });
|
|
||||||
+ // petal start
|
|
||||||
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
|
|
||||||
+
|
|
||||||
+ // drop game events that are too far away (32 blocks) from loaded sections
|
|
||||||
+ // this matches the highest radius of game events in the game
|
|
||||||
+ if (sectionIndex < 0 || sectionIndex >= this.gameEventDispatcherSections.length) {
|
|
||||||
+ return GameEventDispatcher.NOOP;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ var dispatcher = this.gameEventDispatcherSections[sectionIndex];
|
|
||||||
+
|
|
||||||
+ if (dispatcher == null) {
|
|
||||||
+ dispatcher = this.gameEventDispatcherSections[sectionIndex] = new EuclideanGameEventDispatcher(worldserver);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return dispatcher;
|
|
||||||
+ // petal end
|
|
||||||
} else {
|
|
||||||
return super.getEventDispatcher(ySectionCoord);
|
|
||||||
}
|
|
||||||
@@ -812,7 +837,7 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
|
|
||||||
gameeventdispatcher.unregister(gameeventlistener);
|
|
||||||
if (gameeventdispatcher.isEmpty()) {
|
|
||||||
- this.gameEventDispatcherSections.remove(i);
|
|
||||||
+ this.gameEventDispatcherSections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(i))] = null; // petal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
|
||||||
index 0dd708ebe81f73710de51215529c05ec61837dd3..f5b402efa86f824c460db8cac20c1c2b090f82d0 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
|
||||||
@@ -13,8 +13,8 @@ import net.minecraft.world.phys.Vec3;
|
|
||||||
|
|
||||||
public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
private final List<GameEventListener> listeners = Lists.newArrayList();
|
|
||||||
- private final Set<GameEventListener> listenersToRemove = Sets.newHashSet();
|
|
||||||
- private final List<GameEventListener> listenersToAdd = Lists.newArrayList();
|
|
||||||
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // petal - not necessary
|
|
||||||
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // petal
|
|
||||||
private boolean processing;
|
|
||||||
private final ServerLevel level;
|
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
@Override
|
|
||||||
public void register(GameEventListener listener) {
|
|
||||||
if (this.processing) {
|
|
||||||
- this.listenersToAdd.add(listener);
|
|
||||||
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
|
|
||||||
} else {
|
|
||||||
this.listeners.add(listener);
|
|
||||||
}
|
|
||||||
@@ -41,7 +41,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
@Override
|
|
||||||
public void unregister(GameEventListener listener) {
|
|
||||||
if (this.processing) {
|
|
||||||
- this.listenersToRemove.add(listener);
|
|
||||||
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
|
|
||||||
} else {
|
|
||||||
this.listeners.remove(listener);
|
|
||||||
}
|
|
||||||
@@ -58,7 +58,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
|
|
||||||
while(iterator.hasNext()) {
|
|
||||||
GameEventListener gameEventListener = iterator.next();
|
|
||||||
- if (this.listenersToRemove.remove(gameEventListener)) {
|
|
||||||
+ if (false) { // petal - disallow concurrent modification
|
|
||||||
iterator.remove();
|
|
||||||
} else {
|
|
||||||
Optional<Vec3> optional = getPostableListenerPosition(this.level, pos, gameEventListener);
|
|
||||||
@@ -72,6 +72,8 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
this.processing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // petal start
|
|
||||||
+ /*
|
|
||||||
if (!this.listenersToAdd.isEmpty()) {
|
|
||||||
this.listeners.addAll(this.listenersToAdd);
|
|
||||||
this.listenersToAdd.clear();
|
|
||||||
@@ -81,6 +83,8 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
|
||||||
this.listeners.removeAll(this.listenersToRemove);
|
|
||||||
this.listenersToRemove.clear();
|
|
||||||
}
|
|
||||||
+ */
|
|
||||||
+ // petal end
|
|
||||||
|
|
||||||
return bl;
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
|
||||||
index e5601afe8b739da518f36ae306f5e0cb252238f0..bc8f04424c5e8c416d6988f0e06d8cadbb400ca7 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
|
||||||
@@ -12,4 +12,10 @@ public interface GameEventListener {
|
|
||||||
int getListenerRadius();
|
|
||||||
|
|
||||||
boolean handleGameEvent(ServerLevel world, GameEvent.Message event);
|
|
||||||
+
|
|
||||||
+ // petal start - add check for seeing if this listener cares about an event
|
|
||||||
+ default boolean listensToEvent(net.minecraft.world.level.gameevent.GameEvent gameEvent, net.minecraft.world.level.gameevent.GameEvent.Context context) {
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ // petal end
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
|
||||||
index e45f54534bbf054eaf0008546ff459d4c11ddd50..e49d0d1c2a539fcd7e75262c4010475193964287 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
|
||||||
@@ -162,6 +162,13 @@ public class VibrationListener implements GameEventListener {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // petal start
|
|
||||||
+ @Override
|
|
||||||
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
|
|
||||||
+ return this.receivingEvent == null && gameEvent.is(this.config.getListenableEvents());
|
|
||||||
+ }
|
|
||||||
+ // petal end
|
|
||||||
+
|
|
||||||
public interface VibrationListenerConfig {
|
|
||||||
|
|
||||||
default TagKey<GameEvent> getListenableEvents() {
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||||
index 2a335f277bd0e4b8ad0f60d8226eb8aaa80a871f..527f5fb55b596b44c7418a6f70e7243432c160dd 100644
|
index 2a335f277bd0e4b8ad0f60d8226eb8aaa80a871f..527f5fb55b596b44c7418a6f70e7243432c160dd 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||||
362
patches/removed/0004-Multithreaded-tracker.patch
Normal file
362
patches/removed/0004-Multithreaded-tracker.patch
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: peaches94 <peachescu94@gmail.com>
|
||||||
|
Date: Sat, 2 Jul 2022 00:35:56 -0500
|
||||||
|
Subject: [PATCH] Multithreaded tracker
|
||||||
|
|
||||||
|
Original code by Bloom-host, licensed under GNU General Public License v3.0
|
||||||
|
You can find the original code on https://github.com/Bloom-host/Petal
|
||||||
|
|
||||||
|
Co-authored-by: Paul Sauve <paul@technove.co>
|
||||||
|
Co-authored-by: Kevin Raneri <kevin.raneri@gmail.com>
|
||||||
|
|
||||||
|
based off the airplane multithreaded tracker this patch properly handles
|
||||||
|
concurrent accesses everywhere, as well as being much simpler to maintain
|
||||||
|
|
||||||
|
some things are too unsafe to run off the main thread so we don't attempt to do
|
||||||
|
that. this multithreaded tracker remains accurate, non-breaking and fast
|
||||||
|
|
||||||
|
we also learned from pufferfish core that changes have to be sent ordered
|
||||||
|
now we do that in an optimized way
|
||||||
|
|
||||||
|
diff --git a/src/main/java/host/bloom/tracker/MultithreadedTracker.java b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..d27b7224ed2bcc63386dc46c33bfb8b272d91f92
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/host/bloom/tracker/MultithreadedTracker.java
|
||||||
|
@@ -0,0 +1,154 @@
|
||||||
|
+package host.bloom.tracker;
|
||||||
|
+
|
||||||
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
+import io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
|
||||||
|
+import io.papermc.paper.world.ChunkEntitySlices;
|
||||||
|
+import net.minecraft.server.MinecraftServer;
|
||||||
|
+import net.minecraft.server.level.ChunkMap;
|
||||||
|
+import net.minecraft.world.entity.Entity;
|
||||||
|
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
+
|
||||||
|
+import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
+import java.util.concurrent.Executor;
|
||||||
|
+import java.util.concurrent.Executors;
|
||||||
|
+import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
+
|
||||||
|
+public class MultithreadedTracker {
|
||||||
|
+
|
||||||
|
+ private enum TrackerStage {
|
||||||
|
+ UPDATE_PLAYERS,
|
||||||
|
+ SEND_CHANGES
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static final int parallelism = Math.max(4, Runtime.getRuntime().availableProcessors());
|
||||||
|
+ private static final Executor trackerExecutor = Executors.newFixedThreadPool(parallelism, new ThreadFactoryBuilder()
|
||||||
|
+ .setNameFormat("petal-tracker-%d")
|
||||||
|
+ .setPriority(Thread.NORM_PRIORITY - 2)
|
||||||
|
+ .build());
|
||||||
|
+
|
||||||
|
+ private final IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks;
|
||||||
|
+ private final AtomicInteger taskIndex = new AtomicInteger();
|
||||||
|
+
|
||||||
|
+ private final ConcurrentLinkedQueue<Runnable> mainThreadTasks;
|
||||||
|
+ private final AtomicInteger finishedTasks = new AtomicInteger();
|
||||||
|
+
|
||||||
|
+ public MultithreadedTracker(IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks, ConcurrentLinkedQueue<Runnable> mainThreadTasks) {
|
||||||
|
+ this.entityTickingChunks = entityTickingChunks;
|
||||||
|
+ this.mainThreadTasks = mainThreadTasks;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void tick() {
|
||||||
|
+ int iterator = this.entityTickingChunks.createRawIterator();
|
||||||
|
+
|
||||||
|
+ if (iterator == -1) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // start with updating players
|
||||||
|
+ try {
|
||||||
|
+ this.taskIndex.set(iterator);
|
||||||
|
+ this.finishedTasks.set(0);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < parallelism; i++) {
|
||||||
|
+ trackerExecutor.execute(this::runUpdatePlayers);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (this.taskIndex.get() < this.entityTickingChunks.getListSize()) {
|
||||||
|
+ this.runMainThreadTasks();
|
||||||
|
+ this.handleChunkUpdates(5); // assist
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (this.finishedTasks.get() != parallelism) {
|
||||||
|
+ this.runMainThreadTasks();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.runMainThreadTasks(); // finish any remaining tasks
|
||||||
|
+ } finally {
|
||||||
|
+ this.entityTickingChunks.finishRawIterator();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // then send changes
|
||||||
|
+ iterator = this.entityTickingChunks.createRawIterator();
|
||||||
|
+
|
||||||
|
+ if (iterator == -1) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ try {
|
||||||
|
+ do {
|
||||||
|
+ LevelChunk chunk = this.entityTickingChunks.rawGet(iterator);
|
||||||
|
+
|
||||||
|
+ if (chunk != null) {
|
||||||
|
+ this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
|
||||||
|
+ }
|
||||||
|
+ } while (++iterator < this.entityTickingChunks.getListSize());
|
||||||
|
+ } finally {
|
||||||
|
+ this.entityTickingChunks.finishRawIterator();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void runMainThreadTasks() {
|
||||||
|
+ try {
|
||||||
|
+ Runnable task;
|
||||||
|
+ while ((task = this.mainThreadTasks.poll()) != null) {
|
||||||
|
+ task.run();
|
||||||
|
+ }
|
||||||
|
+ } catch (Throwable throwable) {
|
||||||
|
+ MinecraftServer.LOGGER.warn("Tasks failed while ticking track queue", throwable);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void runUpdatePlayers() {
|
||||||
|
+ try {
|
||||||
|
+ while (handleChunkUpdates(10));
|
||||||
|
+ } finally {
|
||||||
|
+ this.finishedTasks.incrementAndGet();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private boolean handleChunkUpdates(int tasks) {
|
||||||
|
+ int index;
|
||||||
|
+ while ((index = this.taskIndex.getAndAdd(tasks)) < this.entityTickingChunks.getListSize()) {
|
||||||
|
+ for (int i = index; i < index + tasks && i < this.entityTickingChunks.getListSize(); i++) {
|
||||||
|
+ LevelChunk chunk = this.entityTickingChunks.rawGet(i);
|
||||||
|
+ if (chunk != null) {
|
||||||
|
+ try {
|
||||||
|
+ this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
|
||||||
|
+ } catch (Throwable throwable) {
|
||||||
|
+ MinecraftServer.LOGGER.warn("Ticking tracker failed", throwable);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
|
||||||
|
+ final ChunkEntitySlices entitySlices = chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ);
|
||||||
|
+ if (entitySlices == null) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final Entity[] rawEntities = entitySlices.entities.getRawData();
|
||||||
|
+ final ChunkMap chunkMap = chunk.level.chunkSource.chunkMap;
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < rawEntities.length; i++) {
|
||||||
|
+ Entity entity = rawEntities[i];
|
||||||
|
+ if (entity != null) {
|
||||||
|
+ ChunkMap.TrackedEntity entityTracker = chunkMap.entityMap.get(entity.getId());
|
||||||
|
+ if (entityTracker != null) {
|
||||||
|
+ if (trackerStage == TrackerStage.SEND_CHANGES) {
|
||||||
|
+ entityTracker.serverEntity.sendChanges();
|
||||||
|
+ } else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
|
||||||
|
+ entityTracker.updatePlayers(entityTracker.entity.getPlayersInTrackRange());
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
||||||
|
index 0fd814f1d65c111266a2b20f86561839a4cef755..169ac3ad1b1e8e3e1874ada2471e478233c6ada7 100644
|
||||||
|
--- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
||||||
|
@@ -15,7 +15,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
||||||
|
|
||||||
|
/* list impl */
|
||||||
|
protected E[] listElements;
|
||||||
|
- protected int listSize;
|
||||||
|
+ protected int listSize; public int getListSize() { return this.listSize; } // petal - expose listSize
|
||||||
|
|
||||||
|
protected final double maxFragFactor;
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||||
|
index f597d65d56964297eeeed6c7e77703764178fee0..665c377e2d0d342f4dcc89c4cbdfcc9e4b96e95c 100644
|
||||||
|
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
||||||
|
@@ -35,7 +35,7 @@ public final class ChunkEntitySlices {
|
||||||
|
protected final EntityCollectionBySection allEntities;
|
||||||
|
protected final EntityCollectionBySection hardCollidingEntities;
|
||||||
|
protected final Reference2ObjectOpenHashMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
|
||||||
|
- protected final EntityList entities = new EntityList();
|
||||||
|
+ public final EntityList entities = new EntityList();
|
||||||
|
|
||||||
|
public ChunkHolder.FullChunkStatus status;
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
|
index 3203b953709ca7cb9172f5912a922131ad7ec9eb..3c99de7bc5b3c5159ad76f63d67877756f152385 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
|
@@ -1237,8 +1237,37 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
entity.tracker = null; // Paper - We're no longer tracked
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // petal start - multithreaded tracker
|
||||||
|
+ private @Nullable host.bloom.tracker.MultithreadedTracker multithreadedTracker;
|
||||||
|
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
||||||
|
+ private boolean tracking = false;
|
||||||
|
+
|
||||||
|
+ public void runOnTrackerMainThread(final Runnable runnable) {
|
||||||
|
+ if (this.tracking) {
|
||||||
|
+ this.trackerMainThreadTasks.add(runnable);
|
||||||
|
+ } else {
|
||||||
|
+ runnable.run();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Paper start - optimised tracker
|
||||||
|
private final void processTrackQueue() {
|
||||||
|
+ if (true) {
|
||||||
|
+ if (this.multithreadedTracker == null) {
|
||||||
|
+ this.multithreadedTracker = new host.bloom.tracker.MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.trackerMainThreadTasks);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ this.tracking = true;
|
||||||
|
+ try {
|
||||||
|
+ this.multithreadedTracker.tick();
|
||||||
|
+ } finally {
|
||||||
|
+ this.tracking = false;
|
||||||
|
+ }
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ // petal end
|
||||||
|
+
|
||||||
|
+ this.level.timings.tracker1.startTiming();
|
||||||
|
//this.level.timings.tracker1.startTiming(); // Purpur
|
||||||
|
try {
|
||||||
|
for (TrackedEntity tracker : this.entityMap.values()) {
|
||||||
|
@@ -1462,11 +1491,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
|
||||||
|
public class TrackedEntity {
|
||||||
|
|
||||||
|
- final ServerEntity serverEntity;
|
||||||
|
- final Entity entity;
|
||||||
|
+ public final ServerEntity serverEntity; // petal -> public
|
||||||
|
+ public final Entity entity; // petal -> public
|
||||||
|
private final int range;
|
||||||
|
SectionPos lastSectionPos;
|
||||||
|
- public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
|
||||||
|
+ public final Set<ServerPlayerConnection> seenBy = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new ReferenceOpenHashSet<>()); // Paper - optimise map impl // petal - sync
|
||||||
|
|
||||||
|
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
|
||||||
|
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
|
||||||
|
@@ -1478,7 +1507,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
// Paper start - use distance map to optimise tracker
|
||||||
|
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;
|
||||||
|
|
||||||
|
- final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) {
|
||||||
|
+ public final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) { // petal -> public
|
||||||
|
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
|
||||||
|
this.lastTrackerCandidates = newTrackerCandidates;
|
||||||
|
|
||||||
|
@@ -1550,7 +1579,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayer(ServerPlayer player) {
|
||||||
|
- org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
||||||
|
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot // petal - we can remove async too
|
||||||
|
if (this.seenBy.remove(player.connection)) {
|
||||||
|
this.serverEntity.removePairing(player);
|
||||||
|
}
|
||||||
|
@@ -1558,7 +1587,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlayer(ServerPlayer player) {
|
||||||
|
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
||||||
|
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot // petal - we can update async
|
||||||
|
if (player != this.entity) {
|
||||||
|
// Paper start - remove allocation of Vec3D here
|
||||||
|
// Vec3 vec3d = player.position().subtract(this.entity.position());
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/level/ServerBossEvent.java b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||||
|
index ca42c2642a729b90d22b968af7258f3aee72e14b..40261b80d947a6be43465013fae5532197cfe721 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
|
||||||
|
@@ -13,7 +13,7 @@ import net.minecraft.util.Mth;
|
||||||
|
import net.minecraft.world.BossEvent;
|
||||||
|
|
||||||
|
public class ServerBossEvent extends BossEvent {
|
||||||
|
- private final Set<ServerPlayer> players = Sets.newHashSet();
|
||||||
|
+ private final Set<ServerPlayer> players = Sets.newConcurrentHashSet(); // petal - players can be removed in async tracking
|
||||||
|
private final Set<ServerPlayer> unmodifiablePlayers = Collections.unmodifiableSet(this.players);
|
||||||
|
public boolean visible = true;
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
index 3441339e1ba5efb0e25c16fa13cb65d2fbdafc42..555336cf6700566e8a99e0f0cd6f0cc41b6c5ba0 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||||
|
@@ -249,14 +249,18 @@ public class ServerEntity {
|
||||||
|
|
||||||
|
public void removePairing(ServerPlayer player) {
|
||||||
|
this.entity.stopSeenByPlayer(player);
|
||||||
|
- player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
|
||||||
|
+ // petal start - ensure main thread
|
||||||
|
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
||||||
|
+ player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}))
|
||||||
|
+ );
|
||||||
|
+ // petal end
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPairing(ServerPlayer player) {
|
||||||
|
ServerGamePacketListenerImpl playerconnection = player.connection;
|
||||||
|
|
||||||
|
Objects.requireNonNull(player.connection);
|
||||||
|
- this.sendPairingData(playerconnection::send, player); // CraftBukkit - add player
|
||||||
|
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() -> this.sendPairingData(playerconnection::send, player)); // CraftBukkit - add player // petal - main thread
|
||||||
|
this.entity.startSeenByPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -362,19 +366,30 @@ public class ServerEntity {
|
||||||
|
SynchedEntityData datawatcher = this.entity.getEntityData();
|
||||||
|
|
||||||
|
if (datawatcher.isDirty()) {
|
||||||
|
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false));
|
||||||
|
+ // Petal start - sync
|
||||||
|
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() ->
|
||||||
|
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), datawatcher, false))
|
||||||
|
+ );
|
||||||
|
+ // Petal end
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.entity instanceof LivingEntity) {
|
||||||
|
Set<AttributeInstance> set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes();
|
||||||
|
|
||||||
|
if (!set.isEmpty()) {
|
||||||
|
+ // Petal start - sync
|
||||||
|
+ final var copy = Lists.newArrayList(set);
|
||||||
|
+ ((ServerLevel) this.entity.level).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
|
||||||
|
+
|
||||||
|
// CraftBukkit start - Send scaled max health
|
||||||
|
if (this.entity instanceof ServerPlayer) {
|
||||||
|
- ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(set, false);
|
||||||
|
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(copy, false);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set));
|
||||||
|
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
|
||||||
|
+
|
||||||
|
+ });
|
||||||
|
+ // Petal end
|
||||||
|
}
|
||||||
|
|
||||||
|
set.clear();
|
||||||
204
patches/removed/0006-Reduce-work-done-by-game-event-system.patch
Normal file
204
patches/removed/0006-Reduce-work-done-by-game-event-system.patch
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: peaches94 <peachescu94@gmail.com>
|
||||||
|
Date: Sun, 10 Jul 2022 13:29:20 -0500
|
||||||
|
Subject: [PATCH] Reduce work done by game event system
|
||||||
|
|
||||||
|
Original code by Bloom-host, licensed under GNU General Public License v3.0
|
||||||
|
You can find the original code on https://github.com/Bloom-host/Petal
|
||||||
|
|
||||||
|
1. going into game event dispatching can be expensive so run the checks before dispatching
|
||||||
|
|
||||||
|
2. euclideangameeventdispatcher is not used concurrently so we ban that usage for improved performance with allays
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
|
index 571a1cbee376032b6b9f36c9fe3f9199a3ad3197..92e7ba78e18efb8263475ecc076bc49e88b85e84 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
|
@@ -1703,6 +1703,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||||
|
if (chunk != null) {
|
||||||
|
for (int j2 = k; j2 <= j1; ++j2) {
|
||||||
|
flag |= chunk.getEventDispatcher(j2).walkListeners(event, emitterPos, emitter, (gameeventlistener, vec3d1) -> {
|
||||||
|
+ if (!gameeventlistener.listensToEvent(event, emitter)) return; // petal - if they don't listen, ignore
|
||||||
|
(gameeventlistener.handleEventsImmediately() ? list : this.gameEventMessages).add(new GameEvent.Message(event, emitterPos, emitter, gameeventlistener, vec3d1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||||
|
index 22c309343299e60ed8028229b7f134109001ff35..d5947d29295ddc93ba8ac1c0fc61f7badad582c4 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||||
|
@@ -85,6 +85,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // petal start
|
||||||
|
+ @Override
|
||||||
|
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
|
||||||
|
+ return !this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE && context.sourceEntity() instanceof LivingEntity;
|
||||||
|
+ }
|
||||||
|
+ // petal end
|
||||||
|
+
|
||||||
|
public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) {
|
||||||
|
org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
||||||
|
blockEntity.sculkSpreader.updateCursors(world, pos, world.getRandom(), true);
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
index 620173eef4c2f30a97a4c2f8049ea01fcc60d0b2..bdf67c916fe435f3bd04a61cce6db93c606515ce 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
|
@@ -84,7 +84,18 @@ public class LevelChunk extends ChunkAccess {
|
||||||
|
private Supplier<ChunkHolder.FullChunkStatus> fullStatus;
|
||||||
|
@Nullable
|
||||||
|
private LevelChunk.PostLoadProcessor postLoad;
|
||||||
|
- private final Int2ObjectMap<GameEventDispatcher> gameEventDispatcherSections;
|
||||||
|
+ // petal start
|
||||||
|
+ private final GameEventDispatcher[] gameEventDispatcherSections;
|
||||||
|
+ private static final int GAME_EVENT_DISPATCHER_RADIUS = 2;
|
||||||
|
+
|
||||||
|
+ private static int getGameEventSectionIndex(int sectionIndex) {
|
||||||
|
+ return sectionIndex + GAME_EVENT_DISPATCHER_RADIUS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static int getGameEventSectionLength(int sectionCount) {
|
||||||
|
+ return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
|
||||||
|
+ }
|
||||||
|
+ // petal end
|
||||||
|
private final LevelChunkTicks<Block> blockTicks;
|
||||||
|
private final LevelChunkTicks<Fluid> fluidTicks;
|
||||||
|
|
||||||
|
@@ -113,7 +124,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
|
this.tickersInLevel = Maps.newHashMap();
|
||||||
|
this.clientLightReady = false;
|
||||||
|
this.level = (ServerLevel) world; // CraftBukkit - type
|
||||||
|
- this.gameEventDispatcherSections = new Int2ObjectOpenHashMap();
|
||||||
|
+ this.gameEventDispatcherSections = new GameEventDispatcher[getGameEventSectionLength(this.getSectionsCount())]; // petal
|
||||||
|
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
|
||||||
|
int j = aheightmap_type.length;
|
||||||
|
|
||||||
|
@@ -446,9 +457,23 @@ public class LevelChunk extends ChunkAccess {
|
||||||
|
if (world instanceof ServerLevel) {
|
||||||
|
ServerLevel worldserver = (ServerLevel) world;
|
||||||
|
|
||||||
|
- return (GameEventDispatcher) this.gameEventDispatcherSections.computeIfAbsent(ySectionCoord, (j) -> {
|
||||||
|
- return new EuclideanGameEventDispatcher(worldserver);
|
||||||
|
- });
|
||||||
|
+ // petal start
|
||||||
|
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
|
||||||
|
+
|
||||||
|
+ // drop game events that are too far away (32 blocks) from loaded sections
|
||||||
|
+ // this matches the highest radius of game events in the game
|
||||||
|
+ if (sectionIndex < 0 || sectionIndex >= this.gameEventDispatcherSections.length) {
|
||||||
|
+ return GameEventDispatcher.NOOP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ var dispatcher = this.gameEventDispatcherSections[sectionIndex];
|
||||||
|
+
|
||||||
|
+ if (dispatcher == null) {
|
||||||
|
+ dispatcher = this.gameEventDispatcherSections[sectionIndex] = new EuclideanGameEventDispatcher(worldserver);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return dispatcher;
|
||||||
|
+ // petal end
|
||||||
|
} else {
|
||||||
|
return super.getEventDispatcher(ySectionCoord);
|
||||||
|
}
|
||||||
|
@@ -812,7 +837,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
|
|
||||||
|
gameeventdispatcher.unregister(gameeventlistener);
|
||||||
|
if (gameeventdispatcher.isEmpty()) {
|
||||||
|
- this.gameEventDispatcherSections.remove(i);
|
||||||
|
+ this.gameEventDispatcherSections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(i))] = null; // petal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
||||||
|
index 0dd708ebe81f73710de51215529c05ec61837dd3..f5b402efa86f824c460db8cac20c1c2b090f82d0 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventDispatcher.java
|
||||||
|
@@ -13,8 +13,8 @@ import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
private final List<GameEventListener> listeners = Lists.newArrayList();
|
||||||
|
- private final Set<GameEventListener> listenersToRemove = Sets.newHashSet();
|
||||||
|
- private final List<GameEventListener> listenersToAdd = Lists.newArrayList();
|
||||||
|
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // petal - not necessary
|
||||||
|
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // petal
|
||||||
|
private boolean processing;
|
||||||
|
private final ServerLevel level;
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
@Override
|
||||||
|
public void register(GameEventListener listener) {
|
||||||
|
if (this.processing) {
|
||||||
|
- this.listenersToAdd.add(listener);
|
||||||
|
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
|
||||||
|
} else {
|
||||||
|
this.listeners.add(listener);
|
||||||
|
}
|
||||||
|
@@ -41,7 +41,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
@Override
|
||||||
|
public void unregister(GameEventListener listener) {
|
||||||
|
if (this.processing) {
|
||||||
|
- this.listenersToRemove.add(listener);
|
||||||
|
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
|
||||||
|
} else {
|
||||||
|
this.listeners.remove(listener);
|
||||||
|
}
|
||||||
|
@@ -58,7 +58,7 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
GameEventListener gameEventListener = iterator.next();
|
||||||
|
- if (this.listenersToRemove.remove(gameEventListener)) {
|
||||||
|
+ if (false) { // petal - disallow concurrent modification
|
||||||
|
iterator.remove();
|
||||||
|
} else {
|
||||||
|
Optional<Vec3> optional = getPostableListenerPosition(this.level, pos, gameEventListener);
|
||||||
|
@@ -72,6 +72,8 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
this.processing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // petal start
|
||||||
|
+ /*
|
||||||
|
if (!this.listenersToAdd.isEmpty()) {
|
||||||
|
this.listeners.addAll(this.listenersToAdd);
|
||||||
|
this.listenersToAdd.clear();
|
||||||
|
@@ -81,6 +83,8 @@ public class EuclideanGameEventDispatcher implements GameEventDispatcher {
|
||||||
|
this.listeners.removeAll(this.listenersToRemove);
|
||||||
|
this.listenersToRemove.clear();
|
||||||
|
}
|
||||||
|
+ */
|
||||||
|
+ // petal end
|
||||||
|
|
||||||
|
return bl;
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
||||||
|
index e5601afe8b739da518f36ae306f5e0cb252238f0..bc8f04424c5e8c416d6988f0e06d8cadbb400ca7 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
|
||||||
|
@@ -12,4 +12,10 @@ public interface GameEventListener {
|
||||||
|
int getListenerRadius();
|
||||||
|
|
||||||
|
boolean handleGameEvent(ServerLevel world, GameEvent.Message event);
|
||||||
|
+
|
||||||
|
+ // petal start - add check for seeing if this listener cares about an event
|
||||||
|
+ default boolean listensToEvent(net.minecraft.world.level.gameevent.GameEvent gameEvent, net.minecraft.world.level.gameevent.GameEvent.Context context) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ // petal end
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
||||||
|
index e45f54534bbf054eaf0008546ff459d4c11ddd50..e49d0d1c2a539fcd7e75262c4010475193964287 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
|
||||||
|
@@ -162,6 +162,13 @@ public class VibrationListener implements GameEventListener {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // petal start
|
||||||
|
+ @Override
|
||||||
|
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
|
||||||
|
+ return this.receivingEvent == null && gameEvent.is(this.config.getListenableEvents());
|
||||||
|
+ }
|
||||||
|
+ // petal end
|
||||||
|
+
|
||||||
|
public interface VibrationListenerConfig {
|
||||||
|
|
||||||
|
default TagKey<GameEvent> getListenableEvents() {
|
||||||
59
patches/removed/0008-Reduce-sensor-work.patch
Normal file
59
patches/removed/0008-Reduce-sensor-work.patch
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: peaches94 <peachescu94@gmail.com>
|
||||||
|
Date: Sun, 10 Jul 2022 15:44:38 -0500
|
||||||
|
Subject: [PATCH] Reduce sensor work
|
||||||
|
|
||||||
|
Original code by Bloom-host, licensed under GNU General Public License v3.0
|
||||||
|
You can find the original code on https://github.com/Bloom-host/Petal
|
||||||
|
|
||||||
|
this patch is focused around the sensors used for ai
|
||||||
|
delete the line of sight cache less often and use a faster nearby comparison
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
index ba673b7e5ae1084caa6b23763c9a83aac60269bb..9d824c56914292810091b358ff7d718add617f21 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
|
@@ -1012,20 +1012,22 @@ public abstract class LivingEntity extends Entity {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
||||||
|
+ // petal start - only do itemstack lookup if we need to
|
||||||
|
+ //ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
|
||||||
|
EntityType<?> entitytypes = entity.getType();
|
||||||
|
|
||||||
|
// Purpur start
|
||||||
|
- if (entitytypes == EntityType.SKELETON && itemstack.is(Items.SKELETON_SKULL)) {
|
||||||
|
+ if (entitytypes == EntityType.SKELETON && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.SKELETON_SKULL)) {
|
||||||
|
d0 *= entity.level.purpurConfig.skeletonHeadVisibilityPercent;
|
||||||
|
}
|
||||||
|
- else if (entitytypes == EntityType.ZOMBIE && itemstack.is(Items.ZOMBIE_HEAD)) {
|
||||||
|
+ else if (entitytypes == EntityType.ZOMBIE && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.ZOMBIE_HEAD)) {
|
||||||
|
d0 *= entity.level.purpurConfig.zombieHeadVisibilityPercent;
|
||||||
|
}
|
||||||
|
- else if (entitytypes == EntityType.CREEPER && itemstack.is(Items.CREEPER_HEAD)) {
|
||||||
|
+ else if (entitytypes == EntityType.CREEPER && this.getItemBySlot(EquipmentSlot.HEAD).is(Items.CREEPER_HEAD)) {
|
||||||
|
d0 *= entity.level.purpurConfig.creeperHeadVisibilityPercent;
|
||||||
|
}
|
||||||
|
// Purpur end
|
||||||
|
+ // petal end
|
||||||
|
|
||||||
|
// Purpur start
|
||||||
|
if (entity instanceof LivingEntity entityliving) {
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
index d5e3bd662da349fc2ee58c7800d79c60300f33b3..0981873ee37fc839035b8398bac03d15adecb301 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||||
|
@@ -884,10 +884,10 @@ public abstract class Mob extends LivingEntity {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Paper end
|
||||||
|
+ int i = this.level.getServer().getTickCount() + this.getId(); // petal - move up
|
||||||
|
//this.level.getProfiler().push("sensing"); // Purpur
|
||||||
|
- this.sensing.tick();
|
||||||
|
+ if (i % 10 == 0) this.sensing.tick(); // petal - only refresh line of sight cache every half second
|
||||||
|
//this.level.getProfiler().pop(); // Purpur
|
||||||
|
- int i = this.level.getServer().getTickCount() + this.getId();
|
||||||
|
|
||||||
|
if (i % 2 != 0 && this.tickCount > 1) {
|
||||||
|
//this.level.getProfiler().push("targetSelector"); // Purpur
|
||||||
@@ -1083,7 +1083,7 @@ index 6c27b22dd1d497687c0f4d3835e34149bcf952c1..445f21c3764d148de937f558e3f087ae
|
|||||||
|
|
||||||
public static Direction getNearest(double x, double y, double z) {
|
public static Direction getNearest(double x, double y, double z) {
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
index 92e7ba78e18efb8263475ecc076bc49e88b85e84..2a9219e0139670674319a7cf17ad664582b42715 100644
|
index 571a1cbee376032b6b9f36c9fe3f9199a3ad3197..df014d5b1b2d3b1d0e7a0b9eedb3c19ee693b836 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -227,6 +227,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
@@ -227,6 +227,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||||
@@ -1468,7 +1468,7 @@ index bef8f4d080fb6067f87b9df986ac33f7003c2a84..a727875f6db8d9950d1d9ada67dd3948
|
|||||||
public InteractionResult interact(Player player, InteractionHand hand) {
|
public InteractionResult interact(Player player, InteractionHand hand) {
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
index 9fe6d0700f8f4d4cc018bcb4f33fffaa5f51a1d9..9d824c56914292810091b358ff7d718add617f21 100644
|
index 1fc877194950ee754e9ffdbe3ff9b80bb316560f..ba673b7e5ae1084caa6b23763c9a83aac60269bb 100644
|
||||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
@@ -577,11 +577,11 @@ public abstract class LivingEntity extends Entity {
|
@@ -577,11 +577,11 @@ public abstract class LivingEntity extends Entity {
|
||||||
@@ -1494,7 +1494,7 @@ index 9fe6d0700f8f4d4cc018bcb4f33fffaa5f51a1d9..9d824c56914292810091b358ff7d718a
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2552,6 +2552,8 @@ public abstract class LivingEntity extends Entity {
|
@@ -2550,6 +2550,8 @@ public abstract class LivingEntity extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateSwingTime() {
|
protected void updateSwingTime() {
|
||||||
@@ -1503,7 +1503,7 @@ index 9fe6d0700f8f4d4cc018bcb4f33fffaa5f51a1d9..9d824c56914292810091b358ff7d718a
|
|||||||
int i = this.getCurrentSwingDuration();
|
int i = this.getCurrentSwingDuration();
|
||||||
|
|
||||||
if (this.swinging) {
|
if (this.swinging) {
|
||||||
@@ -3531,6 +3533,8 @@ public abstract class LivingEntity extends Entity {
|
@@ -3529,6 +3531,8 @@ public abstract class LivingEntity extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFallFlying() {
|
private void updateFallFlying() {
|
||||||
@@ -196,10 +196,10 @@ index ec587cf6592a1dc0d90d6f54af1bdfab97aec7c6..0afd56a8b27fce044f7d43b1e4f86b61
|
|||||||
|
|
||||||
public static double lengthSquared(double a, double b, double c) {
|
public static double lengthSquared(double a, double b, double c) {
|
||||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d63315818f54 100644
|
index ba673b7e5ae1084caa6b23763c9a83aac60269bb..b163ad5fb6fea59982e26fdbd4dd5b5dcb4350a5 100644
|
||||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||||
@@ -1532,7 +1532,7 @@ public abstract class LivingEntity extends Entity {
|
@@ -1530,7 +1530,7 @@ public abstract class LivingEntity extends Entity {
|
||||||
if (this instanceof ServerPlayer) {
|
if (this instanceof ServerPlayer) {
|
||||||
CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, source, f1, amount, flag);
|
CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, source, f1, amount, flag);
|
||||||
if (f2 > 0.0F && f2 < 3.4028235E37F) {
|
if (f2 > 0.0F && f2 < 3.4028235E37F) {
|
||||||
@@ -208,7 +208,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2100,9 +2100,9 @@ public abstract class LivingEntity extends Entity {
|
@@ -2098,9 +2098,9 @@ public abstract class LivingEntity extends Entity {
|
||||||
|
|
||||||
if (f3 > 0.0F && f3 < 3.4028235E37F) {
|
if (f3 > 0.0F && f3 < 3.4028235E37F) {
|
||||||
if (this instanceof ServerPlayer) {
|
if (this instanceof ServerPlayer) {
|
||||||
@@ -220,7 +220,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2214,9 +2214,9 @@ public abstract class LivingEntity extends Entity {
|
@@ -2212,9 +2212,9 @@ public abstract class LivingEntity extends Entity {
|
||||||
float f3 = (float) -event.getDamage(DamageModifier.RESISTANCE);
|
float f3 = (float) -event.getDamage(DamageModifier.RESISTANCE);
|
||||||
if (f3 > 0.0F && f3 < 3.4028235E37F) {
|
if (f3 > 0.0F && f3 < 3.4028235E37F) {
|
||||||
if (this instanceof ServerPlayer) {
|
if (this instanceof ServerPlayer) {
|
||||||
@@ -232,7 +232,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2248,10 +2248,10 @@ public abstract class LivingEntity extends Entity {
|
@@ -2246,10 +2246,10 @@ public abstract class LivingEntity extends Entity {
|
||||||
float f2 = absorptionModifier;
|
float f2 = absorptionModifier;
|
||||||
|
|
||||||
if (f2 > 0.0F && f2 < 3.4028235E37F && this instanceof net.minecraft.world.entity.player.Player) {
|
if (f2 > 0.0F && f2 < 3.4028235E37F && this instanceof net.minecraft.world.entity.player.Player) {
|
||||||
@@ -245,7 +245,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Purpur start
|
// Purpur start
|
||||||
@@ -2273,7 +2273,7 @@ public abstract class LivingEntity extends Entity {
|
@@ -2271,7 +2271,7 @@ public abstract class LivingEntity extends Entity {
|
||||||
// PAIL: Be sure to drag all this code from the EntityHuman subclass each update.
|
// PAIL: Be sure to drag all this code from the EntityHuman subclass each update.
|
||||||
((net.minecraft.world.entity.player.Player) this).causeFoodExhaustion(damagesource.getFoodExhaustion(), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.DAMAGED); // CraftBukkit - EntityExhaustionEvent
|
((net.minecraft.world.entity.player.Player) this).causeFoodExhaustion(damagesource.getFoodExhaustion(), org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.DAMAGED); // CraftBukkit - EntityExhaustionEvent
|
||||||
if (f < 3.4028235E37F) {
|
if (f < 3.4028235E37F) {
|
||||||
@@ -254,7 +254,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
@@ -2295,7 +2295,7 @@ public abstract class LivingEntity extends Entity {
|
@@ -2293,7 +2293,7 @@ public abstract class LivingEntity extends Entity {
|
||||||
CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, damagesource, f, originalDamage, true);
|
CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((ServerPlayer) this, damagesource, f, originalDamage, true);
|
||||||
f2 = (float) -event.getDamage(DamageModifier.BLOCKING);
|
f2 = (float) -event.getDamage(DamageModifier.BLOCKING);
|
||||||
if (f2 > 0.0F && f2 < 3.4028235E37F) {
|
if (f2 > 0.0F && f2 < 3.4028235E37F) {
|
||||||
@@ -263,7 +263,7 @@ index 9d824c56914292810091b358ff7d718add617f21..4f3cce05807715b978792ffa28f2d633
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3100,13 +3100,13 @@ public abstract class LivingEntity extends Entity {
|
@@ -3098,13 +3098,13 @@ public abstract class LivingEntity extends Entity {
|
||||||
//this.level.getProfiler().push("rangeChecks"); // Purpur
|
//this.level.getProfiler().push("rangeChecks"); // Purpur
|
||||||
|
|
||||||
// Paper start - stop large pitch and yaw changes from crashing the server
|
// Paper start - stop large pitch and yaw changes from crashing the server
|
||||||
@@ -445,7 +445,7 @@ index a5d3aa309d3fdaab9e0fea2dfb91a080a3ac1193..384733b2b0bc7c5108ebdc725c0d1354
|
|||||||
|
|
||||||
private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) {
|
private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) {
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
index bdf67c916fe435f3bd04a61cce6db93c606515ce..f01dd420e2ff4f87b00682681a4f7dbf05955d24 100644
|
index 620173eef4c2f30a97a4c2f8049ea01fcc60d0b2..1ef5f03a332e832817be132bbbf3ac1021f085d1 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
@@ -53,6 +53,10 @@ import net.minecraft.world.level.material.Fluids;
|
@@ -53,6 +53,10 @@ import net.minecraft.world.level.material.Fluids;
|
||||||
@@ -459,7 +459,7 @@ index bdf67c916fe435f3bd04a61cce6db93c606515ce..f01dd420e2ff4f87b00682681a4f7dbf
|
|||||||
|
|
||||||
public class LevelChunk extends ChunkAccess {
|
public class LevelChunk extends ChunkAccess {
|
||||||
|
|
||||||
@@ -957,7 +961,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -932,7 +936,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
if (this.needsDecoration) {
|
if (this.needsDecoration) {
|
||||||
//try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper // Purpur
|
//try (co.aikar.timings.Timing ignored = this.level.timings.chunkLoadPopulate.startTiming()) { // Paper // Purpur
|
||||||
this.needsDecoration = false;
|
this.needsDecoration = false;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: nostalgic853 <yuu8583@proton.me>
|
From: nostalgic853 <yuu8583@proton.me>
|
||||||
Date: Mon, 24 Oct 2022 23:28:07 +0800
|
Date: Tue, 25 Oct 2022 01:29:25 +0800
|
||||||
Subject: [PATCH] Revert purpur "Remove Timings"
|
Subject: [PATCH] Revert purpur "Remove Timings"
|
||||||
|
|
||||||
This reverts commit 0fb6171d
|
This reverts commit 0fb6171d
|
||||||
@@ -510,7 +510,7 @@ index 383045ae681d5366761c807a0032156203cdf9c9..443aa5012152cb7969147dbbeba259e1
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
index 3c99de7bc5b3c5159ad76f63d67877756f152385..a2a4965aec45f3ff83703b636e46f5c545cfb48e 100644
|
index 3203b953709ca7cb9172f5912a922131ad7ec9eb..a2a4965aec45f3ff83703b636e46f5c545cfb48e 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||||
@@ -606,20 +606,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -606,20 +606,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
@@ -542,42 +542,12 @@ index 3c99de7bc5b3c5159ad76f63d67877756f152385..a2a4965aec45f3ff83703b636e46f5c5
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasWork() {
|
public boolean hasWork() {
|
||||||
@@ -1237,55 +1237,26 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -1239,24 +1239,24 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
entity.tracker = null; // Paper - We're no longer tracked
|
|
||||||
}
|
|
||||||
|
|
||||||
- // petal start - multithreaded tracker
|
|
||||||
- private @Nullable host.bloom.tracker.MultithreadedTracker multithreadedTracker;
|
|
||||||
- private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
|
||||||
- private boolean tracking = false;
|
|
||||||
-
|
|
||||||
- public void runOnTrackerMainThread(final Runnable runnable) {
|
|
||||||
- if (this.tracking) {
|
|
||||||
- this.trackerMainThreadTasks.add(runnable);
|
|
||||||
- } else {
|
|
||||||
- runnable.run();
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
// Paper start - optimised tracker
|
// Paper start - optimised tracker
|
||||||
private final void processTrackQueue() {
|
private final void processTrackQueue() {
|
||||||
- if (true) {
|
|
||||||
- if (this.multithreadedTracker == null) {
|
|
||||||
- this.multithreadedTracker = new host.bloom.tracker.MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.trackerMainThreadTasks);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- this.tracking = true;
|
|
||||||
- try {
|
|
||||||
- this.multithreadedTracker.tick();
|
|
||||||
- } finally {
|
|
||||||
- this.tracking = false;
|
|
||||||
- }
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
- // petal end
|
|
||||||
-
|
|
||||||
this.level.timings.tracker1.startTiming();
|
|
||||||
- //this.level.timings.tracker1.startTiming(); // Purpur
|
- //this.level.timings.tracker1.startTiming(); // Purpur
|
||||||
|
+ this.level.timings.tracker1.startTiming();
|
||||||
try {
|
try {
|
||||||
for (TrackedEntity tracker : this.entityMap.values()) {
|
for (TrackedEntity tracker : this.entityMap.values()) {
|
||||||
// update tracker entry
|
// update tracker entry
|
||||||
@@ -601,7 +571,7 @@ index 3c99de7bc5b3c5159ad76f63d67877756f152385..a2a4965aec45f3ff83703b636e46f5c5
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Paper end - optimised tracker
|
// Paper end - optimised tracker
|
||||||
@@ -1300,7 +1271,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -1271,7 +1271,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
List<ServerPlayer> list = Lists.newArrayList();
|
List<ServerPlayer> list = Lists.newArrayList();
|
||||||
List<ServerPlayer> list1 = this.level.players();
|
List<ServerPlayer> list1 = this.level.players();
|
||||||
ObjectIterator objectiterator = this.entityMap.values().iterator();
|
ObjectIterator objectiterator = this.entityMap.values().iterator();
|
||||||
@@ -610,7 +580,7 @@ index 3c99de7bc5b3c5159ad76f63d67877756f152385..a2a4965aec45f3ff83703b636e46f5c5
|
|||||||
|
|
||||||
ChunkMap.TrackedEntity playerchunkmap_entitytracker;
|
ChunkMap.TrackedEntity playerchunkmap_entitytracker;
|
||||||
|
|
||||||
@@ -1325,17 +1296,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -1296,17 +1296,17 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
playerchunkmap_entitytracker.serverEntity.sendChanges();
|
playerchunkmap_entitytracker.serverEntity.sendChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,48 +601,6 @@ index 3c99de7bc5b3c5159ad76f63d67877756f152385..a2a4965aec45f3ff83703b636e46f5c5
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1491,11 +1462,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
|
|
||||||
public class TrackedEntity {
|
|
||||||
|
|
||||||
- public final ServerEntity serverEntity; // petal -> public
|
|
||||||
- public final Entity entity; // petal -> public
|
|
||||||
+ final ServerEntity serverEntity;
|
|
||||||
+ final Entity entity;
|
|
||||||
private final int range;
|
|
||||||
SectionPos lastSectionPos;
|
|
||||||
- public final Set<ServerPlayerConnection> seenBy = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new ReferenceOpenHashSet<>()); // Paper - optimise map impl // petal - sync
|
|
||||||
+ public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
|
|
||||||
|
|
||||||
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
|
|
||||||
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
|
|
||||||
@@ -1507,7 +1478,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
// Paper start - use distance map to optimise tracker
|
|
||||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;
|
|
||||||
|
|
||||||
- public final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) { // petal -> public
|
|
||||||
+ final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) {
|
|
||||||
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
|
|
||||||
this.lastTrackerCandidates = newTrackerCandidates;
|
|
||||||
|
|
||||||
@@ -1579,7 +1550,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePlayer(ServerPlayer player) {
|
|
||||||
- //org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot // petal - we can remove async too
|
|
||||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
|
|
||||||
if (this.seenBy.remove(player.connection)) {
|
|
||||||
this.serverEntity.removePairing(player);
|
|
||||||
}
|
|
||||||
@@ -1587,7 +1558,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePlayer(ServerPlayer player) {
|
|
||||||
- //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot // petal - we can update async
|
|
||||||
+ org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
|
|
||||||
if (player != this.entity) {
|
|
||||||
// Paper start - remove allocation of Vec3D here
|
|
||||||
// Vec3 vec3d = player.position().subtract(this.entity.position());
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||||
index cd5533c3c53215c9cc4be0b9097d76efbf5bd0c1..7266e6703d5cd0fea90ec88c74a7d4567f2420ae 100644
|
index cd5533c3c53215c9cc4be0b9097d76efbf5bd0c1..7266e6703d5cd0fea90ec88c74a7d4567f2420ae 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||||
@@ -869,7 +797,7 @@ index cd5533c3c53215c9cc4be0b9097d76efbf5bd0c1..7266e6703d5cd0fea90ec88c74a7d456
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
index 2a9219e0139670674319a7cf17ad664582b42715..55fe8b0f21f00b02e78257a64fd8d63980d50995 100644
|
index df014d5b1b2d3b1d0e7a0b9eedb3c19ee693b836..55fe8b0f21f00b02e78257a64fd8d63980d50995 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -227,13 +227,6 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
@@ -227,13 +227,6 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||||
@@ -1191,14 +1119,6 @@ index 2a9219e0139670674319a7cf17ad664582b42715..55fe8b0f21f00b02e78257a64fd8d639
|
|||||||
// Paper - rewrite chunk system - entity saving moved into ChunkHolder
|
// Paper - rewrite chunk system - entity saving moved into ChunkHolder
|
||||||
|
|
||||||
} else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system
|
} else if (close) { chunkproviderserver.close(false); } // Paper - rewrite chunk system
|
||||||
@@ -1710,7 +1703,6 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
||||||
if (chunk != null) {
|
|
||||||
for (int j2 = k; j2 <= j1; ++j2) {
|
|
||||||
flag |= chunk.getEventDispatcher(j2).walkListeners(event, emitterPos, emitter, (gameeventlistener, vec3d1) -> {
|
|
||||||
- if (!gameeventlistener.listensToEvent(event, emitter)) return; // petal - if they don't listen, ignore
|
|
||||||
(gameeventlistener.handleEventsImmediately() ? list : this.gameEventMessages).add(new GameEvent.Message(event, emitterPos, emitter, gameeventlistener, vec3d1));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
index 66c632f9a824e705420b9bb86de294f0e7305c50..4c5d7f00b68e4ec103a5841beaccfbdbef30f130 100644
|
index 66c632f9a824e705420b9bb86de294f0e7305c50..4c5d7f00b68e4ec103a5841beaccfbdbef30f130 100644
|
||||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||||
@@ -1429,7 +1349,7 @@ index bca69d595ef0f18a5910cbd6f7e6f742830a0800..386ed2c102aaa3ec68e828e20fff6bfe
|
|||||||
if (entityhuman != null) {
|
if (entityhuman != null) {
|
||||||
double d2 = entityhuman.distanceToSqr(d0, (double) i, d1);
|
double d2 = entityhuman.distanceToSqr(d0, (double) i, d1);
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e2ab7eef7 100644
|
index 1ef5f03a332e832817be132bbbf3ac1021f085d1..636c98d04eb4e14eab1fa208d9cb097e2ab7eef7 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
@@ -53,10 +53,6 @@ import net.minecraft.world.level.material.Fluids;
|
@@ -53,10 +53,6 @@ import net.minecraft.world.level.material.Fluids;
|
||||||
@@ -1443,72 +1363,7 @@ index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e
|
|||||||
|
|
||||||
public class LevelChunk extends ChunkAccess {
|
public class LevelChunk extends ChunkAccess {
|
||||||
|
|
||||||
@@ -88,18 +84,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -934,9 +930,9 @@ public class LevelChunk extends ChunkAccess {
|
||||||
private Supplier<ChunkHolder.FullChunkStatus> fullStatus;
|
|
||||||
@Nullable
|
|
||||||
private LevelChunk.PostLoadProcessor postLoad;
|
|
||||||
- // petal start
|
|
||||||
- private final GameEventDispatcher[] gameEventDispatcherSections;
|
|
||||||
- private static final int GAME_EVENT_DISPATCHER_RADIUS = 2;
|
|
||||||
-
|
|
||||||
- private static int getGameEventSectionIndex(int sectionIndex) {
|
|
||||||
- return sectionIndex + GAME_EVENT_DISPATCHER_RADIUS;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- private static int getGameEventSectionLength(int sectionCount) {
|
|
||||||
- return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
|
|
||||||
- }
|
|
||||||
- // petal end
|
|
||||||
+ private final Int2ObjectMap<GameEventDispatcher> gameEventDispatcherSections;
|
|
||||||
private final LevelChunkTicks<Block> blockTicks;
|
|
||||||
private final LevelChunkTicks<Fluid> fluidTicks;
|
|
||||||
|
|
||||||
@@ -128,7 +113,7 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
this.tickersInLevel = Maps.newHashMap();
|
|
||||||
this.clientLightReady = false;
|
|
||||||
this.level = (ServerLevel) world; // CraftBukkit - type
|
|
||||||
- this.gameEventDispatcherSections = new GameEventDispatcher[getGameEventSectionLength(this.getSectionsCount())]; // petal
|
|
||||||
+ this.gameEventDispatcherSections = new Int2ObjectOpenHashMap();
|
|
||||||
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
|
|
||||||
int j = aheightmap_type.length;
|
|
||||||
|
|
||||||
@@ -461,23 +446,9 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
if (world instanceof ServerLevel) {
|
|
||||||
ServerLevel worldserver = (ServerLevel) world;
|
|
||||||
|
|
||||||
- // petal start
|
|
||||||
- int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
|
|
||||||
-
|
|
||||||
- // drop game events that are too far away (32 blocks) from loaded sections
|
|
||||||
- // this matches the highest radius of game events in the game
|
|
||||||
- if (sectionIndex < 0 || sectionIndex >= this.gameEventDispatcherSections.length) {
|
|
||||||
- return GameEventDispatcher.NOOP;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- var dispatcher = this.gameEventDispatcherSections[sectionIndex];
|
|
||||||
-
|
|
||||||
- if (dispatcher == null) {
|
|
||||||
- dispatcher = this.gameEventDispatcherSections[sectionIndex] = new EuclideanGameEventDispatcher(worldserver);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return dispatcher;
|
|
||||||
- // petal end
|
|
||||||
+ return (GameEventDispatcher) this.gameEventDispatcherSections.computeIfAbsent(ySectionCoord, (j) -> {
|
|
||||||
+ return new EuclideanGameEventDispatcher(worldserver);
|
|
||||||
+ });
|
|
||||||
} else {
|
|
||||||
return super.getEventDispatcher(ySectionCoord);
|
|
||||||
}
|
|
||||||
@@ -841,7 +812,7 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
|
|
||||||
gameeventdispatcher.unregister(gameeventlistener);
|
|
||||||
if (gameeventdispatcher.isEmpty()) {
|
|
||||||
- this.gameEventDispatcherSections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(i))] = null; // petal
|
|
||||||
+ this.gameEventDispatcherSections.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -959,9 +930,9 @@ public class LevelChunk extends ChunkAccess {
|
|
||||||
this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system
|
this.chunkHolder.getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system
|
||||||
|
|
||||||
if (this.needsDecoration) {
|
if (this.needsDecoration) {
|
||||||
@@ -1520,7 +1375,7 @@ index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e
|
|||||||
random.setSeed(this.level.getSeed());
|
random.setSeed(this.level.getSeed());
|
||||||
long xRand = random.nextLong() / 2L * 2L + 1L;
|
long xRand = random.nextLong() / 2L * 2L + 1L;
|
||||||
long zRand = random.nextLong() / 2L * 2L + 1L;
|
long zRand = random.nextLong() / 2L * 2L + 1L;
|
||||||
@@ -979,7 +950,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -954,7 +950,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(this.bukkitChunk));
|
server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(this.bukkitChunk));
|
||||||
@@ -1529,7 +1384,7 @@ index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1321,10 +1292,10 @@ public class LevelChunk extends ChunkAccess {
|
@@ -1296,10 +1292,10 @@ public class LevelChunk extends ChunkAccess {
|
||||||
|
|
||||||
if (LevelChunk.this.isTicking(blockposition)) {
|
if (LevelChunk.this.isTicking(blockposition)) {
|
||||||
try {
|
try {
|
||||||
@@ -1543,7 +1398,7 @@ index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e
|
|||||||
BlockState iblockdata = LevelChunk.this.getBlockState(blockposition);
|
BlockState iblockdata = LevelChunk.this.getBlockState(blockposition);
|
||||||
|
|
||||||
if (this.blockEntity.getType().isValid(iblockdata)) {
|
if (this.blockEntity.getType().isValid(iblockdata)) {
|
||||||
@@ -1335,7 +1306,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -1310,7 +1306,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
LevelChunk.LOGGER.warn("Block entity {} @ {} state {} invalid for ticking:", new Object[]{LogUtils.defer(this::getType), LogUtils.defer(this::getPos), iblockdata});
|
LevelChunk.LOGGER.warn("Block entity {} @ {} state {} invalid for ticking:", new Object[]{LogUtils.defer(this::getType), LogUtils.defer(this::getPos), iblockdata});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1552,7 +1407,7 @@ index f01dd420e2ff4f87b00682681a4f7dbf05955d24..636c98d04eb4e14eab1fa208d9cb097e
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
if (throwable instanceof ThreadDeath) throw throwable; // Paper
|
if (throwable instanceof ThreadDeath) throw throwable; // Paper
|
||||||
// Paper start - Prevent tile entity and entity crashes
|
// Paper start - Prevent tile entity and entity crashes
|
||||||
@@ -1346,7 +1317,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -1321,7 +1317,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
// Paper end
|
// Paper end
|
||||||
// Spigot start
|
// Spigot start
|
||||||
} finally {
|
} finally {
|
||||||
Reference in New Issue
Block a user