пробуем читать региональные файлы (r.X.Z.mca)
This commit is contained in:
@@ -4,6 +4,10 @@ version '1.0-SNAPSHOT'
|
||||
dependencies {
|
||||
/* Core */
|
||||
compile_excludeCopy project(':core')
|
||||
|
||||
/* Simple log */
|
||||
compile_excludeCopy (group: 'org.slf4j', name: 'slf4j-simple', version: slf4j_version)
|
||||
|
||||
/* Named Binary Tags */
|
||||
compile (group: 'com.flowpowered', name: 'flow-nbt', version: '1.0.0')
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
package mc.world.anvil;
|
||||
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -12,13 +8,7 @@ public class Main {
|
||||
public static void main(String[] args) throws IOException {
|
||||
final Path levelDatPath = Paths.get(args[0]);
|
||||
|
||||
FileInputStream fis = new FileInputStream(levelDatPath.toFile());
|
||||
NBTInputStream nbtInputStream = new NBTInputStream(fis);
|
||||
|
||||
Tag rootTag = nbtInputStream.readTag();
|
||||
System.out.println(rootTag.toString());
|
||||
|
||||
nbtInputStream.close();
|
||||
fis.close();
|
||||
RegionFile regionFile = new RegionFile(levelDatPath.toFile());
|
||||
regionFile.getChunk(0,0);
|
||||
}
|
||||
}
|
||||
|
||||
95
anvil-loader/src/main/java/mc/world/anvil/RegionFile.java
Normal file
95
anvil-loader/src/main/java/mc/world/anvil/RegionFile.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package mc.world.anvil;
|
||||
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.world.chunk.Chunk;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
@Slf4j
|
||||
public class RegionFile implements Closeable {
|
||||
private RandomAccessFile file;
|
||||
private List<Boolean> sectorFree; //TODO заменить на Trove TByteList
|
||||
private final int[] offsets = new int[1024];
|
||||
|
||||
public RegionFile(File file) throws IOException {
|
||||
this.file = new RandomAccessFile(file, "rw");
|
||||
|
||||
int sizeOfSectorFree = (int)this.file.length() / 4096;
|
||||
sectorFree = new ArrayList<>(sizeOfSectorFree);
|
||||
sectorFree.add(false);
|
||||
sectorFree.add(false);
|
||||
for (int i = 0; i < sizeOfSectorFree-2; i++) {
|
||||
sectorFree.add(true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < offsets.length; ++i) {
|
||||
int read = this.file.readInt();
|
||||
offsets[i] = read;
|
||||
|
||||
if (read != 0 && (read >> 8) + (read & 255) <= this.sectorFree.size()) {
|
||||
for (int j = 0; j < (read & 255); ++j) {
|
||||
this.sectorFree.set((read >> 8) + j, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.file.skipBytes(1024);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Chunk getChunk(int x, int z) {
|
||||
int offset = getOffset(x, z);
|
||||
|
||||
if (offset == 0) return null;
|
||||
|
||||
int v1 = offset >> 8; // j
|
||||
int v2 = offset & 255; // k
|
||||
|
||||
if (v1 + v2 > sectorFree.size()) return null;
|
||||
|
||||
try {
|
||||
file.seek((long) (v1 * 4096));
|
||||
int read = file.readInt();
|
||||
if (read <= 0 || read > 4096 * v2) return null;
|
||||
|
||||
boolean gzippedData = (file.readByte() == 0x01);
|
||||
|
||||
if (gzippedData) {
|
||||
log.info("GZipped");
|
||||
} else {
|
||||
log.info("Inflaten");
|
||||
|
||||
byte[] buffer = new byte[read - 1];
|
||||
file.read(buffer);
|
||||
InflaterInputStream inputStream = new InflaterInputStream(new ByteArrayInputStream(buffer));
|
||||
|
||||
NBTInputStream nbtInputStream = new NBTInputStream(inputStream, false);
|
||||
|
||||
Tag rootTag = nbtInputStream.readTag();
|
||||
log.info(rootTag.toString());
|
||||
|
||||
nbtInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Get chunk", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getOffset(int x, int z) {
|
||||
return offsets[x + z * 32];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (file != null) file.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user