Begin fixing issues

See diff in the update text file
This commit is contained in:
Spottedleaf 2024-10-24 08:18:20 -07:00
parent 47258a7118
commit ecf4d9715e
11 changed files with 2922 additions and 2863 deletions

View file

@ -13,12 +13,7 @@ add notes to moonrise patch:
todo: todo:
- double check that the misc changes commit on dev/1.21.2 moonrise is applied - double check that the misc changes commit on dev/1.21.2 moonrise is applied
- implement platformhooks - implement platformhooks
- delete old block state table patch
- in StateHolder, implement getNullableValue from blockstate_propertyaccess
- ChunkEntitySlices getChunkEntities(), callEntitiesLoadEvent(), callEntitiesUnloadEvent()
- in ChunkEntitySlices, implement modifySavedEntities() by copying from old - in ChunkEntitySlices, implement modifySavedEntities() by copying from old
- in ChunkEntitySlices, implement unload() Entity.setRemoved()
- change PersistentEntitySectionManager addEntity chunk system call to have event=true
- implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch - implement PlayerChunkUnloadEvent in PlatformHooks#onChunkUnWatch
- make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk - make sure chunk pos is passed in PlatformHooks#postLoadProtoChunk
- implement chunk_system.ChunkMapMixin diff from reference - implement chunk_system.ChunkMapMixin diff from reference
@ -32,11 +27,10 @@ todo:
- implement chunk_system.ServerLevelMixin diff from reference - implement chunk_system.ServerLevelMixin diff from reference
- implement chunk_tick_iteration - implement chunk_tick_iteration
- implement collisions.ServerExplosionMixin diff from reference - implement collisions.ServerExplosionMixin diff from reference
- implement modifyEntityTrackingRange with org.spigotmc.TrackingRange.getEntityTrackingRange
- implement random_ticking.BiomeMixin diff from reference
- implement starlight.LevelLightEngineMixin diff from reference - implement starlight.LevelLightEngineMixin diff from reference
- implement starlight.ThreadedLevelLightEngineMixin diff from reference - implement starlight.ThreadedLevelLightEngineMixin diff from reference
- implement starlight.ChunkSerializerMixin diff from reference - implement starlight.ChunkSerializerMixin diff from reference
- implement starlight.SerializableChunkData$SectionData diff from reference - implement starlight.SerializableChunkData$SectionData diff from reference
- implement starlight.SerializableChunkDataMixin diff from reference - implement starlight.SerializableChunkDataMixin diff from reference
- unfuck the chtunk system config diff
- chunk system: move get entity lookup reroute into the folia scheduler api patch

View file

