mirror of
https://github.com/taoneill/war.git
synced 2024-11-10 20:50:04 +01:00
Added a sort of config framework
Cascading downwards
This commit is contained in:
parent
1d54a2a6c0
commit
2280e5d857
@ -108,7 +108,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>spongeapi</artifactId>
|
||||
<artifactId>SpongeAPI</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.tommytony.war;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.tommytony.war.zone.ZoneConfig;
|
||||
import org.spongepowered.api.entity.Player;
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -17,6 +18,7 @@ import java.util.UUID;
|
||||
*/
|
||||
public class WarConfig implements Closeable {
|
||||
private final WarPlugin plugin;
|
||||
private final ZoneConfig zoneDefaults;
|
||||
/**
|
||||
* Database configuration descriptor.
|
||||
*/
|
||||
@ -39,6 +41,7 @@ public class WarConfig implements Closeable {
|
||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS zones (name TEXT)");
|
||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS zonemakers (uuid TEXT)");
|
||||
}
|
||||
zoneDefaults = new ZoneConfig(conn, "zone_settings");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,12 +58,21 @@ public class WarConfig implements Closeable {
|
||||
if (result.next()) {
|
||||
return result.getInt(1);
|
||||
} else {
|
||||
return (int) setting.defaultValue;
|
||||
return (Integer) setting.defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to zone default settings.
|
||||
*
|
||||
* @return controller of server zone defaults.
|
||||
*/
|
||||
public ZoneConfig getZoneDefaults() {
|
||||
return zoneDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the enabled war zones on the server.
|
||||
*
|
||||
|
@ -4,6 +4,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.api.Game;
|
||||
import org.spongepowered.api.event.SpongeEventHandler;
|
||||
import org.spongepowered.api.event.state.PreInitializationEvent;
|
||||
import org.spongepowered.api.event.state.ServerStartedEvent;
|
||||
import org.spongepowered.api.event.state.ServerStartingEvent;
|
||||
import org.spongepowered.api.plugin.Plugin;
|
||||
|
||||
@ -37,6 +38,11 @@ public class WarPlugin {
|
||||
config = new WarConfig(this, new File(dataDir, "war.sl3"));
|
||||
}
|
||||
|
||||
@SpongeEventHandler
|
||||
public void onStart(ServerStartedEvent event) {
|
||||
// register commands
|
||||
}
|
||||
|
||||
public Game getGame() {
|
||||
return game;
|
||||
}
|
||||
@ -45,6 +51,10 @@ public class WarPlugin {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public File getDataDir() {
|
||||
return dataDir;
|
||||
}
|
||||
|
||||
public WarConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
54
sponge/src/main/java/com/tommytony/war/zone/Warzone.java
Normal file
54
sponge/src/main/java/com/tommytony/war/zone/Warzone.java
Normal file
@ -0,0 +1,54 @@
|
||||
package com.tommytony.war.zone;
|
||||
|
||||
import com.tommytony.war.WarPlugin;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Representation of a war zone area, blocks, and settings.
|
||||
* Each zone is to only have one instance of Warzone.class at any given time while the server is running.
|
||||
*/
|
||||
public class Warzone {
|
||||
private static Pattern zoneName = Pattern.compile("[./%]+");
|
||||
private final WarPlugin plugin;
|
||||
private final String name;
|
||||
private final ZoneStorage db;
|
||||
private final ZoneConfig config;
|
||||
|
||||
/**
|
||||
* Load or create a war zone from the war settings store.
|
||||
*
|
||||
* @param plugin Instance of the plugin War.
|
||||
* @param name Name of the zone. Used to locate the zone data file.
|
||||
*/
|
||||
public Warzone(WarPlugin plugin, String name) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
try {
|
||||
this.db = new ZoneStorage(this, plugin);
|
||||
this.config = new ZoneConfig(db.getConnection(), "settings", plugin.getConfig().getZoneDefaults());
|
||||
} catch (SQLException ex) {
|
||||
plugin.getLogger().error("Failed to load zone database and settings", ex);
|
||||
throw new RuntimeException("Can't create/load database for warzone " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified name is valid for a zone.
|
||||
* Specifically, characters that could be part of a file path or web URL.
|
||||
* '.', '/', and '%' are invalid.
|
||||
*
|
||||
* @param name Potential zone name to check.
|
||||
* @return true if the name can be used.
|
||||
*/
|
||||
public static boolean zoneNameValid(String name) {
|
||||
Matcher m = zoneName.matcher(name);
|
||||
return m.find();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
75
sponge/src/main/java/com/tommytony/war/zone/ZoneConfig.java
Normal file
75
sponge/src/main/java/com/tommytony/war/zone/ZoneConfig.java
Normal file
@ -0,0 +1,75 @@
|
||||
package com.tommytony.war.zone;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* The zone configuration settings database.
|
||||
*/
|
||||
public class ZoneConfig {
|
||||
/**
|
||||
* Database configuration descriptor.
|
||||
*/
|
||||
private final Connection conn;
|
||||
/**
|
||||
* Table of values to manage. May be a table in a zone database or the main war database.
|
||||
*/
|
||||
private final String table;
|
||||
/**
|
||||
* Root zone config, for fallback. Null if this is the war main settings.
|
||||
*/
|
||||
private final ZoneConfig parent;
|
||||
|
||||
/**
|
||||
* Manages a zone configuration section.
|
||||
*
|
||||
* @param database Active database to use.
|
||||
* @param table Table name to use in database. Created if it does not exist. Needs to be trusted input.
|
||||
* @param parent Parent zone config, for fallback. Could be zone config for a team or war global for zones.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public ZoneConfig(Connection database, String table, ZoneConfig parent) throws SQLException {
|
||||
this.conn = database;
|
||||
this.table = table;
|
||||
this.parent = parent;
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.executeUpdate(String.format("CREATE TABLE IF NOT EXISTS %s (option TEXT, value BLOB)", table));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages a zone configuration section.
|
||||
*
|
||||
* @param database Active database to use.
|
||||
* @param table Table name to use in database. Created if it does not exist. Needs to be trusted input.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public ZoneConfig(Connection database, String table) throws SQLException {
|
||||
this(database, table, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of an integer setting.
|
||||
*
|
||||
* @param setting The type of setting to look up.
|
||||
* @return the value of the setting or the default if not found.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public int getInt(ZoneSetting setting) throws SQLException {
|
||||
try (PreparedStatement stmt = conn.prepareStatement(String.format("SELECT value FROM %s WHERE option = ?", table))) {
|
||||
stmt.setString(1, setting.name());
|
||||
try (ResultSet result = stmt.executeQuery()) {
|
||||
if (result.next()) {
|
||||
// found an override for this config level
|
||||
return result.getInt(1);
|
||||
} else if (parent != null) {
|
||||
// look for it in zone/global configs; will be recursive upwards
|
||||
return parent.getInt(setting);
|
||||
} else {
|
||||
// the hard-coded value for fallback
|
||||
return (Integer) setting.getDefaultValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
25
sponge/src/main/java/com/tommytony/war/zone/ZoneSetting.java
Normal file
25
sponge/src/main/java/com/tommytony/war/zone/ZoneSetting.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.tommytony.war.zone;
|
||||
|
||||
/**
|
||||
* Settings that can be changed on a per-zone basis.
|
||||
* Some can be overridden per-team.
|
||||
*/
|
||||
public enum ZoneSetting {
|
||||
/**
|
||||
* Maximum players in a zone or team. Zone max is still observed even if team settings allow for more.
|
||||
*/
|
||||
MAXPLAYERS(Integer.class, 10, true);
|
||||
private final Class<?> dataType;
|
||||
private final Object defaultValue;
|
||||
private final boolean perTeam;
|
||||
|
||||
private ZoneSetting(Class<?> dataType, Object defaultValue, boolean perTeam) {
|
||||
this.dataType = dataType;
|
||||
this.defaultValue = defaultValue;
|
||||
this.perTeam = perTeam;
|
||||
}
|
||||
|
||||
public Object getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
76
sponge/src/main/java/com/tommytony/war/zone/ZoneStorage.java
Normal file
76
sponge/src/main/java/com/tommytony/war/zone/ZoneStorage.java
Normal file
@ -0,0 +1,76 @@
|
||||
package com.tommytony.war.zone;
|
||||
|
||||
import com.tommytony.war.WarPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* Manages the war zone database file, which contains all the data for the war zone.
|
||||
*/
|
||||
public class ZoneStorage implements AutoCloseable {
|
||||
private static int DATABASE_VERSION = 1;
|
||||
private final Warzone zone;
|
||||
private final WarPlugin plugin;
|
||||
private final Connection connection;
|
||||
private final File dataStore;
|
||||
|
||||
/**
|
||||
* Initiates a database for a new or existing database.
|
||||
*
|
||||
* @param zone The server war zone object for this database.
|
||||
* @param plugin The war plugin, for storage information and configuration.
|
||||
* @throws SQLException
|
||||
*/
|
||||
ZoneStorage(Warzone zone, WarPlugin plugin) throws SQLException {
|
||||
this.zone = zone;
|
||||
this.plugin = plugin;
|
||||
dataStore = new File(plugin.getDataDir(), String.format("%s.warzone", zone.getName()));
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dataStore.getPath());
|
||||
this.upgradeDatabase();
|
||||
}
|
||||
|
||||
Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the database stored version information and perform upgrade tasks if necessary.
|
||||
*
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void upgradeDatabase() throws SQLException {
|
||||
int version;
|
||||
try (
|
||||
Statement stmt = connection.createStatement();
|
||||
ResultSet resultSet = stmt.executeQuery("PRAGMA user_version");
|
||||
) {
|
||||
version = resultSet.getInt("user_version");
|
||||
}
|
||||
if (version > DATABASE_VERSION) {
|
||||
// version is from a future version
|
||||
throw new IllegalStateException(String.format("Unsupported zone version: %d. War current version: %d",
|
||||
version, DATABASE_VERSION));
|
||||
} else if (version == 0) {
|
||||
// brand new database file
|
||||
} else if (version < DATABASE_VERSION) {
|
||||
// upgrade
|
||||
switch (version) {
|
||||
// none yet
|
||||
default:
|
||||
// some odd bug or people messing with their database
|
||||
throw new IllegalStateException(String.format("Unsupported zone version: %d.", version));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this resource, relinquishing any underlying resources.
|
||||
*
|
||||
* @throws Exception if this resource cannot be closed
|
||||
*/
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
connection.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user