fix fix fix

This commit is contained in:
iceBear67 committed 2025-10-01 16:59:17 +08:00
1 parent 394a4d986d
commit 48bf045825
16 files changed
+172 -59

No files matched your search

@@ -62,12 +62,18 @@ public class BundleReader {
entryData.writeBytes(buffer, 0, read);
}
try (var reassembler = new RegionParser(entryData, allocator)) {
var result = reassembler.writeReassembled(RegionFile.CompressType.GZIP);
var result = reassembler.writeReassembled(RegionFile.CompressType.ZLIB);
try (var fc = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
result.readBytes(fc, 0, result.readableBytes());
} finally {
result.release();
}
} catch (Exception e) {
try (var ch = FileChannel.open(Path.of("dump.mca"), StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
entryData.readerIndex(0);
entryData.readBytes(ch, 0, entryData.readableBytes());
}
throw new IOException("Error while reassembling " + entry.name(), e);
}
} else {
writePlain(path, entry, in);
@@ -75,7 +75,7 @@ public class BundleWriter implements Closeable {
var futures = new ArrayList<CompletableFuture<Path>>();
for (int i = 0; i < parted.size(); i++) {
var pathList = parted.get(i);
var output = parentOfBundle.resolve("Worker_" + System.currentTimeMillis() + "_" + i + ".jbp.zst");
var output = parentOfBundle.resolve("Worker_" + System.currentTimeMillis() + "_" + i + ".swb.zst");
var future = CompletableFuture.supplyAsync(() -> createBundleWorker(pathList, output, config), executor);
futures.add(future);
}
@@ -142,7 +142,7 @@ public class BundleWriter implements Closeable {
}
public void write(Path path, boolean suggestGunzip) throws IOException {
if (suggestGunzip) {
if (suggestGunzip && allowReassemble) {
//todo size limit
writeReassembleInMem(path);
return;
@@ -158,22 +158,26 @@ public class BundleWriter implements Closeable {
return;
}
if(verbose) System.out.println("Reassembling " + path);
var uncompressed = allocator.buffer();
var finalResult = allocator.buffer();
var rPath = relativeRoot.toAbsolutePath().relativize(path.toAbsolutePath());
try (var out = new EntryOutputStream(new ByteBufOutputStream(uncompressed));
try (var out = new EntryOutputStream(new ByteBufOutputStream(finalResult));
var rf = new RegionParser(path, allocator)) {
// uncompressed result
var result = rf.writeReassembled(RegionFile.CompressType.NONE);
var length = result.readableBytes();
out.writeEntryHeader(rPath.toString(), BundleEntry.ATTR_REASSEMBLE, length, System.currentTimeMillis());
result.readBytes(out, length);
result.release();
uncompressed.readBytes(outputStream, uncompressed.readableBytes());
// all done
} catch (IOException e) {
System.err.println("Failed to parse region " + path + ": " + e);
finalResult.release();
writePlain(path);
} finally {
uncompressed.release();
return;
}
finalResult.readBytes(outputStream, finalResult.readableBytes());
finalResult.release();
}
private void writePlain(Path path) throws IOException {
@@ -186,6 +190,9 @@ public class BundleWriter implements Closeable {
while ((read = fs.read(buffer)) > 0) {
outputStream.write(buffer, 0, read);
}
}catch(IOException e){
System.err.println("Error while bundling "+path);
throw e;
}
}
@@ -26,7 +26,7 @@ public class Main {
@SneakyThrows
public static void main(String[] args) {
var opts = ArgOpts.builder()
.args(args).description("Tools for .jbp.zst format bundle").programName("jpack").build();
.args(args).description("Tools for .swb.zst format bundle").programName("jpack").build();
var in = opts.string("in", "Input. Can be directory or jpack bundle", null);
var out = opts.string("out", "Output. Can be jpack bundle or directory", null);
var help = opts.bool("help", false);
@@ -81,9 +81,9 @@ public class Main {
return;
}
if (in.endsWith(".jbp.zst")) {
if (in.endsWith(".swb.zst")) {
BundleReader.builder().build().extract(inPath, outPath);
} else if (out.endsWith(".jbp.zst")) {
} else if (out.endsWith(".swb.zst")) {
UnaryOperator<BundleWriter.BundleWriterBuilder> cfg = it -> it
.allowGunzip(allowGunzip)
.relativeRoot(inPath)
@@ -89,11 +89,14 @@ public class RegionFile implements Closeable {
}
public ByteBuf writeOutput() {
var sect = allocator.buffer(8192);
var sect = allocator.buffer(4096);
sect.setZero(0, 4096);
sect.writerIndex(4096);
var compositeByteBuf = allocator.compositeBuffer(2 + regionData.size());
var beginSector = 2;
compositeByteBuf.addComponent(true, sect);
timestamp.retain();
timestamp.readerIndex(0);
compositeByteBuf.addComponent(true, timestamp);
for (var entry : regionData.short2ObjectEntrySet()) {
var chunkKey = entry.getShortKey();
@@ -102,12 +105,21 @@ public class RegionFile implements Closeable {
var chunk = entry.getValue();
var size = chunk.readableBytes();
var sizeSectors = Math.ceilDiv(size, 4096);
var zeros = 4096 - (size % 4096);
for (int i = 0; i < zeros; i++) {
chunk.writeByte(0);
}
if (sizeSectors > 255) {
throw new IllegalArgumentException("MCC not supported.");
}
var indexEntry = Integer.reverseBytes(beginSector) << 1 | (sizeSectors & 0xFF);
// sect = int[1024]
sect.setInt((x + 32 * z) * 4, indexEntry);
if(sizeSectors < 0) {
throw new IllegalArgumentException("Invalid sizeSectors: "+sizeSectors);
}
var begin = (x + 32 * z) * 4;
sect.setByte(begin, (beginSector >>> 16) & 0xFF);
sect.setByte(begin+1, (beginSector >>> 8) & 0xFF);
sect.setByte(begin+2, beginSector & 0xFF);
sect.setByte(begin+3, sizeSectors & 0xFF);
chunk.retain(); // retain a local reference
compositeByteBuf.addComponent(true, chunk);
beginSector += sizeSectors;
@@ -22,12 +22,12 @@ public class RegionParser implements Closeable {
this.allocator = allocator;
var size = (int) Files.size(file);
if (size < 8192) throw new IOException("The region file " + file + " has been truncated");
if(size > 8388608 * 2) throw new IOException("The region file " + file + " is too large"); //todo bug
if (size > 8388608 * 2) throw new IOException("The region file " + file + " is too large"); //todo bug
source = allocator.buffer(size);
try (var fc = FileChannel.open(file, StandardOpenOption.READ)) {
var toRead = size;
while(toRead > 0){
while (toRead > 0) {
toRead -= source.writeBytes(fc, 0L, (int) size);
}
}
@@ -66,6 +66,7 @@ public class RegionParser implements Closeable {
if (compressType < 0) {
// mcc todo
}
if (sectorLen == 0) return compressType;
buf.writeBytes(source, sectorLen - 1);
return compressType;
}
@@ -7,16 +7,32 @@ import io.netty.buffer.Unpooled;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class TestRegionReassembler {
@Test
public void testReassembler() throws IOException {
testMethod("region/r.9.-5.mca");
testMethod("region/r.-1.-1.mca");
}
private static void testMethod(String key) throws IOException {
byte[] bytes;
try(var in = TestRegionReassembler.class.getClassLoader().getResourceAsStream("region/r.9.-5.mca")){
try(var in = TestRegionReassembler.class.getClassLoader().getResourceAsStream(key)){
bytes = in.readAllBytes();
}
try(var reasm = new RegionParser(Unpooled.wrappedBuffer(bytes), ByteBufAllocator.DEFAULT)) {
var result = reasm.writeReassembled(RegionFile.CompressType.NONE);
try(var foc = FileChannel.open(Path.of("./test.mca"), StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
result.readBytes(foc, 0, result.readableBytes());
}
result.readerIndex(0);
try(var reader = new RegionFile(ByteBufAllocator.DEFAULT)) {
result = reasm.writeReassembled(RegionFile.CompressType.ZLIB);
}
}
}
}
Binary file not shown.