Use Tectonic for world configs

This commit is contained in:
dfsek
2020-12-06 02:15:34 -07:00
parent c9b2c83dc4
commit 0f8ce8966a
4 changed files with 86 additions and 61 deletions

View File

@@ -17,12 +17,14 @@ import java.util.Map;
public class TerraWorld {
private static final Map<World, TerraWorld> map = new HashMap<>();
private static final Map<String, WorldConfig> 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());

View File

@@ -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;
}
}

View File

@@ -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<ImageLoader> {
@Override
public ImageLoader load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) 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);
}
}
}

View File

@@ -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));
}
}