Package net.glowstone.util

Source Code of net.glowstone.util.ServerConfig

package net.glowstone.util;

import net.glowstone.GlowServer;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.FileUtil;
import org.yaml.snakeyaml.error.YAMLException;

import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;

/**
* Utilities for handling the server configuration files.
*/
public final class ServerConfig {

    /**
     * The directory configurations are stored in.
     */
    private final File configDir;

    /**
     * The main configuration file.
     */
    private final File configFile;

    /**
     * The actual configuration data.
     */
    private final YamlConfiguration config = new YamlConfiguration();

    /**
     * Extra configuration files (help, permissions, commands).
     */
    private final Map<String, YamlConfiguration> extraConfig = new HashMap<>();

    /**
     * Parameters with which the server is ran.
     */
    private final Map<Key, Object> parameters;

    /**
     * Initialize a new ServerConfig and associated settings.
     * @param configDir The config directory, or null for default.
     * @param configFile The config file, or null for default.
     * @param parameters The command-line parameters used as overrides.
     */
    public ServerConfig(File configDir, File configFile, Map<Key, Object> parameters) {
        Validate.notNull(configDir);
        Validate.notNull(configFile);
        Validate.notNull(parameters);

        this.configDir = configDir;
        this.configFile = configFile;
        this.parameters = parameters;

        config.options().indent(4);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Modification

    /**
     * Save the configuration back to file.
     */
    public void save() {
        try {
            config.save(configFile);
        } catch (IOException e) {
            GlowServer.logger.log(Level.SEVERE, "Failed to write config: " + configFile, e);
        }
    }

    /**
     * Change a configuration value at runtime.
     * @see ServerConfig#save()
     * @param key the config key to write the value to
     * @param value value to write to config key
     */
    public void set(Key key, Object value) {
        config.set(key.path, value);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Value getters

    public String getString(Key key) {
        if (parameters.containsKey(key)) {
            return parameters.get(key).toString();
        }

        return config.getString(key.path, key.def.toString());
    }

    public int getInt(Key key) {
        if (parameters.containsKey(key)) {
            return (Integer) parameters.get(key);
        }

        return config.getInt(key.path, (Integer) key.def);
    }

    public boolean getBoolean(Key key) {
        if (parameters.containsKey(key)) {
            return (Boolean) parameters.get(key);
        }

        return config.getBoolean(key.path, (Boolean) key.def);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Fancy stuff

    public ConfigurationSection getConfigFile(Key key) {
        String filename = getString(key);
        if (extraConfig.containsKey(filename)) {
            return extraConfig.get(filename);
        }

        final YamlConfiguration conf = new YamlConfiguration();
        final File file = getFile(filename), migrateFrom = new File(key.def.toString());

        // create file if it doesn't exist
        if (!file.exists()) {
            if (migrateFrom.exists()) {
                FileUtil.copy(migrateFrom, file);
            } else {
                copyDefaults(key.def.toString(), file);
            }
        }

        // read in config
        try {
            conf.load(file);
        } catch (IOException e) {
            GlowServer.logger.log(Level.SEVERE, "Failed to read config: " + file, e);
        } catch (InvalidConfigurationException e) {
            report(file, e);
        }

        extraConfig.put(filename, conf);
        return conf;
    }

    public ConfigurationSection getWorlds() {
        return config.getConfigurationSection("worlds");
    }

    public File getDirectory() {
        return configDir;
    }

    public File getFile(String filename) {
        return new File(configDir, filename);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Load and internals

    public void load() {
        // load extra config files again next time they're needed
        extraConfig.clear();

        // create default file if needed
        final boolean exists = configFile.exists();
        if (!exists) {
            // create config directory
            if (!configDir.isDirectory() && !configDir.mkdirs()) {
                GlowServer.logger.severe("Cannot create directory: " + configDir);
                return;
            }

            copyDefaults("glowstone.yml", configFile);
        }

        // load config
        try {
            config.load(configFile);
        } catch (IOException e) {
            GlowServer.logger.log(Level.SEVERE, "Failed to read config: " + configFile, e);
        } catch (InvalidConfigurationException e) {
            report(configFile, e);
        }

        // if we just created defaults, attempt to migrate
        if (!exists && migrate()) {
            // save config, including any new defaults
            try {
                config.save(configFile);
            } catch (IOException e) {
                GlowServer.logger.log(Level.SEVERE, "Failed to write config: " + configFile, e);
                return;
            }

            GlowServer.logger.info("Migrated configuration from CraftBukkit");
        }
    }

    private void copyDefaults(String source, File dest) {
        final URL resource = getClass().getClassLoader().getResource("defaults/" + source);
        if (resource == null) {
            GlowServer.logger.warning("Could not find default " + source + " on classpath");
            return;
        }

        try (final InputStream in = resource.openStream();
             final OutputStream out = new FileOutputStream(dest)) {
            final byte[] buf = new byte[2048];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        } catch (IOException e) {
            GlowServer.logger.log(Level.WARNING, "Could not save default config: " + dest, e);
            return;
        }

        GlowServer.logger.info("Created default config: " + dest);
    }

    private void report(File file, InvalidConfigurationException e) {
        if (e.getCause() instanceof YAMLException) {
            GlowServer.logger.severe("Config file " + file + " isn't valid! " + e.getCause());
        } else if ((e.getCause() == null) || (e.getCause() instanceof ClassCastException)) {
            GlowServer.logger.severe("Config file " + file + " isn't valid!");
        } else {
            GlowServer.logger.log(Level.SEVERE, "Cannot load " + file + ": " + e.getCause().getClass(), e);
        }
    }

    private boolean migrate() {
        boolean migrateStatus = false;

        final File bukkitYml = new File("bukkit.yml");
        if (bukkitYml.exists()) {
            YamlConfiguration bukkit = new YamlConfiguration();
            try {
                bukkit.load(bukkitYml);
            } catch (InvalidConfigurationException e) {
                report(bukkitYml, e);
            } catch (IOException e) {
                GlowServer.logger.log(Level.WARNING, "Could not migrate from " + bukkitYml, e);
            }

            for (Key key : Key.values()) {
                if (key.migrate == Migrate.BUKKIT && bukkit.contains(key.migratePath)) {
                    config.set(key.path, bukkit.get(key.migratePath));
                    migrateStatus = true;
                }
            }

            config.set("aliases", bukkit.get("aliases"));
            config.set("worlds", bukkit.get("worlds"));
        }

        final File serverProps = new File("server.properties");
        if (serverProps.exists()) {
            Properties props = new Properties();
            try {
                props.load(new FileInputStream(serverProps));
            } catch (IOException e) {
                GlowServer.logger.log(Level.WARNING, "Could not migrate from " + serverProps, e);
            }

            for (Key key : Key.values()) {
                if (key.migrate == Migrate.PROPS && props.containsKey(key.migratePath)) {
                    String value = props.getProperty(key.migratePath);
                    if (key.def instanceof Integer) {
                        try {
                            config.set(key.path, Integer.parseInt(value));
                        } catch (NumberFormatException e) {
                            GlowServer.logger.log(Level.WARNING, "Could not migrate " + key.migratePath + " from " + serverProps, e);
                            continue;
                        }
                    } else if (key.def instanceof Boolean) {
                        config.set(key.path, Boolean.parseBoolean(value));
                    } else {
                        config.set(key.path, value);
                    }
                    migrateStatus = true;
                }
            }
        }

        return migrateStatus;
    }

    /**
     * An enum containing configuration keys used by the server.
     */
    public static enum Key {
        // server
        SERVER_IP("server.ip", "", Migrate.PROPS, "server-ip"),
        SERVER_PORT("server.port", 25565, Migrate.PROPS, "server-port"),
        SERVER_NAME("server.name", "Glowstone Server", Migrate.PROPS, "server-name"),
        LOG_FILE("server.log-file", "logs/log-%D.txt"),
        ONLINE_MODE("server.online-mode", true, Migrate.PROPS, "online-mode"),
        MAX_PLAYERS("server.max-players", 20, Migrate.PROPS, "max-players"),
        WHITELIST("server.whitelisted", false, Migrate.PROPS, "white-list"),
        MOTD("server.motd", "Glowstone Server", Migrate.PROPS, "motd"),
        SHUTDOWN_MESSAGE("server.shutdown-message", "Server shutting down.", Migrate.BUKKIT, "settings.shutdown-message"),
        USE_JLINE("server.use-jline", true),

        // folders
        PLUGIN_FOLDER("folders.plugins", "plugins"),
        UPDATE_FOLDER("folders.update", "update", Migrate.BUKKIT, "settings.update-folder"),
        WORLD_FOLDER("folders.worlds", "worlds", Migrate.BUKKIT, "settings.world-container"),

        // files
        PERMISSIONS_FILE("files.permissions", "permissions.yml", Migrate.BUKKIT, "settings.permissions-file"),
        COMMANDS_FILE("files.commands", "commands.yml"),
        HELP_FILE("files.help", "help.yml"),

        // advanced
        CONNECTION_THROTTLE("advanced.connection-throttle", 4000, Migrate.BUKKIT, "settings.connection-throttle"),
        //PING_PACKET_LIMIT("advanced.ping-packet-limit", 100, Migrate.BUKKIT, "settings.ping-packet-limit"),
        PLAYER_IDLE_TIMEOUT("advanced.idle-timeout", 0, Migrate.PROPS, "player-idle-timeout"),
        WARN_ON_OVERLOAD("advanced.warn-on-overload", true, Migrate.BUKKIT, "settings.warn-on-overload"),
        EXACT_LOGIN_LOCATION("advanced.exact-login-location", false, Migrate.BUKKIT, "settings.use-exact-login-location"),
        PLUGIN_PROFILING("advanced.plugin-profiling", false, Migrate.BUKKIT, "settings.plugin-profiling"),
        WARNING_STATE("advanced.deprecated-verbose", "false", Migrate.BUKKIT, "settings.deprecated-verbose"),
        COMPRESSION_THRESHOLD("advanced.compression-threshold", 256, Migrate.PROPS, "network-compression-threshold"),
        PROXY_SUPPORT("advanced.proxy-support", false),

        // query rcon etc
        QUERY_ENABLED("extras.query-enabled", false, Migrate.PROPS, "enable-query"),
        QUERY_PORT("extras.query-port", 25614, Migrate.PROPS, "query.port"),
        QUERY_PLUGINS("extras.query-plugins", true, Migrate.BUKKIT, "settings.query-plugins"),
        RCON_ENABLED("extras.rcon-enabled", false, Migrate.PROPS, "enable-rcon"),
        RCON_PASSWORD("extras.rcon-password", "glowstone", Migrate.PROPS, "rcon.password"),
        RCON_PORT("extras.rcon-port", 25575, Migrate.PROPS, "rcon.port"),
        RCON_COLORS("extras.rcon-colors", true),

        // level props
        LEVEL_NAME("world.name", "world", Migrate.PROPS, "level-name"),
        LEVEL_SEED("world.seed", "", Migrate.PROPS, "level-seed"),
        LEVEL_TYPE("world.level-type", "DEFAULT", Migrate.PROPS, "level-type"),
        SPAWN_RADIUS("world.spawn-radius", 16, Migrate.PROPS, "spawn-protection"),
        VIEW_DISTANCE("world.view-distance", 8, Migrate.PROPS, "view-distance"),
        GENERATE_STRUCTURES("world.gen-structures", true, Migrate.PROPS, "generate-structures"),
        GENERATOR_SETTINGS("world.gen-settings", "", Migrate.PROPS, "generator-settings"),
        ALLOW_NETHER("world.allow-nether", true, Migrate.PROPS, "allow-nether"),
        ALLOW_END("world.allow-end", true, Migrate.BUKKIT, "settings.allow-end"),
        PERSIST_SPAWN("world.keep-spawn-loaded", true),

        // game props
        GAMEMODE("game.gamemode", "SURVIVAL", Migrate.PROPS, "gamemode"),
        FORCE_GAMEMODE("game.gamemode-force", "false", Migrate.PROPS, "force-gamemode"),
        DIFFICULTY("game.difficulty", "NORMAL", Migrate.PROPS, "difficulty"),
        HARDCORE("game.hardcore", false, Migrate.PROPS, "hardcore"),
        PVP_ENABLED("game.pvp", true, Migrate.PROPS, "pvp"),
        MAX_BUILD_HEIGHT("game.max-build-height", 256, Migrate.PROPS, "max-build-height"),
        ANNOUNCE_ACHIEVEMENTS("game.announce-achievements", true, Migrate.PROPS, "announce-player-achievements"),

        // server.properties keys
        ALLOW_FLIGHT("game.allow-flight", false, Migrate.PROPS, "allow-flight"),
        ENABLE_COMMAND_BLOCK("game.command-blocks", false, Migrate.PROPS, "enable-command-block"),
        //OP_PERMISSION_LEVEL(null, Migrate.PROPS, "op-permission-level"),
        RESOURCE_PACK("game.resource-pack", "", Migrate.PROPS, "resource-pack"),
        RESOURCE_PACK_HASH("game.resource-pack-hash", "", Migrate.PROPS, "resource-pack-hash"),
        SNOOPER_ENABLED("server.snooper-enabled", false, Migrate.PROPS, "snooper-enabled"),

        // critters
        SPAWN_MONSTERS("creatures.enable.monsters", true, Migrate.PROPS, "spawn-monsters"),
        SPAWN_ANIMALS("creatures.enable.animals", true, Migrate.PROPS, "spawn-animals"),
        SPAWN_NPCS("creatures.enable.npcs", true, Migrate.PROPS, "spawn-npcs"),
        MONSTER_LIMIT("creatures.limit.monsters", 70, Migrate.BUKKIT, "spawn-limits.monsters"),
        ANIMAL_LIMIT("creatures.limit.animals", 15, Migrate.BUKKIT, "spawn-limits.animals"),
        WATER_ANIMAL_LIMIT("creatures.limit.water", 5, Migrate.BUKKIT, "spawn-limits.water-animals"),
        AMBIENT_LIMIT("creatures.limit.ambient", 15, Migrate.BUKKIT, "spawn-limits.ambient"),
        MONSTER_TICKS("creatures.ticks.monsters", 1, Migrate.BUKKIT, "ticks-per.monster-spawns"),
        ANIMAL_TICKS("creatures.ticks.animal", 400, Migrate.BUKKIT, "ticks-per.animal-spawns"),

        // database
        DB_DRIVER("database.driver", "org.sqlite.JDBC", Migrate.BUKKIT, "database.driver"),
        DB_URL("database.url", "jdbc:sqlite:config/database.db", Migrate.BUKKIT, "database.url"),
        DB_USERNAME("database.username", "glowstone", Migrate.BUKKIT, "database.username"),
        DB_PASSWORD("database.password", "nether", Migrate.BUKKIT, "database.password"),
        DB_ISOLATION("database.isolation", "SERIALIZABLE", Migrate.BUKKIT, "database.isolation");

        private final String path;
        private final Object def;
        private final Migrate migrate;
        private final String migratePath;

        private Key(String path, Object def) {
            this(path, def, null, null);
        }

        private Key(String path, Object def, Migrate migrate, String migratePath) {
            this.path = path;
            this.def = def;
            this.migrate = migrate;
            this.migratePath = migratePath;
        }

        @Override
        public String toString() {
            return name() + "(" + path + ", " + def + ")";
        }
    }

    private static enum Migrate {
        BUKKIT, PROPS
    }

}
TOP

Related Classes of net.glowstone.util.ServerConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.