Skip to content

Commit 5f0b829

Browse files
committed
Re-add chunk position check to regionfile recalculation patch
1 parent 89cdcba commit 5f0b829

1 file changed

Lines changed: 90 additions & 11 deletions

File tree

paper-server/patches/features/0022-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ we instead drop the current regionfile header and recalculate -
99
hoping that at least then we don't swap chunks, and maybe recover
1010
them all.
1111

12+
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
13+
index 1acea58838f057ab87efd103cbecb6f5aeaef393..09320f243a54f855b29d3833089b096975ca0075 100644
14+
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
15+
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
16+
@@ -1447,7 +1447,7 @@ public final class MoonriseRegionFileIO {
17+
18+
public abstract void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException;
19+
20+
- public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead) {
21+
+ public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead, int recalculateCount) { // Paper - Attempt to recalculate regionfile header if it is corrupt
22+
public static enum ReadResult {
23+
NO_DATA,
24+
HAS_DATA,
1225
diff --git a/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/net/minecraft/world/level/chunk/storage/RegionBitmap.java
1326
index 64a718c98f799c62a5bb28e1e8e5f66cc96c915d..666f2e967c99f78422c83fb20e1a3bf3efa7845e 100644
1427
--- a/net/minecraft/world/level/chunk/storage/RegionBitmap.java
@@ -42,10 +55,10 @@ index 64a718c98f799c62a5bb28e1e8e5f66cc96c915d..666f2e967c99f78422c83fb20e1a3bf3
4255
this.used.set(sectorOffset, sectorOffset + sectorCount);
4356
}
4457
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
45-
index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b9535fd6300f 100644
58+
index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..22f3aa1674664906e8ec45372d758d79017e3987 100644
4659
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
4760
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
48-
@@ -46,6 +46,355 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
61+
@@ -46,6 +46,363 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
4962
@VisibleForTesting
5063
protected final RegionBitmap usedSectors = new RegionBitmap();
5164

@@ -127,6 +140,12 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
127140
+ }
128141
+
129142
+ // note: only call for CHUNK regionfiles
143+
+ private final java.util.concurrent.atomic.AtomicInteger recalculateCount = new java.util.concurrent.atomic.AtomicInteger();
144+
+
145+
+ public int getRecalculateCount() {
146+
+ return this.recalculateCount.get();
147+
+ }
148+
+
130149
+ boolean recalculateHeader() throws IOException {
131150
+ if (!this.canRecalcHeader) {
132151
+ return false;
@@ -137,6 +156,8 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
137156
+ return false;
138157
+ }
139158
+ synchronized (this) {
159+
+ this.recalculateCount.getAndIncrement();
160+
+
140161
+ LOGGER.warn("Corrupt regionfile header detected! Attempting to re-calculate header offsets for regionfile " + this.path.toAbsolutePath(), new Throwable());
141162
+
142163
+ // try to backup file so maybe it could be sent to us for further investigation
@@ -401,15 +422,15 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
401422
// Paper start - rewrite chunk system
402423
@Override
403424
public final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(final net.minecraft.nbt.CompoundTag data, final ChunkPos pos) throws IOException {
404-
@@ -74,6 +423,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
425+
@@ -74,6 +431,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
405426
throw new IllegalArgumentException("Expected directory, got " + externalFileDir.toAbsolutePath());
406427
} else {
407428
this.externalFileDir = externalFileDir;
408429
+ this.canRecalcHeader = RegionFileStorage.isChunkDataFolder(this.externalFileDir); // Paper - add can recalc flag
409430
this.offsets = this.header.asIntBuffer();
410431
this.offsets.limit(1024);
411432
this.header.position(4096);
412-
@@ -94,11 +444,13 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
433+
@@ -94,11 +452,13 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
413434

414435
long size = Files.size(path);
415436

@@ -426,7 +447,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
426447
// Spigot start
427448
if (numSectors == 255) {
428449
// We're maxed out, so we need to read the proper length from the section
429-
@@ -109,18 +461,62 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
450+
@@ -109,18 +469,62 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
430451
// Spigot end
431452
if (sectorNumber < 2) {
432453
LOGGER.warn("Region file {} has invalid sector at index: {}; sector {} overlaps with header", path, i1, sectorNumber);
@@ -493,7 +514,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
493514
}
494515
}
495516
}
496-
@@ -130,10 +526,35 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
517+
@@ -130,10 +534,35 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
497518
}
498519

499520
private Path getExternalChunkPath(ChunkPos chunkPos) {
@@ -530,7 +551,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
530551
@Nullable
531552
public synchronized DataInputStream getChunkDataInputStream(ChunkPos chunkPos) throws IOException {
532553
int offset = this.getOffset(chunkPos);
533-
@@ -155,30 +576,67 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
554+
@@ -155,30 +584,67 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
534555
byteBuffer.flip();
535556
if (byteBuffer.remaining() < 5) {
536557
LOGGER.error("Chunk {} header is truncated: expected {} but read {}", chunkPos, i, byteBuffer.remaining());
@@ -600,7 +621,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
600621
}
601622
}
602623
}
603-
@@ -361,9 +819,14 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
624+
@@ -361,9 +827,14 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
604625
}
605626

