mirror of
https://github.com/BX-Team/DivineMC.git
synced 2025-12-21 15:59:23 +00:00
merge and update some patches
This commit is contained in:
@@ -1510,7 +1510,7 @@ index a9f723528dd05cb9583319edcb14143b784a2fd7..21d41b477cc0e8d2476d1e3141bdf23d
|
|||||||
this.stopUsingItem();
|
this.stopUsingItem();
|
||||||
this.connection.send(new ClientboundPlayerAbilitiesPacket(this.getAbilities()));
|
this.connection.send(new ClientboundPlayerAbilitiesPacket(this.getAbilities()));
|
||||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
index 398c1733824b689520170de0be94006731afa5cd..0c499eca39371993c46d510fa45298efdd67d20c 100644
|
index c089a01765945277aafc62cb3566d81162c40c1d..801dd76a2c7f76fc6fdb7167cbf3ab1310be36c9 100644
|
||||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
@@ -24,7 +24,6 @@ import net.minecraft.network.protocol.cookie.ServerboundCookieResponsePacket;
|
@@ -24,7 +24,6 @@ import net.minecraft.network.protocol.cookie.ServerboundCookieResponsePacket;
|
||||||
@@ -1521,7 +1521,7 @@ index 398c1733824b689520170de0be94006731afa5cd..0c499eca39371993c46d510fa45298ef
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
public abstract class ServerCommonPacketListenerImpl implements ServerCommonPacketListener, org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection { // CraftBukkit
|
public abstract class ServerCommonPacketListenerImpl implements ServerCommonPacketListener, org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection { // CraftBukkit
|
||||||
@@ -252,7 +251,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -256,7 +255,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void keepConnectionAlive() {
|
protected void keepConnectionAlive() {
|
||||||
@@ -1529,7 +1529,7 @@ index 398c1733824b689520170de0be94006731afa5cd..0c499eca39371993c46d510fa45298ef
|
|||||||
long millis = Util.getMillis();
|
long millis = Util.getMillis();
|
||||||
// Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
// Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||||
// This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
// This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
||||||
@@ -286,8 +284,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -290,8 +288,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,114 +542,6 @@ index 9641219c190261dea0db5f95f040a705ba0a3ff9..a3fccdeb2c076e12b611683da55d45e0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/biome/BiomeManager.java b/net/minecraft/world/level/biome/BiomeManager.java
|
|
||||||
index 73962e79a0f3d892e3155443a1b84508b0f4042e..db400d7b25e454b4a1ac8d09a590c3c7d2504052 100644
|
|
||||||
--- a/net/minecraft/world/level/biome/BiomeManager.java
|
|
||||||
+++ b/net/minecraft/world/level/biome/BiomeManager.java
|
|
||||||
@@ -14,6 +14,7 @@ public class BiomeManager {
|
|
||||||
private static final int ZOOM_MASK = 3;
|
|
||||||
private final BiomeManager.NoiseBiomeSource noiseBiomeSource;
|
|
||||||
private final long biomeZoomSeed;
|
|
||||||
+ private static final double maxOffset = 0.4500000001D; // DivineMC - Math Optimizations
|
|
||||||
|
|
||||||
public BiomeManager(BiomeManager.NoiseBiomeSource noiseBiomeSource, long biomeZoomSeed) {
|
|
||||||
this.noiseBiomeSource = noiseBiomeSource;
|
|
||||||
@@ -29,39 +30,65 @@ public class BiomeManager {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Holder<Biome> getBiome(BlockPos pos) {
|
|
||||||
- int i = pos.getX() - 2;
|
|
||||||
- int i1 = pos.getY() - 2;
|
|
||||||
- int i2 = pos.getZ() - 2;
|
|
||||||
- int i3 = i >> 2;
|
|
||||||
- int i4 = i1 >> 2;
|
|
||||||
- int i5 = i2 >> 2;
|
|
||||||
- double d = (i & 3) / 4.0;
|
|
||||||
- double d1 = (i1 & 3) / 4.0;
|
|
||||||
- double d2 = (i2 & 3) / 4.0;
|
|
||||||
- int i6 = 0;
|
|
||||||
- double d3 = Double.POSITIVE_INFINITY;
|
|
||||||
+ // DivineMC start - Math Optimizations
|
|
||||||
+ int xMinus2 = pos.getX() - 2;
|
|
||||||
+ int yMinus2 = pos.getY() - 2;
|
|
||||||
+ int zMinus2 = pos.getZ() - 2;
|
|
||||||
+ int x = xMinus2 >> 2;
|
|
||||||
+ int y = yMinus2 >> 2;
|
|
||||||
+ int z = zMinus2 >> 2;
|
|
||||||
+ double quartX = (double) (xMinus2 & 3) / 4.0;
|
|
||||||
+ double quartY = (double) (yMinus2 & 3) / 4.0;
|
|
||||||
+ double quartZ = (double) (zMinus2 & 3) / 4.0;
|
|
||||||
+ int smallestX = 0;
|
|
||||||
+ double smallestDist = Double.POSITIVE_INFINITY;
|
|
||||||
+ for (int biomeX = 0; biomeX < 8; ++biomeX) {
|
|
||||||
+ boolean everyOtherQuad = (biomeX & 4) == 0;
|
|
||||||
+ boolean everyOtherPair = (biomeX & 2) == 0;
|
|
||||||
+ boolean everyOther = (biomeX & 1) == 0;
|
|
||||||
+ double quartXX = everyOtherQuad ? quartX : quartX - 1.0;
|
|
||||||
+ double quartYY = everyOtherPair ? quartY : quartY - 1.0;
|
|
||||||
+ double quartZZ = everyOther ? quartZ : quartZ - 1.0;
|
|
||||||
|
|
||||||
- for (int i7 = 0; i7 < 8; i7++) {
|
|
||||||
- boolean flag = (i7 & 4) == 0;
|
|
||||||
- boolean flag1 = (i7 & 2) == 0;
|
|
||||||
- boolean flag2 = (i7 & 1) == 0;
|
|
||||||
- int i8 = flag ? i3 : i3 + 1;
|
|
||||||
- int i9 = flag1 ? i4 : i4 + 1;
|
|
||||||
- int i10 = flag2 ? i5 : i5 + 1;
|
|
||||||
- double d4 = flag ? d : d - 1.0;
|
|
||||||
- double d5 = flag1 ? d1 : d1 - 1.0;
|
|
||||||
- double d6 = flag2 ? d2 : d2 - 1.0;
|
|
||||||
- double fiddledDistance = getFiddledDistance(this.biomeZoomSeed, i8, i9, i10, d4, d5, d6);
|
|
||||||
- if (d3 > fiddledDistance) {
|
|
||||||
- i6 = i7;
|
|
||||||
- d3 = fiddledDistance;
|
|
||||||
+ double maxQuartYY = 0.0, maxQuartZZ = 0.0;
|
|
||||||
+ if (biomeX != 0) {
|
|
||||||
+ maxQuartYY = Mth.square(Math.max(quartYY + maxOffset, Math.abs(quartYY - maxOffset)));
|
|
||||||
+ maxQuartZZ = Mth.square(Math.max(quartZZ + maxOffset, Math.abs(quartZZ - maxOffset)));
|
|
||||||
+ double maxQuartXX = Mth.square(Math.max(quartXX + maxOffset, Math.abs(quartXX - maxOffset)));
|
|
||||||
+ if (smallestDist < maxQuartXX + maxQuartYY + maxQuartZZ) continue;
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ int xx = everyOtherQuad ? x : x + 1;
|
|
||||||
+ int yy = everyOtherPair ? y : y + 1;
|
|
||||||
+ int zz = everyOther ? z : z + 1;
|
|
||||||
+
|
|
||||||
+ long seed = LinearCongruentialGenerator.next(this.biomeZoomSeed, xx);
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, yy);
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, zz);
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, xx);
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, yy);
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, zz);
|
|
||||||
+ double offsetX = getFiddle(seed);
|
|
||||||
+ double sqrX = Mth.square(quartXX + offsetX);
|
|
||||||
+ if (biomeX != 0 && smallestDist < sqrX + maxQuartYY + maxQuartZZ) continue;
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
|
|
||||||
+ double offsetY = getFiddle(seed);
|
|
||||||
+ double sqrY = Mth.square(quartYY + offsetY);
|
|
||||||
+ if (biomeX != 0 && smallestDist < sqrX + sqrY + maxQuartZZ) continue;
|
|
||||||
+ seed = LinearCongruentialGenerator.next(seed, this.biomeZoomSeed);
|
|
||||||
+ double offsetZ = getFiddle(seed);
|
|
||||||
+ double biomeDist = sqrX + sqrY + Mth.square(quartZZ + offsetZ);
|
|
||||||
|
|
||||||
- int i7x = (i6 & 4) == 0 ? i3 : i3 + 1;
|
|
||||||
- int i11 = (i6 & 2) == 0 ? i4 : i4 + 1;
|
|
||||||
- int i12 = (i6 & 1) == 0 ? i5 : i5 + 1;
|
|
||||||
- return this.noiseBiomeSource.getNoiseBiome(i7x, i11, i12);
|
|
||||||
+ if (smallestDist > biomeDist) {
|
|
||||||
+ smallestX = biomeX;
|
|
||||||
+ smallestDist = biomeDist;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return this.noiseBiomeSource.getNoiseBiome(
|
|
||||||
+ (smallestX & 4) == 0 ? x : x + 1,
|
|
||||||
+ (smallestX & 2) == 0 ? y : y + 1,
|
|
||||||
+ (smallestX & 1) == 0 ? z : z + 1
|
|
||||||
+ );
|
|
||||||
+ // DivineMC end - Math Optimizations
|
|
||||||
}
|
|
||||||
|
|
||||||
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java
|
diff --git a/net/minecraft/world/level/levelgen/blending/Blender.java b/net/minecraft/world/level/levelgen/blending/Blender.java
|
||||||
index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644
|
index 01e5b29d6e9a5c53c0e23b61ed0c1d7be1a0fe08..d80df05e40f3941ade5ed320e12f8dcf47e6b247 100644
|
||||||
--- a/net/minecraft/world/level/levelgen/blending/Blender.java
|
--- a/net/minecraft/world/level/levelgen/blending/Blender.java
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,985 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
|
|
||||||
Date: Sat, 1 Feb 2025 00:33:03 +0300
|
|
||||||
Subject: [PATCH] Chunk System optimization
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
|
||||||
index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..b588449cfe766c14a0cf4ea9640b04a51bbcf433 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
|
||||||
@@ -59,12 +59,15 @@ public final class NearbyPlayers {
|
|
||||||
public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4);
|
|
||||||
|
|
||||||
private final ServerLevel world;
|
|
||||||
- private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
|
|
||||||
- private final Long2ReferenceOpenHashMap<TrackedChunk> byChunk = new Long2ReferenceOpenHashMap<>();
|
|
||||||
- private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private final Object callbackLock = new Object();
|
|
||||||
+ private final it.unimi.dsi.fastutil.objects.Reference2ReferenceMap<ServerPlayer, TrackedPlayer[]> players = it.unimi.dsi.fastutil.objects.Reference2ReferenceMaps.synchronize(new Reference2ReferenceOpenHashMap<>());
|
|
||||||
+ private final it.unimi.dsi.fastutil.longs.Long2ReferenceMap<TrackedChunk> byChunk = it.unimi.dsi.fastutil.longs.Long2ReferenceMaps.synchronize(new Long2ReferenceOpenHashMap<>());
|
|
||||||
+ private final it.unimi.dsi.fastutil.longs.Long2ReferenceMap<ReferenceList<ServerPlayer>>[] directByChunk = new it.unimi.dsi.fastutil.longs.Long2ReferenceMap[TOTAL_MAP_TYPES];
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
{
|
|
||||||
for (int i = 0; i < this.directByChunk.length; ++i) {
|
|
||||||
- this.directByChunk[i] = new Long2ReferenceOpenHashMap<>();
|
|
||||||
+ this.directByChunk[i] = it.unimi.dsi.fastutil.longs.Long2ReferenceMaps.synchronize(new Long2ReferenceOpenHashMap<>()); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -188,7 +191,10 @@ public final class NearbyPlayers {
|
|
||||||
final ReferenceList<ServerPlayer> list = this.players[idx];
|
|
||||||
if (list == null) {
|
|
||||||
++this.nonEmptyLists;
|
|
||||||
- final ReferenceList<ServerPlayer> players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY));
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY);
|
|
||||||
+ final ReferenceList<ServerPlayer> players = this.players[idx];
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players);
|
|
||||||
players.add(player);
|
|
||||||
return;
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java b/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java
|
|
||||||
index 866f38eb0f379ffbe2888023a7d1c290f521a231..08666b4aa1c7663861dc361f60e6f1cc46694521 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/blockstate_propertyaccess/util/ZeroCollidingReferenceStateTable.java
|
|
||||||
@@ -21,13 +21,15 @@ import net.minecraft.world.level.block.state.properties.Property;
|
|
||||||
|
|
||||||
public final class ZeroCollidingReferenceStateTable<O, S> {
|
|
||||||
|
|
||||||
- private final Int2ObjectOpenHashMap<Indexer> propertyToIndexer;
|
|
||||||
+ private final it.unimi.dsi.fastutil.ints.Int2ObjectMap<Indexer> propertyToIndexer; // DivineMC - Chunk System optimization
|
|
||||||
private S[] lookup;
|
|
||||||
private final Collection<Property<?>> properties;
|
|
||||||
|
|
||||||
public ZeroCollidingReferenceStateTable(final Collection<Property<?>> properties) {
|
|
||||||
- this.propertyToIndexer = new Int2ObjectOpenHashMap<>(properties.size());
|
|
||||||
- this.properties = new ReferenceArrayList<>(properties);
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ this.propertyToIndexer = it.unimi.dsi.fastutil.ints.Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>(properties.size()));
|
|
||||||
+ this.properties = it.unimi.dsi.fastutil.objects.ReferenceLists.synchronize(new ReferenceArrayList<>(properties));
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
|
|
||||||
final List<Property<?>> sortedProperties = new ArrayList<>(properties);
|
|
||||||
|
|
||||||
@@ -77,11 +79,11 @@ public final class ZeroCollidingReferenceStateTable<O, S> {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- public boolean isLoaded() {
|
|
||||||
+ public synchronized boolean isLoaded() { // DivineMC - Chunk System optimization
|
|
||||||
return this.lookup != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
- public void loadInTable(final Map<Map<Property<?>, Comparable<?>>, S> universe) {
|
|
||||||
+ public synchronized void loadInTable(final Map<Map<Property<?>, Comparable<?>>, S> universe) { // DivineMC - Chunk System optimization
|
|
||||||
if (this.lookup != null) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
@@ -117,7 +119,7 @@ public final class ZeroCollidingReferenceStateTable<O, S> {
|
|
||||||
return ((PropertyAccess<T>)property).moonrise$getById((int)modded);
|
|
||||||
}
|
|
||||||
|
|
||||||
- public <T extends Comparable<T>> S set(final long index, final Property<T> property, final T with) {
|
|
||||||
+ public synchronized <T extends Comparable<T>> S set(final long index, final Property<T> property, final T with) { // DivineMC - Chunk System optimization
|
|
||||||
final int newValueId = ((PropertyAccess<T>)property).moonrise$getIdFor(with);
|
|
||||||
if (newValueId < 0) {
|
|
||||||
return null;
|
|
||||||
@@ -139,7 +141,7 @@ public final class ZeroCollidingReferenceStateTable<O, S> {
|
|
||||||
return this.lookup[(int)newIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
- public <T extends Comparable<T>> S trySet(final long index, final Property<T> property, final T with, final S dfl) {
|
|
||||||
+ public synchronized <T extends Comparable<T>> S trySet(final long index, final Property<T> property, final T with, final S dfl) { // DivineMC - Chunk System optimization
|
|
||||||
final Indexer indexer = this.propertyToIndexer.get(((PropertyAccess<T>)property).moonrise$getId());
|
|
||||||
if (indexer == null) {
|
|
||||||
return dfl;
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
|
||||||
index 8ef5a1aaac9c27873ce746eb281f77bb318a3c69..76b8d42ae530b59cdaba0583365a557da6b90ede 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
|
||||||
@@ -301,7 +301,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
- public void tick() {
|
|
||||||
+ public synchronized void tick() { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
TickThread.ensureTickThread("Cannot tick player chunk loader async");
|
|
||||||
long currTime = System.nanoTime();
|
|
||||||
for (final ServerPlayer player : new java.util.ArrayList<>(this.world.players())) {
|
|
||||||
@@ -312,6 +312,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
loader.update(); // can't invoke plugin logic
|
|
||||||
loader.updateQueues(currTime);
|
|
||||||
+ player.connection.resumeFlushing(); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -362,7 +363,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
GENERATED_TICKET_LEVEL,
|
|
||||||
TICK_TICKET_LEVEL
|
|
||||||
};
|
|
||||||
- private final Long2ByteOpenHashMap chunkTicketStage = new Long2ByteOpenHashMap();
|
|
||||||
+ private final it.unimi.dsi.fastutil.longs.Long2ByteMap chunkTicketStage = it.unimi.dsi.fastutil.longs.Long2ByteMaps.synchronize(new Long2ByteOpenHashMap()); // DivineMC - Chunk System optimization
|
|
||||||
{
|
|
||||||
this.chunkTicketStage.defaultReturnValue(CHUNK_TICKET_STAGE_NONE);
|
|
||||||
}
|
|
||||||
@@ -384,10 +385,19 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
final int centerX = PlayerChunkLoaderData.this.lastChunkX;
|
|
||||||
final int centerZ = PlayerChunkLoaderData.this.lastChunkZ;
|
|
||||||
|
|
||||||
- return Integer.compare(
|
|
||||||
- Math.abs(c1x - centerX) + Math.abs(c1z - centerZ),
|
|
||||||
- Math.abs(c2x - centerX) + Math.abs(c2z - centerZ)
|
|
||||||
- );
|
|
||||||
+ // DivineMC start - Chunk Loading Priority Optimization
|
|
||||||
+ if (org.bxteam.divinemc.DivineConfig.chunkTaskPriority == org.bxteam.divinemc.server.chunk.ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN) {
|
|
||||||
+ return Integer.compare(
|
|
||||||
+ (c1x - centerX) * (c1x - centerX) + (c1z - centerZ) * (c1z - centerZ),
|
|
||||||
+ (c2x - centerX) * (c2x - centerX) + (c2z - centerZ) * (c2z - centerZ)
|
|
||||||
+ );
|
|
||||||
+ } else {
|
|
||||||
+ return Integer.compare(
|
|
||||||
+ Math.abs(c1x - centerX) + Math.abs(c1z - centerZ),
|
|
||||||
+ Math.abs(c2x - centerX) + Math.abs(c2z - centerZ)
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk Loading Priority Optimization
|
|
||||||
};
|
|
||||||
private final LongHeapPriorityQueue sendQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST);
|
|
||||||
private final LongHeapPriorityQueue tickingQueue = new LongHeapPriorityQueue(CLOSEST_MANHATTAN_DIST);
|
|
||||||
@@ -490,7 +500,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
- protected void removeCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) {
|
|
||||||
+ protected synchronized void removeCallback(final PlayerChunkLoaderData parameter, final int chunkX, final int chunkZ) { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
final long chunk = CoordinateUtils.getChunkKey(chunkX, chunkZ);
|
|
||||||
// note: by the time this is called, the tick cleanup should have ran - so, if the chunk is at
|
|
||||||
// the tick stage it was deemed in range for loading. Thus, we need to move it to generated
|
|
||||||
@@ -624,7 +634,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
return Math.max(Math.abs(dx), Math.abs(dz)) <= this.lastTickDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
- private boolean areNeighboursGenerated(final int chunkX, final int chunkZ, final int radius) {
|
|
||||||
+ private synchronized boolean areNeighboursGenerated(final int chunkX, final int chunkZ, final int radius) { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
for (int dz = -radius; dz <= radius; ++dz) {
|
|
||||||
for (int dx = -radius; dx <= radius; ++dx) {
|
|
||||||
if ((dx | dz) == 0) {
|
|
||||||
@@ -643,19 +653,11 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
- void updateQueues(final long time) {
|
|
||||||
+ synchronized void updateQueues(final long time) { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
TickThread.ensureTickThread(this.player, "Cannot tick player chunk loader async");
|
|
||||||
if (this.removed) {
|
|
||||||
throw new IllegalStateException("Ticking removed player chunk loader");
|
|
||||||
}
|
|
||||||
- // update rate limits
|
|
||||||
- final double loadRate = this.getMaxChunkLoadRate();
|
|
||||||
- final double genRate = this.getMaxChunkGenRate();
|
|
||||||
- final double sendRate = this.getMaxChunkSendRate();
|
|
||||||
-
|
|
||||||
- this.chunkLoadTicketLimiter.tickAllocation(time, loadRate, loadRate);
|
|
||||||
- this.chunkGenerateTicketLimiter.tickAllocation(time, genRate, genRate);
|
|
||||||
- this.chunkSendLimiter.tickAllocation(time, sendRate, sendRate);
|
|
||||||
|
|
||||||
// try to progress chunk loads
|
|
||||||
while (!this.loadingQueue.isEmpty()) {
|
|
||||||
@@ -682,8 +684,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to push more chunk loads
|
|
||||||
- final long maxLoads = Math.max(0L, Math.min(MAX_RATE, Math.min(this.loadQueue.size(), this.getMaxChunkLoads())));
|
|
||||||
- final int maxLoadsThisTick = (int)this.chunkLoadTicketLimiter.takeAllocation(time, loadRate, maxLoads);
|
|
||||||
+ final int maxLoadsThisTick = this.loadQueue.size(); // DivineMC - Chunk System optimization
|
|
||||||
if (maxLoadsThisTick > 0) {
|
|
||||||
final LongArrayList chunks = new LongArrayList(maxLoadsThisTick);
|
|
||||||
for (int i = 0; i < maxLoadsThisTick; ++i) {
|
|
||||||
@@ -758,9 +759,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to push more chunk generations
|
|
||||||
- final long maxGens = Math.max(0L, Math.min(MAX_RATE, Math.min(this.genQueue.size(), this.getMaxChunkGenerates())));
|
|
||||||
- // preview the allocations, as we may not actually utilise all of them
|
|
||||||
- final long maxGensThisTick = this.chunkGenerateTicketLimiter.previewAllocation(time, genRate, maxGens);
|
|
||||||
+ final long maxGensThisTick = this.genQueue.size(); // DivineMC - Chunk System optimization
|
|
||||||
long ratedGensThisTick = 0L;
|
|
||||||
while (!this.genQueue.isEmpty()) {
|
|
||||||
final long chunkKey = this.genQueue.firstLong();
|
|
||||||
@@ -790,8 +789,6 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
);
|
|
||||||
this.generatingQueue.enqueue(chunkKey);
|
|
||||||
}
|
|
||||||
- // take the allocations we actually used
|
|
||||||
- this.chunkGenerateTicketLimiter.takeAllocation(time, genRate, ratedGensThisTick);
|
|
||||||
|
|
||||||
// try to pull ticking chunks
|
|
||||||
while (!this.tickingQueue.isEmpty()) {
|
|
||||||
@@ -821,10 +818,10 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to pull sending chunks
|
|
||||||
- final long maxSends = Math.max(0L, Math.min(MAX_RATE, Integer.MAX_VALUE)); // note: no logic to track concurrent sends
|
|
||||||
- final int maxSendsThisTick = Math.min((int)this.chunkSendLimiter.takeAllocation(time, sendRate, maxSends), this.sendQueue.size());
|
|
||||||
+ final int maxSendsThisTick = this.sendQueue.size(); // DivineMC - Chunk System optimization
|
|
||||||
// we do not return sends that we took from the allocation back because we want to limit the max send rate, not target it
|
|
||||||
for (int i = 0; i < maxSendsThisTick; ++i) {
|
|
||||||
+ if (this.sendQueue.isEmpty()) break; // DivineMC - Chunk System optimization
|
|
||||||
final long pendingSend = this.sendQueue.firstLong();
|
|
||||||
final int pendingSendX = CoordinateUtils.getChunkX(pendingSend);
|
|
||||||
final int pendingSendZ = CoordinateUtils.getChunkZ(pendingSend);
|
|
||||||
@@ -889,9 +886,6 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
|
|
||||||
// reset limiters, they will start at a zero allocation
|
|
||||||
final long time = System.nanoTime();
|
|
||||||
- this.chunkLoadTicketLimiter.reset(time);
|
|
||||||
- this.chunkGenerateTicketLimiter.reset(time);
|
|
||||||
- this.chunkSendLimiter.reset(time);
|
|
||||||
|
|
||||||
// now we can update
|
|
||||||
this.update();
|
|
||||||
@@ -910,10 +904,10 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
- void update() {
|
|
||||||
+ synchronized void update() { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
TickThread.ensureTickThread(this.player, "Cannot update player asynchronously");
|
|
||||||
if (this.removed) {
|
|
||||||
- throw new IllegalStateException("Updating removed player chunk loader");
|
|
||||||
+ return; // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
final ViewDistances playerDistances = ((ChunkSystemServerPlayer)this.player).moonrise$getViewDistanceHolder().getViewDistances();
|
|
||||||
final ViewDistances worldDistances = ((ChunkSystemServerLevel)this.world).moonrise$getViewDistanceHolder().getViewDistances();
|
|
||||||
@@ -1062,7 +1056,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
this.flushDelayedTicketOps();
|
|
||||||
}
|
|
||||||
|
|
||||||
- void remove() {
|
|
||||||
+ synchronized void remove() { // DivineMC - Chunk System optimization - synchronized
|
|
||||||
TickThread.ensureTickThread(this.player, "Cannot add player asynchronously");
|
|
||||||
if (this.removed) {
|
|
||||||
throw new IllegalStateException("Removing removed player chunk loader");
|
|
||||||
@@ -1090,7 +1084,7 @@ public final class RegionizedPlayerChunkLoader {
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongOpenHashSet getSentChunksRaw() {
|
|
||||||
- return this.sentChunks;
|
|
||||||
+ return new LongOpenHashSet(this.sentChunks); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
||||||
index 0c99bffa769d53562a10d23c4a9b37dc59c7f478..f4fcc3b2676b17ebc276dcb177285f18a0cdfe99 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
|
|
||||||
@@ -71,36 +71,49 @@ public final class ChunkHolderManager {
|
|
||||||
private static final long PROBE_MARKER = Long.MIN_VALUE + 1;
|
|
||||||
public final ReentrantAreaLock ticketLockArea;
|
|
||||||
|
|
||||||
- private final ConcurrentLong2ReferenceChainedHashTable<SortedArraySet<Ticket<?>>> tickets = new ConcurrentLong2ReferenceChainedHashTable<>();
|
|
||||||
- private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = new ConcurrentLong2ReferenceChainedHashTable<>();
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private final ConcurrentLong2ReferenceChainedHashTable<SortedArraySet<Ticket<?>>> tickets = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
|
||||||
+ private final ConcurrentLong2ReferenceChainedHashTable<Long2IntOpenHashMap> sectionToChunkToExpireCount = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F);
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
final ChunkUnloadQueue unloadQueue;
|
|
||||||
|
|
||||||
- private final ConcurrentLong2ReferenceChainedHashTable<NewChunkHolder> chunkHolders = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(16384, 0.25f);
|
|
||||||
+ private final ConcurrentLong2ReferenceChainedHashTable<NewChunkHolder> chunkHolders = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(20, 0.9F); // DivineMC - Chunk System optimization
|
|
||||||
private final ServerLevel world;
|
|
||||||
private final ChunkTaskScheduler taskScheduler;
|
|
||||||
private long currentTick;
|
|
||||||
|
|
||||||
- private final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = new ArrayDeque<>();
|
|
||||||
- private final ObjectRBTreeSet<NewChunkHolder> autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> {
|
|
||||||
- if (c1 == c2) {
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ public static class LevelHolderData {
|
|
||||||
+ private final java.util.concurrent.ConcurrentLinkedDeque<NewChunkHolder> pendingFullLoadUpdate = new java.util.concurrent.ConcurrentLinkedDeque<>();
|
|
||||||
+ private final ObjectRBTreeSet<NewChunkHolder> autoSaveQueue = new ObjectRBTreeSet<>((final NewChunkHolder c1, final NewChunkHolder c2) -> {
|
|
||||||
+ if (c1 == c2) {
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- final int saveTickCompare = Long.compare(c1.lastAutoSave, c2.lastAutoSave);
|
|
||||||
+ final int saveTickCompare = Long.compare(c1.lastAutoSave, c2.lastAutoSave);
|
|
||||||
|
|
||||||
- if (saveTickCompare != 0) {
|
|
||||||
- return saveTickCompare;
|
|
||||||
- }
|
|
||||||
+ if (saveTickCompare != 0) {
|
|
||||||
+ return saveTickCompare;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- final long coord1 = CoordinateUtils.getChunkKey(c1.chunkX, c1.chunkZ);
|
|
||||||
- final long coord2 = CoordinateUtils.getChunkKey(c2.chunkX, c2.chunkZ);
|
|
||||||
+ final long coord1 = CoordinateUtils.getChunkKey(c1.chunkX, c1.chunkZ);
|
|
||||||
+ final long coord2 = CoordinateUtils.getChunkKey(c2.chunkX, c2.chunkZ);
|
|
||||||
|
|
||||||
- if (coord1 == coord2) {
|
|
||||||
- throw new IllegalStateException("Duplicate chunkholder in auto save queue");
|
|
||||||
- }
|
|
||||||
+ if (coord1 == coord2) {
|
|
||||||
+ throw new IllegalStateException("Duplicate chunkholder in auto save queue");
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- return Long.compare(coord1, coord2);
|
|
||||||
- });
|
|
||||||
+ return Long.compare(coord1, coord2);
|
|
||||||
+ });
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public LevelHolderData getData() {
|
|
||||||
+ if (this.world == null) {
|
|
||||||
+ throw new RuntimeException("World was null!");
|
|
||||||
+ }
|
|
||||||
+ return world.chunkHolderData;
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
|
|
||||||
public ChunkHolderManager(final ServerLevel world, final ChunkTaskScheduler taskScheduler) {
|
|
||||||
this.world = world;
|
|
||||||
@@ -222,26 +235,29 @@ public final class ChunkHolderManager {
|
|
||||||
this.taskScheduler.setShutdown(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
- void ensureInAutosave(final NewChunkHolder holder) {
|
|
||||||
- if (!this.autoSaveQueue.contains(holder)) {
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ synchronized void ensureInAutosave(final NewChunkHolder holder) {
|
|
||||||
+ final LevelHolderData data = getData();
|
|
||||||
+ if (!data.autoSaveQueue.contains(holder)) {
|
|
||||||
holder.lastAutoSave = this.currentTick;
|
|
||||||
- this.autoSaveQueue.add(holder);
|
|
||||||
+ data.autoSaveQueue.add(holder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- public void autoSave() {
|
|
||||||
+ public synchronized void autoSave() {
|
|
||||||
+ final LevelHolderData data = getData();
|
|
||||||
final List<NewChunkHolder> reschedule = new ArrayList<>();
|
|
||||||
final long currentTick = this.currentTick;
|
|
||||||
final long maxSaveTime = currentTick - Math.max(1L, PlatformHooks.get().configAutoSaveInterval(this.world));
|
|
||||||
final int maxToSave = PlatformHooks.get().configMaxAutoSavePerTick(this.world);
|
|
||||||
- for (int autoSaved = 0; autoSaved < maxToSave && !this.autoSaveQueue.isEmpty();) {
|
|
||||||
- final NewChunkHolder holder = this.autoSaveQueue.first();
|
|
||||||
+ for (int autoSaved = 0; autoSaved < maxToSave && !data.autoSaveQueue.isEmpty();) {
|
|
||||||
+ final NewChunkHolder holder = data.autoSaveQueue.first();
|
|
||||||
|
|
||||||
if (holder.lastAutoSave > maxSaveTime) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- this.autoSaveQueue.remove(holder);
|
|
||||||
+ data.autoSaveQueue.remove(holder);
|
|
||||||
|
|
||||||
holder.lastAutoSave = currentTick;
|
|
||||||
if (holder.save(false) != null) {
|
|
||||||
@@ -255,10 +271,11 @@ public final class ChunkHolderManager {
|
|
||||||
|
|
||||||
for (final NewChunkHolder holder : reschedule) {
|
|
||||||
if (holder.getChunkStatus().isOrAfter(FullChunkStatus.FULL)) {
|
|
||||||
- this.autoSaveQueue.add(holder);
|
|
||||||
+ data.autoSaveQueue.add(holder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
|
|
||||||
public void saveAllChunks(final boolean flush, final boolean shutdown, final boolean logProgress) {
|
|
||||||
final List<NewChunkHolder> holders = this.getChunkHolders();
|
|
||||||
@@ -317,13 +334,9 @@ public final class ChunkHolderManager {
|
|
||||||
}
|
|
||||||
if (logProgress) {
|
|
||||||
final long currTime = System.nanoTime();
|
|
||||||
- if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(10L)) {
|
|
||||||
+ if ((currTime - lastLog) > TimeUnit.SECONDS.toNanos(5L)) { // DivineMC - Log a bit more frequently
|
|
||||||
lastLog = currTime;
|
|
||||||
- LOGGER.info(
|
|
||||||
- "Saved " + savedChunk + " block chunks, " + savedEntity + " entity chunks, " + savedPoi
|
|
||||||
- + " poi chunks in world '" + WorldUtil.getWorldName(this.world) + "', progress: "
|
|
||||||
- + format.format((double)(i+1)/(double)len * 100.0)
|
|
||||||
- );
|
|
||||||
+ LOGGER.info("Saved {} block chunks, {} entity chunks, {} poi chunks in world '{}', progress: {}", savedChunk, savedEntity, savedPoi, ca.spottedleaf.moonrise.common.util.WorldUtil.getWorldName(this.world), format.format((double) (i + 1) / (double) len * 100.0)); // DivineMC - Beautify log
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -425,8 +438,8 @@ public final class ChunkHolderManager {
|
|
||||||
final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> ret = new Long2ObjectOpenHashMap<>();
|
|
||||||
final Long2ObjectOpenHashMap<LongArrayList> sections = new Long2ObjectOpenHashMap<>();
|
|
||||||
final int sectionShift = this.taskScheduler.getChunkSystemLockShift();
|
|
||||||
- for (final PrimitiveIterator.OfLong iterator = this.tickets.keyIterator(); iterator.hasNext();) {
|
|
||||||
- final long coord = iterator.nextLong();
|
|
||||||
+ for (final Iterator<Long> iterator = this.tickets.keyIterator(); iterator.hasNext();) { // DivineMC - Chunk System optimization
|
|
||||||
+ final long coord = iterator.next(); // DivineMC - Chunk System optimization
|
|
||||||
sections.computeIfAbsent(
|
|
||||||
CoordinateUtils.getChunkKey(
|
|
||||||
CoordinateUtils.getChunkX(coord) >> sectionShift,
|
|
||||||
@@ -523,7 +536,7 @@ public final class ChunkHolderManager {
|
|
||||||
chunkZ >> sectionShift
|
|
||||||
);
|
|
||||||
|
|
||||||
- this.sectionToChunkToExpireCount.computeIfAbsent(sectionKey, (final long keyInMap) -> {
|
|
||||||
+ this.sectionToChunkToExpireCount.computeIfAbsent(sectionKey, (keyInMap) -> { // DivineMC - Chunk System optimization
|
|
||||||
return new Long2IntOpenHashMap();
|
|
||||||
}).addTo(chunkKey, 1);
|
|
||||||
}
|
|
||||||
@@ -567,7 +580,7 @@ public final class ChunkHolderManager {
|
|
||||||
|
|
||||||
final ReentrantAreaLock.Node ticketLock = lock ? this.ticketLockArea.lock(chunkX, chunkZ) : null;
|
|
||||||
try {
|
|
||||||
- final SortedArraySet<Ticket<?>> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (final long keyInMap) -> {
|
|
||||||
+ final SortedArraySet<Ticket<?>> ticketsAtChunk = this.tickets.computeIfAbsent(chunk, (keyInMap) -> { // DivineMC - Chunk System optimization
|
|
||||||
return SortedArraySet.create(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -697,8 +710,8 @@ public final class ChunkHolderManager {
|
|
||||||
|
|
||||||
final Long2ObjectOpenHashMap<LongArrayList> sections = new Long2ObjectOpenHashMap<>();
|
|
||||||
final int sectionShift = this.taskScheduler.getChunkSystemLockShift();
|
|
||||||
- for (final PrimitiveIterator.OfLong iterator = this.tickets.keyIterator(); iterator.hasNext();) {
|
|
||||||
- final long coord = iterator.nextLong();
|
|
||||||
+ for (final Iterator<Long> iterator = this.tickets.keyIterator(); iterator.hasNext();) { // DivineMC - Chunk System optimization
|
|
||||||
+ final long coord = iterator.next(); // DivineMC - Chunk System optimization
|
|
||||||
sections.computeIfAbsent(
|
|
||||||
CoordinateUtils.getChunkKey(
|
|
||||||
CoordinateUtils.getChunkX(coord) >> sectionShift,
|
|
||||||
@@ -746,8 +759,8 @@ public final class ChunkHolderManager {
|
|
||||||
return removeDelay <= 0L;
|
|
||||||
};
|
|
||||||
|
|
||||||
- for (final PrimitiveIterator.OfLong iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) {
|
|
||||||
- final long sectionKey = iterator.nextLong();
|
|
||||||
+ for (final Iterator<Long> iterator = this.sectionToChunkToExpireCount.keyIterator(); iterator.hasNext();) { // DivineMC - Chunk System optimization
|
|
||||||
+ final long sectionKey = iterator.next(); // DivineMC - Chunk System optimization
|
|
||||||
|
|
||||||
if (!this.sectionToChunkToExpireCount.containsKey(sectionKey)) {
|
|
||||||
// removed concurrently
|
|
||||||
@@ -1033,7 +1046,7 @@ public final class ChunkHolderManager {
|
|
||||||
}
|
|
||||||
if (!TickThread.isTickThreadFor(world)) { // DivineMC - parallel world ticking
|
|
||||||
this.taskScheduler.scheduleChunkTask(() -> {
|
|
||||||
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = ChunkHolderManager.this.pendingFullLoadUpdate;
|
|
||||||
+ final java.util.Deque<NewChunkHolder> pendingFullLoadUpdate = ChunkHolderManager.this.getData().pendingFullLoadUpdate; // DivineMC - Chunk System optimization
|
|
||||||
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
|
|
||||||
pendingFullLoadUpdate.add(changedFullStatus.get(i));
|
|
||||||
}
|
|
||||||
@@ -1041,16 +1054,16 @@ public final class ChunkHolderManager {
|
|
||||||
ChunkHolderManager.this.processPendingFullUpdate();
|
|
||||||
}, Priority.HIGHEST);
|
|
||||||
} else {
|
|
||||||
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
|
|
||||||
+ final java.util.Deque<NewChunkHolder> pendingFullLoadUpdate = this.getData().pendingFullLoadUpdate; // DivineMC - Chunk System optimization
|
|
||||||
for (int i = 0, len = changedFullStatus.size(); i < len; ++i) {
|
|
||||||
pendingFullLoadUpdate.add(changedFullStatus.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- private void removeChunkHolder(final NewChunkHolder holder) {
|
|
||||||
+ private synchronized void removeChunkHolder(final NewChunkHolder holder) { // DivineMC - Chunk System optimization
|
|
||||||
holder.onUnload();
|
|
||||||
- this.autoSaveQueue.remove(holder);
|
|
||||||
+ this.getData().autoSaveQueue.remove(holder); // DivineMC - Chunk System optimization
|
|
||||||
PlatformHooks.get().onChunkHolderDelete(this.world, holder.vanillaChunkHolder);
|
|
||||||
this.chunkHolders.remove(CoordinateUtils.getChunkKey(holder.chunkX, holder.chunkZ));
|
|
||||||
}
|
|
||||||
@@ -1208,6 +1221,27 @@ public final class ChunkHolderManager {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ public final java.util.Set<Long> blockTickingChunkHolders = java.util.Collections.synchronizedSet(new org.agrona.collections.ObjectHashSet<>(10, 0.88f, true));
|
|
||||||
+ public final java.util.Set<Long> entityTickingChunkHolders = java.util.Collections.synchronizedSet(new org.agrona.collections.ObjectHashSet<>(10, 0.88f, true));
|
|
||||||
+
|
|
||||||
+ public void markBlockTicking(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
|
||||||
+ this.blockTickingChunkHolders.add(newChunkHolder.getCachedLongPos());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public void markNonBlockTickingIfPossible(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
|
||||||
+ this.blockTickingChunkHolders.remove(newChunkHolder.getCachedLongPos());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public void markEntityTicking(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
|
||||||
+ this.entityTickingChunkHolders.add(newChunkHolder.getCachedLongPos());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public void markNonEntityTickingIfPossible(@org.jetbrains.annotations.NotNull NewChunkHolder newChunkHolder) {
|
|
||||||
+ this.entityTickingChunkHolders.remove(newChunkHolder.getCachedLongPos());
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
+
|
|
||||||
public enum TicketOperationType {
|
|
||||||
ADD, REMOVE, ADD_IF_REMOVED, ADD_AND_REMOVE
|
|
||||||
}
|
|
||||||
@@ -1381,7 +1415,7 @@ public final class ChunkHolderManager {
|
|
||||||
|
|
||||||
// only call on tick thread
|
|
||||||
private boolean processPendingFullUpdate() {
|
|
||||||
- final ArrayDeque<NewChunkHolder> pendingFullLoadUpdate = this.pendingFullLoadUpdate;
|
|
||||||
+ final java.util.Deque<NewChunkHolder> pendingFullLoadUpdate = this.getData().pendingFullLoadUpdate; // DivineMC - Chunk System optimization
|
|
||||||
|
|
||||||
boolean ret = false;
|
|
||||||
|
|
||||||
@@ -1417,8 +1451,7 @@ public final class ChunkHolderManager {
|
|
||||||
final JsonArray allTicketsJson = new JsonArray();
|
|
||||||
ret.add("tickets", allTicketsJson);
|
|
||||||
|
|
||||||
- for (final Iterator<ConcurrentLong2ReferenceChainedHashTable.TableEntry<SortedArraySet<Ticket<?>>>> iterator = this.tickets.entryIterator();
|
|
||||||
- iterator.hasNext();) {
|
|
||||||
+ for (final Iterator<ConcurrentLong2ReferenceChainedHashTable.TableEntry<SortedArraySet<Ticket<?>>>> iterator = this.tickets.entryIterator(); iterator.hasNext();) { // DivineMC - Chunk System optimization
|
|
||||||
final ConcurrentLong2ReferenceChainedHashTable.TableEntry<SortedArraySet<Ticket<?>>> coordinateTickets = iterator.next();
|
|
||||||
final long coordinate = coordinateTickets.getKey();
|
|
||||||
final SortedArraySet<Ticket<?>> tickets = coordinateTickets.getValue();
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
|
||||||
index e4a5fa25ed368fc4662c30934da2963ef446d782..6da0ea5cd83a00578223e0a19f952c917bcbcdae 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
|
|
||||||
@@ -644,11 +644,19 @@ public final class NewChunkHolder {
|
|
||||||
}
|
|
||||||
|
|
||||||
public final ChunkHolder vanillaChunkHolder;
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private final long cachedLongPos;
|
|
||||||
+
|
|
||||||
+ public long getCachedLongPos() {
|
|
||||||
+ return cachedLongPos;
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
|
|
||||||
public NewChunkHolder(final ServerLevel world, final int chunkX, final int chunkZ, final ChunkTaskScheduler scheduler) {
|
|
||||||
this.world = world;
|
|
||||||
this.chunkX = chunkX;
|
|
||||||
this.chunkZ = chunkZ;
|
|
||||||
+ this.cachedLongPos = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(this.chunkX, this.chunkZ); // DivineMC - Chunk System optimization
|
|
||||||
this.scheduler = scheduler;
|
|
||||||
this.vanillaChunkHolder = new ChunkHolder(
|
|
||||||
new ChunkPos(chunkX, chunkZ), ChunkHolderManager.MAX_TICKET_LEVEL, world,
|
|
||||||
@@ -790,9 +798,11 @@ public final class NewChunkHolder {
|
|
||||||
|
|
||||||
// note: these are completed with null to indicate that no write occurred
|
|
||||||
// they are also completed with null to indicate a null write occurred
|
|
||||||
- private UnloadTask chunkDataUnload;
|
|
||||||
- private UnloadTask entityDataUnload;
|
|
||||||
- private UnloadTask poiDataUnload;
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private volatile UnloadTask chunkDataUnload;
|
|
||||||
+ private volatile UnloadTask entityDataUnload;
|
|
||||||
+ private volatile UnloadTask poiDataUnload;
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
|
|
||||||
public static final record UnloadTask(CallbackCompletable<CompoundTag> completable, PrioritisedExecutor.PrioritisedTask task,
|
|
||||||
LazyRunnable toRun) {}
|
|
||||||
@@ -1190,6 +1200,7 @@ public final class NewChunkHolder {
|
|
||||||
for (int dz = -NEIGHBOUR_RADIUS; dz <= NEIGHBOUR_RADIUS; ++dz) {
|
|
||||||
for (int dx = -NEIGHBOUR_RADIUS; dx <= NEIGHBOUR_RADIUS; ++dx) {
|
|
||||||
final NewChunkHolder holder = (dx | dz) == 0 ? this : this.scheduler.chunkHolderManager.getChunkHolder(dx + this.chunkX, dz + this.chunkZ);
|
|
||||||
+ if (holder == null) continue; // DivineMC - Chunk System optimization
|
|
||||||
if (loaded) {
|
|
||||||
if (holder.setNeighbourFullLoaded(-dx, -dz)) {
|
|
||||||
changedFullStatus.add(holder);
|
|
||||||
@@ -1214,6 +1225,19 @@ public final class NewChunkHolder {
|
|
||||||
|
|
||||||
private void updateCurrentState(final FullChunkStatus to) {
|
|
||||||
this.currentFullChunkStatus = to;
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ if (to.isOrAfter(FullChunkStatus.BLOCK_TICKING)) {
|
|
||||||
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markBlockTicking(this);
|
|
||||||
+ } else {
|
|
||||||
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markNonBlockTickingIfPossible(this);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (to.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
|
||||||
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markEntityTicking(this);
|
|
||||||
+ } else {
|
|
||||||
+ this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.markNonEntityTickingIfPossible(this);
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
// only to be called on the main thread, no locks need to be held
|
|
||||||
@@ -1348,11 +1372,11 @@ public final class NewChunkHolder {
|
|
||||||
return this.requestedGenStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
- private final Reference2ObjectOpenHashMap<ChunkStatus, List<Consumer<ChunkAccess>>> statusWaiters = new Reference2ObjectOpenHashMap<>();
|
|
||||||
+ private final Map<ChunkStatus, List<Consumer<ChunkAccess>>> statusWaiters = new java.util.concurrent.ConcurrentHashMap<>(); // DivineMC - Chunk System optimization
|
|
||||||
|
|
||||||
void addStatusConsumer(final ChunkStatus status, final Consumer<ChunkAccess> consumer) {
|
|
||||||
this.statusWaiters.computeIfAbsent(status, (final ChunkStatus keyInMap) -> {
|
|
||||||
- return new ArrayList<>(4);
|
|
||||||
+ return new java.util.concurrent.CopyOnWriteArrayList<>(); // DivineMC - Chunk System optimization
|
|
||||||
}).add(consumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1394,11 +1418,11 @@ public final class NewChunkHolder {
|
|
||||||
}, Priority.HIGHEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
- private final Reference2ObjectOpenHashMap<FullChunkStatus, List<Consumer<LevelChunk>>> fullStatusWaiters = new Reference2ObjectOpenHashMap<>();
|
|
||||||
+ private final Map<FullChunkStatus, List<Consumer<LevelChunk>>> fullStatusWaiters = new java.util.concurrent.ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
void addFullStatusConsumer(final FullChunkStatus status, final Consumer<LevelChunk> consumer) {
|
|
||||||
this.fullStatusWaiters.computeIfAbsent(status, (final FullChunkStatus keyInMap) -> {
|
|
||||||
- return new ArrayList<>(4);
|
|
||||||
+ return new java.util.concurrent.CopyOnWriteArrayList<>(); // DivineMC - Chunk System optimization
|
|
||||||
}).add(consumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java b/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java
|
|
||||||
index e97e7d276faf055c89207385d3820debffb06463..4aeb75a2cdcfb4206bab3eee5ad674dd9890e720 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_tick_iteration/ChunkTickConstants.java
|
|
||||||
@@ -2,6 +2,6 @@ package ca.spottedleaf.moonrise.patches.chunk_tick_iteration;
|
|
||||||
|
|
||||||
public final class ChunkTickConstants {
|
|
||||||
|
|
||||||
- public static final int PLAYER_SPAWN_TRACK_RANGE = 8;
|
|
||||||
+ public static final int PLAYER_SPAWN_TRACK_RANGE = (int) Math.round(org.bxteam.divinemc.DivineConfig.playerNearChunkDetectionRange / 16.0); // DivineMC - Chunk System optimization
|
|
||||||
|
|
||||||
}
|
|
||||||
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
||||||
index 4ca68a903e67606fc4ef0bfa9862a73797121c8b..f94f443f862611f039454d1dc8ff2a4ba5f081d3 100644
|
|
||||||
--- a/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
||||||
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/SWMRNibbleArray.java
|
|
||||||
@@ -325,7 +325,7 @@ public final class SWMRNibbleArray {
|
|
||||||
}
|
|
||||||
|
|
||||||
// operation type: updating
|
|
||||||
- public boolean updateVisible() {
|
|
||||||
+ public synchronized boolean updateVisible() { // DivineMC - Chunk System optimization
|
|
||||||
if (!this.isDirty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
diff --git a/net/minecraft/server/level/DistanceManager.java b/net/minecraft/server/level/DistanceManager.java
|
|
||||||
index 5eab6179ce3913cb4e4d424f910ba423faf21c85..4b1efd53e423bdfe90d5efd472823869fc87e73b 100644
|
|
||||||
--- a/net/minecraft/server/level/DistanceManager.java
|
|
||||||
+++ b/net/minecraft/server/level/DistanceManager.java
|
|
||||||
@@ -178,15 +178,13 @@ public abstract class DistanceManager implements ca.spottedleaf.moonrise.patches
|
|
||||||
|
|
||||||
public boolean inEntityTickingRange(long chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos);
|
|
||||||
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
|
||||||
+ return this.moonrise$getChunkHolderManager().entityTickingChunkHolders.contains(chunkPos); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inBlockTickingRange(long chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkHolderManager().getChunkHolder(chunkPos);
|
|
||||||
- return chunkHolder != null && chunkHolder.isTickingReady();
|
|
||||||
+ return this.moonrise$getChunkHolderManager().blockTickingChunkHolders.contains(chunkPos); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
index ab30af9cd58ff7310e05be87b08f42bacf69e11e..ae0e36d198ad8243920c8e8a55c0be4945542763 100644
|
|
||||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
|
||||||
@@ -439,8 +439,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
||||||
|
|
||||||
public boolean isPositionTicking(long chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder newChunkHolder = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
|
||||||
- return newChunkHolder != null && newChunkHolder.isTickingReady();
|
|
||||||
+ return ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
|
||||||
index 973198ae0a73d6747e73548bdcbc1de46b6fb107..1581bf8ff425c6e0df28d107300d7266e9f87ed5 100644
|
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
||||||
@@ -181,6 +181,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
||||||
public final ServerChunkCache chunkSource;
|
|
||||||
private final MinecraftServer server;
|
|
||||||
public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type
|
|
||||||
+ public final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager.LevelHolderData chunkHolderData; // DivineMC - Chunk System optimization
|
|
||||||
private int lastSpawnChunkRadius;
|
|
||||||
final EntityTickList entityTickList = new EntityTickList(this); // DivineMC - parallel world ticking
|
|
||||||
// Paper - rewrite chunk system
|
|
||||||
@@ -689,6 +690,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks()));
|
|
||||||
this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this);
|
|
||||||
+ this.chunkHolderData = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager.LevelHolderData(); // DivineMC - Chunk System optimization
|
|
||||||
this.entityDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController(
|
|
||||||
new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController.EntityRegionFileStorage(
|
|
||||||
new RegionStorageInfo(levelStorageAccess.getLevelId(), dimension, "entities"),
|
|
||||||
@@ -832,8 +834,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
||||||
@Override
|
|
||||||
public boolean shouldTickBlocksAt(long chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder holder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
|
||||||
- return holder != null && holder.isTickingReady();
|
|
||||||
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2525,30 +2526,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
||||||
|
|
||||||
private boolean isPositionTickingWithEntitiesLoaded(long chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos);
|
|
||||||
- // isTicking implies the chunk is loaded, and the chunk is loaded now implies the entities are loaded
|
|
||||||
- return chunkHolder != null && chunkHolder.isTickingReady();
|
|
||||||
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.blockTickingChunkHolders.contains(chunkPos); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPositionEntityTicking(BlockPos pos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos));
|
|
||||||
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
|
||||||
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.entityTickingChunkHolders.contains(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos)); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNaturalSpawningAllowed(BlockPos pos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos));
|
|
||||||
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
|
||||||
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.entityTickingChunkHolders.contains(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos)); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNaturalSpawningAllowed(ChunkPos chunkPos) {
|
|
||||||
// Paper start - rewrite chunk system
|
|
||||||
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkPos));
|
|
||||||
- return chunkHolder != null && chunkHolder.isEntityTickingReady();
|
|
||||||
+ return this.moonrise$getChunkTaskScheduler().chunkHolderManager.entityTickingChunkHolders.contains(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkPos)); // DivineMC - Chunk System optimization
|
|
||||||
// Paper end - rewrite chunk system
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/LevelReader.java b/net/minecraft/world/level/LevelReader.java
|
|
||||||
index 26c8c1e5598daf3550aef05b12218c47bda6618b..94c824ab1457939c425e1f99929d3222ee2c18a0 100644
|
|
||||||
--- a/net/minecraft/world/level/LevelReader.java
|
|
||||||
+++ b/net/minecraft/world/level/LevelReader.java
|
|
||||||
@@ -70,10 +70,27 @@ public interface LevelReader extends ca.spottedleaf.moonrise.patches.chunk_syste
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default Holder<Biome> getNoiseBiome(int x, int y, int z) {
|
|
||||||
- ChunkAccess chunk = this.getChunk(QuartPos.toSection(x), QuartPos.toSection(z), ChunkStatus.BIOMES, false);
|
|
||||||
+ ChunkAccess chunk = this.fasterChunkAccess(this, QuartPos.toSection(x), QuartPos.toSection(z), ChunkStatus.BIOMES, false); // DivineMC - Chunk System optimization
|
|
||||||
return chunk != null ? chunk.getNoiseBiome(x, y, z) : this.getUncachedNoiseBiome(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private @Nullable ChunkAccess fasterChunkAccess(LevelReader instance, int x, int z, ChunkStatus chunkStatus, boolean create) {
|
|
||||||
+ if (!create && instance instanceof net.minecraft.server.level.ServerLevel world) {
|
|
||||||
+ final net.minecraft.server.level.ChunkHolder holder = (world.getChunkSource().chunkMap).getVisibleChunkIfPresent(ChunkPos.asLong(x, z));
|
|
||||||
+ if (holder != null) {
|
|
||||||
+ final java.util.concurrent.CompletableFuture<net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.LevelChunk>> future = holder.getFullChunkFuture();
|
|
||||||
+ final net.minecraft.server.level.ChunkResult<net.minecraft.world.level.chunk.LevelChunk> either = future.getNow(null);
|
|
||||||
+ if (either != null) {
|
|
||||||
+ final net.minecraft.world.level.chunk.LevelChunk chunk = either.orElse(null);
|
|
||||||
+ if (chunk != null) return chunk;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return instance.getChunk(x, z, chunkStatus, create);
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
+
|
|
||||||
Holder<Biome> getUncachedNoiseBiome(int x, int y, int z);
|
|
||||||
|
|
||||||
boolean isClientSide();
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/ProtoChunk.java b/net/minecraft/world/level/chunk/ProtoChunk.java
|
|
||||||
index e66239e2da91bd3ddf358d239be796719c0da327..35e9d8cfe12252d3419626f1cefb64d30e20069e 100644
|
|
||||||
--- a/net/minecraft/world/level/chunk/ProtoChunk.java
|
|
||||||
+++ b/net/minecraft/world/level/chunk/ProtoChunk.java
|
|
||||||
@@ -41,7 +41,7 @@ public class ProtoChunk extends ChunkAccess {
|
|
||||||
@Nullable
|
|
||||||
private volatile LevelLightEngine lightEngine;
|
|
||||||
private volatile ChunkStatus status = ChunkStatus.EMPTY;
|
|
||||||
- private final List<CompoundTag> entities = Lists.newArrayList();
|
|
||||||
+ private final List<CompoundTag> entities = Collections.synchronizedList(Lists.newArrayList()); // DivineMC - Chunk System optimization
|
|
||||||
@Nullable
|
|
||||||
private CarvingMask carvingMask;
|
|
||||||
@Nullable
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/IOWorker.java b/net/minecraft/world/level/chunk/storage/IOWorker.java
|
|
||||||
index 2199a9e2a0141c646d108f2687a27f1d165453c5..c28c2583b257f92207b822a1fdde8f5b7e480992 100644
|
|
||||||
--- a/net/minecraft/world/level/chunk/storage/IOWorker.java
|
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/IOWorker.java
|
|
||||||
@@ -212,7 +212,38 @@ public class IOWorker implements ChunkScanAccess, AutoCloseable {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ private void checkHardLimit() {
|
|
||||||
+ if (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheLimit) {
|
|
||||||
+ LOGGER.warn("Chunk data cache size exceeded hard limit ({} >= {}), forcing writes to disk (you can increase chunkDataCacheLimit in c2me.toml)", this.pendingWrites.size(), org.bxteam.divinemc.DivineConfig.chunkDataCacheLimit);
|
|
||||||
+ while (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit * 0.75) {
|
|
||||||
+ writeResult0();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void writeResult0() {
|
|
||||||
+ java.util.Iterator<java.util.Map.Entry<net.minecraft.world.level.ChunkPos, net.minecraft.world.level.chunk.storage.IOWorker.PendingStore>> iterator = this.pendingWrites.entrySet().iterator();
|
|
||||||
+ if (iterator.hasNext()) {
|
|
||||||
+ java.util.Map.Entry<ChunkPos, IOWorker.PendingStore> entry = iterator.next();
|
|
||||||
+ iterator.remove();
|
|
||||||
+ this.runStore(entry.getKey(), entry.getValue());
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
+
|
|
||||||
private void storePendingChunk() {
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ if (!this.pendingWrites.isEmpty()) {
|
|
||||||
+ checkHardLimit();
|
|
||||||
+ if (this.pendingWrites.size() >= org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit) {
|
|
||||||
+ int writeFrequency = Math.min(1, (this.pendingWrites.size() - (int) org.bxteam.divinemc.DivineConfig.chunkDataCacheSoftLimit) / 16);
|
|
||||||
+ for (int i = 0; i < writeFrequency; i++) {
|
|
||||||
+ writeResult0();
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
Entry<ChunkPos, IOWorker.PendingStore> entry = this.pendingWrites.pollFirstEntry();
|
|
||||||
if (entry != null) {
|
|
||||||
this.runStore(entry.getKey(), entry.getValue());
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
|
||||||
index 6ebd1300c2561116b83cb2472ac7939ead36d576..16cd10ab8de69ca3d29c84cf93715645322fd72a 100644
|
|
||||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
|
||||||
@@ -244,7 +244,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
|
||||||
|
|
||||||
protected RegionFileStorage(RegionStorageInfo info, Path folder, boolean sync) { // Paper - protected
|
|
||||||
this.folder = folder;
|
|
||||||
- this.sync = sync;
|
|
||||||
+ this.sync = Boolean.parseBoolean(System.getProperty("com.ishland.c2me.chunkio.syncDiskWrites", String.valueOf(sync))); // DivineMC - C2ME: sync disk writes
|
|
||||||
this.info = info;
|
|
||||||
this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
|
|
||||||
}
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/Column.java b/net/minecraft/world/level/levelgen/Column.java
|
|
||||||
index 4a1df0f8578c9ee5538ed8c94d3c7911f36f83b8..716c2c69843234cdef34339d859babc95ffe318c 100644
|
|
||||||
--- a/net/minecraft/world/level/levelgen/Column.java
|
|
||||||
+++ b/net/minecraft/world/level/levelgen/Column.java
|
|
||||||
@@ -156,7 +156,7 @@ public abstract class Column {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int height() {
|
|
||||||
- return this.ceiling - this.floor - 1;
|
|
||||||
+ return net.minecraft.util.Mth.abs(this.ceiling - this.floor - 1); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/WorldgenRandom.java b/net/minecraft/world/level/levelgen/WorldgenRandom.java
|
|
||||||
index c2d7cd788071e25b8ba2503c30ae80c7a9f353ed..0a2e13c4a3db6517267e1f9e74b6152c73e8351f 100644
|
|
||||||
--- a/net/minecraft/world/level/levelgen/WorldgenRandom.java
|
|
||||||
+++ b/net/minecraft/world/level/levelgen/WorldgenRandom.java
|
|
||||||
@@ -73,7 +73,7 @@ public class WorldgenRandom extends LegacyRandomSource {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum Algorithm {
|
|
||||||
- LEGACY(LegacyRandomSource::new),
|
|
||||||
+ LEGACY(ThreadSafeLegacyRandomSource::new), // DivineMC - Chunk System optimization
|
|
||||||
XOROSHIRO(XoroshiroRandomSource::new);
|
|
||||||
|
|
||||||
private final LongFunction<RandomSource> constructor;
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/feature/stateproviders/RandomizedIntStateProvider.java b/net/minecraft/world/level/levelgen/feature/stateproviders/RandomizedIntStateProvider.java
|
|
||||||
index f4009671880b00ecec98fe604215e2824e453cdf..c607c801223ea71343ece67b81151e31362f1c31 100644
|
|
||||||
--- a/net/minecraft/world/level/levelgen/feature/stateproviders/RandomizedIntStateProvider.java
|
|
||||||
+++ b/net/minecraft/world/level/levelgen/feature/stateproviders/RandomizedIntStateProvider.java
|
|
||||||
@@ -55,17 +55,21 @@ public class RandomizedIntStateProvider extends BlockStateProvider {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getState(RandomSource random, BlockPos pos) {
|
|
||||||
- BlockState state = this.source.getState(random, pos);
|
|
||||||
- if (this.property == null || !state.hasProperty(this.property)) {
|
|
||||||
- IntegerProperty integerProperty = findProperty(state, this.propertyName);
|
|
||||||
- if (integerProperty == null) {
|
|
||||||
- return state;
|
|
||||||
+ // DivineMC start - Chunk System optimization
|
|
||||||
+ BlockState blockState = this.source.getState(random, pos);
|
|
||||||
+ IntegerProperty propertyLocal = this.property;
|
|
||||||
+ if (propertyLocal == null || !blockState.hasProperty(propertyLocal)) {
|
|
||||||
+ IntegerProperty intProperty = findProperty(blockState, this.propertyName);
|
|
||||||
+ if (intProperty == null) {
|
|
||||||
+ return blockState;
|
|
||||||
}
|
|
||||||
|
|
||||||
- this.property = integerProperty;
|
|
||||||
+ propertyLocal = intProperty;
|
|
||||||
+ this.property = intProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return state.setValue(this.property, Integer.valueOf(this.values.sample(random)));
|
|
||||||
+ return (BlockState)blockState.setValue(propertyLocal, this.values.sample(random));
|
|
||||||
+ // DivineMC end - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/structure/ScatteredFeaturePiece.java b/net/minecraft/world/level/levelgen/structure/ScatteredFeaturePiece.java
|
|
||||||
index d122221deefb218db962e97ba2d958c33d903b8a..56311b439ac22700593d2d31da3a4efe3a519d53 100644
|
|
||||||
--- a/net/minecraft/world/level/levelgen/structure/ScatteredFeaturePiece.java
|
|
||||||
+++ b/net/minecraft/world/level/levelgen/structure/ScatteredFeaturePiece.java
|
|
||||||
@@ -12,7 +12,7 @@ public abstract class ScatteredFeaturePiece extends StructurePiece {
|
|
||||||
protected final int width;
|
|
||||||
protected final int height;
|
|
||||||
protected final int depth;
|
|
||||||
- protected int heightPosition = -1;
|
|
||||||
+ protected volatile int heightPosition = -1; // DivineMC - Chunk System optimization - make volatile
|
|
||||||
|
|
||||||
protected ScatteredFeaturePiece(StructurePieceType type, int x, int y, int z, int width, int height, int depth, Direction orientation) {
|
|
||||||
super(type, 0, StructurePiece.makeBoundingBox(x, y, z, orientation, width, height, depth));
|
|
||||||
diff --git a/net/minecraft/world/level/levelgen/structure/StructureStart.java b/net/minecraft/world/level/levelgen/structure/StructureStart.java
|
|
||||||
index 4dafa79dd4ec55a443ba3731a79e7cd6e8052f48..8aeab4d773473ad20b1c64295c93d6fcb4ea02a1 100644
|
|
||||||
--- a/net/minecraft/world/level/levelgen/structure/StructureStart.java
|
|
||||||
+++ b/net/minecraft/world/level/levelgen/structure/StructureStart.java
|
|
||||||
@@ -26,7 +26,7 @@ public final class StructureStart {
|
|
||||||
private final Structure structure;
|
|
||||||
private final PiecesContainer pieceContainer;
|
|
||||||
private final ChunkPos chunkPos;
|
|
||||||
- private int references;
|
|
||||||
+ private final java.util.concurrent.atomic.AtomicInteger references = new java.util.concurrent.atomic.AtomicInteger(); // DivineMC - Chunk System optimization
|
|
||||||
@Nullable
|
|
||||||
private volatile BoundingBox cachedBoundingBox;
|
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public final class StructureStart {
|
|
||||||
public StructureStart(Structure structure, ChunkPos chunkPos, int references, PiecesContainer pieceContainer) {
|
|
||||||
this.structure = structure;
|
|
||||||
this.chunkPos = chunkPos;
|
|
||||||
- this.references = references;
|
|
||||||
+ this.references.set(references); // DivineMC - Chunk System optimization
|
|
||||||
this.pieceContainer = pieceContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ public final class StructureStart {
|
|
||||||
compoundTag.putString("id", context.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString());
|
|
||||||
compoundTag.putInt("ChunkX", chunkPos.x);
|
|
||||||
compoundTag.putInt("ChunkZ", chunkPos.z);
|
|
||||||
- compoundTag.putInt("references", this.references);
|
|
||||||
+ compoundTag.putInt("references", this.references.get()); // DivineMC - Chunk System optimization
|
|
||||||
compoundTag.put("Children", this.pieceContainer.save(context));
|
|
||||||
return compoundTag;
|
|
||||||
} else {
|
|
||||||
@@ -144,15 +144,15 @@ public final class StructureStart {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canBeReferenced() {
|
|
||||||
- return this.references < this.getMaxReferences();
|
|
||||||
+ return this.references.get() < this.getMaxReferences(); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addReference() {
|
|
||||||
- this.references++;
|
|
||||||
+ this.references.getAndIncrement(); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getReferences() {
|
|
||||||
- return this.references;
|
|
||||||
+ return this.references.get(); // DivineMC - Chunk System optimization
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getMaxReferences() {
|
|
||||||
@@ -17,7 +17,7 @@ index 9f7698f8ce56d5d89cf86f6ea2d5b4d51b18c9a2..351b035d1f3025af28b5147b95b912e0
|
|||||||
if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
|
if (org.bxteam.divinemc.DivineConfig.enableParallelWorldTicking) {
|
||||||
serverLevelTickingSemaphore.acquire();
|
serverLevelTickingSemaphore.acquire();
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 1581bf8ff425c6e0df28d107300d7266e9f87ed5..8c136d77451c17613834c4a7dab6ab6c2fe4d716 100644
|
index 59aa7f9c06b62de4e8997f325d66daba28fa5871..5cb64b5da32183b7cd1e052c638e0789cc796bc4 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -194,7 +194,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -194,7 +194,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -29,7 +29,7 @@ index 1581bf8ff425c6e0df28d107300d7266e9f87ed5..8c136d77451c17613834c4a7dab6ab6c
|
|||||||
protected final Raids raids;
|
protected final Raids raids;
|
||||||
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
||||||
private final List<BlockEventData> blockEventsToReschedule = new ArrayList<>(64);
|
private final List<BlockEventData> blockEventsToReschedule = new ArrayList<>(64);
|
||||||
@@ -1729,7 +1729,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -1728,7 +1728,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {
|
||||||
@@ -38,7 +38,7 @@ index 1581bf8ff425c6e0df28d107300d7266e9f87ed5..8c136d77451c17613834c4a7dab6ab6c
|
|||||||
String string = "recursive call to sendBlockUpdated";
|
String string = "recursive call to sendBlockUpdated";
|
||||||
Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated"));
|
Util.logAndPauseIfInIde("recursive call to sendBlockUpdated", new IllegalStateException("recursive call to sendBlockUpdated"));
|
||||||
}
|
}
|
||||||
@@ -1760,13 +1760,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -1759,13 +1759,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
// Paper end - catch CME see below why
|
// Paper end - catch CME see below why
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -54,7 +54,7 @@ index 1581bf8ff425c6e0df28d107300d7266e9f87ed5..8c136d77451c17613834c4a7dab6ab6c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // Paper - option to disable pathfinding updates
|
} // Paper - option to disable pathfinding updates
|
||||||
@@ -2653,7 +2653,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -2652,7 +2652,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity instanceof Mob mob) {
|
if (entity instanceof Mob mob) {
|
||||||
@@ -63,7 +63,7 @@ index 1581bf8ff425c6e0df28d107300d7266e9f87ed5..8c136d77451c17613834c4a7dab6ab6c
|
|||||||
String string = "onTrackingStart called during navigation iteration";
|
String string = "onTrackingStart called during navigation iteration";
|
||||||
Util.logAndPauseIfInIde(
|
Util.logAndPauseIfInIde(
|
||||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||||
@@ -2723,7 +2723,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -2722,7 +2722,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity instanceof Mob mob) {
|
if (entity instanceof Mob mob) {
|
||||||
@@ -25,7 +25,7 @@ index 351b035d1f3025af28b5147b95b912e0e2ab9212..1bcccba4df407ec4d53f49c3c2c7493d
|
|||||||
this.tickCount++;
|
this.tickCount++;
|
||||||
this.tickRateManager.tick();
|
this.tickRateManager.tick();
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 8c136d77451c17613834c4a7dab6ab6c2fe4d716..f7f7a553d52f42cbbc5d839b850d65ddf97c3ed1 100644
|
index 5cb64b5da32183b7cd1e052c638e0789cc796bc4..e3e00afd4621c4b487f5d2f0a74f773e631ed776 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -218,6 +218,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -218,6 +218,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -25,7 +25,7 @@ index 1bcccba4df407ec4d53f49c3c2c7493db87b2240..54c8605a4e36605208344e39726a4c3b
|
|||||||
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
|
CrashReport crashReport = CrashReport.forThrowable(levelTickingException, "Exception ticking world");
|
||||||
serverLevel.fillReportDetails(crashReport);
|
serverLevel.fillReportDetails(crashReport);
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index f7f7a553d52f42cbbc5d839b850d65ddf97c3ed1..fdaf752b4d39402de504cc8dfb6f0593f9b19d9a 100644
|
index e3e00afd4621c4b487f5d2f0a74f773e631ed776..a8a5da1f8519fe97f45ddd140afb9dc2a64c015e 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -574,6 +574,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -574,6 +574,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -218,10 +218,10 @@ index 9fcdff2be139296f4e14b54c33cc795efdff0c7f..64c3bbe540599e5195f0cc89635bff2c
|
|||||||
// Paper start - Add setting for proxy online mode status
|
// Paper start - Add setting for proxy online mode status
|
||||||
return properties.enforceSecureProfile
|
return properties.enforceSecureProfile
|
||||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
index 0c499eca39371993c46d510fa45298efdd67d20c..2eccb615dfebf64ca76d2cce1876d6ec2afe518d 100644
|
index 801dd76a2c7f76fc6fdb7167cbf3ab1310be36c9..4fa55fac5dab26a505cba2c1876e9459a582da12 100644
|
||||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
@@ -308,10 +308,64 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -312,10 +312,64 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(Packet<?> packet) {
|
public void send(Packet<?> packet) {
|
||||||
@@ -231,7 +231,7 @@ index 4a6da3648c513a6cce16cf71246937d2d0ad014d..6af4c9026e814dee1ed4c7593ad00b5f
|
|||||||
+ // Quiil end - Optimize Structure Generation
|
+ // Quiil end - Optimize Structure Generation
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
diff --git a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||||
index ab1dcbe416e2c3c94cfddf04b7ed053425a71806..985d11f0b72858d66ad011d83106730b07e25242 100644
|
index a37eb2e29b4577ebc711e8ef7b47fbbc3bc66897..45d6fbeeaac577bb35adb69fd344b9486953ea03 100644
|
||||||
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||||
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||||
@@ -249,6 +249,12 @@ public class StructureTemplate {
|
@@ -249,6 +249,12 @@ public class StructureTemplate {
|
||||||
@@ -10,7 +10,7 @@ As part of: ModernFix (https://github.com/embeddedt/ModernFix)
|
|||||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
index 230cb433c38f9b6ffb1adeaa8b6040490f13e826..a436ec61bafc90d3ba6da0d5534f3b56b498b29b 100644
|
index ea870afe24eb33a1333a32a42df5277155501ebc..450c119dcef10bcc2c0ef044aaed8760050c78db 100644
|
||||||
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
--- a/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
+++ b/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||||
@@ -275,6 +275,28 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
@@ -275,6 +275,28 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||||
@@ -31,7 +31,7 @@ index ae0a3c3d9d6300293a6d0dff5cae49ebe7c11dab..3b08dad7a9fac7ac9acec0bfb85d4826
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index fdaf752b4d39402de504cc8dfb6f0593f9b19d9a..74d6cf9b0fa0e47d5c94a16ce54f32810afb2da5 100644
|
index a8a5da1f8519fe97f45ddd140afb9dc2a64c015e..60fe99648a3d579f24172eb10067d859115d0ac9 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -816,6 +816,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
@@ -816,6 +816,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Optimize canSee checks
|
|||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
index db2cd4603c26bca59654f0a5225b18c446a7f612..fcc124e1005f4ddda10b9d08226e6d64693f9009 100644
|
index d2010fc46215c37c3ef1d8a75cc39bce655d2c3f..3cb2cd294874ece5fbefd0618b4db27701ef118a 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||||
@@ -215,7 +215,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
@@ -210,7 +210,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
private boolean hasPlayedBefore = false;
|
private boolean hasPlayedBefore = false;
|
||||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||||
private final Set<String> channels = new HashSet<String>();
|
private final Set<String> channels = new HashSet<String>();
|
||||||
@@ -17,7 +17,7 @@ index db2cd4603c26bca59654f0a5225b18c446a7f612..fcc124e1005f4ddda10b9d08226e6d64
|
|||||||
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
||||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||||
private int hash = 0;
|
private int hash = 0;
|
||||||
@@ -2272,9 +2272,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
@@ -2267,9 +2267,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canSee(org.bukkit.entity.Entity entity) {
|
public boolean canSee(org.bukkit.entity.Entity entity) {
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ public class DivineConfig {
|
|||||||
public static ChunkSystemAlgorithms chunkWorkerAlgorithm = ChunkSystemAlgorithms.C2ME;
|
public static ChunkSystemAlgorithms chunkWorkerAlgorithm = ChunkSystemAlgorithms.C2ME;
|
||||||
public static ChunkTaskPriority chunkTaskPriority = ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN;
|
public static ChunkTaskPriority chunkTaskPriority = ChunkTaskPriority.EUCLIDEAN_CIRCLE_PATTERN;
|
||||||
public static int threadPoolPriority = Thread.NORM_PRIORITY + 1;
|
public static int threadPoolPriority = Thread.NORM_PRIORITY + 1;
|
||||||
public static boolean enableAsyncNoiseFill = false;
|
|
||||||
public static boolean asyncChunkSendingEnabled = true;
|
public static boolean asyncChunkSendingEnabled = true;
|
||||||
public static boolean enableSecureSeed = false;
|
public static boolean enableSecureSeed = false;
|
||||||
public static boolean smoothBedrockLayer = false;
|
public static boolean smoothBedrockLayer = false;
|
||||||
@@ -223,8 +222,6 @@ public class DivineConfig {
|
|||||||
" - DEFAULT_DIAMOND_PATTERN: Default one, chunk priorities will be ordered in a diamond pattern"));
|
" - DEFAULT_DIAMOND_PATTERN: Default one, chunk priorities will be ordered in a diamond pattern"));
|
||||||
threadPoolPriority = getInt("settings.chunks.thread-pool-priority", threadPoolPriority,
|
threadPoolPriority = getInt("settings.chunks.thread-pool-priority", threadPoolPriority,
|
||||||
"Sets the priority of the thread pool used for chunk generation");
|
"Sets the priority of the thread pool used for chunk generation");
|
||||||
enableAsyncNoiseFill = getBoolean("settings.chunks.enable-async-noise-fill", enableAsyncNoiseFill,
|
|
||||||
"Runs noise filling and biome populating in a virtual thread executor. If disabled, it will run sync.");
|
|
||||||
|
|
||||||
enableSecureSeed = getBoolean("settings.chunks.enable-secure-seed", enableSecureSeed,
|
enableSecureSeed = getBoolean("settings.chunks.enable-secure-seed", enableSecureSeed,
|
||||||
"This feature is based on Secure Seed mod by Earthcomputer.",
|
"This feature is based on Secure Seed mod by Earthcomputer.",
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.bxteam.divinemc.util;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.DynamicOps;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class SynchronizedCodec<A> implements Codec<A> {
|
||||||
|
private final ReentrantLock lock = new ReentrantLock(false);
|
||||||
|
private final Codec<A> delegate;
|
||||||
|
|
||||||
|
public SynchronizedCodec(Codec<A> delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<Pair<A, T>> decode(DynamicOps<T> ops, T input) {
|
||||||
|
try {
|
||||||
|
lock.lockInterruptibly();
|
||||||
|
return this.delegate.decode(ops, input);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (lock.isHeldByCurrentThread()) lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<T> encode(A input, DynamicOps<T> ops, T prefix) {
|
||||||
|
try {
|
||||||
|
lock.lockInterruptibly();
|
||||||
|
return this.delegate.encode(input, ops, prefix);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (lock.isHeldByCurrentThread()) lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user