1 package com.irtimaled.bbor.client.interop;
3 import com.irtimaled.bbor.common.EventBus;
4 import com.irtimaled.bbor.common.events.StructuresLoaded;
5 import com.irtimaled.bbor.common.models.DimensionId;
6 import net.minecraft.nbt.CompoundNBT;
7 import net.minecraft.nbt.ListNBT;
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.biome.Biome;
12 import net.minecraft.world.chunk.storage.RegionFileCache;
13 import net.minecraft.world.dimension.DimensionType;
14 import net.minecraft.world.gen.ChunkGenerator;
15 import net.minecraft.world.gen.feature.structure.LegacyStructureDataUtil;
16 import net.minecraft.world.gen.feature.structure.StructurePiece;
17 import net.minecraft.world.gen.feature.structure.StructureStart;
18 import net.minecraft.world.gen.feature.template.TemplateManager;
19 import net.minecraft.world.storage.DimensionSavedDataManager;
20 import net.minecraft.world.storage.SaveHandler;
23 import java.io.IOException;
26 class NBTStructureLoader {
27 private final DimensionId dimensionId;
28 private final Set<String> loadedChunks = new HashSet<>();
30 private LegacyStructureDataUtil legacyStructureDataUtil = null;
31 private SaveHandler saveHandler = null;
32 private File chunkSaveLocation = null;
33 private ChunkLoader chunkLoader;
35 NBTStructureLoader(DimensionId dimensionId, SaveHandler saveHandler, File worldDirectory) {
36 this.dimensionId = dimensionId;
37 this.configure(saveHandler, worldDirectory);
41 this.legacyStructureDataUtil = null;
42 this.saveHandler = null;
43 this.chunkSaveLocation = null;
44 this.loadedChunks.clear();
46 if (this.chunkLoader == null) return;
48 this.chunkLoader.close();
49 } catch (IOException ignored) {
51 this.chunkLoader = null;
54 void configure(SaveHandler saveHandler, File worldDirectory) {
55 this.saveHandler = saveHandler;
56 if (worldDirectory != null) {
57 this.chunkSaveLocation = new File(dimensionId.getDimensionType().getDirectory(worldDirectory), "region");
58 this.chunkLoader = new ChunkLoader(this.chunkSaveLocation);
62 private LegacyStructureDataUtil getLegacyStructureDataUtil() {
63 if (this.legacyStructureDataUtil == null) {
64 File dataFolder = new File(DimensionType.OVERWORLD.getDirectory(this.saveHandler.getWorldDirectory()), "data");
65 this.legacyStructureDataUtil = LegacyStructureDataUtil.func_215130_a(dimensionId.getDimensionType(),
66 new DimensionSavedDataManager(dataFolder, this.saveHandler.getFixer()));
68 return this.legacyStructureDataUtil;
71 private CompoundNBT loadStructureStarts(int chunkX, int chunkZ) {
73 CompoundNBT compound = this.chunkLoader.readChunk(chunkX, chunkZ);
74 if (compound == null) return null;
75 int dataVersion = compound.contains("DataVersion", 99) ? compound.getInt("DataVersion") : -1;
76 if (dataVersion < 1493) {
77 if (compound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
78 compound = getLegacyStructureDataUtil().func_212181_a(compound);
81 return compound.getCompound("Level").getCompound("Structures").getCompound("Starts");
82 } catch (IOException ignored) {
87 void loadStructures(int chunkX, int chunkZ) {
88 if (saveHandler == null) return;
90 if (!loadedChunks.add(String.format("%s,%s", chunkX, chunkZ))) return;
92 CompoundNBT structureStarts = loadStructureStarts(chunkX, chunkZ);
93 if (structureStarts == null || structureStarts.size() == 0) return;
95 Map<String, StructureStart> structureStartMap = new HashMap<>();
96 for (String key : structureStarts.keySet()) {
97 CompoundNBT compound = structureStarts.getCompound(key);
98 if (compound.contains("BB")) {
99 structureStartMap.put(key, new SimpleStructureStart(compound));
103 EventBus.publish(new StructuresLoaded(structureStartMap, dimensionId));
106 private static class SimpleStructureStart extends StructureStart {
107 SimpleStructureStart(CompoundNBT compound) {
112 new MutableBoundingBox(compound.getIntArray("BB")),
116 ListNBT children = compound.getList("Children", 10);
117 for (int index = 0; index < children.size(); ++index) {
118 CompoundNBT child = children.getCompound(index);
119 if (child.contains("BB")) this.components.add(new SimpleStructurePiece(child));
124 public void init(ChunkGenerator<?> chunkGenerator, TemplateManager templateManager, int i, int i1, Biome biome) {
129 private static class SimpleStructurePiece extends StructurePiece {
130 SimpleStructurePiece(CompoundNBT compound) {
131 super(null, compound);
135 protected void readAdditional(CompoundNBT compoundNBT) {
140 public boolean addComponentParts(IWorld iWorld, Random random, MutableBoundingBox mutableBoundingBox, ChunkPos chunkPos) {
145 private static class ChunkLoader {
146 private final RegionFileCache regionFileCache;
148 public ChunkLoader(File file) {
149 this.regionFileCache = new RegionFileCache(file) {
153 public CompoundNBT readChunk(int chunkX, int chunkZ) throws IOException {
154 return regionFileCache.readChunk(new ChunkPos(chunkX, chunkZ));
157 public void close() throws IOException {
158 regionFileCache.close();