606627
private ByteBuffer createExternalStub() {
@@ -617,7 +638,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
617638
return byteBuffer;
618639
}
619640
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
620-
index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf9ecee195 100644
641+
index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..384f2cd090d6d23bd1308d6e82c24338f2bf55d1 100644
621642
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
622643
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
623644
@@ -23,6 +23,36 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -657,15 +678,73 @@ index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf
657678
// Paper start - rewrite chunk system
658679
private static final int REGION_SHIFT = 5;
659680
private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
660-
@@ -216,6 +246,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
681+
@@ -169,12 +199,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
682+
683+
if (input == null) {
684+
return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
685+
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null
686+
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null, regionFile == null ? 0 : regionFile.getRecalculateCount() // Paper - Attempt to recalculate regionfile header if it is corrupt
687+
);
688+
}
689+
690+
final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData ret = new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
691+
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null
692+
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null, regionFile.getRecalculateCount() // Paper - Attempt to recalculate regionfile header if it is corrupt
693+
);
694+
695+
if (!(input instanceof ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker)) {
696+
@@ -190,7 +220,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
697+
}
698+
699+
return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
700+
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead
701+
+ ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead, regionFile.getRecalculateCount() // Paper - Attempt to recalculate regionfile header if it is corrupt
702+
);
703+
}
704+
705+
@@ -200,7 +230,32 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
706+
final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData readData
707+
) throws IOException {
708+
try {
709+
- return NbtIo.read(readData.input());
710+
+ // Paper start - Attempt to recalculate regionfile header if it is corrupt
711+
+ final CompoundTag ret = NbtIo.read(readData.input());
712+
+ if (!this.isChunkData) {
713+
+ return ret;
714+
+ }
715+
+
716+
+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
717+
+ final ChunkPos headerChunkPos = SerializableChunkData.getChunkCoordinate(ret);
718+
+ final RegionFile regionFile = this.getRegionFile(pos);
719+
+
720+
+ if (regionFile.getRecalculateCount() != readData.recalculateCount()) {
721+
+ return null;
722+
+ }
723+
+
724+
+ if (!headerChunkPos.equals(pos)) {
725+
+ LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + headerChunkPos + " instead! Attempting regionfile recalculation " + regionFile.getPath().toAbsolutePath());
726+
+ if (regionFile.recalculateHeader()) {
727+
+ return null;
728+
+ }
729+
+
730+
+ LOGGER.error(com.mojang.logging.LogUtils.FATAL_MARKER, "Can't recalculate regionfile header?");
731+
+ return ret;
732+
+ }
733+
+
734+
+ return ret;
735+
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
736+
} finally {
737+
readData.input().close();
738+
}
739+
@@ -216,6 +271,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
661740
this.folder = folder;
662741
this.sync = sync;
663742
this.info = info;
664743
+ this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers
665744
}
666745

667746
@org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
668-
@@ -309,6 +340,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
747+
@@ -309,6 +365,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
669748
}
670749

671750
var4 = NbtIo.read(chunkDataInputStream);

0 commit comments

Comments
 (0)