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 c4d6fdcff0
commit 77baea3bf9
9 changed files with 2540 additions and 2481 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

@ -12,10 +12,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+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..00000000000000000000000000000000
+ +
+ 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);
+ +
@ -694,11 +694,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-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;
@@ -0,0 +0,0 @@ public final class ChunkSystem { @@ -0,0 +0,0 @@ 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,27 +707,47 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- 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);
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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");
@@ -0,0 +0,0 @@ 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);
});
} }
@@ -0,0 +0,0 @@ public final class ChunkSystem { @@ -0,0 +0,0 @@ public final class ChunkSystem {
@ -1002,6 +1022,211 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
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..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -0,0 +0,0 @@
+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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
// 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..0000000000000000000000000000000000000000
--- /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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
@@ -0,0 +0,0 @@
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;
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ 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();
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
+++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java
@@ -0,0 +0,0 @@
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;
@@ -0,0 +0,0 @@ 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -0,0 +0,0 @@ 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

@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- a/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
+++ /dev/null
@@ -0,0 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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;

File diff suppressed because it is too large Load diff

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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java
@@ -0,0 +0,0 @@ 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;
}
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ 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

@ -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..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/table/ZeroCollidingReferenceStateTable.java
@@ -0,0 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ 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 {
@@ -0,0 +0,0 @@ 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) {
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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;