Skip to content

Commit 841a097

Browse files
authored
Added 1.17 entities storage import support (fixing #65) (#87)
1 parent a39347e commit 841a097

File tree

1 file changed

+64
-6
lines changed
  • slimeworldmanager-importer/src/main/java/com/grinderwolf/swm/importer

1 file changed

+64
-6
lines changed

slimeworldmanager-importer/src/main/java/com/grinderwolf/swm/importer/SWMImporter.java

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class SWMImporter {
4242

4343
private static final Pattern MAP_FILE_PATTERN = Pattern.compile("^(?:map_([0-9]*).dat)$");
4444
private static final int SECTOR_SIZE = 4096;
45+
private static boolean entityCustomStorage;
4546

4647
public static void main(String[] args) {
4748
if (args.length == 0) {
@@ -132,6 +133,14 @@ public static void importWorld(File worldFolder, File outputFile, boolean debug)
132133
throw new InvalidWorldException(worldFolder, "The world appears to be corrupted");
133134
}
134135

136+
File entitiesDir = new File(worldFolder, "entities");
137+
138+
if(entitiesDir.exists()) {
139+
entityCustomStorage = true;
140+
141+
if(debug) System.out.println("Entities will be imported from custom storage (1.17 world or above)");
142+
}
143+
135144
if(debug) System.out.println("Loading world...");
136145

137146
File levelFile = new File(worldFolder, "level.dat");
@@ -171,7 +180,7 @@ public static void importWorld(File worldFolder, File outputFile, boolean debug)
171180

172181
for (File file : regionDir.listFiles((dir, name) -> name.endsWith(".mca"))) {
173182
try {
174-
chunks.addAll(loadChunks(file, worldVersion, debug));
183+
chunks.addAll(loadChunks(file, entitiesDir, worldVersion, debug));
175184
} catch (IOException ex) {
176185
throw new IOException("Failed to read region file", ex);
177186
}
@@ -248,7 +257,7 @@ private static CompoundTag loadMap(File mapFile) throws IOException {
248257
return tag;
249258
}
250259

251-
private static List<SlimeChunk> loadChunks(File file, byte worldVersion, boolean debug) throws IOException {
260+
private static List<SlimeChunk> loadChunks(File file, File entitiesDir, byte worldVersion, boolean debug) throws IOException {
252261
if(debug) System.out.println("Loading chunks from region file '" + file.getName() + "':");
253262

254263
byte[] regionByteArray = Files.readAllBytes(file.toPath());
@@ -287,7 +296,12 @@ private static List<SlimeChunk> loadChunks(File file, byte worldVersion, boolean
287296

288297
CompoundTag levelCompound = (CompoundTag) globalMap.get("Level");
289298

290-
return readChunk(levelCompound, worldVersion);
299+
List<CompoundTag> entityList = null;
300+
301+
if(entityCustomStorage)
302+
entityList = readEntities(file, entitiesDir, entry.getOffset(), entry.getPaddedSize(), worldVersion, debug);
303+
304+
return readChunk(levelCompound, entityList, worldVersion);
291305
} catch (IOException ex) {
292306
throw new RuntimeException(ex);
293307
}
@@ -299,7 +313,46 @@ private static List<SlimeChunk> loadChunks(File file, byte worldVersion, boolean
299313
return loadedChunks;
300314
}
301315

302-
private static SlimeChunk readChunk(CompoundTag compound, byte worldVersion) {
316+
private static List<CompoundTag> readEntities(File regionFile, File entityDir, int offset, int paddedSize, byte worldVersion, boolean debug) throws IOException {
317+
File file = new File(entityDir.getPath(), regionFile.getName());
318+
List<CompoundTag> entities = new ListTag<CompoundTag>("Entities", TagType.TAG_COMPOUND, new ArrayList<>()).getValue();
319+
320+
if(!file.exists()) {
321+
return entities;
322+
}
323+
324+
if(debug) System.out.println("Loading chunk entities from region file '" + file.getName() + "':");
325+
326+
byte[] regionByteArray = Files.readAllBytes(file.toPath());
327+
328+
try {
329+
DataInputStream headerStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, offset, paddedSize));
330+
331+
if(headerStream.available() <= 0) {
332+
return entities;
333+
}
334+
335+
int chunkSize = headerStream.readInt() - 1;
336+
337+
int compressionScheme = headerStream.readByte();
338+
339+
DataInputStream chunkStream = new DataInputStream(new ByteArrayInputStream(regionByteArray, offset + 5, chunkSize));
340+
InputStream decompressorStream = compressionScheme == 1 ? new GZIPInputStream(chunkStream) : new InflaterInputStream(chunkStream);
341+
NBTInputStream nbtStream = new NBTInputStream(decompressorStream, NBTInputStream.NO_COMPRESSION, ByteOrder.BIG_ENDIAN);
342+
CompoundTag globalCompound = (CompoundTag) nbtStream.readTag();
343+
344+
entities = ((ListTag<CompoundTag>) globalCompound.getAsListTag("Entities")
345+
.orElse(new ListTag<>("Entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue();
346+
} catch (IOException ex) {
347+
throw new RuntimeException(ex);
348+
}
349+
350+
if(debug) System.out.println( entities.size() + " entities loaded at " + regionFile.getName());
351+
352+
return entities;
353+
}
354+
355+
private static SlimeChunk readChunk(CompoundTag compound, List<CompoundTag> entityList, byte worldVersion) {
303356
int chunkX = compound.getAsIntTag("xPos").get().getValue();
304357
int chunkZ = compound.getAsIntTag("zPos").get().getValue();
305358
Optional<String> status = compound.getStringValue("Status");
@@ -336,8 +389,13 @@ private static SlimeChunk readChunk(CompoundTag compound, byte worldVersion) {
336389

337390
List<CompoundTag> tileEntities = ((ListTag<CompoundTag>) compound.getAsListTag("TileEntities")
338391
.orElse(new ListTag<>("TileEntities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue();
339-
List<CompoundTag> entities = ((ListTag<CompoundTag>) compound.getAsListTag("Entities")
340-
.orElse(new ListTag<>("Entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue();
392+
List<CompoundTag> entities = null;
393+
if(entityCustomStorage) {
394+
entities = entityList;
395+
} else {
396+
entities = ((ListTag<CompoundTag>) compound.getAsListTag("Entities")
397+
.orElse(new ListTag<>("Entities", TagType.TAG_COMPOUND, new ArrayList<>()))).getValue();
398+
}
341399
ListTag<CompoundTag> sectionsTag = (ListTag<CompoundTag>) compound.getAsListTag("Sections").get();
342400
SlimeChunkSection[] sectionArray = new SlimeChunkSection[16];
343401

0 commit comments

Comments
 (0)