From 22c2772c70cdfe9bf73822c83c2287c2a2170b84 Mon Sep 17 00:00:00 2001 From: "Blue (Lukas Rieger)" Date: Tue, 31 Dec 2019 12:23:41 +0100 Subject: [PATCH] Autopopulate configs with discovered blockids and biomes --- .../bluemap/core/config/BiomeConfig.java | 32 ++++++++++- .../bluemap/core/config/BlockIdConfig.java | 30 +++++++++- .../core/config/BlockPropertiesConfig.java | 29 +++++++++- .../bluemap/core/config/ConfigManager.java | 56 +++++++++++++------ .../core/resourcepack/BlockStateResource.java | 53 ++++++++++-------- .../bluemap/core/world/BlockState.java | 6 +- BlueMapCore/src/main/resources/blockIds.json | 1 + .../bluemap/sponge/SpongePlugin.java | 1 + 8 files changed, 159 insertions(+), 49 deletions(-) diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BiomeConfig.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BiomeConfig.java index 7441a36e..8e0fbcd0 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BiomeConfig.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BiomeConfig.java @@ -24,18 +24,28 @@ */ package de.bluecolored.bluemap.core.config; +import java.io.IOException; import java.util.HashMap; import java.util.Map.Entry; +import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.mca.mapping.BiomeMapper; import de.bluecolored.bluemap.core.world.Biome; import ninja.leaping.configurate.ConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; public class BiomeConfig implements BiomeMapper { + private ConfigurationLoader autopoulationConfigLoader; private HashMap biomes; public BiomeConfig(ConfigurationNode node) { + this(node, null); + } + + public BiomeConfig(ConfigurationNode node, ConfigurationLoader autopoulationConfigLoader) { + this.autopoulationConfigLoader = autopoulationConfigLoader; + biomes = new HashMap<>(); for (Entry e : node.getChildrenMap().entrySet()){ @@ -48,7 +58,27 @@ public BiomeConfig(ConfigurationNode node) { @Override public Biome get(int id) { - return biomes.getOrDefault(id, Biome.DEFAULT); + Biome biome = biomes.get(id); + + if (biome == null) { + if (autopoulationConfigLoader != null) { + biomes.put(id, Biome.DEFAULT); + + synchronized (autopoulationConfigLoader) { + try { + ConfigurationNode node = autopoulationConfigLoader.load(); + node.getNode("unknown:" + id).getNode("id").setValue(id); + autopoulationConfigLoader.save(node); + } catch (IOException ex) { + Logger.global.noFloodError("biomeconf-autopopulate-ioex", "Failed to auto-populate BiomeConfig!", ex); + } + } + } + + return Biome.DEFAULT; + } + + return biome; } } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java index bb497ebc..4fe6f648 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java @@ -24,6 +24,7 @@ */ package de.bluecolored.bluemap.core.config; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -32,12 +33,20 @@ import de.bluecolored.bluemap.core.mca.mapping.BlockIdMapper; import de.bluecolored.bluemap.core.world.BlockState; import ninja.leaping.configurate.ConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; public class BlockIdConfig implements BlockIdMapper { + private ConfigurationLoader autopoulationConfigLoader; private Map mappings; - + public BlockIdConfig(ConfigurationNode node) { + this(node, null); + } + + public BlockIdConfig(ConfigurationNode node, ConfigurationLoader autopoulationConfigLoader) { + this.autopoulationConfigLoader = autopoulationConfigLoader; + mappings = new HashMap<>(); for (Entry e : node.getChildrenMap().entrySet()){ @@ -69,10 +78,27 @@ public BlockIdConfig(ConfigurationNode node) { @Override public BlockState get(int id, int meta) { - BlockState state = mappings.get(new BlockIDMeta(id, meta)); + if (id == 0) return BlockState.AIR; + + BlockIDMeta idmeta = new BlockIDMeta(id, meta); + BlockState state = mappings.get(idmeta); if (state == null) { state = mappings.getOrDefault(new BlockIDMeta(id, 0), BlockState.AIR); //meta-fallback + + if (autopoulationConfigLoader != null) { + mappings.put(idmeta, state); + + synchronized (autopoulationConfigLoader) { + try { + ConfigurationNode node = autopoulationConfigLoader.load(); + node.getNode(id + ":" + meta).setValue(state.toString()); + autopoulationConfigLoader.save(node); + } catch (IOException ex) { + Logger.global.noFloodError("blockidconf-autopopulate-ioex", "Failed to auto-populate BlockIdConfig!", ex); + } + } + } } return state; diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java index eb3d1e01..86125a81 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java @@ -33,20 +33,28 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.mca.mapping.BlockPropertiesMapper; import de.bluecolored.bluemap.core.world.BlockProperties; import de.bluecolored.bluemap.core.world.BlockState; import ninja.leaping.configurate.ConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; public class BlockPropertiesConfig implements BlockPropertiesMapper { + private ConfigurationLoader autopoulationConfigLoader; + private Multimap> mappings; private LoadingCache mappingCache; public BlockPropertiesConfig(ConfigurationNode node) throws IOException { + this(node, null); + } + + public BlockPropertiesConfig(ConfigurationNode node, ConfigurationLoader autopoulationConfigLoader) throws IOException { + this.autopoulationConfigLoader = autopoulationConfigLoader; + mappings = HashMultimap.create(); for (Entry e : node.getChildrenMap().entrySet()){ @@ -65,8 +73,6 @@ public BlockPropertiesConfig(ConfigurationNode node) throws IOException { } } - mappings = Multimaps.unmodifiableMultimap(mappings); - mappingCache = CacheBuilder.newBuilder() .concurrencyLevel(8) .maximumSize(10000) @@ -92,6 +98,23 @@ private BlockProperties mapNoCache(BlockState bs){ } } + if (autopoulationConfigLoader != null) { + mappings.put(bs.getFullId(), new BlockStateMapping(new BlockState(bs.getFullId()), BlockProperties.DEFAULT)); + + synchronized (autopoulationConfigLoader) { + try { + ConfigurationNode node = autopoulationConfigLoader.load(); + ConfigurationNode bpNode = node.getNode(bs.getFullId()); + bpNode.getNode("culling").setValue(false); + bpNode.getNode("occluding").setValue(false); + bpNode.getNode("flammable").setValue(false); + autopoulationConfigLoader.save(node); + } catch (IOException ex) { + Logger.global.noFloodError("blockpropsconf-autopopulate-ioex", "Failed to auto-populate BlockPropertiesConfig!", ex); + } + } + } + return BlockProperties.DEFAULT; } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java index ad56c33f..98683036 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java @@ -113,38 +113,52 @@ public void loadOrCreateConfigs() throws IOException { mainConfig = new MainConfig(loadOrCreate(getMainConfigFile(), defaultMainConfig, mainConfigDefaultValues, true)); URL blockIdsConfigUrl = BlueMap.class.getResource("/blockIds.json"); - blockIdConfig = new BlockIdConfig(loadOrCreate(getBlockIdConfigFile(), blockIdsConfigUrl, blockIdsConfigUrl, false)); + blockIdConfig = new BlockIdConfig(loadOrCreate(getBlockIdConfigFile(), null, blockIdsConfigUrl, false), getLoader(makeAutogen(getBlockIdConfigFile()))); URL blockPropertiesConfigUrl = BlueMap.class.getResource("/blockProperties.json"); - blockPropertiesConfig = new BlockPropertiesConfig(loadOrCreate(getBlockPropertiesConfigFile(), blockPropertiesConfigUrl, blockPropertiesConfigUrl, false)); + blockPropertiesConfig = new BlockPropertiesConfig(loadOrCreate(getBlockPropertiesConfigFile(), null, blockPropertiesConfigUrl, false), getLoader(makeAutogen(getBlockPropertiesConfigFile()))); URL biomeConfigUrl = BlueMap.class.getResource("/biomes.json"); - biomeConfig = new BiomeConfig(loadOrCreate(getBiomeConfigFile(), biomeConfigUrl, biomeConfigUrl, false)); + biomeConfig = new BiomeConfig(loadOrCreate(getBiomeConfigFile(), null, biomeConfigUrl, false), getLoader(makeAutogen(getBiomeConfigFile()))); } private ConfigurationNode loadOrCreate(File configFile, URL defaultConfig, URL defaultValues, boolean usePlaceholders) throws IOException { + ConfigurationNode configNode; if (!configFile.exists()) { configFile.getParentFile().mkdirs(); - //load content of default config - String content; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(defaultConfig.openStream(), StandardCharsets.UTF_8))){ - content = reader.lines().collect(Collectors.joining("\n")); - } - - //replace placeholders if enabled - if (usePlaceholders) { - for (Placeholder placeholder : CONFIG_PLACEHOLDERS) { - content = placeholder.apply(content); + if (defaultConfig != null) { + //load content of default config + String content; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(defaultConfig.openStream(), StandardCharsets.UTF_8))){ + content = reader.lines().collect(Collectors.joining("\n")); } + + //replace placeholders if enabled + if (usePlaceholders) { + for (Placeholder placeholder : CONFIG_PLACEHOLDERS) { + content = placeholder.apply(content); + } + } + + //create the config file + Files.write(configFile.toPath(), content.getBytes(StandardCharsets.UTF_8)); + + //load + configNode = getLoader(configFile).load(); + } else { + //create empty config + ConfigurationLoader loader = getLoader(configFile); + configNode = loader.createEmptyNode(); + + //save to create file + loader.save(configNode); } - - //create the config file - Files.write(configFile.toPath(), content.getBytes(StandardCharsets.UTF_8)); + } else { + //load config + configNode = getLoader(configFile).load(); } - - ConfigurationNode configNode = getLoader(configFile).load(); //populate missing values with default values if (defaultValues != null) { @@ -155,6 +169,12 @@ private ConfigurationNode loadOrCreate(File configFile, URL defaultConfig, URL d return configNode; } + private File makeAutogen(File file) throws IOException { + File autogenFile = file.getCanonicalFile().toPath().getParent().resolve("generated").resolve(file.getName()).toFile(); + autogenFile.getParentFile().mkdirs(); + return autogenFile; + } + private ConfigurationLoader getLoader(URL url){ if (url.getFile().endsWith(".json")) return GsonConfigurationLoader.builder().setURL(url).build(); if (url.getFile().endsWith(".yaml") || url.getFile().endsWith(".yml")) return YAMLConfigurationLoader.builder().setURL(url).build(); diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java index 52f97c9c..ff665c8c 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java @@ -136,30 +136,38 @@ public BlockStateResource build(String blockstateFile) throws IOException { //create variants for (Entry entry : config.getNode("variants").getChildrenMap().entrySet()) { - String conditionString = entry.getKey().toString(); - ConfigurationNode transformedModelNode = entry.getValue(); - - Variant variant = blockState.new Variant(); - variant.condition = parseConditionString(conditionString); - variant.models = loadModels(transformedModelNode, blockstateFile); - - variant.updateTotalWeight(); - - blockState.variants.add(variant); + try { + String conditionString = entry.getKey().toString(); + ConfigurationNode transformedModelNode = entry.getValue(); + + Variant variant = blockState.new Variant(); + variant.condition = parseConditionString(conditionString); + variant.models = loadModels(transformedModelNode, blockstateFile); + + variant.updateTotalWeight(); + + blockState.variants.add(variant); + } catch (Exception ex) { + Logger.global.logWarning("Failed to parse a variant of " + blockstateFile + ": " + ex); + } } //create multipart for (ConfigurationNode partNode : config.getNode("multipart").getChildrenList()) { - Variant variant = blockState.new Variant(); - ConfigurationNode whenNode = partNode.getNode("when"); - if (!whenNode.isVirtual()) { - variant.condition = parseCondition(whenNode); + try { + Variant variant = blockState.new Variant(); + ConfigurationNode whenNode = partNode.getNode("when"); + if (!whenNode.isVirtual()) { + variant.condition = parseCondition(whenNode); + } + variant.models = loadModels(partNode.getNode("apply"), blockstateFile); + + variant.updateTotalWeight(); + + blockState.multipart.add(variant); + } catch (Exception ex) { + Logger.global.logWarning("Failed to parse a multipart-part of " + blockstateFile + ": " + ex); } - variant.models = loadModels(partNode.getNode("apply"), blockstateFile); - - variant.updateTotalWeight(); - - blockState.multipart.add(variant); } return blockState; @@ -233,12 +241,13 @@ private PropertyCondition parseCondition(ConfigurationNode conditionNode) { return PropertyCondition.and(andConditions.toArray(new PropertyCondition[andConditions.size()])); } - private PropertyCondition parseConditionString(String conditionString) { + private PropertyCondition parseConditionString(String conditionString) throws IllegalArgumentException { List conditions = new ArrayList<>(); - if (!conditionString.isEmpty() && !conditionString.equals("default")) { + if (!conditionString.isEmpty() && !conditionString.equals("default") && !conditionString.equals("normal")) { String[] conditionSplit = StringUtils.split(conditionString, ','); for (String element : conditionSplit) { - String[] keyval = StringUtils.split(element, "=", 2); //TODO what if it is wrong formatted? + String[] keyval = StringUtils.split(element, "=", 2); + if (keyval.length < 2) throw new IllegalArgumentException("Condition-String '" + conditionString + "' is invalid!"); conditions.add(PropertyCondition.property(keyval[0], keyval[1])); } } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java index 269c46d6..2dcde1e2 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/world/BlockState.java @@ -155,7 +155,7 @@ public final boolean checkVariantCondition(String condition){ public boolean equals(Object obj) { if (!(obj instanceof BlockState)) return false; BlockState b = (BlockState) obj; - if (!Objects.equals(getId(), b.getId())) return false; + if (!Objects.equals(getFullId(), b.getFullId())) return false; if (!Objects.equals(getProperties(), b.getProperties())) return false; return true; } @@ -163,7 +163,7 @@ public boolean equals(Object obj) { @Override public int hashCode() { if (!hashed){ - hash = Objects.hash( getId(), getProperties() ); + hash = Objects.hash( getFullId(), getProperties() ); hashed = true; } @@ -177,7 +177,7 @@ public String toString() { sj.add(e.getKey() + "=" + e.getValue()); } - return getId() + "[" + sj.toString() + "]"; + return getFullId() + "[" + sj.toString() + "]"; } public static BlockState fromString(String serializedBlockState) throws IllegalArgumentException { diff --git a/BlueMapCore/src/main/resources/blockIds.json b/BlueMapCore/src/main/resources/blockIds.json index a2556d6b..55f47c9d 100644 --- a/BlueMapCore/src/main/resources/blockIds.json +++ b/BlueMapCore/src/main/resources/blockIds.json @@ -1,4 +1,5 @@ { + "0:0": "minecraft:air", "1:0": "minecraft:stone", "1:1": "minecraft:granite", "1:2": "minecraft:polished_granite", diff --git a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java index 140a430e..af326251 100644 --- a/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java +++ b/BlueMapSponge/src/main/java/de/bluecolored/bluemap/sponge/SpongePlugin.java @@ -135,6 +135,7 @@ public synchronized void load() throws ExecutionException, IOException, Interrup URL defaultSpongeConfig = SpongePlugin.class.getResource("/bluemap-sponge.conf"); URL spongeConfigDefaults = SpongePlugin.class.getResource("/bluemap-sponge-defaults.conf"); ConfigManager configManager = new ConfigManager(getConfigPath().toFile(), defaultSpongeConfig, spongeConfigDefaults); + configManager.loadOrCreateConfigs(); config = configManager.getMainConfig(); File blockColorsConfigFile = getConfigPath().resolve("blockColors.json").toFile();