couple more patches

This commit is contained in:
Jake 2021-11-29 21:25:11 -08:00 committed by MiniDigger | Martin
parent bcc11dd95a
commit 5ff792342c
68 changed files with 25 additions and 22 deletions

View file

@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Thu, 18 Jun 2020 18:23:20 -0700
Subject: [PATCH] Prevent unload() calls removing tickets for sync loads
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index e13a8e3dc11292aed13ff12ee8e0f9d6a95f0c34..9f0321179fb1d87b6e1b74e128955157983b0500 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -725,6 +725,8 @@ public class ServerChunkCache extends ChunkSource {
return completablefuture;
}
+ private long syncLoadCounter; // Paper - prevent plugin unloads from removing our ticket
+
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
// Paper start - add isUrgent - old sig left in place for dirty nms plugins
return getChunkFutureMainThread(chunkX, chunkZ, leastStatus, create, false);
@@ -743,9 +745,12 @@ public class ServerChunkCache extends ChunkSource {
ChunkHolder.FullChunkStatus currentChunkState = ChunkHolder.getFullChunkStatus(playerchunk.getTicketLevel());
currentlyUnloading = (oldChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER) && !currentChunkState.isOrAfter(ChunkHolder.FullChunkStatus.BORDER));
}
+ final Long identifier; // Paper - prevent plugin unloads from removing our ticket
if (create && !currentlyUnloading) {
// CraftBukkit end
this.distanceManager.addTicket(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair);
+ identifier = Long.valueOf(this.syncLoadCounter++); // Paper - prevent plugin unloads from removing our ticket
+ this.distanceManager.addTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper - prevent plugin unloads from removing our ticket
if (isUrgent) this.distanceManager.markUrgent(chunkcoordintpair); // Paper - Chunk priority
if (this.chunkAbsent(playerchunk, l)) {
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
@@ -756,13 +761,21 @@ public class ServerChunkCache extends ChunkSource {
playerchunk = this.getVisibleChunkIfPresent(k);
gameprofilerfiller.pop();
if (this.chunkAbsent(playerchunk, l)) {
+ this.distanceManager.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier); // Paper
throw (IllegalStateException) Util.pauseInIde(new IllegalStateException("No chunk holder after ticket has been added"));
}
}
- }
+ } else { identifier = null; } // Paper - prevent plugin unloads from removing our ticket
// Paper start - Chunk priority
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = this.chunkAbsent(playerchunk, l) ? ChunkHolder.UNLOADED_CHUNK_FUTURE : playerchunk.getOrScheduleFuture(leastStatus, this.chunkMap);
+ // Paper start - prevent plugin unloads from removing our ticket
+ if (create && !currentlyUnloading) {
+ future.thenAcceptAsync((either) -> {
+ ServerChunkCache.this.distanceManager.removeTicketAtLevel(TicketType.REQUIRED_LOAD, chunkcoordintpair, l, identifier);
+ }, ServerChunkCache.this.mainThreadProcessor);
+ }
+ // Paper end - prevent plugin unloads from removing our ticket
if (isUrgent) {
future.thenAccept(either -> this.distanceManager.clearUrgent(chunkcoordintpair));
}
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
index 3c1698ba0d3bc412ab957777d9b5211dbc555208..41ddcf6775f99c56cf4b13b284420061e5dd6bdc 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -31,6 +31,7 @@ public class TicketType<T> {
public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit
public static final TicketType<org.bukkit.plugin.Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit
public static final TicketType<Long> DELAY_UNLOAD = create("delay_unload", Long::compareTo, 300); // Paper
+ public static final TicketType<Long> REQUIRED_LOAD = create("required_load", Long::compareTo); // Paper - make sure getChunkAt does not fail
public static <T> TicketType<T> create(String name, Comparator<T> argumentComparator) {
return new TicketType<>(name, argumentComparator, 0L);

View file

@ -19,10 +19,10 @@ index eada966d7f108a6081be7a848f5c1dfcb1eed676..a977f7483f37df473096b2234dc1308b
public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks");
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index e13a8e3dc11292aed13ff12ee8e0f9d6a95f0c34..660ce57b008985d9064271b1ef861f4291d7e09f 100644
index 9f0321179fb1d87b6e1b74e128955157983b0500..0d9f8180110b072e54d6c0f8c64df584b40776b9 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -821,6 +821,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -834,6 +834,7 @@ public class ServerChunkCache extends ChunkSource {
public boolean runDistanceManagerUpdates() {
if (distanceManager.delayDistanceManagerTick) return false; // Paper - Chunk priority
if (this.chunkMap.unloadingPlayerChunk) { net.minecraft.server.MinecraftServer.LOGGER.fatal("Cannot tick distance manager while unloading playerchunks", new Throwable()); throw new IllegalStateException("Cannot tick distance manager while unloading playerchunks"); } // Paper
@ -30,7 +30,7 @@ index e13a8e3dc11292aed13ff12ee8e0f9d6a95f0c34..660ce57b008985d9064271b1ef861f42
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
boolean flag1 = this.chunkMap.promoteChunkMap();
@@ -830,6 +831,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -843,6 +844,7 @@ public class ServerChunkCache extends ChunkSource {
this.clearCache();
return true;
}

View file

@ -22,10 +22,10 @@ With this change I could get all 200 on at 0ms ping.
So in general this patch should reduce Netty I/O thread load.
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 660ce57b008985d9064271b1ef861f4291d7e09f..5ca10071d98ee743671f09b57d43d519ea03da19 100644
index 0d9f8180110b072e54d6c0f8c64df584b40776b9..758bb0fae0f9ba9672250e4a65c27f1175eab12d 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -1040,7 +1040,24 @@ public class ServerChunkCache extends ChunkSource {
@@ -1053,7 +1053,24 @@ public class ServerChunkCache extends ChunkSource {
});
gameprofilerfiller.pop();
gameprofilerfiller.pop();

View file

@ -4746,13 +4746,13 @@ index fec2a2a9f958492eefbbffcaf8179a2fac5a4d99..731001489eb6d2562e4685af79efa811
// Paper end
}
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
index 3c1698ba0d3bc412ab957777d9b5211dbc555208..858e94f07b675f4aed2930491633fb6e3a7d168e 100644
index 41ddcf6775f99c56cf4b13b284420061e5dd6bdc..ae46429264e6a7e5c88b6b6a41a6df4db7b3e70d 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -31,6 +31,7 @@ public class TicketType<T> {
public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit
@@ -32,6 +32,7 @@ public class TicketType<T> {
public static final TicketType<org.bukkit.plugin.Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit
public static final TicketType<Long> DELAY_UNLOAD = create("delay_unload", Long::compareTo, 300); // Paper
public static final TicketType<Long> REQUIRED_LOAD = create("required_load", Long::compareTo); // Paper - make sure getChunkAt does not fail
+ public static final TicketType<Long> CHUNK_RELIGHT = create("light_update", Long::compareTo); // Paper - ensure chunks stay loaded for lighting
public static <T> TicketType<T> create(String name, Comparator<T> argumentComparator) {

View file

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 23 Aug 2021 04:50:05 -0700
Subject: [PATCH] Always parse protochunk light sources unless it is marked as
non-lit
Chunks not marked as lit will always go through the light engine,
so they should always have their block sources parsed.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index e54376b463b017d5e371f8d3204a37993b0e78e7..9b7bc1c9091d20671d281fa304722ac45fbf6e2e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -304,16 +304,33 @@ public class ChunkSerializer {
BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen();
boolean flag2 = chunkstatus.isOrAfter(ChunkStatus.LIGHT) || belowzeroretrogen != null && belowzeroretrogen.targetStatus().isOrAfter(ChunkStatus.LIGHT);
- if (!flag && flag2) {
- Iterator iterator = BlockPos.betweenClosed(chunkPos.getMinBlockX(), world.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), world.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ()).iterator();
+ if (!flag) { // Paper - fix incorrect parsing of blocks that emit light - it should always parse it, unless the chunk is marked as lit
+ // Paper start - let's make sure the implementation isn't as slow as possible
+ int offX = chunkPos.x << 4;
+ int offZ = chunkPos.z << 4;
+
+ int minChunkSection = io.papermc.paper.util.WorldUtil.getMinSection(world);
+ int maxChunkSection = io.papermc.paper.util.WorldUtil.getMaxSection(world);
+
+ LevelChunkSection[] sections = achunksection;
+ for (int sectionY = minChunkSection; sectionY <= maxChunkSection; ++sectionY) {
+ LevelChunkSection section = sections[sectionY - minChunkSection];
+ if (section == null || section.hasOnlyAir()) {
+ // no sources in empty sections
+ continue;
+ }
+ int offY = sectionY << 4;
- while (iterator.hasNext()) {
- BlockPos blockposition = (BlockPos) iterator.next();
+ for (int index = 0; index < (16 * 16 * 16); ++index) {
+ if (section.states.get(index).getLightEmission() <= 0) {
+ continue;
+ }
- if (((ChunkAccess) object).getBlockState(blockposition).getLightEmission() != 0) {
- protochunk.addLight(blockposition);
+ // index = x | (z << 4) | (y << 8)
+ protochunk.addLight(new BlockPos(offX | (index & 15), offY | (index >>> 8), offZ | ((index >>> 4) & 15)));
}
}
+ // Paper end
}
}