]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/interop/NBTStructureLoader.java
Switch to using DimensionId object
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / interop / NBTStructureLoader.java
1 package com.irtimaled.bbor.client.interop;
2
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;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.*;
25
26 class NBTStructureLoader {
27     private final DimensionId dimensionId;
28     private final Set<String> loadedChunks = new HashSet<>();
29
30     private LegacyStructureDataUtil legacyStructureDataUtil = null;
31     private SaveHandler saveHandler = null;
32     private File chunkSaveLocation = null;
33     private ChunkLoader chunkLoader;
34
35     NBTStructureLoader(DimensionId dimensionId, SaveHandler saveHandler, File worldDirectory) {
36         this.dimensionId = dimensionId;
37         this.configure(saveHandler, worldDirectory);
38     }
39
40     void clear() {
41         this.legacyStructureDataUtil = null;
42         this.saveHandler = null;
43         this.chunkSaveLocation = null;
44         this.loadedChunks.clear();
45
46         if (this.chunkLoader == null) return;
47         try {
48             this.chunkLoader.close();
49         } catch (IOException ignored) {
50         }
51         this.chunkLoader = null;
52     }
53
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);
59         }
60     }
61
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()));
67         }
68         return this.legacyStructureDataUtil;
69     }
70
71     private CompoundNBT loadStructureStarts(int chunkX, int chunkZ) {
72         try {
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);
79                 }
80             }
81             return compound.getCompound("Level").getCompound("Structures").getCompound("Starts");
82         } catch (IOException ignored) {
83         }
84         return null;
85     }
86
87     void loadStructures(int chunkX, int chunkZ) {
88         if (saveHandler == null) return;
89
90         if (!loadedChunks.add(String.format("%s,%s", chunkX, chunkZ))) return;
91
92         CompoundNBT structureStarts = loadStructureStarts(chunkX, chunkZ);
93         if (structureStarts == null || structureStarts.size() == 0) return;
94
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));
100             }
101         }
102
103         EventBus.publish(new StructuresLoaded(structureStartMap, dimensionId));
104     }
105
106     private static class SimpleStructureStart extends StructureStart {
107         SimpleStructureStart(CompoundNBT compound) {
108             super(null,
109                     0,
110                     0,
111                     null,
112                     new MutableBoundingBox(compound.getIntArray("BB")),
113                     0,
114                     0);
115
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));
120             }
121         }
122
123         @Override
124         public void init(ChunkGenerator<?> chunkGenerator, TemplateManager templateManager, int i, int i1, Biome biome) {
125
126         }
127     }
128
129     private static class SimpleStructurePiece extends StructurePiece {
130         SimpleStructurePiece(CompoundNBT compound) {
131             super(null, compound);
132         }
133
134         @Override
135         protected void readAdditional(CompoundNBT compoundNBT) {
136
137         }
138
139         @Override
140         public boolean addComponentParts(IWorld iWorld, Random random, MutableBoundingBox mutableBoundingBox, ChunkPos chunkPos) {
141             return false;
142         }
143     }
144
145     private static class ChunkLoader {
146         private final RegionFileCache regionFileCache;
147
148         public ChunkLoader(File file) {
149             this.regionFileCache = new RegionFileCache(file) {
150             };
151         }
152
153         public CompoundNBT readChunk(int chunkX, int chunkZ) throws IOException {
154             return regionFileCache.readChunk(new ChunkPos(chunkX, chunkZ));
155         }
156
157         public void close() throws IOException {
158             regionFileCache.close();
159         }
160     }
161 }