1 package com.irtimaled.bbor.client.interop;
3 import com.irtimaled.bbor.common.EventBus;
4 import com.irtimaled.bbor.common.events.StructuresLoaded;
5 import net.minecraft.nbt.CompressedStreamTools;
6 import net.minecraft.nbt.NBTTagCompound;
7 import net.minecraft.nbt.NBTTagList;
8 import net.minecraft.util.math.ChunkPos;
9 import net.minecraft.util.math.MutableBoundingBox;
10 import net.minecraft.world.IWorld;
11 import net.minecraft.world.chunk.storage.RegionFileCache;
12 import net.minecraft.world.dimension.DimensionType;
13 import net.minecraft.world.gen.feature.structure.LegacyStructureDataUtil;
14 import net.minecraft.world.gen.feature.structure.StructurePiece;
15 import net.minecraft.world.gen.feature.structure.StructureStart;
16 import net.minecraft.world.gen.feature.template.TemplateManager;
17 import net.minecraft.world.storage.ISaveHandler;
18 import net.minecraft.world.storage.WorldSavedDataStorage;
20 import java.io.DataInputStream;
22 import java.io.IOException;
25 class NBTStructureLoader {
26 private final int dimensionId;
27 private final Set<String> loadedChunks = new HashSet<>();
29 private LegacyStructureDataUtil legacyStructureDataUtil = null;
30 private ISaveHandler saveHandler = null;
31 private File chunkSaveLocation = null;
33 NBTStructureLoader(int dimensionId, ISaveHandler saveHandler, File worldDirectory) {
34 this.dimensionId = dimensionId;
35 this.configure(saveHandler, worldDirectory);
39 this.saveHandler = null;
40 this.chunkSaveLocation = null;
41 this.loadedChunks.clear();
44 void configure(ISaveHandler saveHandler, File worldDirectory) {
45 this.saveHandler = saveHandler;
46 if(worldDirectory != null) {
47 this.chunkSaveLocation = DimensionType.getById(dimensionId).getDirectory(worldDirectory);
51 private LegacyStructureDataUtil getLegacyStructureDataUtil() {
52 if (this.legacyStructureDataUtil == null) {
53 this.legacyStructureDataUtil = LegacyStructureDataUtil.func_212183_a(DimensionType.getById(dimensionId), new WorldSavedDataStorage(saveHandler));
55 return this.legacyStructureDataUtil;
58 private NBTTagCompound loadStructureStarts(int chunkX, int chunkZ) {
60 DataInputStream stream = RegionFileCache.getChunkInputStream(chunkSaveLocation, chunkX, chunkZ);
62 NBTTagCompound compound = CompressedStreamTools.read(stream);
64 int dataVersion = compound.contains("DataVersion", 99) ? compound.getInt("DataVersion") : -1;
65 if (dataVersion < 1493) {
66 if (compound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
67 compound = getLegacyStructureDataUtil().func_212181_a(compound);
70 return compound.getCompound("Level").getCompound("Structures").getCompound("Starts");
72 } catch (IOException ignored) {
77 void loadStructures(int chunkX, int chunkZ) {
78 if (saveHandler == null) return;
80 if (!loadedChunks.add(String.format("%s,%s", chunkX, chunkZ))) return;
82 NBTTagCompound structureStarts = loadStructureStarts(chunkX, chunkZ);
83 if (structureStarts == null || structureStarts.size() == 0) return;
85 Map<String, StructureStart> structureStartMap = new HashMap<>();
86 for (String key : structureStarts.keySet()) {
87 NBTTagCompound compound = structureStarts.getCompound(key);
88 if (compound.contains("BB")) {
89 structureStartMap.put(key, new SimpleStructureStart(compound));
93 EventBus.publish(new StructuresLoaded(structureStartMap, dimensionId));
96 private static class SimpleStructureStart extends StructureStart {
97 SimpleStructureStart(NBTTagCompound compound) {
98 this.boundingBox = new MutableBoundingBox(compound.getIntArray("BB"));
100 NBTTagList children = compound.getList("Children", 10);
101 for (int index = 0; index < children.size(); ++index) {
102 NBTTagCompound child = children.getCompound(index);
103 if (child.contains("BB")) this.components.add(new SimpleStructurePiece(child));
108 private static class SimpleStructurePiece extends StructurePiece {
109 SimpleStructurePiece(NBTTagCompound compound) {
110 this.boundingBox = new MutableBoundingBox(compound.getIntArray("BB"));
114 protected void writeAdditional(NBTTagCompound nbtTagCompound) {
118 protected void readAdditional(NBTTagCompound nbtTagCompound, TemplateManager templateManager) {
122 public boolean addComponentParts(IWorld iWorld, Random random, MutableBoundingBox mutableBoundingBox, ChunkPos chunkPos) {