]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/NBTFileParser.java
Re-add NBT loading
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / NBTFileParser.java
1 package com.irtimaled.bbor.client;
2
3 import com.irtimaled.bbor.Logger;
4 import com.irtimaled.bbor.common.BoundingBoxCache;
5 import com.irtimaled.bbor.common.BoundingBoxType;
6 import com.irtimaled.bbor.common.Dimensions;
7 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
8 import com.irtimaled.bbor.common.models.BoundingBoxStructure;
9 import com.irtimaled.bbor.common.models.BoundingBoxVillage;
10 import com.irtimaled.bbor.common.models.Coords;
11 import com.irtimaled.bbor.config.ConfigManager;
12 import net.minecraft.nbt.CompressedStreamTools;
13 import net.minecraft.nbt.NBTTagCompound;
14 import net.minecraft.nbt.NBTTagList;
15
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.IOException;
19 import java.util.HashSet;
20 import java.util.Set;
21
22 class NBTFileParser {
23     static void loadLocalDatFiles(String host, int port, SetWorldData setWorldData, GetCache createCache) {
24         Logger.info("Looking for local structures (host:port=%s:%d)", host, port);
25         String path = String.format("BBOutlineReloaded%s%s%s%d", File.separator, host, File.separator, port);
26         File localStructuresFolder = new File(ConfigManager.configDir, path);
27         Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
28         if (!localStructuresFolder.exists()) {
29             path = String.format("BBOutlineReloaded%s%s", File.separator, host);
30             localStructuresFolder = new File(ConfigManager.configDir, path);
31             Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
32         }
33         if (!localStructuresFolder.exists()) {
34             path = String.format("BBOutlineReloaded%s%s,%d", File.separator, host, port);
35             localStructuresFolder = new File(ConfigManager.configDir, path);
36             Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
37         }
38         if (!localStructuresFolder.exists()) {
39             Logger.info("No local structures folders found");
40             return;
41         }
42         loadWorldData(localStructuresFolder, setWorldData);
43         populateBoundingBoxCache(localStructuresFolder, createCache);
44     }
45
46     private static void loadWorldData(File localStructuresFolder, SetWorldData setWorldData) {
47         File file = new File(localStructuresFolder, "level.dat");
48         NBTTagCompound nbt = loadNbtFile(file);
49         if (nbt == null)
50             return;
51
52         NBTTagCompound data = nbt.getCompoundTag("Data");
53         long seed = data.getLong("RandomSeed");
54         int spawnX = data.getInteger("SpawnX");
55         int spawnZ = data.getInteger("SpawnZ");
56         Logger.info("Loaded level.dat (seed: %d, spawn: %d,%d)", seed, spawnX, spawnZ);
57         setWorldData.accept(seed, spawnX, spawnZ);
58     }
59
60     private static void populateBoundingBoxCache(File localStructuresFolder, GetCache createCache) {
61         loadOverworldStructures(localStructuresFolder, createCache.apply(Dimensions.OVERWORLD));
62         loadNetherStructures(localStructuresFolder, createCache.apply(Dimensions.NETHER));
63         loadEndStructures(localStructuresFolder, createCache.apply(Dimensions.THE_END));
64     }
65
66     private static void loadOverworldStructures(File localStructuresFolder, BoundingBoxCache cache) {
67         loadStructure(localStructuresFolder, cache, "Temple.dat", "TeDP", BoundingBoxType.DesertTemple);
68         loadStructure(localStructuresFolder, cache, "Temple.dat", "TeJP", BoundingBoxType.JungleTemple);
69         loadStructure(localStructuresFolder, cache, "Temple.dat", "TeSH", BoundingBoxType.WitchHut);
70         loadStructure(localStructuresFolder, cache, "Monument.dat", "*", BoundingBoxType.OceanMonument);
71         loadStructure(localStructuresFolder, cache, "Stronghold.dat", "*", BoundingBoxType.Stronghold);
72         loadStructure(localStructuresFolder, cache, "Mansion.dat", "*", BoundingBoxType.Mansion);
73         loadStructure(localStructuresFolder, cache, "Mineshaft.dat", "*", BoundingBoxType.MineShaft);
74         loadVillages(localStructuresFolder, cache, "Villages.dat");
75     }
76
77     private static void loadNetherStructures(File localStructuresFolder, BoundingBoxCache cache) {
78         loadStructure(localStructuresFolder, cache, "Fortress.dat", "*", BoundingBoxType.NetherFortress);
79         loadVillages(localStructuresFolder, cache, "villages_nether.dat");
80     }
81
82     private static void loadEndStructures(File localStructuresFolder, BoundingBoxCache cache) {
83         loadVillages(localStructuresFolder, cache, "Villages_end.dat");
84         loadStructure(localStructuresFolder, cache, "EndCity.dat", "*", BoundingBoxType.EndCity);
85     }
86
87     private static void loadStructure(File localStructuresFolder, BoundingBoxCache cache, String fileName, String id, BoundingBoxType type) {
88         File file = new File(localStructuresFolder, fileName);
89         NBTTagCompound nbt = loadNbtFile(file);
90         if (nbt == null)
91             return;
92
93         NBTTagCompound features = nbt.getCompoundTag("data")
94                 .getCompoundTag("Features");
95         int loadedStructureCount = 0;
96         for (Object key : features.getKeySet()) {
97             NBTTagCompound feature = features.getCompoundTag((String) key);
98             AbstractBoundingBox structure = buildStructure(feature, type);
99             Set<AbstractBoundingBox> boundingBoxes = new HashSet<>();
100             NBTTagCompound[] children = getChildCompoundTags(feature, "Children");
101             for (NBTTagCompound child : children) {
102                 if (id.equals(child.getString("id")) || id.equals("*"))
103                     boundingBoxes.add(buildStructure(child, type));
104             }
105             if (boundingBoxes.size() > 0)
106                 ++loadedStructureCount;
107             cache.addBoundingBoxes(structure, boundingBoxes);
108         }
109
110         Logger.info("Loaded %s (%d structures with type %s)", fileName, loadedStructureCount, id);
111     }
112
113     private static BoundingBoxStructure buildStructure(NBTTagCompound feature, BoundingBoxType type) {
114         int[] bb = feature.getIntArray("BB");
115         Coords minCoords = new Coords(bb[0], bb[1], bb[2]);
116         Coords maxCoords = new Coords(bb[3], bb[4], bb[5]);
117         return BoundingBoxStructure.from(minCoords, maxCoords, type);
118     }
119
120     private static void loadVillages(File localStructuresFolder, BoundingBoxCache cache, String fileName) {
121         File file = new File(localStructuresFolder, fileName);
122         NBTTagCompound nbt = loadNbtFile(file);
123         if (nbt == null)
124             return;
125
126         NBTTagCompound[] villages = getChildCompoundTags(nbt.getCompoundTag("data"), "Villages");
127         for (NBTTagCompound village : villages) {
128             Coords center = new Coords(village.getInteger("CX"), village.getInteger("CY"), village.getInteger("CZ"));
129             int radius = village.getInteger("Radius");
130             int population = village.getInteger("PopSize");
131             Set<Coords> doors = getDoors(village);
132             AbstractBoundingBox boundingBox = BoundingBoxVillage.from(center, radius, village.hashCode(), population, doors);
133             cache.addBoundingBox(boundingBox);
134         }
135
136         Logger.info("Loaded %s (%d villages)", fileName, villages.length);
137     }
138
139     private static Set<Coords> getDoors(NBTTagCompound village) {
140         Set<Coords> doors = new HashSet<>();
141         for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
142             doors.add(new Coords(door.getInteger("X"), door.getInteger("Y"), door.getInteger("Z")));
143         }
144         return doors;
145     }
146
147     private static NBTTagCompound loadNbtFile(File file) {
148         if (!file.exists())
149             return null;
150         try {
151             return CompressedStreamTools.readCompressed(new FileInputStream(file));
152         } catch (IOException e) {
153             return null;
154         }
155     }
156
157     private static NBTTagCompound[] getChildCompoundTags(NBTTagCompound parent, String key) {
158         NBTTagList tagList = parent.getTagList(key, 10);
159         NBTTagCompound[] result = new NBTTagCompound[tagList.tagCount()];
160         for (int index = 0; index < tagList.tagCount(); index++) {
161             result[index] = tagList.getCompoundTagAt(index);
162         }
163         return result;
164     }
165 }