103 lines
4.4 KiB
Diff
103 lines
4.4 KiB
Diff
--- a/net/minecraft/world/chunk/storage/RegionFile.java
|
|
+++ b/net/minecraft/world/chunk/storage/RegionFile.java
|
|
@@ -33,6 +33,7 @@
|
|
private final IntBuffer field_76716_d;
|
|
private final IntBuffer field_227127_h_;
|
|
private final RegionBitmap field_227128_i_ = new RegionBitmap();
|
|
+ private final Path filePath;
|
|
|
|
public RegionFile(File p_i225784_1_, File p_i225784_2_) throws IOException {
|
|
this(p_i225784_1_.toPath(), p_i225784_2_.toPath(), RegionFileVersion.field_227159_b_);
|
|
@@ -40,6 +41,7 @@
|
|
|
|
public RegionFile(Path p_i225785_1_, Path p_i225785_2_, RegionFileVersion p_i225785_3_) throws IOException {
|
|
this.field_227125_e_ = p_i225785_3_;
|
|
+ this.filePath = p_i225785_1_;
|
|
if (!Files.isDirectory(p_i225785_2_)) {
|
|
throw new IllegalArgumentException("Expected directory, got " + p_i225785_2_.toAbsolutePath());
|
|
} else {
|
|
@@ -62,6 +64,8 @@
|
|
if (k != 0) {
|
|
int l = func_227142_b_(k);
|
|
int i1 = func_227131_a_(k);
|
|
+ if (i1 == 255)
|
|
+ i1 = forgeGetRealLength(j, l);
|
|
this.field_227128_i_.func_227120_a_(l, i1);
|
|
}
|
|
}
|
|
@@ -70,6 +74,66 @@
|
|
}
|
|
}
|
|
|
|
+ private int forgeGetRealLength(int index, int offset) throws IOException {
|
|
+ int chunkX = index & 31;
|
|
+ int chunkZ = (index >> 5) & 31;
|
|
+
|
|
+ ByteBuffer header = ByteBuffer.allocate(5);
|
|
+ this.field_76719_c.read(header, offset * 4096);
|
|
+ ((Buffer)header).flip();
|
|
+
|
|
+ if (header.remaining() < 5) {
|
|
+ field_227122_a_.error("Chunk {},{} in {} header is truncated: expected 5 but read {}", chunkX, chunkZ, this.filePath.getFileName(), header.remaining());
|
|
+ return 255;
|
|
+ }
|
|
+
|
|
+ return (header.getInt() + 4) / 4096 + 1;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * In 1.14, Forge added support for large chunks by allowing it to overflow the 255 section limit.
|
|
+ * Deferring the section size to the 'length' header in front of the chunk data.
|
|
+ * In 1.15, Mojang solved this issue by adding an external '.mcc' file for large chunks.
|
|
+ * Here, we attempt to detect and extract these large chunks from Forge's format to Vanilla's
|
|
+ */
|
|
+ public RegionFile extractLargeChunks(ChunkPos pos) throws IOException {
|
|
+ ChunkPos regionBase = new ChunkPos(pos.func_222241_h() * 32, pos.func_222242_i() * 32);
|
|
+ for (int index = 0; index < 1024; index++) {
|
|
+ int offset = this.field_76716_d.get(index);
|
|
+ if (func_227131_a_(offset) != 255) //If it's not 255, then it's not possible to be a oversized chunk. Move on.
|
|
+ continue;
|
|
+ offset = func_227142_b_(offset);
|
|
+
|
|
+ ChunkPos chunk = new ChunkPos(regionBase.field_77276_a + (index & 31), regionBase.field_77275_b + ((index >> 5) & 31));
|
|
+
|
|
+ ByteBuffer header = ByteBuffer.allocate(5);
|
|
+ this.field_76719_c.read(header, offset * 4096);
|
|
+ ((Buffer)header).flip();
|
|
+
|
|
+ if (header.remaining() < 5) {
|
|
+ field_227122_a_.error("Chunk {} in {} header is truncated: expected 5 but read {}", chunk, this.filePath.getFileName(), header.remaining());
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ int length = header.getInt();
|
|
+ byte version = header.get();
|
|
+ int sectors = (length + 4) / 4096 + 1;
|
|
+ if (sectors <= 255 || func_227130_a_(version))
|
|
+ continue; //Not over sized, or already external
|
|
+
|
|
+ ByteBuffer data = ByteBuffer.allocate(length + 4);
|
|
+ this.field_76719_c.read(data, offset * 4096);
|
|
+ ((Buffer)data).flip();
|
|
+
|
|
+ if (data.remaining() < length + 4) {
|
|
+ field_227122_a_.error("Chunk {} in {} is truncated: expected {} but read {}", chunk, this.filePath.getFileName(), length + 4, data.remaining());
|
|
+ continue;
|
|
+ }
|
|
+ func_227135_a_(chunk, data); //Save the chunk data, it'll be spit out to an external file.
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
private Path func_227145_e_(ChunkPos p_227145_1_) {
|
|
String s = "c." + p_227145_1_.field_77276_a + "." + p_227145_1_.field_77275_b + ".mcc";
|
|
return this.field_227124_d_.resolve(s);
|
|
@@ -225,6 +289,7 @@
|
|
int j = this.field_76716_d.get(i);
|
|
int k = func_227142_b_(j);
|
|
int l = func_227131_a_(j);
|
|
+ if (l == 255) l = forgeGetRealLength(i, k); //Forge: Old Forge fix, get real length, so we can free if needed
|
|
int i1 = p_227135_2_.remaining();
|
|
int j1 = func_227144_c_(i1);
|
|
int k1;
|