From 2cf4b82d7140a48cfd78ff089f1919e7d173915d Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 27 Dec 2021 13:35:09 -0800
Subject: [PATCH] Correctly parse last update for old chunks for regionfile
 recalc

It's required so that comparisons between two chunks can be
made
---
 ...culate-regionfile-header-if-it-is-co.patch | 16 ++++++++----
 .../0810-Rewrite-the-light-engine.patch       | 26 +++++++++----------
 ...tochunk-light-sources-unless-it-is-m.patch |  4 +--
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/patches/server/0754-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/patches/server/0754-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
index 48436825c0..920fd81640 100644
--- a/patches/server/0754-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
+++ b/patches/server/0754-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch
@@ -10,23 +10,29 @@ hoping that at least then we don't swap chunks, and maybe recover
 them all.
 
 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 8866ded0567fee710aa301dbc89f4c45b7283447..cf042295fe250d74c67a04f8f0d2b233860d4d1d 100644
+index 8866ded0567fee710aa301dbc89f4c45b7283447..75ef7c9ddafc23fa122c1421f55b3d7e0dcb2eef 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
-@@ -66,6 +66,12 @@ import org.apache.logging.log4j.LogManager;
+@@ -66,6 +66,18 @@ import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
  public class ChunkSerializer {
 +    // Paper start
 +    // TODO: Check on update
 +    public static long getLastWorldSaveTime(CompoundTag chunkData) {
-+        return chunkData.getLong("LastUpdate");
++        final int dataVersion = ChunkStorage.getVersion(chunkData);
++        if (dataVersion < 2842) { // Level tag is removed after this version
++            final CompoundTag levelData = chunkData.getCompound("Level");
++            return levelData.getLong("LastUpdate");
++        } else {
++            return chunkData.getLong("LastUpdate");
++        }
 +    }
 +    // Paper end
  
      public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states
      private static final Logger LOGGER = LogManager.getLogger();
-@@ -454,7 +460,7 @@ public class ChunkSerializer {
+@@ -454,7 +466,7 @@ public class ChunkSerializer {
          nbttagcompound.putInt("xPos", chunkcoordintpair.x);
          nbttagcompound.putInt("yPos", chunk.getMinSection());
          nbttagcompound.putInt("zPos", chunkcoordintpair.z);
@@ -36,7 +42,7 @@ index 8866ded0567fee710aa301dbc89f4c45b7283447..cf042295fe250d74c67a04f8f0d2b233
          nbttagcompound.putString("Status", chunk.getStatus().getName());
          BlendingData blendingdata = chunk.getBlendingData();
 diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
-index b1b1fa19cfd533d5625a462af399c5fd055629b0..a99a0ea2d04ebee66982a7da9422ae7a64127d3b 100644
+index 392fd2f5919d6a8f37c9f2b0421831d6ce381e0c..f706058877dc3f88aab4e7028665ca53376beac1 100644
 --- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
 +++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
 @@ -38,7 +38,7 @@ public class ChunkStorage implements AutoCloseable {
diff --git a/patches/server/0810-Rewrite-the-light-engine.patch b/patches/server/0810-Rewrite-the-light-engine.patch
index 2aef0702ca..15068b80c3 100644
--- a/patches/server/0810-Rewrite-the-light-engine.patch
+++ b/patches/server/0810-Rewrite-the-light-engine.patch
@@ -4432,7 +4432,7 @@ index 825fdb0336b0388dbbc54c8da99781900612031c..d271871563fa883efb77b35ec3b1dfbb
      private final DebugBuffer<ChunkHolder.ChunkSaveDebug> chunkToSaveHistory;
      public int oldTicketLevel;
 diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
-index b5ea631f93b9390f82475560cf3e33585d034cd6..0c046cd0fab44aecd41ef5c1477b13ea9606aee4 100644
+index 6e11040cdead829b1329ce0a95f5bf95a65bc6de..3be958576599995e083d4bea85e89099911795a6 100644
 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
 +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
 @@ -130,7 +130,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -5019,10 +5019,10 @@ index 0dfa51c8826b9e984586a3e4e050a50a4fbb1bd3..e947a47dd8c6906bc36eca757c4b9f9f
          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 cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54d2888c19 100644
+index 75ef7c9ddafc23fa122c1421f55b3d7e0dcb2eef..c553c926d147bae370ccd50dca74edc8b19c2f06 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
-@@ -79,6 +79,14 @@ public class ChunkSerializer {
+@@ -85,6 +85,14 @@ public class ChunkSerializer {
      private static final String BLOCK_TICKS_TAG = "block_ticks";
      private static final String FLUID_TICKS_TAG = "fluid_ticks";
  
@@ -5037,7 +5037,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
      public ChunkSerializer() {}
  
      // Paper start - guard against serializing mismatching coordinates
-@@ -138,13 +146,20 @@ public class ChunkSerializer {
+@@ -144,13 +152,20 @@ public class ChunkSerializer {
          }
  
          UpgradeData chunkconverter = nbt.contains("UpgradeData", 10) ? new UpgradeData(nbt.getCompound("UpgradeData"), world) : UpgradeData.EMPTY;
@@ -5059,7 +5059,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
  
          if (flag) {
              tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
-@@ -158,7 +173,7 @@ public class ChunkSerializer {
+@@ -164,7 +179,7 @@ public class ChunkSerializer {
          DataResult dataresult;
  
          for (int j = 0; j < nbttaglist.size(); ++j) {
@@ -5068,7 +5068,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
              byte b0 = nbttagcompound1.getByte("Y");
              int k = world.getSectionIndexFromSectionY(b0);
  
-@@ -203,23 +218,29 @@ public class ChunkSerializer {
+@@ -209,23 +224,29 @@ public class ChunkSerializer {
              }
  
              if (flag) {
@@ -5112,7 +5112,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
              }
          }
  
-@@ -248,6 +269,8 @@ public class ChunkSerializer {
+@@ -254,6 +275,8 @@ public class ChunkSerializer {
              }, chunkPos);
  
              object = new LevelChunk(world.getLevel(), chunkPos, chunkconverter, levelchunkticks, levelchunkticks1, l, achunksection, ChunkSerializer.postLoadChunk(world, nbt), blendingdata);
@@ -5121,7 +5121,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
          } else {
              ProtoChunkTicks<Block> protochunkticklist = ProtoChunkTicks.load(nbt.getList("block_ticks", 10), (s) -> {
                  return Registry.BLOCK.getOptional(ResourceLocation.tryParse(s));
-@@ -256,6 +279,8 @@ public class ChunkSerializer {
+@@ -262,6 +285,8 @@ public class ChunkSerializer {
                  return Registry.FLUID.getOptional(ResourceLocation.tryParse(s));
              }, chunkPos);
              ProtoChunk protochunk = new ProtoChunk(chunkPos, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, world, iregistry, blendingdata);
@@ -5130,7 +5130,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
  
              object = protochunk;
              protochunk.setInhabitedTime(l);
-@@ -401,7 +426,7 @@ public class ChunkSerializer {
+@@ -407,7 +432,7 @@ public class ChunkSerializer {
          DataLayer[] blockLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()];
          DataLayer[] skyLight = new DataLayer[lightenginethreaded.getMaxLightSection() - lightenginethreaded.getMinLightSection()];
  
@@ -5139,7 +5139,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
              DataLayer blockArray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkPos, i));
              DataLayer skyArray = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkPos, i));
  
-@@ -453,6 +478,12 @@ public class ChunkSerializer {
+@@ -459,6 +484,12 @@ public class ChunkSerializer {
      }
      public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata) {
          // Paper end
@@ -5152,7 +5152,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
          ChunkPos chunkcoordintpair = chunk.getPos();
          CompoundTag nbttagcompound = new CompoundTag();
  
-@@ -503,20 +534,14 @@ public class ChunkSerializer {
+@@ -509,20 +540,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;
@@ -5180,7 +5180,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
  
                  if (flag1) {
                      LevelChunkSection chunksection = achunksection[j];
-@@ -531,13 +556,27 @@ public class ChunkSerializer {
+@@ -537,13 +562,27 @@ public class ChunkSerializer {
                      nbttagcompound1.put("biomes", (Tag) dataresult1.getOrThrow(false, logger1::error));
                  }
  
@@ -5212,7 +5212,7 @@ index cf042295fe250d74c67a04f8f0d2b233860d4d1d..2ade441dc4456d1670a81a3f58d4aa54
  
                  if (!nbttagcompound1.isEmpty()) {
                      nbttagcompound1.putByte("Y", (byte) i);
-@@ -548,7 +587,8 @@ public class ChunkSerializer {
+@@ -554,7 +593,8 @@ public class ChunkSerializer {
  
          nbttagcompound.put("sections", nbttaglist);
          if (flag) {
diff --git a/patches/server/0811-Always-parse-protochunk-light-sources-unless-it-is-m.patch b/patches/server/0811-Always-parse-protochunk-light-sources-unless-it-is-m.patch
index 96c4a80599..c1ca1cdb1a 100644
--- a/patches/server/0811-Always-parse-protochunk-light-sources-unless-it-is-m.patch
+++ b/patches/server/0811-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 2ade441dc4456d1670a81a3f58d4aa54d2888c19..300c95a3839954b9e631aa4d76c131a5c2d96394 100644
+index c553c926d147bae370ccd50dca74edc8b19c2f06..8246204ce5d8f825c7796f87006e658d7a019876 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 {
+@@ -310,16 +310,33 @@ public class ChunkSerializer {
              BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen();
              boolean flag2 = chunkstatus.isOrAfter(ChunkStatus.LIGHT) || belowzeroretrogen != null && belowzeroretrogen.targetStatus().isOrAfter(ChunkStatus.LIGHT);