From ee7d16111dea48b3e244343031649639a8e218a5 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 10 Jun 2022 21:08:37 -0700 Subject: [PATCH] Make starlight light read non-fatal if it throws Brings behavior in line with the mod, we shouldn't kill the chunk if the light data is corrupt, we can regenerate the light data --- .../0790-Rewrite-the-light-engine.patch | 29 +++++++++++++------ ...tochunk-light-sources-unless-it-is-m.patch | 4 +-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/patches/server/0790-Rewrite-the-light-engine.patch b/patches/server/0790-Rewrite-the-light-engine.patch index 91c1b9935..9ffeb6c4d 100644 --- a/patches/server/0790-Rewrite-the-light-engine.patch +++ b/patches/server/0790-Rewrite-the-light-engine.patch @@ -5040,7 +5040,7 @@ index 5ce6a2b83546f4dbc3183a386f51b4bacc173744..a7231ceda4f3e96c0e0c11eee953f129 this.fluidTicks = fluidTickScheduler; } 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 be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdbab2dbeaca 100644 +index be9c15fe141ede1132dbe07ba4bfcf22036ab194..b479c4a617becd3f31080ade0388c50727a56ba0 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 @@ -94,6 +94,14 @@ public class ChunkSerializer { @@ -5089,7 +5089,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba byte b0 = nbttagcompound1.getByte("Y"); int k = world.getSectionIndexFromSectionY(b0); -@@ -214,31 +229,34 @@ public class ChunkSerializer { +@@ -214,31 +229,45 @@ public class ChunkSerializer { boolean flag3 = nbttagcompound1.contains("BlockLight", 7); boolean flag4 = flag1 && nbttagcompound1.contains("SkyLight", 7); @@ -5097,7 +5097,9 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba - if (!flag2) { + // Paper start - rewrite the light engine + if (flag) { ++ try { + if ((flag3 || flag4) && !flag2) { ++ // Paper end - rewrite the light engine tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main lightengine.retainData(chunkPos, true); }); // Paper - delay this task since we're executing off-main @@ -5112,11 +5114,13 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba - lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), blockLight, true); - }); - // Paper end - delay this task since we're executing off-main ++ // Paper start - rewrite the light engine + // this is where our diff is + blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("BlockLight").clone(), sectionData.getInt(BLOCKLIGHT_STATE_TAG)); // clone for data safety + } else { + blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(BLOCKLIGHT_STATE_TAG)); } ++ // Paper end - rewrite the light engine if (flag4) { - // Paper start - delay this task since we're executing off-main @@ -5125,6 +5129,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba - lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), skyLight, true); - }); - // Paper end - delay this task since we're executing off-mai ++ // Paper start - rewrite the light engine + // we store under the same key so mod programs editing nbt + // can still read the data, hopefully. + // however, for compatibility we store chunks as unlit so vanilla @@ -5134,11 +5139,17 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba + } else { + skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(SKYLIGHT_STATE_TAG)); } ++ // Paper end - rewrite the light engine ++ // Paper start - rewrite the light engine ++ } catch (Exception ex) { ++ LOGGER.warn("Failed to load light data for chunk " + chunkPos + " in world '" + world.getWorld().getName() + "', light will be regenerated", ex); ++ flag = false; ++ } + // Paper end - rewrite light engine } } -@@ -267,6 +285,8 @@ public class ChunkSerializer { +@@ -267,6 +296,8 @@ public class ChunkSerializer { }, chunkPos); object1 = new LevelChunk(world.getLevel(), chunkPos, chunkconverter, levelchunkticks, levelchunkticks1, l, achunksection, ChunkSerializer.postLoadChunk(world, nbt), blendingdata); @@ -5147,7 +5158,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba } else { ProtoChunkTicks protochunkticklist = ProtoChunkTicks.load(nbt.getList("block_ticks", 10), (s) -> { return Registry.BLOCK.getOptional(ResourceLocation.tryParse(s)); -@@ -275,6 +295,8 @@ public class ChunkSerializer { +@@ -275,6 +306,8 @@ public class ChunkSerializer { return Registry.FLUID.getOptional(ResourceLocation.tryParse(s)); }, chunkPos); ProtoChunk protochunk = new ProtoChunk(chunkPos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world, iregistry, blendingdata); @@ -5156,7 +5167,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba object1 = protochunk; protochunk.setInhabitedTime(l); -@@ -420,7 +442,7 @@ public class ChunkSerializer { +@@ -420,7 +453,7 @@ public class ChunkSerializer { DataLayer[] blockLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()]; DataLayer[] skyLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()]; @@ -5165,7 +5176,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba DataLayer blockArray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkPos, i)); DataLayer skyArray = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkPos, i)); -@@ -478,6 +500,12 @@ public class ChunkSerializer { +@@ -478,6 +511,12 @@ public class ChunkSerializer { } public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata) { // Paper end @@ -5178,7 +5189,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba ChunkPos chunkcoordintpair = chunk.getPos(); CompoundTag nbttagcompound = new CompoundTag(); -@@ -528,20 +556,14 @@ public class ChunkSerializer { +@@ -528,20 +567,14 @@ public class ChunkSerializer { for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) { int j = chunk.getSectionIndexFromSectionY(i); boolean flag1 = j >= 0 && j < achunksection.length; @@ -5206,7 +5217,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba if (flag1) { LevelChunkSection chunksection = achunksection[j]; -@@ -556,13 +578,27 @@ public class ChunkSerializer { +@@ -556,13 +589,27 @@ public class ChunkSerializer { nbttagcompound1.put("biomes", (Tag) dataresult1.getOrThrow(false, logger1::error)); } @@ -5238,7 +5249,7 @@ index be9c15fe141ede1132dbe07ba4bfcf22036ab194..e843b0684693867dad566aa87104fdba if (!nbttagcompound1.isEmpty()) { nbttagcompound1.putByte("Y", (byte) i); -@@ -573,7 +609,8 @@ public class ChunkSerializer { +@@ -573,7 +620,8 @@ public class ChunkSerializer { nbttagcompound.put("sections", nbttaglist); if (flag) { diff --git a/patches/server/0791-Always-parse-protochunk-light-sources-unless-it-is-m.patch b/patches/server/0791-Always-parse-protochunk-light-sources-unless-it-is-m.patch index 6ebf11f2d..cff106411 100644 --- a/patches/server/0791-Always-parse-protochunk-light-sources-unless-it-is-m.patch +++ b/patches/server/0791-Always-parse-protochunk-light-sources-unless-it-is-m.patch @@ -8,10 +8,10 @@ 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 e843b0684693867dad566aa87104fdbab2dbeaca..dd0bb7a0b27bf7eb60e606398d0bd3fe5b1f5af5 100644 +index b479c4a617becd3f31080ade0388c50727a56ba0..184d1742e5943f4a438e33fcf19f96196a3824e8 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 -@@ -320,16 +320,33 @@ public class ChunkSerializer { +@@ -331,16 +331,33 @@ public class ChunkSerializer { BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen(); boolean flag5 = chunkstatus.isOrAfter(ChunkStatus.LIGHT) || belowzeroretrogen != null && belowzeroretrogen.targetStatus().isOrAfter(ChunkStatus.LIGHT);