diff --git a/src/main/java/com/dfsek/terra/TerraWorld.java b/src/main/java/com/dfsek/terra/TerraWorld.java index 0d0297296..88efd6c34 100644 --- a/src/main/java/com/dfsek/terra/TerraWorld.java +++ b/src/main/java/com/dfsek/terra/TerraWorld.java @@ -17,12 +17,14 @@ import java.util.Map; public class TerraWorld { private static final Map map = new HashMap<>(); private static final Map loaded = new HashMap<>(); + private final TerraBiomeGrid grid; private final BiomeZone zone; private final ConfigPack config; private final WorldConfig worldConfig; private boolean safe; + private TerraWorld(World w) { safe = true; worldConfig = loaded.get(w.getName()); diff --git a/src/main/java/com/dfsek/terra/config/base/WorldConfig.java b/src/main/java/com/dfsek/terra/config/base/WorldConfig.java index 8e4d1f7e1..7499d5ac2 100644 --- a/src/main/java/com/dfsek/terra/config/base/WorldConfig.java +++ b/src/main/java/com/dfsek/terra/config/base/WorldConfig.java @@ -1,33 +1,50 @@ package com.dfsek.terra.config.base; -import com.dfsek.tectonic.config.ConfigTemplate; -import com.dfsek.terra.Debug; -import com.dfsek.terra.config.lang.LangUtil; +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.config.ValidatedConfigTemplate; +import com.dfsek.tectonic.exception.ConfigException; +import com.dfsek.tectonic.exception.ValidationException; +import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.terra.image.ImageLoader; import com.dfsek.terra.registry.ConfigRegistry; +import com.dfsek.terra.util.ConfigUtil; import org.apache.commons.io.FileUtils; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.polydev.gaea.GaeaPlugin; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.Objects; -import java.util.logging.Level; -public class WorldConfig implements ConfigTemplate { +public class WorldConfig implements ValidatedConfigTemplate { + private static final ConfigLoader LOADER = new ConfigLoader(); + + static { + ConfigUtil.registerAllLoaders(LOADER); + } + private final String worldID; private final String configID; private final GaeaPlugin main; - public boolean fromImage; - public ConfigPack config; - public ImageLoader.Channel biomeXChannel; - public ImageLoader.Channel biomeZChannel; - public ImageLoader.Channel zoneChannel; - public ImageLoader imageLoader; - private ConfigPack tConfig; + @Value("image.enable") + @Default + public boolean fromImage = false; + @Value("image.channels.biome-x") + @Default + public ImageLoader.Channel biomeXChannel = ImageLoader.Channel.RED; + @Value("image.channels.biome-z") + @Default + public ImageLoader.Channel biomeZChannel = ImageLoader.Channel.GREEN; + @Value("image.channels.zone") + @Default + public ImageLoader.Channel zoneChannel = ImageLoader.Channel.BLUE; + + @Value("image") + @Default + public ImageLoader imageLoader = null; + private ConfigPack tConfig; public WorldConfig(String w, String configID, GaeaPlugin main) { this.worldID = w; @@ -37,55 +54,24 @@ public class WorldConfig implements ConfigTemplate { } public void load() { - long start = System.nanoTime(); - LangUtil.log("world-config.load", Level.INFO, worldID); - FileConfiguration config = new YamlConfiguration(); - Debug.info("Loading config " + configID + " for world " + worldID); - try { // Load/create world config file - File configFile = new File(main.getDataFolder() + File.separator + "worlds", worldID + ".yml"); - if(!configFile.exists()) { + tConfig = ConfigRegistry.getRegistry().get(configID); + + if(tConfig == null) throw new IllegalStateException("No such config pack \"" + configID + "\""); + + File file = new File(main.getDataFolder() + File.separator + "worlds", worldID + ".yml"); + + try { + if(!file.exists()) { //noinspection ResultOfMethodCallIgnored - configFile.getParentFile().mkdirs(); - LangUtil.log("world-config.not-found", Level.WARNING, worldID); - FileUtils.copyInputStreamToFile(Objects.requireNonNull(main.getResource("world.yml")), configFile); + file.getParentFile().mkdirs(); + FileUtils.copyInputStreamToFile(Objects.requireNonNull(main.getResource("world.yml")), file); } - config.load(configFile); - - // Get values from config. - fromImage = config.getBoolean("image.enable", false); - - tConfig = ConfigRegistry.getRegistry().get(configID); - - // Load image stuff - try { - biomeXChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-x", "red")).toUpperCase()); - biomeZChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.biome-z", "green")).toUpperCase()); - if(biomeZChannel.equals(biomeXChannel)) - throw new InvalidConfigurationException("2 objects share the same image channels: biome-x and biome-z"); - zoneChannel = ImageLoader.Channel.valueOf(Objects.requireNonNull(config.getString("image.channels.zone", "blue")).toUpperCase()); - if(zoneChannel.equals(biomeXChannel) || zoneChannel.equals(biomeZChannel)) - throw new InvalidConfigurationException("2 objects share the same image channels: zone and biome-x/z"); - if(fromImage) { - try { - //noinspection ConstantConditions - imageLoader = new ImageLoader(new File(config.getString("image.file")), - ImageLoader.Align.valueOf(config.getString("image.align", "center").toUpperCase())); - LangUtil.log("world-config.using-image", Level.INFO, worldID); - } catch(IOException | NullPointerException e) { - e.printStackTrace(); - fromImage = false; - } - } - } catch(IllegalArgumentException | NullPointerException e) { - throw new InvalidConfigurationException(e.getCause()); - } - Debug.info("Loaded " + tConfig.getTemplate().getGrids().size() + " BiomeGrids from list."); - } catch(IOException | InvalidConfigurationException e) { - e.printStackTrace(); - LangUtil.log("world-config.error", Level.SEVERE, worldID); - throw new IllegalStateException("Unable to proceed due to fatal configuration error."); + LOADER.load(this, new FileInputStream(file)); + } catch(IOException e) { + throw new IllegalStateException("Unable to load configuration.", e); + } catch(ConfigException e) { + throw new IllegalStateException("Unable to proceed due to fatal configuration error.", e); } - LangUtil.log("world-config.done", Level.INFO, worldID, String.valueOf(((double) (System.nanoTime() - start)) / 1000000)); } public String getWorldID() { @@ -95,4 +81,11 @@ public class WorldConfig implements ConfigTemplate { public ConfigPack getConfig() { return tConfig; } + + @Override + public boolean validate() throws ValidationException { + if(biomeZChannel.equals(biomeXChannel) || zoneChannel.equals(biomeXChannel) || zoneChannel.equals(biomeZChannel)) + throw new ValidationException("2 objects share the same image channels: biome-x and biome-z"); + return true; + } } diff --git a/src/main/java/com/dfsek/terra/config/loaders/ImageLoaderLoader.java b/src/main/java/com/dfsek/terra/config/loaders/ImageLoaderLoader.java new file mode 100644 index 000000000..46673c8e6 --- /dev/null +++ b/src/main/java/com/dfsek/terra/config/loaders/ImageLoaderLoader.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.loading.TypeLoader; +import com.dfsek.terra.image.ImageLoader; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class ImageLoaderLoader implements TypeLoader { + @Override + public ImageLoader load(Type type, Object o, ConfigLoader configLoader) throws LoadException { + Map map = (Map) o; + File image = new File((String) map.get("file")); + try { + return new ImageLoader(image, (ImageLoader.Align) configLoader.loadType(ImageLoader.Align.class, map.get("align"))); + } catch(IOException e) { + throw new LoadException("Unable to load image", e); + } + } +} diff --git a/src/main/java/com/dfsek/terra/util/ConfigUtil.java b/src/main/java/com/dfsek/terra/util/ConfigUtil.java index 959275a3b..00465d4b8 100644 --- a/src/main/java/com/dfsek/terra/util/ConfigUtil.java +++ b/src/main/java/com/dfsek/terra/util/ConfigUtil.java @@ -4,6 +4,7 @@ import com.dfsek.tectonic.loading.TypeRegistry; import com.dfsek.terra.biome.palette.PaletteHolder; import com.dfsek.terra.biome.palette.PaletteLayer; import com.dfsek.terra.carving.CarverPalette; +import com.dfsek.terra.config.loaders.ImageLoaderLoader; import com.dfsek.terra.config.loaders.MaterialSetLoader; import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.RangeLoader; @@ -24,6 +25,7 @@ import com.dfsek.terra.generation.items.ores.Ore; import com.dfsek.terra.generation.items.ores.OreConfig; import com.dfsek.terra.generation.items.ores.OreHolder; import com.dfsek.terra.generation.items.tree.TreeLayer; +import com.dfsek.terra.image.ImageLoader; import com.dfsek.terra.procgen.GridSpawn; import com.dfsek.terra.structure.features.Feature; import org.bukkit.Bukkit; @@ -58,8 +60,11 @@ public final class ConfigUtil { .registerLoader(MaterialSet.class, new MaterialSetLoader()) .registerLoader(OreHolder.class, new OreHolderLoader()) .registerLoader(Feature.class, new StructureFeatureLoader()) + .registerLoader(ImageLoader.class, new ImageLoaderLoader()) .registerLoader(EntityType.class, (t, o, l) -> EntityType.valueOf((String) o)) .registerLoader(StructureTypeEnum.class, (t, o, l) -> StructureTypeEnum.valueOf((String) o)) + .registerLoader(ImageLoader.Channel.class, (t, o, l) -> ImageLoader.Channel.valueOf((String) o)) + .registerLoader(ImageLoader.Align.class, (t, o, l) -> ImageLoader.Align.valueOf((String) o)) .registerLoader(TerraFlora.Search.class, (t, o, l) -> TerraFlora.Search.valueOf((String) o)); } }