mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-22 08:29:28 +00:00
688 lines
35 KiB
Diff
688 lines
35 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: BuildTools <unconfigured@null.spigotmc.org>
|
|
Date: Wed, 4 Jan 2023 11:37:44 +0800
|
|
Subject: [PATCH] Hearse: Async entity ai
|
|
|
|
Original license:
|
|
Original project: https://github.com/NaturalCodeClub/Hearse
|
|
|
|
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..fe4d76875462ac9d408c972b968647af78f2ed14 100644
|
|
--- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
|
+++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
|
|
@@ -94,7 +94,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
return 1.0 - ((double)this.indexMap.size() / (double)this.listSize);
|
|
}
|
|
|
|
- public int createRawIterator() {
|
|
+ public synchronized int createRawIterator() {
|
|
if (this.allowSafeIteration()) {
|
|
++this.iteratorCount;
|
|
}
|
|
@@ -105,7 +105,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
}
|
|
|
|
- public int advanceRawIterator(final int index) {
|
|
+ public synchronized int advanceRawIterator(final int index) {
|
|
final E[] elements = this.listElements;
|
|
int ret = index + 1;
|
|
for (int len = this.listSize; ret < len; ++ret) {
|
|
@@ -117,7 +117,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
return -1;
|
|
}
|
|
|
|
- public void finishRawIterator() {
|
|
+ public synchronized void finishRawIterator() {
|
|
if (this.allowSafeIteration() && --this.iteratorCount == 0) {
|
|
if (this.getFragFactor() >= this.maxFragFactor) {
|
|
this.defrag();
|
|
@@ -125,7 +125,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
}
|
|
|
|
- public boolean remove(final E element) {
|
|
+ public synchronized boolean remove(final E element) {
|
|
final int index = this.indexMap.removeInt(element);
|
|
if (index >= 0) {
|
|
if (this.firstInvalidIndex < 0 || index < this.firstInvalidIndex) {
|
|
@@ -144,11 +144,11 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
return false;
|
|
}
|
|
|
|
- public boolean contains(final E element) {
|
|
+ public synchronized boolean contains(final E element) {
|
|
return this.indexMap.containsKey(element);
|
|
}
|
|
|
|
- public boolean add(final E element) {
|
|
+ public synchronized boolean add(final E element) {
|
|
final int listSize = this.listSize;
|
|
|
|
final int previous = this.indexMap.putIfAbsent(element, listSize);
|
|
@@ -223,30 +223,30 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
//this.check();
|
|
}
|
|
|
|
- public E rawGet(final int index) {
|
|
+ public synchronized E rawGet(final int index) {
|
|
return this.listElements[index];
|
|
}
|
|
|
|
- public int size() {
|
|
+ public synchronized int size() {
|
|
// always returns the correct amount - listSize can be different
|
|
return this.indexMap.size();
|
|
}
|
|
|
|
- public IteratorSafeOrderedReferenceSet.Iterator<E> iterator() {
|
|
+ public synchronized IteratorSafeOrderedReferenceSet.Iterator<E> iterator() {
|
|
return this.iterator(0);
|
|
}
|
|
|
|
- public IteratorSafeOrderedReferenceSet.Iterator<E> iterator(final int flags) {
|
|
+ public synchronized IteratorSafeOrderedReferenceSet.Iterator<E> iterator(final int flags) {
|
|
if (this.allowSafeIteration()) {
|
|
++this.iteratorCount;
|
|
}
|
|
return new BaseIterator<>(this, true, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize);
|
|
}
|
|
|
|
- public java.util.Iterator<E> unsafeIterator() {
|
|
+ public synchronized java.util.Iterator<E> unsafeIterator() {
|
|
return this.unsafeIterator(0);
|
|
}
|
|
- public java.util.Iterator<E> unsafeIterator(final int flags) {
|
|
+ public synchronized java.util.Iterator<E> unsafeIterator(final int flags) {
|
|
return new BaseIterator<>(this, false, (flags & ITERATOR_FLAG_SEE_ADDITIONS) != 0 ? Integer.MAX_VALUE : this.listSize);
|
|
}
|
|
|
|
@@ -273,7 +273,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
|
|
@Override
|
|
- public boolean hasNext() {
|
|
+ public synchronized boolean hasNext() {
|
|
if (this.finished) {
|
|
return false;
|
|
}
|
|
@@ -297,7 +297,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
|
|
@Override
|
|
- public E next() {
|
|
+ public synchronized E next() {
|
|
if (!this.hasNext()) {
|
|
throw new NoSuchElementException();
|
|
}
|
|
@@ -310,7 +310,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
|
|
@Override
|
|
- public void remove() {
|
|
+ public synchronized void remove() {
|
|
final E lastReturned = this.lastReturned;
|
|
if (lastReturned == null) {
|
|
throw new IllegalStateException();
|
|
@@ -320,7 +320,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
|
|
}
|
|
|
|
@Override
|
|
- public void finishedIterating() {
|
|
+ public synchronized void finishedIterating() {
|
|
if (this.finished || !this.canFinish) {
|
|
throw new IllegalStateException();
|
|
}
|
|
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
index f597d65d56964297eeeed6c7e77703764178fee0..b3bcafc8bafe1e4a1a2b690499b91e5316a604f1 100644
|
|
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
|
|
@@ -4,6 +4,7 @@ import com.destroystokyo.paper.util.maplist.EntityList;
|
|
import io.papermc.paper.chunk.system.entity.EntityLookup;
|
|
import io.papermc.paper.util.TickThread;
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
|
|
+import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps;
|
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.server.level.ChunkHolder;
|
|
@@ -34,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 Reference2ObjectMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
|
|
protected final EntityList entities = new EntityList();
|
|
|
|
public ChunkHolder.FullChunkStatus status;
|
|
@@ -61,7 +62,7 @@ public final class ChunkEntitySlices {
|
|
|
|
this.allEntities = new EntityCollectionBySection(this);
|
|
this.hardCollidingEntities = new EntityCollectionBySection(this);
|
|
- this.entitiesByClass = new Reference2ObjectOpenHashMap<>();
|
|
+ this.entitiesByClass = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>());
|
|
|
|
this.status = status;
|
|
}
|
|
@@ -209,7 +210,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
|
|
for (final Iterator<Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection>> iterator =
|
|
- this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) {
|
|
+ this.entitiesByClass.reference2ObjectEntrySet().iterator(); iterator.hasNext();) {
|
|
final Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection> entry = iterator.next();
|
|
|
|
if (entry.getKey().isInstance(entity)) {
|
|
@@ -234,7 +235,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
|
|
for (final Iterator<Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection>> iterator =
|
|
- this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) {
|
|
+ this.entitiesByClass.reference2ObjectEntrySet().iterator(); iterator.hasNext();) {
|
|
final Reference2ObjectMap.Entry<Class<? extends Entity>, EntityCollectionBySection> entry = iterator.next();
|
|
|
|
if (entry.getKey().isInstance(entity)) {
|
|
@@ -312,11 +313,11 @@ public final class ChunkEntitySlices {
|
|
this.storage = (E[])(cap <= 0 ? EMPTY : new Entity[cap]);
|
|
}
|
|
|
|
- public boolean isEmpty() {
|
|
+ public synchronized boolean isEmpty() {
|
|
return this.size == 0;
|
|
}
|
|
|
|
- public int size() {
|
|
+ public synchronized int size() {
|
|
return this.size;
|
|
}
|
|
|
|
@@ -328,7 +329,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public void add(final E entity) {
|
|
+ public synchronized void add(final E entity) {
|
|
final int idx = this.size++;
|
|
if (idx >= this.storage.length) {
|
|
this.resize();
|
|
@@ -338,7 +339,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public int indexOf(final E entity) {
|
|
+ public synchronized int indexOf(final E entity) {
|
|
final E[] storage = this.storage;
|
|
|
|
for (int i = 0, len = Math.min(this.storage.length, this.size); i < len; ++i) {
|
|
@@ -350,7 +351,7 @@ public final class ChunkEntitySlices {
|
|
return -1;
|
|
}
|
|
|
|
- public boolean remove(final E entity) {
|
|
+ public synchronized boolean remove(final E entity) {
|
|
final int idx = this.indexOf(entity);
|
|
if (idx == -1) {
|
|
return false;
|
|
@@ -367,7 +368,7 @@ public final class ChunkEntitySlices {
|
|
return true;
|
|
}
|
|
|
|
- public boolean has(final E entity) {
|
|
+ public synchronized boolean has(final E entity) {
|
|
return this.indexOf(entity) != -1;
|
|
}
|
|
}
|
|
@@ -388,7 +389,7 @@ public final class ChunkEntitySlices {
|
|
this.entitiesBySection = new BasicEntityList[sectionCount];
|
|
}
|
|
|
|
- public void addEntity(final Entity entity, final int sectionIndex) {
|
|
+ public synchronized void addEntity(final Entity entity, final int sectionIndex) {
|
|
BasicEntityList<Entity> list = this.entitiesBySection[sectionIndex];
|
|
|
|
if (list != null && list.has(entity)) {
|
|
@@ -404,7 +405,7 @@ public final class ChunkEntitySlices {
|
|
++this.count;
|
|
}
|
|
|
|
- public void removeEntity(final Entity entity, final int sectionIndex) {
|
|
+ public synchronized void removeEntity(final Entity entity, final int sectionIndex) {
|
|
final BasicEntityList<Entity> list = this.entitiesBySection[sectionIndex];
|
|
|
|
if (list == null || !list.remove(entity)) {
|
|
@@ -419,7 +420,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
|
+ public synchronized void getEntities(final Entity except, final AABB box, final List<Entity> into, final Predicate<? super Entity> predicate) {
|
|
if (this.count == 0) {
|
|
return;
|
|
}
|
|
@@ -457,7 +458,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public void getEntitiesWithEnderDragonParts(final Entity except, final AABB box, final List<Entity> into,
|
|
+ public synchronized void getEntitiesWithEnderDragonParts(final Entity except, final AABB box, final List<Entity> into,
|
|
final Predicate<? super Entity> predicate) {
|
|
if (this.count == 0) {
|
|
return;
|
|
@@ -508,7 +509,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public void getEntitiesWithEnderDragonParts(final Entity except, final Class<?> clazz, final AABB box, final List<Entity> into,
|
|
+ public synchronized void getEntitiesWithEnderDragonParts(final Entity except, final Class<?> clazz, final AABB box, final List<Entity> into,
|
|
final Predicate<? super Entity> predicate) {
|
|
if (this.count == 0) {
|
|
return;
|
|
@@ -559,7 +560,7 @@ public final class ChunkEntitySlices {
|
|
}
|
|
}
|
|
|
|
- public <T extends Entity> void getEntities(final EntityType<?> type, final AABB box, final List<? super T> into,
|
|
+ public synchronized <T extends Entity> void getEntities(final EntityType<?> type, final AABB box, final List<? super T> into,
|
|
final Predicate<? super T> predicate) {
|
|
if (this.count == 0) {
|
|
return;
|
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
index beb7c22cb63021f26c06f91050361e1b25fcc72d..7c3716ff453f0705a67e5cd81776cf84de46ee2a 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -15,6 +15,7 @@ import com.mojang.logging.LogUtils;
|
|
import com.mojang.serialization.DataResult;
|
|
import com.mojang.serialization.JsonOps;
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
+import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
import it.unimi.dsi.fastutil.longs.Long2ByteMap;
|
|
import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
|
|
@@ -25,8 +26,8 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
|
|
import it.unimi.dsi.fastutil.longs.LongIterator;
|
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
|
-import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator;
|
|
-import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
|
+import it.unimi.dsi.fastutil.objects.*;
|
|
+
|
|
import java.io.IOException;
|
|
import java.io.Writer;
|
|
import java.nio.file.Path;
|
|
@@ -52,6 +53,7 @@ import java.util.function.IntSupplier;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Collectors;
|
|
import javax.annotation.Nullable;
|
|
+
|
|
import net.minecraft.CrashReport;
|
|
import net.minecraft.CrashReportCategory;
|
|
import net.minecraft.ReportedException;
|
|
@@ -113,7 +115,6 @@ import org.bukkit.craftbukkit.generator.CustomChunkGenerator;
|
|
import org.bukkit.entity.Player;
|
|
// CraftBukkit end
|
|
|
|
-import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; // Paper
|
|
|
|
public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider {
|
|
|
|
@@ -153,7 +154,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
private final Queue<Runnable> unloadQueue;
|
|
int viewDistance;
|
|
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobDistanceMap; // Paper
|
|
- public final ReferenceOpenHashSet<ChunkHolder> needsChangeBroadcasting = new ReferenceOpenHashSet<>();
|
|
+ public final ReferenceSet<ChunkHolder> needsChangeBroadcasting = ReferenceSets.synchronize(new ReferenceOpenHashSet<>());
|
|
|
|
// Paper - rewrite chunk system
|
|
// Paper start - optimise checkDespawn
|
|
@@ -295,7 +296,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
// Paper - rewrite chunk system
|
|
this.tickingGenerated = new AtomicInteger();
|
|
this.playerMap = new PlayerMap();
|
|
- this.entityMap = new Int2ObjectOpenHashMap();
|
|
+ this.entityMap = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap());
|
|
this.chunkTypeCache = new Long2ByteOpenHashMap();
|
|
this.chunkSaveCooldowns = new Long2LongOpenHashMap();
|
|
this.unloadQueue = Queues.newConcurrentLinkedQueue();
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
index 0ae45cf5a084fd412305e8b2f5dabe608b4eb1c1..686852f5cb6303381c45a673a0daf79a2d3a9dfe 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
@@ -6,12 +6,7 @@ import com.mojang.datafixers.DataFixer;
|
|
import com.mojang.datafixers.util.Either;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
-import java.util.Arrays;
|
|
-import java.util.Collections;
|
|
-import java.util.Iterator;
|
|
-import java.util.List;
|
|
-import java.util.Objects;
|
|
-import java.util.Optional;
|
|
+import java.util.*;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.function.BooleanSupplier;
|
|
@@ -803,7 +798,7 @@ public class ServerChunkCache extends ChunkSource {
|
|
//gameprofilerfiller.popPush("broadcast"); // Purpur
|
|
//this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing // Purpur
|
|
if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) {
|
|
- ReferenceOpenHashSet<ChunkHolder> copy = this.chunkMap.needsChangeBroadcasting.clone();
|
|
+ List<ChunkHolder> copy = new ArrayList<>(this.chunkMap.needsChangeBroadcasting);
|
|
this.chunkMap.needsChangeBroadcasting.clear();
|
|
for (ChunkHolder holder : copy) {
|
|
holder.broadcastChanges(holder.getFullChunkNowUnchecked()); // LevelChunks are NEVER unloaded
|
|
diff --git a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
|
|
index 50a9f33aa31e9273c7c52d4bb2b02f0f884f7ba5..6d94aa3c175345f701ec67175fad3fcde4481041 100644
|
|
--- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
|
|
+++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java
|
|
@@ -10,12 +10,14 @@ import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
+import java.util.concurrent.CopyOnWriteArrayList;
|
|
+import java.util.stream.Collector;
|
|
import java.util.stream.Collectors;
|
|
|
|
public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
|
|
- private final Map<Class<?>, List<T>> byClass = Maps.newHashMap();
|
|
+ private final Map<Class<?>, List<T>> byClass = Maps.newConcurrentMap();
|
|
private final Class<T> baseClass;
|
|
- private final List<T> allInstances = Lists.newArrayList();
|
|
+ private final List<T> allInstances = Lists.newCopyOnWriteArrayList();
|
|
|
|
public ClassInstanceMultiMap(Class<T> elementType) {
|
|
this.baseClass = elementType;
|
|
@@ -58,22 +60,24 @@ public class ClassInstanceMultiMap<T> extends AbstractCollection<T> {
|
|
if (!this.baseClass.isAssignableFrom(type)) {
|
|
throw new IllegalArgumentException("Don't know how to search for " + type);
|
|
} else {
|
|
- List<? extends T> list = this.byClass.computeIfAbsent(type, (typeClass) -> {
|
|
- return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList());
|
|
- });
|
|
- return Collections.unmodifiableCollection(list);
|
|
+ List<? extends T> list = this.byClass.computeIfAbsent(type, (typeClass) -> this.allInstances.stream().filter(typeClass::isInstance).collect(toList()));
|
|
+ return (Collection<S>) Collections.unmodifiableCollection(list);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Iterator<T> iterator() {
|
|
- return (Iterator<T>)(this.allInstances.isEmpty() ? Collections.emptyIterator() : Iterators.unmodifiableIterator(this.allInstances.iterator()));
|
|
+ return this.allInstances.isEmpty() ? Collections.emptyIterator() : Iterators.unmodifiableIterator(this.allInstances.iterator());
|
|
}
|
|
|
|
public List<T> getAllInstances() {
|
|
return ImmutableList.copyOf(this.allInstances);
|
|
}
|
|
|
|
+ public static <T> Collector<T, ?, List<T>> toList() {
|
|
+ return Collectors.toCollection(CopyOnWriteArrayList::new);
|
|
+ }
|
|
+
|
|
@Override
|
|
public int size() {
|
|
return this.allInstances.size();
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
|
index 29fa9ad2223de668c15a5e5b433704b2c4765610..a49247b9007d859928aab21ed05cfa86ad1a13cf 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
|
@@ -23,6 +23,7 @@ import net.minecraft.network.syncher.EntityDataAccessor;
|
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
|
import net.minecraft.network.syncher.SynchedEntityData;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
@@ -216,12 +217,14 @@ public abstract class Mob extends LivingEntity {
|
|
public void inactiveTick() {
|
|
super.inactiveTick();
|
|
boolean isThrottled = gg.pufferfish.pufferfish.PufferfishConfig.throttleInactiveGoalSelectorTick && _pufferfish_inactiveTickDisableCounter++ % 20 != 0; // Pufferfish - throttle inactive goal selector ticking
|
|
- if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking
|
|
- this.goalSelector.tick();
|
|
- }
|
|
- if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority
|
|
- this.targetSelector.tick();
|
|
- }
|
|
+ MinecraftServer.getServer().asyncExecutor.executeWithCallBack(()->{
|
|
+ if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking
|
|
+ this.goalSelector.tick();
|
|
+ }
|
|
+ if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority
|
|
+ this.targetSelector.tick();
|
|
+ }
|
|
+ },()->{});
|
|
}
|
|
// Paper end
|
|
|
|
@@ -877,43 +880,32 @@ public abstract class Mob extends LivingEntity {
|
|
//this.level.getProfiler().push("sensing"); // Purpur
|
|
if (i % 10 == 0) this.sensing.tick(); // petal - only refresh line of sight cache every half second
|
|
//this.level.getProfiler().pop(); // Purpur
|
|
-
|
|
- if (i % 2 != 0 && this.tickCount > 1) {
|
|
- //this.level.getProfiler().push("targetSelector"); // Purpur
|
|
- if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
- this.targetSelector.tickRunningGoals(false);
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- //this.level.getProfiler().push("goalSelector"); // Purpur
|
|
- if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
- this.goalSelector.tickRunningGoals(false);
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- } else {
|
|
- //this.level.getProfiler().push("targetSelector"); // Purpur
|
|
- if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
- this.targetSelector.tick();
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- //this.level.getProfiler().push("goalSelector"); // Purpur
|
|
- if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
- this.goalSelector.tick();
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- }
|
|
-
|
|
- //this.level.getProfiler().push("navigation"); // Purpur
|
|
- this.navigation.tick();
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- //this.level.getProfiler().push("mob tick"); // Purpur
|
|
- this.customServerAiStep();
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- //this.level.getProfiler().push("controls"); // Purpur
|
|
- //this.level.getProfiler().push("move"); // Purpur
|
|
- this.moveControl.tick();
|
|
- //this.level.getProfiler().popPush("look"); // Purpur
|
|
- this.lookControl.tick();
|
|
- //this.level.getProfiler().popPush("jump"); // Purpur
|
|
- this.jumpControl.tick();
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- //this.level.getProfiler().pop(); // Purpur
|
|
- this.sendDebugPackets();
|
|
+ MinecraftServer.getServer().asyncExecutor.executeWithCallBack(() -> {
|
|
+ if (i % 2 != 0 && this.tickCount > 1) {
|
|
+ //this.level.getProfiler().push("targetSelector"); // Purpur
|
|
+ if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
+ this.targetSelector.tickRunningGoals(false);
|
|
+ //this.level.getProfiler().pop(); // Purpur
|
|
+ //this.level.getProfiler().push("goalSelector"); // Purpur
|
|
+ if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
+ this.goalSelector.tickRunningGoals(false);
|
|
+ //this.level.getProfiler().pop(); // Purpur
|
|
+ } else {
|
|
+ //this.level.getProfiler().push("targetSelector"); // Purpur
|
|
+ if (this.targetSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
+ this.targetSelector.tick();
|
|
+ //this.level.getProfiler().pop(); // Purpur
|
|
+ //this.level.getProfiler().push("goalSelector"); // Purpur
|
|
+ if (this.goalSelector.inactiveTick(this.activatedPriority, false)) // Pufferfish - use this to alternate ticking
|
|
+ this.goalSelector.tick();
|
|
+ //this.level.getProfiler().pop(); // Purpur
|
|
+ }
|
|
+ this.navigation.tick();
|
|
+ this.customServerAiStep();
|
|
+ this.moveControl.tick();
|
|
+ this.lookControl.tick();
|
|
+ this.jumpControl.tick();
|
|
+ }, this::sendDebugPackets);
|
|
}
|
|
|
|
protected void sendDebugPackets() {
|
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
|
index 097007c1c25ba55d9916fc820dd1d1149d81f6f4..16eec12db529dd513e0971289a9326652369de58 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java
|
|
@@ -30,11 +30,11 @@ import org.slf4j.Logger;
|
|
public class GossipContainer {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
public static final int DISCARD_THRESHOLD = 2;
|
|
- public final Map<UUID, GossipContainer.EntityGossips> gossips = Maps.newHashMap();
|
|
+ public final Map<UUID, GossipContainer.EntityGossips> gossips = Maps.newConcurrentMap();
|
|
|
|
@VisibleForDebug
|
|
public Map<UUID, Object2IntMap<GossipType>> getGossipEntries() {
|
|
- Map<UUID, Object2IntMap<GossipType>> map = Maps.newHashMap();
|
|
+ Map<UUID, Object2IntMap<GossipType>> map = Maps.newConcurrentMap();
|
|
this.gossips.keySet().forEach((uuid) -> {
|
|
GossipContainer.EntityGossips entityGossips = this.gossips.get(uuid);
|
|
map.put(uuid, entityGossips.entries);
|
|
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
index 2d222e383d48a1a32eebdb722d770b4fc6c0aca7..eb5257fabef397566e784247922fb27e61f96313 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
@@ -274,16 +274,18 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
if (this.getUnhappyCounter() > 0) {
|
|
this.setUnhappyCounter(this.getUnhappyCounter() - 1);
|
|
}
|
|
- if (this.isEffectiveAi()) {
|
|
- if (level.spigotConfig.tickInactiveVillagers) {
|
|
- this.customServerAiStep();
|
|
- } else {
|
|
- this.mobTick(true);
|
|
+ MinecraftServer.getServer().asyncExecutor.executeWithCallBack(()->{
|
|
+ if (this.isEffectiveAi()) {
|
|
+ if (level.spigotConfig.tickInactiveVillagers) {
|
|
+ this.customServerAiStep();
|
|
+ } else {
|
|
+ this.mobTick(true);
|
|
+ }
|
|
}
|
|
- }
|
|
- maybeDecayGossip();
|
|
+ },()->{
|
|
+ maybeDecayGossip();
|
|
+ });
|
|
// Paper end
|
|
-
|
|
super.inactiveTick();
|
|
}
|
|
// Spigot End
|
|
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
|
index d45d832232be5017dde53816191c2b1830a0da32..f73f78e2f7c6e3eae66f7608a92854b3246e153d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
|
+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
|
@@ -8,13 +8,15 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import javax.annotation.Nullable;
|
|
+
|
|
+import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
|
import net.minecraft.util.AbortableIterationConsumer;
|
|
import org.slf4j.Logger;
|
|
|
|
public class EntityLookup<T extends EntityAccess> {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
- private final Int2ObjectMap<T> byId = new Int2ObjectLinkedOpenHashMap<>();
|
|
- private final Map<UUID, T> byUuid = Maps.newHashMap();
|
|
+ private final Int2ObjectMap<T> byId = Int2ObjectMaps.synchronize(new Int2ObjectLinkedOpenHashMap<>());
|
|
+ private final Map<UUID, T> byUuid = Maps.newConcurrentMap();
|
|
|
|
public <U extends T> void getEntities(EntityTypeTest<T, U> filter, AbortableIterationConsumer<U> consumer) {
|
|
for(T entityAccess : this.byId.values()) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
|
index a77985b2dd7137d8eea03909403fc08e89376d73..6bcbbbfc39432076a3d7714ecc2d05d9112d405c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
|
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
|
|
@@ -4,12 +4,8 @@ import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Queues;
|
|
import com.google.common.collect.Sets;
|
|
import com.mojang.logging.LogUtils;
|
|
-import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
+import it.unimi.dsi.fastutil.longs.*;
|
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
|
|
-import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
|
|
-import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
|
-import it.unimi.dsi.fastutil.longs.LongSet;
|
|
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
|
import java.io.IOException;
|
|
import java.io.UncheckedIOException;
|
|
@@ -39,15 +35,15 @@ import org.bukkit.craftbukkit.event.CraftEventFactory;
|
|
public class PersistentEntitySectionManager<T extends EntityAccess> implements AutoCloseable {
|
|
|
|
static final Logger LOGGER = LogUtils.getLogger();
|
|
- final Set<UUID> knownUuids = Sets.newHashSet();
|
|
+ final Set<UUID> knownUuids = Sets.newConcurrentHashSet();
|
|
final LevelCallback<T> callbacks;
|
|
public final EntityPersistentStorage<T> permanentStorage;
|
|
private final EntityLookup<T> visibleEntityStorage = new EntityLookup<>();
|
|
final EntitySectionStorage<T> sectionStorage;
|
|
private final LevelEntityGetter<T> entityGetter;
|
|
- private final Long2ObjectMap<Visibility> chunkVisibility = new Long2ObjectOpenHashMap();
|
|
- private final Long2ObjectMap<PersistentEntitySectionManager.ChunkLoadStatus> chunkLoadStatuses = new Long2ObjectOpenHashMap();
|
|
- private final LongSet chunksToUnload = new LongOpenHashSet();
|
|
+ private final Long2ObjectMap<Visibility> chunkVisibility = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap());
|
|
+ private final Long2ObjectMap<PersistentEntitySectionManager.ChunkLoadStatus> chunkLoadStatuses = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap());
|
|
+ private final LongSet chunksToUnload = LongSets.synchronize(new LongOpenHashSet());
|
|
private final Queue<ChunkEntities<T>> loadingInbox = Queues.newConcurrentLinkedQueue();
|
|
|
|
public PersistentEntitySectionManager(Class<T> entityClass, LevelCallback<T> handler, EntityPersistentStorage<T> dataAccess) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
|
index b1c594dc6a6b8a6c737b99272acab9e7dbd0ed63..4aedee56077159aaf613033b688d2be6833f1ad1 100644
|
|
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
|
+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
|
|
@@ -3,7 +3,10 @@ package net.minecraft.world.level.redstone;
|
|
import com.mojang.logging.LogUtils;
|
|
import java.util.ArrayDeque;
|
|
import java.util.ArrayList;
|
|
+import java.util.Deque;
|
|
import java.util.List;
|
|
+import java.util.concurrent.ConcurrentLinkedDeque;
|
|
+import java.util.concurrent.CopyOnWriteArrayList;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
@@ -16,8 +19,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
private final Level level;
|
|
private final int maxChainedNeighborUpdates;
|
|
- private final ArrayDeque<CollectingNeighborUpdater.NeighborUpdates> stack = new ArrayDeque<>();
|
|
- private final List<CollectingNeighborUpdater.NeighborUpdates> addedThisLayer = new ArrayList<>();
|
|
+ private final Deque<NeighborUpdates> stack = new ConcurrentLinkedDeque<>();
|
|
+ private final List<CollectingNeighborUpdater.NeighborUpdates> addedThisLayer = new CopyOnWriteArrayList<>();
|
|
private int count = 0;
|
|
|
|
public CollectingNeighborUpdater(Level world, int maxChainDepth) {
|
|
@@ -26,22 +29,22 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
|
|
}
|
|
|
|
@Override
|
|
- public void shapeUpdate(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) {
|
|
+ public synchronized void shapeUpdate(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) {
|
|
this.addAndRun(pos, new CollectingNeighborUpdater.ShapeUpdate(direction, neighborState, pos.immutable(), neighborPos.immutable(), flags));
|
|
}
|
|
|
|
@Override
|
|
- public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos sourcePos) {
|
|
+ public synchronized void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos sourcePos) {
|
|
this.addAndRun(pos, new CollectingNeighborUpdater.SimpleNeighborUpdate(pos, sourceBlock, sourcePos.immutable()));
|
|
}
|
|
|
|
@Override
|
|
- public void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
|
+ public synchronized void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
|
this.addAndRun(pos, new CollectingNeighborUpdater.FullNeighborUpdate(state, pos.immutable(), sourceBlock, sourcePos.immutable(), notify));
|
|
}
|
|
|
|
@Override
|
|
- public void updateNeighborsAtExceptFromFacing(BlockPos pos, Block sourceBlock, @Nullable Direction except) {
|
|
+ public synchronized void updateNeighborsAtExceptFromFacing(BlockPos pos, Block sourceBlock, @Nullable Direction except) {
|
|
this.addAndRun(pos, new CollectingNeighborUpdater.MultiNeighborUpdate(pos.immutable(), sourceBlock, except));
|
|
}
|
|
|