mirror of
https://github.com/PaperMC/Paper.git
synced 2025-05-19 05:30:23 -07:00
Re-add chunk position check to regionfile recalculation patch
This commit is contained in:
parent
89cdcba573
commit
5f0b82925e
@ -9,6 +9,19 @@ we instead drop the current regionfile header and recalculate -
|
|||||||
hoping that at least then we don't swap chunks, and maybe recover
|
hoping that at least then we don't swap chunks, and maybe recover
|
||||||
them all.
|
them all.
|
||||||
|
|
||||||
|
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||||
|
index 1acea58838f057ab87efd103cbecb6f5aeaef393..09320f243a54f855b29d3833089b096975ca0075 100644
|
||||||
|
--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||||
|
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java
|
||||||
|
@@ -1447,7 +1447,7 @@ public final class MoonriseRegionFileIO {
|
||||||
|
|
||||||
|
public abstract void finishWrite(final int chunkX, final int chunkZ, final WriteData writeData) throws IOException;
|
||||||
|
|
||||||
|
- public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead) {
|
||||||
|
+ public static record ReadData(ReadResult result, DataInputStream input, CompoundTag syncRead, int recalculateCount) { // Paper - Attempt to recalculate regionfile header if it is corrupt
|
||||||
|
public static enum ReadResult {
|
||||||
|
NO_DATA,
|
||||||
|
HAS_DATA,
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/net/minecraft/world/level/chunk/storage/RegionBitmap.java
|
diff --git a/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/net/minecraft/world/level/chunk/storage/RegionBitmap.java
|
||||||
index 64a718c98f799c62a5bb28e1e8e5f66cc96c915d..666f2e967c99f78422c83fb20e1a3bf3efa7845e 100644
|
index 64a718c98f799c62a5bb28e1e8e5f66cc96c915d..666f2e967c99f78422c83fb20e1a3bf3efa7845e 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/RegionBitmap.java
|
--- a/net/minecraft/world/level/chunk/storage/RegionBitmap.java
|
||||||
@ -42,10 +55,10 @@ index 64a718c98f799c62a5bb28e1e8e5f66cc96c915d..666f2e967c99f78422c83fb20e1a3bf3
|
|||||||
this.used.set(sectorOffset, sectorOffset + sectorCount);
|
this.used.set(sectorOffset, sectorOffset + sectorCount);
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b9535fd6300f 100644
|
index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..22f3aa1674664906e8ec45372d758d79017e3987 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
@@ -46,6 +46,355 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -46,6 +46,363 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected final RegionBitmap usedSectors = new RegionBitmap();
|
protected final RegionBitmap usedSectors = new RegionBitmap();
|
||||||
|
|
||||||
@ -127,6 +140,12 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // note: only call for CHUNK regionfiles
|
+ // note: only call for CHUNK regionfiles
|
||||||
|
+ private final java.util.concurrent.atomic.AtomicInteger recalculateCount = new java.util.concurrent.atomic.AtomicInteger();
|
||||||
|
+
|
||||||
|
+ public int getRecalculateCount() {
|
||||||
|
+ return this.recalculateCount.get();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ boolean recalculateHeader() throws IOException {
|
+ boolean recalculateHeader() throws IOException {
|
||||||
+ if (!this.canRecalcHeader) {
|
+ if (!this.canRecalcHeader) {
|
||||||
+ return false;
|
+ return false;
|
||||||
@ -137,6 +156,8 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
+ return false;
|
+ return false;
|
||||||
+ }
|
+ }
|
||||||
+ synchronized (this) {
|
+ synchronized (this) {
|
||||||
|
+ this.recalculateCount.getAndIncrement();
|
||||||
|
+
|
||||||
+ LOGGER.warn("Corrupt regionfile header detected! Attempting to re-calculate header offsets for regionfile " + this.path.toAbsolutePath(), new Throwable());
|
+ LOGGER.warn("Corrupt regionfile header detected! Attempting to re-calculate header offsets for regionfile " + this.path.toAbsolutePath(), new Throwable());
|
||||||
+
|
+
|
||||||
+ // try to backup file so maybe it could be sent to us for further investigation
|
+ // try to backup file so maybe it could be sent to us for further investigation
|
||||||
@ -401,7 +422,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
// Paper start - rewrite chunk system
|
// Paper start - rewrite chunk system
|
||||||
@Override
|
@Override
|
||||||
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 {
|
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 {
|
||||||
@@ -74,6 +423,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -74,6 +431,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
throw new IllegalArgumentException("Expected directory, got " + externalFileDir.toAbsolutePath());
|
throw new IllegalArgumentException("Expected directory, got " + externalFileDir.toAbsolutePath());
|
||||||
} else {
|
} else {
|
||||||
this.externalFileDir = externalFileDir;
|
this.externalFileDir = externalFileDir;
|
||||||
@ -409,7 +430,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
this.offsets = this.header.asIntBuffer();
|
this.offsets = this.header.asIntBuffer();
|
||||||
this.offsets.limit(1024);
|
this.offsets.limit(1024);
|
||||||
this.header.position(4096);
|
this.header.position(4096);
|
||||||
@@ -94,11 +444,13 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -94,11 +452,13 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
|
|
||||||
long size = Files.size(path);
|
long size = Files.size(path);
|
||||||
|
|
||||||
@ -426,7 +447,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
// Spigot start
|
// Spigot start
|
||||||
if (numSectors == 255) {
|
if (numSectors == 255) {
|
||||||
// We're maxed out, so we need to read the proper length from the section
|
// We're maxed out, so we need to read the proper length from the section
|
||||||
@@ -109,18 +461,62 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -109,18 +469,62 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
// Spigot end
|
// Spigot end
|
||||||
if (sectorNumber < 2) {
|
if (sectorNumber < 2) {
|
||||||
LOGGER.warn("Region file {} has invalid sector at index: {}; sector {} overlaps with header", path, i1, sectorNumber);
|
LOGGER.warn("Region file {} has invalid sector at index: {}; sector {} overlaps with header", path, i1, sectorNumber);
|
||||||
@ -493,7 +514,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,10 +526,35 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -130,10 +534,35 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path getExternalChunkPath(ChunkPos chunkPos) {
|
private Path getExternalChunkPath(ChunkPos chunkPos) {
|
||||||
@ -530,7 +551,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
@Nullable
|
@Nullable
|
||||||
public synchronized DataInputStream getChunkDataInputStream(ChunkPos chunkPos) throws IOException {
|
public synchronized DataInputStream getChunkDataInputStream(ChunkPos chunkPos) throws IOException {
|
||||||
int offset = this.getOffset(chunkPos);
|
int offset = this.getOffset(chunkPos);
|
||||||
@@ -155,30 +576,67 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -155,30 +584,67 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
byteBuffer.flip();
|
byteBuffer.flip();
|
||||||
if (byteBuffer.remaining() < 5) {
|
if (byteBuffer.remaining() < 5) {
|
||||||
LOGGER.error("Chunk {} header is truncated: expected {} but read {}", chunkPos, i, byteBuffer.remaining());
|
LOGGER.error("Chunk {} header is truncated: expected {} but read {}", chunkPos, i, byteBuffer.remaining());
|
||||||
@ -600,7 +621,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,9 +819,14 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
@@ -361,9 +827,14 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuffer createExternalStub() {
|
private ByteBuffer createExternalStub() {
|
||||||
@ -617,7 +638,7 @@ index dea2823a9d1d69dcb0a4759d8ea9b3015ede20dc..0c41177462cca5c4bbab6490e323b953
|
|||||||
return byteBuffer;
|
return byteBuffer;
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||||
index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf9ecee195 100644
|
index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..384f2cd090d6d23bd1308d6e82c24338f2bf55d1 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||||
@@ -23,6 +23,36 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
@@ -23,6 +23,36 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
@ -657,7 +678,65 @@ index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf
|
|||||||
// Paper start - rewrite chunk system
|
// Paper start - rewrite chunk system
|
||||||
private static final int REGION_SHIFT = 5;
|
private static final int REGION_SHIFT = 5;
|
||||||
private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
|
private static final int MAX_NON_EXISTING_CACHE = 1024 * 4;
|
||||||
@@ -216,6 +246,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
@@ -169,12 +199,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
|
|
||||||
|
if (input == null) {
|
||||||
|
return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
|
||||||
|
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.NO_DATA, null, null
|
||||||
|
+ 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData ret = new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
|
||||||
|
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.HAS_DATA, input, null
|
||||||
|
+ 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
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!(input instanceof ca.spottedleaf.moonrise.patches.chunk_system.util.stream.ExternalChunkStreamMarker)) {
|
||||||
|
@@ -190,7 +220,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData(
|
||||||
|
- ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData.ReadResult.SYNC_READ, null, syncRead
|
||||||
|
+ 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -200,7 +230,32 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
|
final int chunkX, final int chunkZ, final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.ReadData readData
|
||||||
|
) throws IOException {
|
||||||
|
try {
|
||||||
|
- return NbtIo.read(readData.input());
|
||||||
|
+ // Paper start - Attempt to recalculate regionfile header if it is corrupt
|
||||||
|
+ final CompoundTag ret = NbtIo.read(readData.input());
|
||||||
|
+ if (!this.isChunkData) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
|
||||||
|
+ final ChunkPos headerChunkPos = SerializableChunkData.getChunkCoordinate(ret);
|
||||||
|
+ final RegionFile regionFile = this.getRegionFile(pos);
|
||||||
|
+
|
||||||
|
+ if (regionFile.getRecalculateCount() != readData.recalculateCount()) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!headerChunkPos.equals(pos)) {
|
||||||
|
+ LOGGER.error("Attempting to read chunk data at " + pos + " but got chunk data for " + headerChunkPos + " instead! Attempting regionfile recalculation " + regionFile.getPath().toAbsolutePath());
|
||||||
|
+ if (regionFile.recalculateHeader()) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ LOGGER.error(com.mojang.logging.LogUtils.FATAL_MARKER, "Can't recalculate regionfile header?");
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+ // Paper end - Attempt to recalculate regionfile header if it is corrupt
|
||||||
|
} finally {
|
||||||
|
readData.input().close();
|
||||||
|
}
|
||||||
|
@@ -216,6 +271,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
this.folder = folder;
|
this.folder = folder;
|
||||||
this.sync = sync;
|
this.sync = sync;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
@ -665,7 +744,7 @@ index e9c7e56343238cfce3f4a3c658f2983ca1ef3f0e..f3ea8b9e8f4510112ec5e41727ebc0cf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
|
@org.jetbrains.annotations.Contract("_, false -> !null") @Nullable private RegionFile getRegionFile(ChunkPos chunkPos, boolean existingOnly) throws IOException { // CraftBukkit
|
||||||
@@ -309,6 +340,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
@@ -309,6 +365,19 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
|
||||||
}
|
}
|
||||||
|
|
||||||
var4 = NbtIo.read(chunkDataInputStream);
|
var4 = NbtIo.read(chunkDataInputStream);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user