@ -6,16 +6,16 @@ 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 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 new file mode 100644
index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea08736888e642 index 0000000000000000000000000000000000000000..3c5ed66328ccf94c4744a191a7c63562dd08158d
--- /dev/null --- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
@@ -0,0 +1,115 @@ @@ -0,0 +1,115 @@
+package ca.spottedleaf.moonrise.common; +package ca.spottedleaf.moonrise.common;
+ +
+import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder;
+import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.DataFixer;
+import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.GenerationChunkHolder; +import net.minecraft.server.level.GenerationChunkHolder;
+import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerPlayer;
@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..69a20e9d72b02f28b349f24fd0ea0873
+ +
+ public boolean allowAsyncTicketUpdates(); + public boolean allowAsyncTicketUpdates();
+ +
+ public void onChunkHolderTicketChange(final ServerLevel world, final NewChunkHolder holder, final int oldLevel, final int newLevel); + public void onChunkHolderTicketChange(final ServerLevel world, final ChunkHolder holder, final int oldLevel, final int newLevel);
+ +
+ public void chunkUnloadFromWorld(final LevelChunk chunk); + public void chunkUnloadFromWorld(final LevelChunk chunk);
+ +
@ -685,7 +685,7 @@ index ab093b0e8ac6f762921eb1d15f5217345c4eba05..bb44de17a37082e57f2292a4f470740b
} }
} }
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java 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 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe6ffdd516 100644 index da323a1105347d5cf4b946df10ded78a953236f2..94bba2b71918d79f54b3e28c35e76098ba0afd8c 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java --- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
+++ b/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 @@ @@ -1,6 +1,7 @@
@ -694,11 +694,11 @@ index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe
-import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor; -import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
+import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.concurrentutil.util.Priority;
+import ca.spottedleaf.moonrise.common.PlatformHooks; +import ca.spottedleaf.moonrise.common.PlatformHooks;
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel; import com.mojang.logging.LogUtils;
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkSystemLevelChunk; import net.minecraft.server.level.ChunkHolder;
import ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader; import net.minecraft.server.level.FullChunkStatus;
@@ -23,27 +24,27 @@ public final class ChunkSystem { @@ -24,15 +25,15 @@ public final class ChunkSystem {
private static final Logger LOGGER = LogUtils.getLogger(); }
public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run) { 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, PrioritisedExecutor.Priority.NORMAL);
@ -707,30 +707,50 @@ index 0abba00741b39b69a7f167e5d2670f2565c9a752..b61611351bf23efc1e90bab8a850ebbe
- 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 PrioritisedExecutor.Priority priority) {
+ public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) { + public static void scheduleChunkTask(final ServerLevel level, final int chunkX, final int chunkZ, final Runnable run, final Priority priority) {
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkTask(chunkX, chunkZ, run, priority); level.chunkSource.mainThreadProcessor.execute(run);
} }
public static void scheduleChunkLoad(final ServerLevel level, final int chunkX, final int chunkZ, final boolean gen, 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 PrioritisedExecutor.Priority priority,
+ final ChunkStatus toStatus, final boolean addTicket, final Priority priority, + final ChunkStatus toStatus, final boolean addTicket, final Priority priority,
final Consumer<ChunkAccess> onComplete) { final Consumer<ChunkAccess> onComplete) {
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, gen, toStatus, addTicket, priority, 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, 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 PrioritisedExecutor.Priority priority, final Consumer<ChunkAccess> onComplete) {
+ final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) { + final boolean addTicket, final Priority priority, final Consumer<ChunkAccess> onComplete) {
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleChunkLoad(chunkX, chunkZ, toStatus, addTicket, priority, 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, public static void scheduleTickingState(final ServerLevel level, final int chunkX, final int chunkZ,
final FullChunkStatus toStatus, final boolean addTicket, final FullChunkStatus toStatus, final boolean addTicket,
- final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) { - final PrioritisedExecutor.Priority priority, final Consumer<LevelChunk> onComplete) {
+ final Priority priority, final Consumer<LevelChunk> onComplete) { + final Priority priority, final Consumer<LevelChunk> onComplete) {
((ChunkSystemServerLevel)level).moonrise$getChunkTaskScheduler().scheduleTickingState(chunkX, chunkZ, toStatus, addTicket, priority, 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);
});
} }
@@ -67,7 +68,10 @@ public final class ChunkSystem { @@ -220,7 +221,10 @@ public final class ChunkSystem {
return getUpdatingChunkHolderCount(level) != 0; return getUpdatingChunkHolderCount(level) != 0;
} }
@ -1002,6 +1022,211 @@ index af9623240ff2d389aa7090623f507720e7dbab7d..efda2688ae1254a82ba7f6bf8bf597ef
} }
public static int getMaxLightSection(final LevelHeightAccessor world) { 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..6f2dc0900dbf13a02410682eecda56cea4481346
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -0,0 +1,199 @@
+package ca.spottedleaf.moonrise.paper;
+
+import ca.spottedleaf.moonrise.common.PlatformHooks;
+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.util.datafix.DataFixTypes;
+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() {
+
+ }
+
+ @Override
+ public double configPlayerMaxLoadRate() {
+
+ }
+
+ @Override
+ public double configPlayerMaxGenRate() {
+
+ }
+
+ @Override
+ public double configPlayerMaxSendRate() {
+
+ }
+
+ @Override
+ public int configPlayerMaxConcurrentLoads() {
+
+ }
+
+ @Override
+ public int configPlayerMaxConcurrentGens() {
+
+ }
+
+ @Override
+ public long configAutoSaveInterval() {
+
+ }
+
+ @Override
+ public int configMaxAutoSavePerTick() {
+
+ }
+
+ @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 DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) {
+ return type.update(dataFixer, nbt, fromVersion, toVersion);
+ }
+
+ @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 int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
+ return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java 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..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644 index 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32fd72b2af 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java --- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@ -1029,3 +1254,10 @@ index 6baa313b8201ed23193d7885c85606b0899ade3c..3eb38271b6ca26099b2da04c2d969e32
} }
// Paper end - chunk system hooks // Paper end - chunk system hooks
if (!this.addEntityUuid(entity)) { 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

View file

@ -0,0 +1,117 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Wed, 23 Oct 2024 22:13:41 -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
index 3c5ed66328ccf94c4744a191a7c63562dd08158d..deb64f7ebebcf6de91ffe0542d6b449a4db64da0 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
@@ -1,5 +1,6 @@
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;
@@ -7,7 +8,6 @@ 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.util.datafix.DataFixTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
@@ -88,7 +88,7 @@ public interface PlatformHooks {
// support for CB chunk mustNotSave
public boolean forceNoSave(final ChunkAccess chunk);
- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt,
+ public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt,
final int fromVersion, final int toVersion);
public boolean hasMainChunkLoadHook();
@@ -99,6 +99,8 @@ public interface PlatformHooks {
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 {
diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
index 6f2dc0900dbf13a02410682eecda56cea4481346..ee514a767f69de69d86e1e88d70fe37c4ab84277 100644
--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -1,14 +1,16 @@
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.util.datafix.DataFixTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
@@ -168,8 +170,11 @@ public final class PaperHooks implements PlatformHooks {
}
@Override
- public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer, final CompoundTag nbt, final int fromVersion, final int toVersion) {
- return type.update(dataFixer, nbt, fromVersion, toVersion);
+ 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
@@ -192,6 +197,11 @@ public final class PaperHooks implements PlatformHooks {
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/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 3eb38271b6ca26099b2da04c2d969e32fd72b2af..5aa74c00a61282830d82359eae2b114e2a48b6d9 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -97,7 +97,7 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
// 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, false);
+ 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;

View file

@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 24 Oct 2024 08:11:12 -0700
Subject: [PATCH] fixup! Paper config files
diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
index 73e8a524925ed6f2580d3bd01616646fabafda78..4bfe7e987450afa433fcad1847f6130654769416 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -30,6 +30,45 @@ public class GlobalConfiguration extends ConfigurationPart {
public static GlobalConfiguration get() {
return instance;
}
+
+ public ChunkLoadingBasic chunkLoadingBasic;
+
+ public class ChunkLoadingBasic extends ConfigurationPart {
+ @Comment("The maximum rate in chunks per second that the server will send to any individual player. Set to -1 to disable this limit.")
+ public double playerMaxChunkSendRate = 75.0;
+
+ @Comment(
+ "The maximum rate at which chunks will load for any individual player. " +
+ "Note that this setting also affects chunk generations, since a chunk load is always first issued to test if a" +
+ "chunk is already generated. Set to -1 to disable this limit."
+ )
+ public double playerMaxChunkLoadRate = 100.0;
+
+ @Comment("The maximum rate at which chunks will generate for any individual player. Set to -1 to disable this limit.")
+ public double playerMaxChunkGenerateRate = -1.0;
+ }
+
+ public ChunkLoadingAdvanced chunkLoadingAdvanced;
+
+ public class ChunkLoadingAdvanced extends ConfigurationPart {
+ @Comment(
+ "Set to true if the server will match the chunk send radius that clients have configured" +
+ "in their view distance settings if the client is less-than the server's send distance."
+ )
+ public boolean autoConfigSendDistance = true;
+
+ @Comment(
+ "Specifies the maximum amount of concurrent chunk loads that an individual player can have." +
+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit."
+ )
+ public int playerMaxConcurrentChunkLoads = 0;
+
+ @Comment(
+ "Specifies the maximum amount of concurrent chunk generations that an individual player can have." +
+ "Set to 0 to let the server configure it automatically per player, or set it to -1 to disable the limit."
+ )
+ public int playerMaxConcurrentChunkGenerates = 0;
+ }
static void set(GlobalConfiguration instance) {
GlobalConfiguration.instance = instance;
}
@@ -145,21 +184,6 @@ public class GlobalConfiguration extends ConfigurationPart {
public int incomingPacketThreshold = 300;
}
- public ChunkLoading chunkLoading;
-
- public class ChunkLoading extends ConfigurationPart {
- public int minLoadRadius = 2;
- public int maxConcurrentSends = 2;
- public boolean autoconfigSendDistance = true;
- public double targetPlayerChunkSendRate = 100.0;
- public double globalMaxChunkSendRate = -1.0;
- public boolean enableFrustumPriority = false;
- public double globalMaxChunkLoadRate = -1.0;
- public double playerMaxConcurrentLoads = 20.0;
- public double globalMaxConcurrentLoads = 500.0;
- public double playerMaxChunkLoadRate = -1.0;
- }
-
public UnsupportedSettings unsupportedSettings;
public class UnsupportedSettings extends ConfigurationPart {
@@ -218,7 +242,7 @@ public class GlobalConfiguration extends ConfigurationPart {
@PostProcess
private void postProcess() {
- //io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.init(this);
+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.init(this);
}
}

View file

@ -5,10 +5,10 @@ Subject: [PATCH] fixup! Optimize BlockPosition helper methods
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e51d7f249 100644 index 0d51fb4be8b49e3b57c3c55aff6bcf13d5c78ddd..a1d54d978d34d75475f92dfb806113586e7e449c 100644
--- a/src/main/java/net/minecraft/core/BlockPos.java --- a/src/main/java/net/minecraft/core/BlockPos.java
+++ b/src/main/java/net/minecraft/core/BlockPos.java +++ b/src/main/java/net/minecraft/core/BlockPos.java
@@ -161,7 +161,7 @@ public class BlockPos extends Vec3i { @@ -162,7 +162,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos above(int distance) { public BlockPos above(int distance) {
@ -17,7 +17,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e
} }
@Override @Override
@@ -171,7 +171,7 @@ public class BlockPos extends Vec3i { @@ -172,7 +172,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos below(int i) { public BlockPos below(int i) {
@ -26,7 +26,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e
} }
@Override @Override
@@ -181,7 +181,7 @@ public class BlockPos extends Vec3i { @@ -182,7 +182,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos north(int distance) { public BlockPos north(int distance) {
@ -35,7 +35,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e
} }
@Override @Override
@@ -191,7 +191,7 @@ public class BlockPos extends Vec3i { @@ -192,7 +192,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos south(int distance) { public BlockPos south(int distance) {
@ -44,7 +44,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e
} }
@Override @Override
@@ -201,7 +201,7 @@ public class BlockPos extends Vec3i { @@ -202,7 +202,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos west(int distance) { public BlockPos west(int distance) {
@ -53,7 +53,7 @@ index 2767d6f97e8b314d23a8e62f22dfd396f5660d31..7362d471f9c1858e0dd7832e1ff59e3e
} }
@Override @Override
@@ -211,7 +211,7 @@ public class BlockPos extends Vec3i { @@ -212,7 +212,7 @@ public class BlockPos extends Vec3i {
@Override @Override
public BlockPos east(int distance) { public BlockPos east(int distance) {

View file

@ -1,345 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 21 Oct 2024 12:52:44 -0700
Subject: [PATCH] Revert "Custom table implementation for blockstate state
lookups"
This reverts commit 14a7e6521ba0ce6dc8ebf98a1ccce59a5ec6a194.
TODO Replace via deleting the patch
diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
deleted file mode 100644
index 57d0cd3ad6f972e986c72a57f1a6e36003f190c2..0000000000000000000000000000000000000000
--- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package io.papermc.paper.util.table;
-
-import com.google.common.collect.Table;
-import net.minecraft.world.level.block.state.StateHolder;
-import net.minecraft.world.level.block.state.properties.Property;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public final class ZeroCollidingReferenceStateTable {
-
- // upper 32 bits: starting index
- // lower 32 bits: bitset for contained ids
- protected final long[] this_index_table;
- protected final Comparable<?>[] this_table;
- protected final StateHolder<?, ?> this_state;
-
- protected long[] index_table;
- protected StateHolder<?, ?>[][] value_table;
-
- public ZeroCollidingReferenceStateTable(final StateHolder<?, ?> state, final Map<Property<?>, Comparable<?>> this_map) {
- this.this_state = state;
- this.this_index_table = this.create_table(this_map.keySet());
-
- int max_id = -1;
- for (final Property<?> property : this_map.keySet()) {
- final int id = lookup_vindex(property, this.this_index_table);
- if (id > max_id) {
- max_id = id;
- }
- }
-
- this.this_table = new Comparable[max_id + 1];
- for (final Map.Entry<Property<?>, Comparable<?>> entry : this_map.entrySet()) {
- this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue();
- }
- }
-
- public void loadInTable(final Table<Property<?>, Comparable<?>, StateHolder<?, ?>> table,
- final Map<Property<?>, Comparable<?>> this_map) {
- final Set<Property<?>> combined = new HashSet<>(table.rowKeySet());
- combined.addAll(this_map.keySet());
-
- this.index_table = this.create_table(combined);
-
- int max_id = -1;
- for (final Property<?> property : combined) {
- final int id = lookup_vindex(property, this.index_table);
- if (id > max_id) {
- max_id = id;
- }
- }
-
- this.value_table = new StateHolder[max_id + 1][];
-
- final Map<Property<?>, Map<Comparable<?>, StateHolder<?, ?>>> map = table.rowMap();
- for (final Property<?> property : map.keySet()) {
- final Map<Comparable<?>, StateHolder<?, ?>> propertyMap = map.get(property);
-
- final int id = lookup_vindex(property, this.index_table);
- final StateHolder<?, ?>[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()];
-
- for (final Map.Entry<Comparable<?>, StateHolder<?, ?>> entry : propertyMap.entrySet()) {
- if (entry.getValue() == null) {
- // TODO what
- continue;
- }
-
- states[((Property)property).getIdFor(entry.getKey())] = entry.getValue();
- }
- }
-
-
- for (final Map.Entry<Property<?>, Comparable<?>> entry : this_map.entrySet()) {
- final Property<?> property = entry.getKey();
- final int index = lookup_vindex(property, this.index_table);
-
- if (this.value_table[index] == null) {
- this.value_table[index] = new StateHolder[property.getPossibleValues().size()];
- }
-
- this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state;
- }
- }
-
-
- protected long[] create_table(final Collection<Property<?>> collection) {
- int max_id = -1;
- for (final Property<?> property : collection) {
- final int id = property.getId();
- if (id > max_id) {
- max_id = id;
- }
- }
-
- final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32)
-
- for (final Property<?> property : collection) {
- final int id = property.getId();
-
- ret[id >>> 5] |= (1L << (id & 31));
- }
-
- int total = 0;
- for (int i = 1, len = ret.length; i < len; ++i) {
- ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32;
- }
-
- return ret;
- }
-
- public Comparable<?> get(final Property<?> state) {
- final Comparable<?>[] table = this.this_table;
- final int index = lookup_vindex(state, this.this_index_table);
-
- if (index < 0 || index >= table.length) {
- return null;
- }
- return table[index];
- }
-
- public StateHolder<?, ?> get(final Property<?> property, final Comparable<?> with) {
- final int withId = ((Property)property).getIdFor(with);
- if (withId < 0) {
- return null;
- }
-
- final int index = lookup_vindex(property, this.index_table);
- final StateHolder<?, ?>[][] table = this.value_table;
- if (index < 0 || index >= table.length) {
- return null;
- }
-
- final StateHolder<?, ?>[] values = table[index];
-
- if (withId >= values.length) {
- return null;
- }
-
- return values[withId];
- }
-
- protected static int lookup_vindex(final Property<?> property, final long[] index_table) {
- final int id = property.getId();
- final long bitset_mask = (1L << (id & 31));
- final long lower_mask = bitset_mask - 1;
- final int index = id >>> 5;
- if (index >= index_table.length) {
- return -1;
- }
- final long index_value = index_table[index];
- final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain
-
- // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id
- // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0,
- // otherwise it comes out as -1.
- return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check);
- }
-}
diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
index 45744d86e9582a93a0cec26009deea091080fbbe..daedcfd867ed6171fb61bdcbded417a11c8a5b0f 100644
--- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
+++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
@@ -39,13 +39,11 @@ public abstract class StateHolder<O, S> {
private final Reference2ObjectArrayMap<Property<?>, Comparable<?>> values;
private Table<Property<?>, Comparable<?>, S> neighbours;
protected final MapCodec<S> propertiesCodec;
- protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup
protected StateHolder(O owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<S> codec) {
this.owner = owner;
this.values = propertyMap;
this.propertiesCodec = codec;
- this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup
}
public <T extends Comparable<T>> S cycle(Property<T> property) {
@@ -86,11 +84,11 @@ public abstract class StateHolder<O, S> {
}
public <T extends Comparable<T>> boolean hasProperty(Property<T> property) {
- return this.optimisedTable.get(property) != null; // Paper - optimise state lookup
+ return this.values.containsKey(property);
}
public <T extends Comparable<T>> T getValue(Property<T> property) {
- Comparable<?> comparable = this.optimisedTable.get(property); // Paper - optimise state lookup
+ Comparable<?> comparable = this.values.get(property);
if (comparable == null) {
throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
} else {
@@ -99,18 +97,24 @@ public abstract class StateHolder<O, S> {
}
public <T extends Comparable<T>> Optional<T> getOptionalValue(Property<T> property) {
- Comparable<?> comparable = this.optimisedTable.get(property); // Paper - optimise state lookup
+ Comparable<?> comparable = this.values.get(property);
return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable));
}
public <T extends Comparable<T>, V extends T> S setValue(Property<T> property, V value) {
- // Paper start - optimise state lookup
- final S ret = (S)this.optimisedTable.get(property, value);
- if (ret == null) {
- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value");
+ Comparable<?> comparable = this.values.get(property);
+ if (comparable == null) {
+ throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner);
+ } else if (comparable.equals(value)) {
+ return (S)this;
+ } else {
+ S object = this.neighbours.get(property, value);
+ if (object == null) {
+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value");
+ } else {
+ return object;
+ }
}
- return ret;
- // Paper end - optimise state lookup
}
public <T extends Comparable<T>, V extends T> S trySetValue(Property<T> property, V value) {
@@ -143,7 +147,7 @@ public abstract class StateHolder<O, S> {
}
}
- this.neighbours = (Table<Property<?>, Comparable<?>, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup
+ this.neighbours = (Table<Property<?>, Comparable<?>, S>)(table.isEmpty() ? table : ArrayTable.create(table));
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
index ff5fd91257c4554c523682009efe1db83f53fd5b..b63116b333b6e06494091a82588acfb639bddb71 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
@@ -7,13 +7,6 @@ import java.util.Optional;
public class BooleanProperty extends Property<Boolean> {
private final ImmutableSet<Boolean> values = ImmutableSet.of(true, false);
- // Paper start - optimise iblockdata state lookup
- @Override
- public final int getIdFor(final Boolean value) {
- return value.booleanValue() ? 1 : 0;
- }
- // Paper end - optimise iblockdata state lookup
-
protected BooleanProperty(String name) {
super(name, Boolean.class);
}
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
index 498c5abe0a9d024d77029719c621c1c8485791f3..3097298fe356df98967cf4bdeaaede69dfe8a441 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
@@ -15,15 +15,6 @@ public class EnumProperty<T extends Enum<T> & StringRepresentable> extends Prope
private final ImmutableSet<T> values;
private final Map<String, T> names = Maps.newHashMap();
- // Paper start - optimise iblockdata state lookup
- private int[] idLookupTable;
-
- @Override
- public final int getIdFor(final T value) {
- return this.idLookupTable[value.ordinal()];
- }
- // Paper end - optimise iblockdata state lookup
-
protected EnumProperty(String name, Class<T> type, Collection<T> values) {
super(name, type);
this.values = ImmutableSet.copyOf(values);
@@ -36,14 +27,6 @@ public class EnumProperty<T extends Enum<T> & StringRepresentable> extends Prope
this.names.put(string, enum_);
}
- // Paper start - optimise BlockState lookup
- int id = 0;
- this.idLookupTable = new int[type.getEnumConstants().length];
- java.util.Arrays.fill(this.idLookupTable, -1);
- for (final T value : this.getPossibleValues()) {
- this.idLookupTable[value.ordinal()] = id++;
- }
- // Paper end - optimise BlockState lookup
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
index 977504f2641d0133a572b0d5de85d058609343bb..3a850321a4bcc68058483b5fd53e829c425a68af 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
@@ -11,16 +11,6 @@ public class IntegerProperty extends Property<Integer> {
public final int min;
public final int max;
- // Paper start - optimise iblockdata state lookup
- @Override
- public final int getIdFor(final Integer value) {
- final int val = value.intValue();
- final int ret = val - this.min;
-
- return ret | ((this.max - ret) >> 31);
- }
- // Paper end - optimise iblockdata state lookup
-
protected IntegerProperty(String name, int min, int max) {
super(name, Integer.class);
if (min < 0) {
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
index b9493e3762410aca8e683c32b5aef187c0bee082..9055f15af0cae55effa6942913a9d7edf3857e07 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
@@ -24,17 +24,6 @@ public abstract class Property<T extends Comparable<T>> {
);
private final Codec<Property.Value<T>> valueCodec = this.codec.xmap(this::value, Property.Value::value);
- // Paper start - optimise iblockdata state lookup
- private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger();
- private final int id = ID_GENERATOR.getAndIncrement();
-
- public final int getId() {
- return this.id;
- }
-
- public abstract int getIdFor(final T value);
- // Paper end - optimise state lookup
-
protected Property(String name, Class<T> type) {
this.clazz = type;
this.name = name;

View file

@ -1,343 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 11 Mar 2021 20:05:44 -0800
Subject: [PATCH] Custom table implementation for blockstate state lookups
Testing some redstone intensive machines showed to bring about a 10%
improvement.
diff --git a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..57d0cd3ad6f972e986c72a57f1a6e36003f190c2
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
@@ -0,0 +1,160 @@
+package io.papermc.paper.util.table;
+
+import com.google.common.collect.Table;
+import net.minecraft.world.level.block.state.StateHolder;
+import net.minecraft.world.level.block.state.properties.Property;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public final class ZeroCollidingReferenceStateTable {
+
+ // upper 32 bits: starting index
+ // lower 32 bits: bitset for contained ids
+ protected final long[] this_index_table;
+ protected final Comparable<?>[] this_table;
+ protected final StateHolder<?, ?> this_state;
+
+ protected long[] index_table;
+ protected StateHolder<?, ?>[][] value_table;
+
+ public ZeroCollidingReferenceStateTable(final StateHolder<?, ?> state, final Map<Property<?>, Comparable<?>> this_map) {
+ this.this_state = state;
+ this.this_index_table = this.create_table(this_map.keySet());
+
+ int max_id = -1;
+ for (final Property<?> property : this_map.keySet()) {
+ final int id = lookup_vindex(property, this.this_index_table);
+ if (id > max_id) {
+ max_id = id;
+ }
+ }
+
+ this.this_table = new Comparable[max_id + 1];
+ for (final Map.Entry<Property<?>, Comparable<?>> entry : this_map.entrySet()) {
+ this.this_table[lookup_vindex(entry.getKey(), this.this_index_table)] = entry.getValue();
+ }
+ }
+
+ public void loadInTable(final Table<Property<?>, Comparable<?>, StateHolder<?, ?>> table,
+ final Map<Property<?>, Comparable<?>> this_map) {
+ final Set<Property<?>> combined = new HashSet<>(table.rowKeySet());
+ combined.addAll(this_map.keySet());
+
+ this.index_table = this.create_table(combined);
+
+ int max_id = -1;
+ for (final Property<?> property : combined) {
+ final int id = lookup_vindex(property, this.index_table);
+ if (id > max_id) {
+ max_id = id;
+ }
+ }
+
+ this.value_table = new StateHolder[max_id + 1][];
+
+ final Map<Property<?>, Map<Comparable<?>, StateHolder<?, ?>>> map = table.rowMap();
+ for (final Property<?> property : map.keySet()) {
+ final Map<Comparable<?>, StateHolder<?, ?>> propertyMap = map.get(property);
+
+ final int id = lookup_vindex(property, this.index_table);
+ final StateHolder<?, ?>[] states = this.value_table[id] = new StateHolder[property.getPossibleValues().size()];
+
+ for (final Map.Entry<Comparable<?>, StateHolder<?, ?>> entry : propertyMap.entrySet()) {
+ if (entry.getValue() == null) {
+ // TODO what
+ continue;
+ }
+
+ states[((Property)property).getIdFor(entry.getKey())] = entry.getValue();
+ }
+ }
+
+
+ for (final Map.Entry<Property<?>, Comparable<?>> entry : this_map.entrySet()) {
+ final Property<?> property = entry.getKey();
+ final int index = lookup_vindex(property, this.index_table);
+
+ if (this.value_table[index] == null) {
+ this.value_table[index] = new StateHolder[property.getPossibleValues().size()];
+ }
+
+ this.value_table[index][((Property)property).getIdFor(entry.getValue())] = this.this_state;
+ }
+ }
+
+
+ protected long[] create_table(final Collection<Property<?>> collection) {
+ int max_id = -1;
+ for (final Property<?> property : collection) {
+ final int id = property.getId();
+ if (id > max_id) {
+ max_id = id;
+ }
+ }
+
+ final long[] ret = new long[((max_id + 1) + 31) >>> 5]; // ceil((max_id + 1) / 32)
+
+ for (final Property<?> property : collection) {
+ final int id = property.getId();
+
+ ret[id >>> 5] |= (1L << (id & 31));
+ }
+
+ int total = 0;
+ for (int i = 1, len = ret.length; i < len; ++i) {
+ ret[i] |= (long)(total += Long.bitCount(ret[i - 1] & 0xFFFFFFFFL)) << 32;
+ }
+
+ return ret;
+ }
+
+ public Comparable<?> get(final Property<?> state) {
+ final Comparable<?>[] table = this.this_table;
+ final int index = lookup_vindex(state, this.this_index_table);
+
+ if (index < 0 || index >= table.length) {
+ return null;
+ }
+ return table[index];
+ }
+
+ public StateHolder<?, ?> get(final Property<?> property, final Comparable<?> with) {
+ final int withId = ((Property)property).getIdFor(with);
+ if (withId < 0) {
+ return null;
+ }
+
+ final int index = lookup_vindex(property, this.index_table);
+ final StateHolder<?, ?>[][] table = this.value_table;
+ if (index < 0 || index >= table.length) {
+ return null;
+ }
+
+ final StateHolder<?, ?>[] values = table[index];
+
+ if (withId >= values.length) {
+ return null;
+ }
+
+ return values[withId];
+ }
+
+ protected static int lookup_vindex(final Property<?> property, final long[] index_table) {
+ final int id = property.getId();
+ final long bitset_mask = (1L << (id & 31));
+ final long lower_mask = bitset_mask - 1;
+ final int index = id >>> 5;
+ if (index >= index_table.length) {
+ return -1;
+ }
+ final long index_value = index_table[index];
+ final long contains_check = ((index_value & bitset_mask) - 1) >> (Long.SIZE - 1); // -1L if doesn't contain
+
+ // index = total bits set in lower table values (upper 32 bits of index_value) plus total bits set in lower indices below id
+ // contains_check is 0 if the bitset had id set, else it's -1: so index is unaffected if contains_check == 0,
+ // otherwise it comes out as -1.
+ return (int)(((index_value >>> 32) + Long.bitCount(index_value & lower_mask)) | contains_check);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
index daedcfd867ed6171fb61bdcbded417a11c8a5b0f..45744d86e9582a93a0cec26009deea091080fbbe 100644
--- a/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
+++ b/src/main/java/net/minecraft/world/level/block/state/StateHolder.java
@@ -39,11 +39,13 @@ public abstract class StateHolder<O, S> {
private final Reference2ObjectArrayMap<Property<?>, Comparable<?>> values;
private Table<Property<?>, Comparable<?>, S> neighbours;
protected final MapCodec<S> propertiesCodec;
+ protected final io.papermc.paper.util.table.ZeroCollidingReferenceStateTable optimisedTable; // Paper - optimise state lookup
protected StateHolder(O owner, Reference2ObjectArrayMap<Property<?>, Comparable<?>> propertyMap, MapCodec<S> codec) {
this.owner = owner;
this.values = propertyMap;
this.propertiesCodec = codec;
+ this.optimisedTable = new io.papermc.paper.util.table.ZeroCollidingReferenceStateTable(this, propertyMap); // Paper - optimise state lookup
}
public <T extends Comparable<T>> S cycle(Property<T> property) {
@@ -84,11 +86,11 @@ public abstract class StateHolder<O, S> {
}
public <T extends Comparable<T>> boolean hasProperty(Property<T> property) {
- return this.values.containsKey(property);
+ return this.optimisedTable.get(property) != null; // Paper - optimise state lookup
}
public <T extends Comparable<T>> T getValue(Property<T> property) {
- Comparable<?> comparable = this.values.get(property);
+ Comparable<?> comparable = this.optimisedTable.get(property); // Paper - optimise state lookup
if (comparable == null) {
throw new IllegalArgumentException("Cannot get property " + property + " as it does not exist in " + this.owner);
} else {
@@ -97,24 +99,18 @@ public abstract class StateHolder<O, S> {
}
public <T extends Comparable<T>> Optional<T> getOptionalValue(Property<T> property) {
- Comparable<?> comparable = this.values.get(property);
+ Comparable<?> comparable = this.optimisedTable.get(property); // Paper - optimise state lookup
return comparable == null ? Optional.empty() : Optional.of(property.getValueClass().cast(comparable));
}
public <T extends Comparable<T>, V extends T> S setValue(Property<T> property, V value) {
- Comparable<?> comparable = this.values.get(property);
- if (comparable == null) {
- throw new IllegalArgumentException("Cannot set property " + property + " as it does not exist in " + this.owner);
- } else if (comparable.equals(value)) {
- return (S)this;
- } else {
- S object = this.neighbours.get(property, value);
- if (object == null) {
- throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value");
- } else {
- return object;
- }
+ // Paper start - optimise state lookup
+ final S ret = (S)this.optimisedTable.get(property, value);
+ if (ret == null) {
+ throw new IllegalArgumentException("Cannot set property " + property + " to " + value + " on " + this.owner + ", it is not an allowed value");
}
+ return ret;
+ // Paper end - optimise state lookup
}
public <T extends Comparable<T>, V extends T> S trySetValue(Property<T> property, V value) {
@@ -147,7 +143,7 @@ public abstract class StateHolder<O, S> {
}
}
- this.neighbours = (Table<Property<?>, Comparable<?>, S>)(table.isEmpty() ? table : ArrayTable.create(table));
+ this.neighbours = (Table<Property<?>, Comparable<?>, S>)(table.isEmpty() ? table : ArrayTable.create(table)); this.optimisedTable.loadInTable((Table)this.neighbours, this.values); // Paper - optimise state lookup
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
index b63116b333b6e06494091a82588acfb639bddb71..ff5fd91257c4554c523682009efe1db83f53fd5b 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
@@ -7,6 +7,13 @@ import java.util.Optional;
public class BooleanProperty extends Property<Boolean> {
private final ImmutableSet<Boolean> values = ImmutableSet.of(true, false);
+ // Paper start - optimise iblockdata state lookup
+ @Override
+ public final int getIdFor(final Boolean value) {
+ return value.booleanValue() ? 1 : 0;
+ }
+ // Paper end - optimise iblockdata state lookup
+
protected BooleanProperty(String name) {
super(name, Boolean.class);
}
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
index 3097298fe356df98967cf4bdeaaede69dfe8a441..498c5abe0a9d024d77029719c621c1c8485791f3 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
@@ -15,6 +15,15 @@ public class EnumProperty<T extends Enum<T> & StringRepresentable> extends Prope
private final ImmutableSet<T> values;
private final Map<String, T> names = Maps.newHashMap();
+ // Paper start - optimise iblockdata state lookup
+ private int[] idLookupTable;
+
+ @Override
+ public final int getIdFor(final T value) {
+ return this.idLookupTable[value.ordinal()];
+ }
+ // Paper end - optimise iblockdata state lookup
+
protected EnumProperty(String name, Class<T> type, Collection<T> values) {
super(name, type);
this.values = ImmutableSet.copyOf(values);
@@ -27,6 +36,14 @@ public class EnumProperty<T extends Enum<T> & StringRepresentable> extends Prope
this.names.put(string, enum_);
}
+ // Paper start - optimise BlockState lookup
+ int id = 0;
+ this.idLookupTable = new int[type.getEnumConstants().length];
+ java.util.Arrays.fill(this.idLookupTable, -1);
+ for (final T value : this.getPossibleValues()) {
+ this.idLookupTable[value.ordinal()] = id++;
+ }
+ // Paper end - optimise BlockState lookup
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
index 3a850321a4bcc68058483b5fd53e829c425a68af..977504f2641d0133a572b0d5de85d058609343bb 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
@@ -11,6 +11,16 @@ public class IntegerProperty extends Property<Integer> {
public final int min;
public final int max;
+ // Paper start - optimise iblockdata state lookup
+ @Override
+ public final int getIdFor(final Integer value) {
+ final int val = value.intValue();
+ final int ret = val - this.min;
+
+ return ret | ((this.max - ret) >> 31);
+ }
+ // Paper end - optimise iblockdata state lookup
+
protected IntegerProperty(String name, int min, int max) {
super(name, Integer.class);
if (min < 0) {
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
index 9055f15af0cae55effa6942913a9d7edf3857e07..b9493e3762410aca8e683c32b5aef187c0bee082 100644
--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
@@ -24,6 +24,17 @@ public abstract class Property<T extends Comparable<T>> {
);
private final Codec<Property.Value<T>> valueCodec = this.codec.xmap(this::value, Property.Value::value);
+ // Paper start - optimise iblockdata state lookup
+ private static final java.util.concurrent.atomic.AtomicInteger ID_GENERATOR = new java.util.concurrent.atomic.AtomicInteger();
+ private final int id = ID_GENERATOR.getAndIncrement();
+
+ public final int getId() {
+ return this.id;
+ }
+
+ public abstract int getIdFor(final T value);
+ // Paper end - optimise state lookup
+
protected Property(String name, Class<T> type) {
this.clazz = type;
this.name = name;