diff --git a/divinemc-server/minecraft-patches/features/0071-Optimize-Moonrise.patch b/divinemc-server/minecraft-patches/features/0071-Optimize-Moonrise.patch index e961bb1..431d745 100644 --- a/divinemc-server/minecraft-patches/features/0071-Optimize-Moonrise.patch +++ b/divinemc-server/minecraft-patches/features/0071-Optimize-Moonrise.patch @@ -30,6 +30,43 @@ index 93272808d94e81d31af728ebe85df9a2bc7aedab..b47be4b838f4c7f6c3fb62e4e18105c6 } } +diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +index 2d24d03bbdb5ee0d862cbfff2219f58afffafe12..b4c55b8fee8dbab278e096580702a05282da2d51 100644 +--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java +@@ -93,8 +93,14 @@ public abstract class EntityLookup implements LevelEntityGetter { + if (entity == null) { + return null; + } +- final Visibility visibility = EntityLookup.getEntityStatus(entity); +- return visibility.isAccessible() ? entity : null; ++ // DivineMC start - Optimize Moonrise ++ final FullChunkStatus entityStatus = ((ChunkSystemEntity) entity).moonrise$getChunkStatus(); ++ return switch (entityStatus) { ++ case INACCESSIBLE -> null; ++ case FULL, BLOCK_TICKING, ENTITY_TICKING -> entity; ++ case null -> null; ++ }; ++ // DivineMC end - Optimize Moonrise + } + + @Override +@@ -398,7 +404,14 @@ public abstract class EntityLookup implements LevelEntityGetter { + return Visibility.TICKING; + } + final FullChunkStatus entityStatus = ((ChunkSystemEntity)entity).moonrise$getChunkStatus(); +- return Visibility.fromFullChunkStatus(entityStatus == null ? FullChunkStatus.INACCESSIBLE : entityStatus); ++ // DivineMC start - Optimize Moonrise ++ return switch (entityStatus) { ++ case INACCESSIBLE -> Visibility.HIDDEN; ++ case FULL, BLOCK_TICKING -> Visibility.TRACKED; ++ case ENTITY_TICKING -> Visibility.TICKING; ++ case null -> Visibility.HIDDEN; ++ }; ++ // DivineMC end - Optimize Moonrise + } + + protected boolean addEntity(final Entity entity, final boolean fromDisk, final boolean event) { diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java index 57fec1f9a210d2ecb74ff7b05cec790ae77f9178..4d0e904d7d7659b24a883893cef167f3e80dfa36 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java diff --git a/divinemc-server/minecraft-patches/features/0073-Entity-Status-Lock.patch b/divinemc-server/minecraft-patches/features/0073-Entity-Status-Lock.patch new file mode 100644 index 0000000..81bf6b8 --- /dev/null +++ b/divinemc-server/minecraft-patches/features/0073-Entity-Status-Lock.patch @@ -0,0 +1,180 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Mon, 8 Sep 2025 00:53:55 +0300 +Subject: [PATCH] Entity Status Lock + + +diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +index b2bcfb3557a0326fd7ec1059f95d6da4568dfd80..5b3e8951c619cc2af023d13c2067b8d3df9e76e3 100644 +--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +@@ -225,8 +225,10 @@ public final class ChunkEntitySlices { + } + } + ++ private final java.util.concurrent.locks.ReentrantLock statusLock = new java.util.concurrent.locks.ReentrantLock(); // DivineMC - Entity Status Lock + private boolean preventStatusUpdates; + public boolean startPreventingStatusUpdates() { ++ this.statusLock.lock(); // DivineMC - Entity Status Lock + final boolean ret = this.preventStatusUpdates; + this.preventStatusUpdates = true; + return ret; +@@ -238,85 +240,107 @@ public final class ChunkEntitySlices { + + public void stopPreventingStatusUpdates(final boolean prev) { + this.preventStatusUpdates = prev; ++ this.statusLock.unlock(); // DivineMC - Entity Status Lock + } + + public void updateStatus(final FullChunkStatus status, final EntityLookup lookup) { +- this.status = status; ++ // DivineMC start - Entity Status Lock ++ this.statusLock.lock(); ++ try { ++ this.status = status; + +- final Entity[] entities = this.entities.getRawData(); ++ final Entity[] entities = this.entities.getRawData(); + +- for (int i = 0, size = this.entities.size(); i < size; ++i) { +- final Entity entity = entities[i]; ++ for (int i = 0, size = this.entities.size(); i < size; ++i) { ++ final Entity entity = entities[i]; + +- final Visibility oldVisibility = EntityLookup.getEntityStatus(entity); +- ((ChunkSystemEntity)entity).moonrise$setChunkStatus(status); +- final Visibility newVisibility = EntityLookup.getEntityStatus(entity); ++ final Visibility oldVisibility = EntityLookup.getEntityStatus(entity); ++ ((ChunkSystemEntity) entity).moonrise$setChunkStatus(status); ++ final Visibility newVisibility = EntityLookup.getEntityStatus(entity); + +- lookup.entityStatusChange(entity, this, oldVisibility, newVisibility, false, false, false); ++ lookup.entityStatusChange(entity, this, oldVisibility, newVisibility, false, false, false); ++ } ++ } finally { ++ this.statusLock.unlock(); + } ++ // DivineMC end - Entity Status Lock + } + + public boolean addEntity(final Entity entity, final int chunkSection) { +- if (!this.entities.add(entity)) { +- return false; +- } +- ((ChunkSystemEntity)entity).moonrise$setChunkStatus(this.status); +- ((ChunkSystemEntity)entity).moonrise$setChunkData(this.chunkData); +- final int sectionIndex = chunkSection - this.minSection; ++ // DivineMC start - Entity Status Lock ++ this.statusLock.lock(); ++ try { ++ if (!this.entities.add(entity)) { ++ return false; ++ } ++ ((ChunkSystemEntity) entity).moonrise$setChunkStatus(this.status); ++ ((ChunkSystemEntity) entity).moonrise$setChunkData(this.chunkData); ++ final int sectionIndex = chunkSection - this.minSection; + +- this.allEntities.addEntity(entity, sectionIndex); ++ this.allEntities.addEntity(entity, sectionIndex); + +- if (((ChunkSystemEntity)entity).moonrise$isHardColliding()) { +- this.hardCollidingEntities.addEntity(entity, sectionIndex); +- } ++ if (((ChunkSystemEntity) entity).moonrise$isHardColliding()) { ++ this.hardCollidingEntities.addEntity(entity, sectionIndex); ++ } + +- for (final Iterator, EntityCollectionBySection>> iterator = +- this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { +- final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); ++ for (final Iterator, EntityCollectionBySection>> iterator = ++ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) { ++ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); + +- if (entry.getKey().isInstance(entity)) { +- entry.getValue().addEntity(entity, sectionIndex); ++ if (entry.getKey().isInstance(entity)) { ++ entry.getValue().addEntity(entity, sectionIndex); ++ } + } +- } + +- EntityCollectionBySection byType = this.entitiesByType.get(entity.getType()); +- if (byType != null) { +- byType.addEntity(entity, sectionIndex); +- } else { +- this.entitiesByType.put(entity.getType(), byType = new EntityCollectionBySection(this)); +- byType.addEntity(entity, sectionIndex); +- } ++ EntityCollectionBySection byType = this.entitiesByType.get(entity.getType()); ++ if (byType != null) { ++ byType.addEntity(entity, sectionIndex); ++ } else { ++ this.entitiesByType.put(entity.getType(), byType = new EntityCollectionBySection(this)); ++ byType.addEntity(entity, sectionIndex); ++ } + +- return true; ++ return true; ++ } finally { ++ this.statusLock.unlock(); ++ } ++ // DivineMC end - Entity Status Lock + } + + public boolean removeEntity(final Entity entity, final int chunkSection) { +- if (!this.entities.remove(entity)) { +- return false; +- } +- ((ChunkSystemEntity)entity).moonrise$setChunkStatus(null); +- ((ChunkSystemEntity)entity).moonrise$setChunkData(null); +- final int sectionIndex = chunkSection - this.minSection; ++ // DivineMC start - Entity Status Lock ++ this.statusLock.lock(); ++ try { ++ if (!this.entities.remove(entity)) { ++ return false; ++ } ++ ((ChunkSystemEntity) entity).moonrise$setChunkStatus(null); ++ ((ChunkSystemEntity) entity).moonrise$setChunkData(null); ++ final int sectionIndex = chunkSection - this.minSection; + +- this.allEntities.removeEntity(entity, sectionIndex); ++ this.allEntities.removeEntity(entity, sectionIndex); + +- if (((ChunkSystemEntity)entity).moonrise$isHardColliding()) { +- this.hardCollidingEntities.removeEntity(entity, sectionIndex); +- } ++ if (((ChunkSystemEntity) entity).moonrise$isHardColliding()) { ++ this.hardCollidingEntities.removeEntity(entity, sectionIndex); ++ } + +- for (final Iterator, EntityCollectionBySection>> iterator = +- this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext();) { +- final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); ++ for (final Iterator, EntityCollectionBySection>> iterator = ++ this.entitiesByClass.reference2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) { ++ final Reference2ObjectMap.Entry, EntityCollectionBySection> entry = iterator.next(); + +- if (entry.getKey().isInstance(entity)) { +- entry.getValue().removeEntity(entity, sectionIndex); ++ if (entry.getKey().isInstance(entity)) { ++ entry.getValue().removeEntity(entity, sectionIndex); ++ } + } +- } + +- final EntityCollectionBySection byType = this.entitiesByType.get(entity.getType()); +- byType.removeEntity(entity, sectionIndex); ++ final EntityCollectionBySection byType = this.entitiesByType.get(entity.getType()); ++ byType.removeEntity(entity, sectionIndex); + +- return true; ++ return true; ++ } finally { ++ this.statusLock.unlock(); ++ } ++ // DivineMC end - Entity Status Lock + } + + public void getHardCollidingEntities(final Entity except, final AABB box, final List into, final Predicate predicate) {