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.CompoundNBT;
6 import net.minecraft.nbt.ListNBT;
7 import net.minecraft.util.math.ChunkPos;
8 import net.minecraft.util.math.MutableBoundingBox;
9 import net.minecraft.world.IWorld;
10 import net.minecraft.world.biome.Biome;
11 import net.minecraft.world.chunk.storage.RegionFileCache;
12 import net.minecraft.world.dimension.DimensionType;
13 import net.minecraft.world.gen.ChunkGenerator;
14 import net.minecraft.world.gen.feature.structure.LegacyStructureDataUtil;
15 import net.minecraft.world.gen.feature.structure.StructurePiece;
16 import net.minecraft.world.gen.feature.structure.StructureStart;
17 import net.minecraft.world.gen.feature.template.TemplateManager;
18 import net.minecraft.world.storage.DimensionSavedDataManager;
19 import net.minecraft.world.storage.SaveHandler;
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 SaveHandler saveHandler = null;
31 private File chunkSaveLocation = null;
32 private ChunkLoader chunkLoader;
34 NBTStructureLoader(int dimensionId, SaveHandler saveHandler, File worldDirectory) {
35 this.dimensionId = dimensionId;
36 this.configure(saveHandler, worldDirectory);
40 this.saveHandler = null;
41 this.chunkSaveLocation = null;
42 this.loadedChunks.clear();
44 if(this.chunkLoader == null) return;
46 this.chunkLoader.close();
47 } catch (IOException ignored) {
51 void configure(SaveHandler saveHandler, File worldDirectory) {
52 this.saveHandler = saveHandler;
53 if (worldDirectory != null) {
54 this.chunkSaveLocation = new File(DimensionType.getById(dimensionId).getDirectory(worldDirectory), "region");
55 this.chunkLoader = new ChunkLoader(this.chunkSaveLocation);
59 private LegacyStructureDataUtil getLegacyStructureDataUtil() {
60 if (this.legacyStructureDataUtil == null) {
61 File dataFolder = new File(DimensionType.OVERWORLD.getDirectory(this.saveHandler.getWorldDirectory()), "data");
62 this.legacyStructureDataUtil = LegacyStructureDataUtil.func_215130_a(DimensionType.getById(dimensionId),
63 new DimensionSavedDataManager(dataFolder, this.saveHandler.getFixer()));
65 return this.legacyStructureDataUtil;
68 private CompoundNBT loadStructureStarts(int chunkX, int chunkZ) {
70 CompoundNBT compound = this.chunkLoader.readChunk(chunkX, chunkZ);
71 if (compound == null) return null;
72 int dataVersion = compound.contains("DataVersion", 99) ? compound.getInt("DataVersion") : -1;
73 if (dataVersion < 1493) {
74 if (compound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
75 compound = getLegacyStructureDataUtil().func_212181_a(compound);
78 return compound.getCompound("Level").getCompound("Structures").getCompound("Starts");
79 } catch (IOException ignored) {
84 void loadStructures(int chunkX, int chunkZ) {
85 if (saveHandler == null) return;
87 if (!loadedChunks.add(String.format("%s,%s", chunkX, chunkZ))) return;
89 CompoundNBT structureStarts = loadStructureStarts(chunkX, chunkZ);
90 if (structureStarts == null || structureStarts.size() == 0) return;
92 Map<String, StructureStart> structureStartMap = new HashMap<>();
93 for (String key : structureStarts.keySet()) {
94 CompoundNBT compound = structureStarts.getCompound(key);
95 if (compound.contains("BB")) {
96 structureStartMap.put(key, new SimpleStructureStart(compound));
100 EventBus.publish(new StructuresLoaded(structureStartMap, dimensionId));
103 private static class SimpleStructureStart extends StructureStart {
104 SimpleStructureStart(CompoundNBT compound) {
109 new MutableBoundingBox(compound.getIntArray("BB")),
113 ListNBT children = compound.getList("Children", 10);
114 for (int index = 0; index < children.size(); ++index) {
115 CompoundNBT child = children.getCompound(index);
116 if (child.contains("BB")) this.components.add(new SimpleStructurePiece(child));
121 public void init(ChunkGenerator<?> chunkGenerator, TemplateManager templateManager, int i, int i1, Biome biome) {
126 private static class SimpleStructurePiece extends StructurePiece {
127 SimpleStructurePiece(CompoundNBT compound) {
128 super(null, compound);
132 protected void readAdditional(CompoundNBT compoundNBT) {
137 public boolean addComponentParts(IWorld iWorld, Random random, MutableBoundingBox mutableBoundingBox, ChunkPos chunkPos) {
142 private static class ChunkLoader {
143 private final RegionFileCache regionFileCache;
145 public ChunkLoader(File file) {
146 this.regionFileCache = new RegionFileCache(file) {
150 public CompoundNBT readChunk(int chunkX, int chunkZ) throws IOException {
151 return regionFileCache.readChunk(new ChunkPos(chunkX, chunkZ));
154 public void close() throws IOException {
155 regionFileCache.close();