Paper/patches/server/2975-fixup-MC-Utils.patch
2024-10-25 11:25:10 -07:00

1338 lines
55 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 21 Oct 2024 12:21:54 -0700
Subject: [PATCH] fixup! MC Utils
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c98d420ea84c10ef4f15d4deb3f04e610ed8548
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
@@ -0,0 +1,117 @@
+package ca.spottedleaf.moonrise.common;
+
+import com.mojang.datafixers.DSL;
+import com.mojang.datafixers.DataFixer;
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.GenerationChunkHolder;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.level.BlockGetter;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.chunk.ChunkAccess;
+import net.minecraft.world.level.chunk.LevelChunk;
+import net.minecraft.world.level.chunk.ProtoChunk;
+import net.minecraft.world.level.chunk.storage.SerializableChunkData;
+import net.minecraft.world.level.entity.EntityTypeTest;
+import net.minecraft.world.phys.AABB;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.function.Predicate;
+
+public interface PlatformHooks {
+ public static PlatformHooks get() {
+ return Holder.INSTANCE;
+ }
+
+ public String getBrand();
+
+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos);
+
+ public Predicate<BlockState> maybeHasLightEmission();
+
+ public boolean hasCurrentlyLoadingChunk();
+
+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder);
+
+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk);
+
+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original);
+
+ public boolean allowAsyncTicketUpdates();
+
+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel);
+
+ public void chunkUnloadFromWorld(final LevelChunk chunk);
+
+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data);
+
+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player);
+
+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player);
+
+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate,
+ final List<Entity> into);
+
+ public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest,
+ final AABB boundingBox, final Predicate<? super T> predicate,
+ final List<? super T> into, final int maxCount);
+
+ public void entityMove(final Entity entity, final long oldSection, final long newSection);
+
+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event);
+
+ public boolean configFixMC224294();
+
+ public boolean configAutoConfigSendDistance();
+
+ public double configPlayerMaxLoadRate();
+
+ public double configPlayerMaxGenRate();
+
+ public double configPlayerMaxSendRate();
+
+ public int configPlayerMaxConcurrentLoads();
+
+ public int configPlayerMaxConcurrentGens();
+
+ public long configAutoSaveInterval(final ServerLevel world);
+
+ public int configMaxAutoSavePerTick(final ServerLevel world);
+
+ public boolean configFixMC159283();
+
+ // support for CB chunk mustNotSave
+ public boolean forceNoSave(final ChunkAccess chunk);
+
+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
+ final int fromVersion, final int toVersion);
+
+ public boolean hasMainChunkLoadHook();
+
+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData);
+
+ public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities);
+
+ public void unloadEntity(final Entity entity);
+
+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk);
+
+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange);
+
+ public static final class Holder {
+ private Holder() {
+ }
+
+ private static final PlatformHooks INSTANCE;
+
+ static {
+ INSTANCE = ServiceLoader.load(PlatformHooks.class, PlatformHooks.class.getClassLoader()).findFirst()
+ .orElseThrow(() -> new RuntimeException("Failed to locate PlatformHooks"));
+ }
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
index ba68998f6ef57b24c72fd833bd7de440de9501cc..7fed43a1e7bcf35c4d7fd3224837a47fedd59860 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java
@@ -13,15 +13,15 @@ import java.util.NoSuchElementException;
*/
public final class EntityList implements Iterable<Entity> {
- protected final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f);
+ private final Int2IntOpenHashMap entityToIndex = new Int2IntOpenHashMap(2, 0.8f);
{
this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE);
}
- protected static final Entity[] EMPTY_LIST = new Entity[0];
+ private static final Entity[] EMPTY_LIST = new Entity[0];
- protected Entity[] entities = EMPTY_LIST;
- protected int count;
+ private Entity[] entities = EMPTY_LIST;
+ private int count;
public int size() {
return this.count;
@@ -94,10 +94,9 @@ public final class EntityList implements Iterable<Entity> {
@Override
public Iterator<Entity> iterator() {
- return new Iterator<Entity>() {
-
- Entity lastRet;
- int current;
+ return new Iterator<>() {
+ private Entity lastRet;
+ private int current;
@Override
public boolean hasNext() {
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java
deleted file mode 100644
index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..0000000000000000000000000000000000000000
--- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package ca.spottedleaf.moonrise.common.list;
-
-import it.unimi.dsi.fastutil.longs.LongIterator;
-import it.unimi.dsi.fastutil.shorts.Short2LongOpenHashMap;
-import java.util.Arrays;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.chunk.GlobalPalette;
-
-public final class IBlockDataList {
-
- private static final GlobalPalette<BlockState> GLOBAL_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY);
-
- // map of location -> (index | (location << 16) | (palette id << 32))
- private final Short2LongOpenHashMap map = new Short2LongOpenHashMap(2, 0.8f);
- {
- this.map.defaultReturnValue(Long.MAX_VALUE);
- }
-
- private static final long[] EMPTY_LIST = new long[0];
-
- private long[] byIndex = EMPTY_LIST;
- private int size;
-
- public static int getLocationKey(final int x, final int y, final int z) {
- return (x & 15) | (((z & 15) << 4)) | ((y & 255) << (4 + 4));
- }
-
- public static BlockState getBlockDataFromRaw(final long raw) {
- return GLOBAL_PALETTE.valueFor((int)(raw >>> 32));
- }
-
- public static int getIndexFromRaw(final long raw) {
- return (int)(raw & 0xFFFF);
- }
-
- public static int getLocationFromRaw(final long raw) {
- return (int)((raw >>> 16) & 0xFFFF);
- }
-
- public static long getRawFromValues(final int index, final int location, final BlockState data) {
- return (long)index | ((long)location << 16) | (((long)GLOBAL_PALETTE.idFor(data)) << 32);
- }
-
- public static long setIndexRawValues(final long value, final int index) {
- return value & ~(0xFFFF) | (index);
- }
-
- public long add(final int x, final int y, final int z, final BlockState data) {
- return this.add(getLocationKey(x, y, z), data);
- }
-
- public long add(final int location, final BlockState data) {
- final long curr = this.map.get((short)location);
-
- if (curr == Long.MAX_VALUE) {
- final int index = this.size++;
- final long raw = getRawFromValues(index, location, data);
- this.map.put((short)location, raw);
-
- if (index >= this.byIndex.length) {
- this.byIndex = Arrays.copyOf(this.byIndex, (int)Math.max(4L, this.byIndex.length * 2L));
- }
-
- this.byIndex[index] = raw;
- return raw;
- } else {
- final int index = getIndexFromRaw(curr);
- final long raw = this.byIndex[index] = getRawFromValues(index, location, data);
-
- this.map.put((short)location, raw);
-
- return raw;
- }
- }
-
- public long remove(final int x, final int y, final int z) {
- return this.remove(getLocationKey(x, y, z));
- }
-
- public long remove(final int location) {
- final long ret = this.map.remove((short)location);
- final int index = getIndexFromRaw(ret);
- if (ret == Long.MAX_VALUE) {
- return ret;
- }
-
- // move the entry at the end to this index
- final int endIndex = --this.size;
- final long end = this.byIndex[endIndex];
- if (index != endIndex) {
- // not empty after this call
- this.map.put((short)getLocationFromRaw(end), setIndexRawValues(end, index));
- }
- this.byIndex[index] = end;
- this.byIndex[endIndex] = 0L;
-
- return ret;
- }
-
- public int size() {
- return this.size;
- }
-
- public long getRaw(final int index) {
- return this.byIndex[index];
- }
-
- public int getLocation(final int index) {
- return getLocationFromRaw(this.getRaw(index));
- }
-
- public BlockState getData(final int index) {
- return getBlockDataFromRaw(this.getRaw(index));
- }
-
- public void clear() {
- this.size = 0;
- this.map.clear();
- }
-
- public LongIterator getRawIterator() {
- return this.map.values().iterator();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f3b25bb2439f283f878db93973a02fcdcd14eed
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IntList.java
@@ -0,0 +1,77 @@
+package ca.spottedleaf.moonrise.common.list;
+
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import java.util.Arrays;
+
+public final class IntList {
+
+ private final Int2IntOpenHashMap map = new Int2IntOpenHashMap();
+ {
+ this.map.defaultReturnValue(Integer.MIN_VALUE);
+ }
+
+ private static final int[] EMPTY_LIST = new int[0];
+
+ private int[] byIndex = EMPTY_LIST;
+ private int count;
+
+ public int size() {
+ return this.count;
+ }
+
+ public void setMinCapacity(final int len) {
+ final int[] byIndex = this.byIndex;
+ if (byIndex.length < len) {
+ this.byIndex = Arrays.copyOf(byIndex, len);
+ }
+ }
+
+ public int getRaw(final int index) {
+ return this.byIndex[index];
+ }
+
+ public boolean add(final int value) {
+ final int count = this.count;
+ final int currIndex = this.map.putIfAbsent(value, count);
+
+ if (currIndex != Integer.MIN_VALUE) {
+ return false; // already in this list
+ }
+
+ int[] list = this.byIndex;
+
+ if (list.length == count) {
+ // resize required
+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative
+ }
+
+ list[count] = value;
+ this.count = count + 1;
+
+ return true;
+ }
+
+ public boolean remove(final int value) {
+ final int index = this.map.remove(value);
+ if (index == Integer.MIN_VALUE) {
+ return false;
+ }
+
+ // move the entry at the end to this index
+ final int endIndex = --this.count;
+ final int end = this.byIndex[endIndex];
+ if (index != endIndex) {
+ // not empty after this call
+ this.map.put(end, index);
+ }
+ this.byIndex[index] = end;
+ this.byIndex[endIndex] = 0;
+
+ return true;
+ }
+
+ public void clear() {
+ this.count = 0;
+ this.map.clear();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bae9949ef325d0001aa638150fbbdf968367e75
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/ShortList.java
@@ -0,0 +1,77 @@
+package ca.spottedleaf.moonrise.common.list;
+
+import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
+import java.util.Arrays;
+
+public final class ShortList {
+
+ private final Short2ShortOpenHashMap map = new Short2ShortOpenHashMap();
+ {
+ this.map.defaultReturnValue(Short.MIN_VALUE);
+ }
+
+ private static final short[] EMPTY_LIST = new short[0];
+
+ private short[] byIndex = EMPTY_LIST;
+ private short count;
+
+ public int size() {
+ return (int)this.count;
+ }
+
+ public short getRaw(final int index) {
+ return this.byIndex[index];
+ }
+
+ public void setMinCapacity(final int len) {
+ final short[] byIndex = this.byIndex;
+ if (byIndex.length < len) {
+ this.byIndex = Arrays.copyOf(byIndex, len);
+ }
+ }
+
+ public boolean add(final short value) {
+ final int count = (int)this.count;
+ final short currIndex = this.map.putIfAbsent(value, (short)count);
+
+ if (currIndex != Short.MIN_VALUE) {
+ return false; // already in this list
+ }
+
+ short[] list = this.byIndex;
+
+ if (list.length == count) {
+ // resize required
+ list = this.byIndex = Arrays.copyOf(list, (int)Math.max(4L, count * 2L)); // overflow results in negative
+ }
+
+ list[count] = value;
+ this.count = (short)(count + 1);
+
+ return true;
+ }
+
+ public boolean remove(final short value) {
+ final short index = this.map.remove(value);
+ if (index == Short.MIN_VALUE) {
+ return false;
+ }
+
+ // move the entry at the end to this index
+ final short endIndex = --this.count;
+ final short end = this.byIndex[endIndex];
+ if (index != endIndex) {
+ // not empty after this call
+ this.map.put(end, index);
+ }
+ this.byIndex[(int)index] = end;
+ this.byIndex[(int)endIndex] = (short)0;
+
+ return true;
+ }
+
+ public void clear() {
+ this.count = (short)0;
+ this.map.clear();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2d917c2eac55b8a4411a6e159f177f9428b1150
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/LazyRunnable.java
@@ -0,0 +1,22 @@
+package ca.spottedleaf.moonrise.common.misc;
+
+import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
+import java.lang.invoke.VarHandle;
+
+public final class LazyRunnable implements Runnable {
+
+ private volatile Runnable toRun;
+ private static final VarHandle TO_RUN_HANDLE = ConcurrentUtil.getVarHandle(LazyRunnable.class, "toRun", Runnable.class);
+
+ public void setRunnable(final Runnable run) {
+ final Runnable prev = (Runnable)TO_RUN_HANDLE.compareAndExchange(this, (Runnable)null, run);
+ if (prev != null) {
+ throw new IllegalStateException("Runnable already set");
+ }
+ }
+
+ @Override
+ public void run() {
+ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740be1d09b11 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
@@ -4,13 +4,17 @@ import ca.spottedleaf.moonrise.common.list.ReferenceList;
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
import ca.spottedleaf.moonrise.common.util.ChunkSystem;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants;
+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
+import java.util.ArrayList;
public final class NearbyPlayers {
@@ -20,7 +24,27 @@ public final class NearbyPlayers {
GENERAL_REALLY_SMALL,
TICK_VIEW_DISTANCE,
VIEW_DISTANCE,
- SPAWN_RANGE, // Moonrise - chunk tick iteration
+ // Moonrise start - chunk tick iteration
+ SPAWN_RANGE {
+ @Override
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ);
+ }
+
+ @Override
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ);
+ }
+ };
+ // Moonrise end - chunk tick iteration
+
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
+
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
}
private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values();
@@ -37,6 +61,12 @@ public final class NearbyPlayers {
private final ServerLevel world;
private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
private final Long2ReferenceOpenHashMap<TrackedChunk> byChunk = new Long2ReferenceOpenHashMap<>();
+ private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
+ {
+ for (int i = 0; i < this.directByChunk.length; ++i) {
+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>();
+ }
+ }
public NearbyPlayers(final ServerLevel world) {
this.world = world;
@@ -70,6 +100,16 @@ public final class NearbyPlayers {
}
}
+ public void clear() {
+ if (this.players.isEmpty()) {
+ return;
+ }
+
+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) {
+ this.removePlayer(player);
+ }
+ }
+
public void tickPlayer(final ServerPlayer player) {
final TrackedPlayer[] players = this.players.get(player);
if (players == null) {
@@ -94,38 +134,41 @@ public final class NearbyPlayers {
return this.byChunk.get(CoordinateUtils.getChunkKey(pos));
}
- public ReferenceList<ServerPlayer> getPlayers(final BlockPos pos, final NearbyMapType type) {
- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos));
+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ }
- return chunk == null ? null : chunk.players[type.ordinal()];
+ public ReferenceList<ServerPlayer> getPlayers(final BlockPos pos, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
}
public ReferenceList<ServerPlayer> getPlayers(final ChunkPos pos, final NearbyMapType type) {
- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(pos));
-
- return chunk == null ? null : chunk.players[type.ordinal()];
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
}
public ReferenceList<ServerPlayer> getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) {
- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
-
- return chunk == null ? null : chunk.players[type.ordinal()];
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
}
public ReferenceList<ServerPlayer> getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) {
- final TrackedChunk chunk = this.byChunk.get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4));
-
- return chunk == null ? null : chunk.players[type.ordinal()];
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4));
}
public static final class TrackedChunk {
private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0];
+ private final long chunkKey;
+ private final NearbyPlayers nearbyPlayers;
private final ReferenceList<ServerPlayer>[] players = new ReferenceList[TOTAL_MAP_TYPES];
private int nonEmptyLists;
private long updateCount;
+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) {
+ this.chunkKey = chunkKey;
+ this.nearbyPlayers = nearbyPlayers;
+ }
+
public boolean isEmpty() {
return this.nonEmptyLists == 0;
}
@@ -145,7 +188,9 @@ public final class NearbyPlayers {
final ReferenceList<ServerPlayer> list = this.players[idx];
if (list == null) {
++this.nonEmptyLists;
- (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY)).add(player);
+ final ReferenceList<ServerPlayer> players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY));
+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players);
+ players.add(player);
return;
}
@@ -169,6 +214,7 @@ public final class NearbyPlayers {
if (list.size() == 0) {
this.players[idx] = null;
+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey);
--this.nonEmptyLists;
}
}
@@ -187,9 +233,19 @@ public final class NearbyPlayers {
protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) {
final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ);
- NearbyPlayers.this.byChunk.computeIfAbsent(chunkKey, (final long keyInMap) -> {
- return new TrackedChunk();
- }).addPlayer(parameter, this.type);
+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey);
+ final NearbyMapType type = this.type;
+ if (chunk != null) {
+ chunk.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+ } else {
+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this);
+ NearbyPlayers.this.byChunk.put(chunkKey, created);
+ created.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+
+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created;
+ }
}
@Override
@@ -201,10 +257,16 @@ public final class NearbyPlayers {
throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey));
}
- chunk.removePlayer(parameter, this.type);
+ final NearbyMapType type = this.type;
+ chunk.removePlayer(parameter, type);
+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
if (chunk.isEmpty()) {
NearbyPlayers.this.byChunk.remove(chunkKey);
+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey);
+ if (chunkData != null) {
+ chunkData.nearbyPlayers = null;
+ }
}
}
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java
index efefd94b652228d877db5dbca8b28354ad42529f..90560769d09538f7a740753a41a3b8e017b0b92a 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java
@@ -2,6 +2,7 @@ package ca.spottedleaf.moonrise.common.misc;
import ca.spottedleaf.concurrentutil.util.IntPairUtil;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
+import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
@@ -14,6 +15,10 @@ public final class PositionCountingAreaMap<T> {
return this.counters.keySet();
}
+ public LongSet getPositions() {
+ return this.positions.keySet();
+ }
+
public int getTotalPositions() {
return this.positions.size();
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
@@ -1,6 +1,7 @@
package ca.spottedleaf.moonrise.common.util;
-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
+import ca.spottedleaf.concurrentutil.util.Priority;
+import ca.spottedleaf.moonrise.common.PlatformHooks;
import com.mojang.logging.LogUtils;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.FullChunkStatus;
@@ -24,15 +25,15 @@ public final class ChunkSystem {
}
public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) {
- scheduleChunkTask(level, chunkX, chunkZ, run, PrioritisedExecutor.Priority.NORMAL);
+ scheduleChunkTask(level, chunkX, chunkZ, run, Priority.NORMAL);
}
- public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final PrioritisedExecutor.Priority priority) {
+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
level.chunkSource.mainThreadProcessor.execute(run);
}
public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen,
- final ChunkStatus toStatus, final boolean addTicket, final PrioritisedExecutor.Priority priority,
+ final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
final Consumer<ChunkAccess> onComplete) {
if (gen) {
scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
@@ -59,7 +60,7 @@ public final class ChunkSystem {
private static long chunkLoadCounter = 0L;
public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final ChunkStatus toStatus,
- final boolean addTicket, final PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) {
+ final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
if (!org.bukkit.Bukkit.isPrimaryThread()) {
scheduleChunkTask(level, chunkX, chunkZ, () -> {
scheduleChunkLoad(level, chunkX, chunkZ, toStatus, addTicket, priority, onComplete);
@@ -113,13 +114,13 @@ public final class ChunkSystem {
}
loadCallback.accept(result.orElse(null));
}, (final Runnable r) -> {
- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST);
+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
});
}
public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
final FullChunkStatus toStatus, final boolean addTicket,
- final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) {
+ final Priority priority, final Consumer<LevelChunk> onComplete) {
// This method goes unused until the chunk system rewrite
if (toStatus == FullChunkStatus.INACCESSIBLE) {
throw new IllegalArgumentException("Cannot wait for INACCESSIBLE status");
@@ -196,7 +197,7 @@ public final class ChunkSystem {
}
loadCallback.accept(result.orElse(null));
}, (final Runnable r) -> {
- scheduleChunkTask(level, chunkX, chunkZ, r, PrioritisedExecutor.Priority.HIGHEST);
+ scheduleChunkTask(level, chunkX, chunkZ, r, Priority.HIGHEST);
});
}
@@ -220,7 +221,10 @@ public final class ChunkSystem {
return getUpdatingChunkHolderCount(level) != 0;
}
- public static boolean screenEntity(final ServerLevel level, final Entity entity) {
+ public static boolean screenEntity(final ServerLevel level, final Entity entity, final boolean fromDisk, final boolean event) {
+ if (!PlatformHooks.get().screenEntity(level, entity, fromDisk, event)) {
+ return false;
+ }
return true;
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java
index ac6f284ee4469d16c5655328b2488d7612832353..97848869df61648fc415e4d39f409f433202c274 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MixinWorkarounds.java
@@ -3,8 +3,12 @@ package ca.spottedleaf.moonrise.common.util;
public final class MixinWorkarounds {
// mixins tries to find the owner of the clone() method, which doesn't exist and NPEs
+ // https://github.com/FabricMC/Mixin/pull/147
public static long[] clone(final long[] values) {
return values.clone();
}
+ public static byte[] clone(final byte[] values) {
+ return values.clone();
+ }
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
index 3abe0bd2a820352b85306d554bf14a4cf6123091..c125c70a68130be373acc989053a6c0e487be924 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
@@ -1,45 +1,100 @@
package ca.spottedleaf.moonrise.common.util;
-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool;
+import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool;
+import ca.spottedleaf.moonrise.common.PlatformHooks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
public final class MoonriseCommon {
private static final Logger LOGGER = LoggerFactory.getLogger(MoonriseCommon.class);
- // Paper start
- public static PrioritisedThreadPool WORKER_POOL;
- public static int WORKER_THREADS;
- public static void init(io.papermc.paper.configuration.GlobalConfiguration.ChunkSystem chunkSystem) {
- // Paper end
+ public static final PrioritisedThreadPool WORKER_POOL = new PrioritisedThreadPool(
+ new Consumer<>() {
+ private final AtomicInteger idGenerator = new AtomicInteger();
+
+ @Override
+ public void accept(Thread thread) {
+ thread.setDaemon(true);
+ thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement());
+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(final Thread thread, final Throwable throwable) {
+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
+ }
+ });
+ }
+ }
+ );
+ public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms
+ public static final int CLIENT_DIVISION = 0;
+ public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0);
+ public static final int SERVER_DIVISION = 1;
+ public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0);
+ public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0);
+ public static final PrioritisedThreadPool.ExecutorGroup LOAD_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0);
+
+ public static void adjustWorkerThreads(final int configWorkerThreads, final int configIoThreads) {
int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2;
if (defaultWorkerThreads <= 4) {
defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2;
} else {
defaultWorkerThreads = defaultWorkerThreads / 2;
}
- defaultWorkerThreads = Integer.getInteger("Paper.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads)); // Paper
+ defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads));
- int workerThreads = chunkSystem.workerThreads; // Paper
+ int workerThreads = configWorkerThreads;
if (workerThreads <= 0) {
workerThreads = defaultWorkerThreads;
}
- WORKER_POOL = new PrioritisedThreadPool(
- "Paper Worker Pool", workerThreads, // Paper
- (final Thread thread, final Integer id) -> {
- thread.setName("Paper Common Worker #" + id.intValue()); // Paper
+ final int ioThreads = Math.max(1, configIoThreads);
+
+ WORKER_POOL.adjustThreadCount(workerThreads);
+ IO_POOL.adjustThreadCount(ioThreads);
+
+ LOGGER.info(PlatformHooks.get().getBrand() + " is using " + workerThreads + " worker threads, " + ioThreads + " I/O threads");
+ }
+
+ public static final PrioritisedThreadPool IO_POOL = new PrioritisedThreadPool(
+ new Consumer<>() {
+ private final AtomicInteger idGenerator = new AtomicInteger();
+
+ @Override
+ public void accept(final Thread thread) {
+ thread.setDaemon(true);
+ thread.setName(PlatformHooks.get().getBrand() + " I/O Worker #" + this.idGenerator.getAndIncrement());
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread, final Throwable throwable) {
LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
}
});
- }, (long)(20.0e6)); // 20ms
- WORKER_THREADS = workerThreads;
+ }
+ }
+ );
+ public static final long IO_QUEUE_HOLD_TIME = (long)(100.0e6); // 100ms
+ public static final PrioritisedThreadPool.ExecutorGroup CLIENT_PROFILER_IO_GROUP = IO_POOL.createExecutorGroup(CLIENT_DIVISION, 0);
+ public static final PrioritisedThreadPool.ExecutorGroup SERVER_REGION_IO_GROUP = IO_POOL.createExecutorGroup(SERVER_DIVISION, 0);
+
+ public static void haltExecutors() {
+ MoonriseCommon.WORKER_POOL.shutdown(false);
+ LOGGER.info("Awaiting termination of worker pool for up to 60s...");
+ if (!MoonriseCommon.WORKER_POOL.join(TimeUnit.SECONDS.toMillis(60L))) {
+ LOGGER.error("Worker pool did not shut down in time!");
+ MoonriseCommon.WORKER_POOL.halt(false);
+ }
+
+ MoonriseCommon.IO_POOL.shutdown(false);
+ LOGGER.info("Awaiting termination of I/O pool for up to 60s...");
+ if (!MoonriseCommon.IO_POOL.join(TimeUnit.SECONDS.toMillis(60L))) {
+ LOGGER.error("I/O pool did not shut down in time!");
+ MoonriseCommon.IO_POOL.halt(false);
+ }
}
private MoonriseCommon() {}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
index 1cf32d7d1bbc8a0a3f7cb9024c793f6744199f64..559c959aff3c9deef867b9e425fba3e2e669cac6 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
@@ -1,8 +1,10 @@
package ca.spottedleaf.moonrise.common.util;
+import ca.spottedleaf.moonrise.common.PlatformHooks;
+
public final class MoonriseConstants {
- public static final int MAX_VIEW_DISTANCE = 32;
+ public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32);
private MoonriseConstants() {}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9ff1c1a70faf4b7a64b265932f07a8b8f00c1ff
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/SimpleRandom.java
@@ -0,0 +1,52 @@
+package ca.spottedleaf.moonrise.common.util;
+
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
+
+/**
+ * Avoid costly CAS of superclass
+ */
+public final class SimpleRandom extends LegacyRandomSource {
+
+ private static final long MULTIPLIER = 25214903917L;
+ private static final long ADDEND = 11L;
+ private static final int BITS = 48;
+ private static final long MASK = (1L << BITS) - 1;
+
+ private long value;
+
+ public SimpleRandom(final long seed) {
+ super(0L);
+ this.value = seed;
+ }
+
+ @Override
+ public void setSeed(final long seed) {
+ this.value = (seed ^ MULTIPLIER) & MASK;
+ }
+
+ private long advanceSeed() {
+ return this.value = ((this.value * MULTIPLIER) + ADDEND) & MASK;
+ }
+
+ @Override
+ public int next(final int bits) {
+ return (int)(this.advanceSeed() >>> (BITS - bits));
+ }
+
+ @Override
+ public int nextInt() {
+ final long seed = this.advanceSeed();
+ return (int)(seed >>> (BITS - Integer.SIZE));
+ }
+
+ @Override
+ public int nextInt(final int bound) {
+ if (bound <= 0) {
+ throw new IllegalArgumentException();
+ }
+
+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
+ final long value = this.advanceSeed() >>> (BITS - Integer.SIZE);
+ return (int)((value * (long)bound) >>> Integer.SIZE);
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
index 11b7f15755dde766140c29bedca456c80d53293f..217d1f908a36a5177ba3cbb80a33f73d4dab0fa0 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
@@ -77,11 +77,15 @@ public class TickThread extends Thread {
}
public TickThread(final Runnable run, final String name) {
- this(run, name, ID_GENERATOR.incrementAndGet());
+ this(null, run, name);
}
- private TickThread(final Runnable run, final String name, final int id) {
- super(run, name);
+ public TickThread(final ThreadGroup group, final Runnable run, final String name) {
+ this(group, run, name, ID_GENERATOR.incrementAndGet());
+ }
+
+ private TickThread(final ThreadGroup group, final Runnable run, final String name, final int id) {
+ super(group, run, name);
this.id = id;
}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java
index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef224cbb86 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/WorldUtil.java
@@ -8,11 +8,19 @@ public final class WorldUtil {
// min, max are inclusive
public static int getMaxSection(final LevelHeightAccessor world) {
- return world.getMaxSection() - 1; // getMaxSection() is exclusive
+ return world.getMaxSectionY();
+ }
+
+ public static int getMaxSection(final Level world) {
+ return world.getMaxSectionY();
}
public static int getMinSection(final LevelHeightAccessor world) {
- return world.getMinSection();
+ return world.getMinSectionY();
+ }
+
+ public static int getMinSection(final Level world) {
+ return world.getMinSectionY();
}
public static int getMaxLightSection(final LevelHeightAccessor world) {
diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
new file mode 100644
index 0000000000000000000000000000000000000000..1aa6be257ce594d7a69fdff008cd29014a04fd75
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -0,0 +1,209 @@
+package ca.spottedleaf.moonrise.paper;
+
+import ca.spottedleaf.moonrise.common.PlatformHooks;
+import com.mojang.datafixers.DSL;
+import com.mojang.datafixers.DataFixer;
+import com.mojang.serialization.Dynamic;
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.GenerationChunkHolder;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.level.BlockGetter;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.chunk.ChunkAccess;
+import net.minecraft.world.level.chunk.LevelChunk;
+import net.minecraft.world.level.chunk.ProtoChunk;
+import net.minecraft.world.level.chunk.storage.SerializableChunkData;
+import net.minecraft.world.level.entity.EntityTypeTest;
+import net.minecraft.world.phys.AABB;
+import java.util.List;
+import java.util.function.Predicate;
+
+public final class PaperHooks implements PlatformHooks {
+
+ @Override
+ public String getBrand() {
+ return "Paper";
+ }
+
+ @Override
+ public int getLightEmission(final BlockState blockState, final BlockGetter world, final BlockPos pos) {
+ return blockState.getLightEmission();
+ }
+
+ @Override
+ public Predicate<BlockState> maybeHasLightEmission() {
+ return (final BlockState state) -> {
+ return state.getLightEmission() != 0;
+ };
+ }
+
+ @Override
+ public boolean hasCurrentlyLoadingChunk() {
+ return false;
+ }
+
+ @Override
+ public LevelChunk getCurrentlyLoadingChunk(final GenerationChunkHolder holder) {
+ return null;
+ }
+
+ @Override
+ public void setCurrentlyLoading(final GenerationChunkHolder holder, final LevelChunk levelChunk) {
+
+ }
+
+ @Override
+ public void chunkFullStatusComplete(final LevelChunk newChunk, final ProtoChunk original) {
+
+ }
+
+ @Override
+ public boolean allowAsyncTicketUpdates() {
+ return true;
+ }
+
+ @Override
+ public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel) {
+
+ }
+
+ @Override
+ public void chunkUnloadFromWorld(final LevelChunk chunk) {
+
+ }
+
+ @Override
+ public void chunkSyncSave(final ServerLevel world, final ChunkAccess chunk, final SerializableChunkData data) {
+
+ }
+
+ @Override
+ public void onChunkWatch(final ServerLevel world, final LevelChunk chunk, final ServerPlayer player) {
+
+ }
+
+ @Override
+ public void onChunkUnWatch(final ServerLevel world, final ChunkPos chunk, final ServerPlayer player) {
+
+ }
+
+ @Override
+ public void addToGetEntities(final Level world, final Entity entity, final AABB boundingBox, final Predicate<? super Entity> predicate, final List<Entity> into) {
+
+ }
+
+ @Override
+ public <T extends Entity> void addToGetEntities(final Level world, final EntityTypeTest<Entity, T> entityTypeTest, final AABB boundingBox, final Predicate<? super T> predicate, final List<? super T> into, final int maxCount) {
+
+ }
+
+ @Override
+ public void entityMove(final Entity entity, final long oldSection, final long newSection) {
+
+ }
+
+ @Override
+ public boolean screenEntity(final ServerLevel world, final Entity entity, final boolean fromDisk, final boolean event) {
+ return true;
+ }
+
+ @Override
+ public boolean configFixMC224294() {
+ return true;
+ }
+
+ @Override
+ public boolean configAutoConfigSendDistance() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.autoConfigSendDistance;
+ }
+
+ @Override
+ public double configPlayerMaxLoadRate() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkLoadRate;
+ }
+
+ @Override
+ public double configPlayerMaxGenRate() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkGenerateRate;
+ }
+
+ @Override
+ public double configPlayerMaxSendRate() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingBasic.playerMaxChunkSendRate;
+ }
+
+ @Override
+ public int configPlayerMaxConcurrentLoads() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkLoads;
+ }
+
+ @Override
+ public int configPlayerMaxConcurrentGens() {
+ return io.papermc.paper.configuration.GlobalConfiguration.get().chunkLoadingAdvanced.playerMaxConcurrentChunkGenerates;
+ }
+
+ @Override
+ public long configAutoSaveInterval(final ServerLevel world) {
+ return world.paperConfig().chunks.autoSaveInterval.value();
+ }
+
+ @Override
+ public int configMaxAutoSavePerTick(final ServerLevel world) {
+ return world.paperConfig().chunks.maxAutoSaveChunksPerTick;
+ }
+
+ @Override
+ public boolean configFixMC159283() {
+ return true;
+ }
+
+ @Override
+ public boolean forceNoSave(final ChunkAccess chunk) {
+ return chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave;
+ }
+
+ @Override
+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
+ final int fromVersion, final int toVersion) {
+ return (CompoundTag)dataFixer.update(
+ type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion
+ ).getValue();
+ }
+
+ @Override
+ public boolean hasMainChunkLoadHook() {
+ return false;
+ }
+
+ @Override
+ public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) {
+
+ }
+
+ @Override
+ public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities) {
+ return entities;
+ }
+
+ @Override
+ public void unloadEntity(final Entity entity) {
+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, org.bukkit.event.entity.EntityRemoveEvent.Cause.UNLOAD);
+ }
+
+ @Override
+ public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
+ }
+
+ @Override
+ public int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
index 4954ed9edf1e1f54cc164e48817eb5b75ea87ce0..8a0cb603cd4dbfa1839e0f4e1606876cbb373277 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -243,7 +243,7 @@ public class GlobalConfiguration extends ConfigurationPart {
@PostProcess
private void postProcess() {
-
+ ca.spottedleaf.moonrise.common.util.MoonriseCommon.adjustWorkerThreads(this.workerThreads, this.ioThreads);
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 2aa4437a76d29cdd793680734a36a41c6133ab91..0cf4f9d60337cfe89075a79eabfd182cdec91695 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -272,7 +272,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
return true;
}
- public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor.Priority priority,
+ public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority,
java.util.function.Consumer<List<net.minecraft.world.level.chunk.ChunkAccess>> onLoad) {
if (Thread.currentThread() != this.thread) {
this.getChunkSource().mainThreadProcessor.execute(() -> {
diff --git a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
index f18c2b85ed9541f646f157184221e333d0ae58bd..aff4c3d63a97d5bbde004a616f7e14fca59b5ab9 100644
--- a/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
+++ b/src/main/java/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
@@ -168,7 +168,7 @@ public class ChunkStatusTasks {
}, context.mainThreadExecutor());
}
- private static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> entities) {
+ public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> entities) { // Paper - public
if (!entities.isEmpty()) {
// CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entities, world, EntitySpawnReason.LOAD).filter((entity) -> {
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 6baa313b8201ed23193d7885c85606b0899ade3c..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -94,15 +94,13 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
private boolean addEntity(T entity, boolean existing) {
org.spigotmc.AsyncCatcher.catchOp("Entity add"); // Paper
// Paper start - chunk system hooks
- if (existing) {
- // I don't want to know why this is a generic type.
- Entity entityCasted = (Entity)entity;
- boolean wasRemoved = entityCasted.isRemoved();
- boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted);
- if ((!wasRemoved && entityCasted.isRemoved()) || !screened) {
- // removed by callback
- return false;
- }
+ // I don't want to know why this is a generic type.
+ Entity entityCasted = (Entity)entity;
+ boolean wasRemoved = entityCasted.isRemoved();
+ boolean screened = ca.spottedleaf.moonrise.common.util.ChunkSystem.screenEntity((net.minecraft.server.level.ServerLevel)entityCasted.level(), entityCasted, existing, true);
+ if ((!wasRemoved && entityCasted.isRemoved()) || !screened) {
+ // removed by callback
+ return false;
}
// Paper end - chunk system hooks
if (!this.addEntityUuid(entity)) {
diff --git a/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks
new file mode 100644
index 0000000000000000000000000000000000000000..e57c3ca79677b1dfe7cf3db36f0406de7ea5bd0a
--- /dev/null
+++ b/src/main/resources/META-INF/services/ca.spottedleaf.moonrise.common.PlatformHooks
@@ -0,0 +1 @@
+ca.spottedleaf.moonrise.paper.PaperHooks