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