CoreProtect v20.0 release
This commit is contained in:
parent
415d7b323a
commit
48ef18e2c8
173 changed files with 25072 additions and 1 deletions
466
src/main/java/net/coreprotect/config/Config.java
Normal file
466
src/main/java/net/coreprotect/config/Config.java
Normal file
|
|
@ -0,0 +1,466 @@
|
|||
package net.coreprotect.config;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.language.Language;
|
||||
|
||||
public class Config extends Language {
|
||||
|
||||
private static final Map<String, String[]> HEADERS = new HashMap<>();
|
||||
private static final Map<String, String> DEFAULT_VALUES = new LinkedHashMap<>();
|
||||
private static final Map<String, Config> CONFIG_BY_WORLD_NAME = new HashMap<>();
|
||||
private static final WeakHashMap<World, Config> CONFIG_BY_WORLD = new WeakHashMap<>();
|
||||
private static final String DEFAULT_FILE_HEADER = "# CoreProtect Config";
|
||||
public static final String LINE_SEPARATOR = "\n";
|
||||
|
||||
private static final Config GLOBAL = new Config();
|
||||
private final HashMap<String, String> config;
|
||||
private Config defaults;
|
||||
|
||||
public String DONATION_KEY;
|
||||
public String PREFIX;
|
||||
public String MYSQL_HOST;
|
||||
public String MYSQL_DATABASE;
|
||||
public String MYSQL_USERNAME;
|
||||
public String MYSQL_PASSWORD;
|
||||
public String LANGUAGE;
|
||||
public boolean HOVER_EVENTS;
|
||||
public boolean DATABASE_LOCK;
|
||||
public boolean HOPPER_FILTER_META;
|
||||
public boolean MYSQL;
|
||||
public boolean CHECK_UPDATES;
|
||||
public boolean API_ENABLED;
|
||||
public boolean VERBOSE;
|
||||
public boolean ROLLBACK_ITEMS;
|
||||
public boolean ROLLBACK_ENTITIES;
|
||||
public boolean SKIP_GENERIC_DATA;
|
||||
public boolean BLOCK_PLACE;
|
||||
public boolean BLOCK_BREAK;
|
||||
public boolean NATURAL_BREAK;
|
||||
public boolean BLOCK_MOVEMENT;
|
||||
public boolean PISTONS;
|
||||
public boolean BLOCK_BURN;
|
||||
public boolean BLOCK_IGNITE;
|
||||
public boolean EXPLOSIONS;
|
||||
public boolean ENTITY_CHANGE;
|
||||
public boolean ENTITY_KILLS;
|
||||
public boolean SIGN_TEXT;
|
||||
public boolean BUCKETS;
|
||||
public boolean LEAF_DECAY;
|
||||
public boolean TREE_GROWTH;
|
||||
public boolean MUSHROOM_GROWTH;
|
||||
public boolean VINE_GROWTH;
|
||||
public boolean PORTALS;
|
||||
public boolean WATER_FLOW;
|
||||
public boolean LAVA_FLOW;
|
||||
public boolean LIQUID_TRACKING;
|
||||
public boolean ITEM_TRANSACTIONS;
|
||||
public boolean ITEM_DROPS;
|
||||
public boolean ITEM_PICKUPS;
|
||||
public boolean HOPPER_TRANSACTIONS;
|
||||
public boolean PLAYER_INTERACTIONS;
|
||||
public boolean PLAYER_MESSAGES;
|
||||
public boolean PLAYER_COMMANDS;
|
||||
public boolean PLAYER_SESSIONS;
|
||||
public boolean USERNAME_CHANGES;
|
||||
public boolean WORLDEDIT;
|
||||
public int MYSQL_PORT;
|
||||
public int DEFAULT_RADIUS;
|
||||
public int MAX_RADIUS;
|
||||
|
||||
static {
|
||||
DEFAULT_VALUES.put("donation-key", "");
|
||||
DEFAULT_VALUES.put("use-mysql", "false");
|
||||
DEFAULT_VALUES.put("table-prefix", "co_");
|
||||
DEFAULT_VALUES.put("mysql-host", "127.0.0.1");
|
||||
DEFAULT_VALUES.put("mysql-port", "3306");
|
||||
DEFAULT_VALUES.put("mysql-database", "database");
|
||||
DEFAULT_VALUES.put("mysql-username", "root");
|
||||
DEFAULT_VALUES.put("mysql-password", "");
|
||||
DEFAULT_VALUES.put("language", "en");
|
||||
DEFAULT_VALUES.put("check-updates", "true");
|
||||
DEFAULT_VALUES.put("api-enabled", "true");
|
||||
DEFAULT_VALUES.put("verbose", "true");
|
||||
DEFAULT_VALUES.put("default-radius", "10");
|
||||
DEFAULT_VALUES.put("max-radius", "100");
|
||||
DEFAULT_VALUES.put("rollback-items", "true");
|
||||
DEFAULT_VALUES.put("rollback-entities", "true");
|
||||
DEFAULT_VALUES.put("skip-generic-data", "true");
|
||||
DEFAULT_VALUES.put("block-place", "true");
|
||||
DEFAULT_VALUES.put("block-break", "true");
|
||||
DEFAULT_VALUES.put("natural-break", "true");
|
||||
DEFAULT_VALUES.put("block-movement", "true");
|
||||
DEFAULT_VALUES.put("pistons", "true");
|
||||
DEFAULT_VALUES.put("block-burn", "true");
|
||||
DEFAULT_VALUES.put("block-ignite", "true");
|
||||
DEFAULT_VALUES.put("explosions", "true");
|
||||
DEFAULT_VALUES.put("entity-change", "true");
|
||||
DEFAULT_VALUES.put("entity-kills", "true");
|
||||
DEFAULT_VALUES.put("sign-text", "true");
|
||||
DEFAULT_VALUES.put("buckets", "true");
|
||||
DEFAULT_VALUES.put("leaf-decay", "true");
|
||||
DEFAULT_VALUES.put("tree-growth", "true");
|
||||
DEFAULT_VALUES.put("mushroom-growth", "true");
|
||||
DEFAULT_VALUES.put("vine-growth", "true");
|
||||
DEFAULT_VALUES.put("portals", "true");
|
||||
DEFAULT_VALUES.put("water-flow", "true");
|
||||
DEFAULT_VALUES.put("lava-flow", "true");
|
||||
DEFAULT_VALUES.put("liquid-tracking", "true");
|
||||
DEFAULT_VALUES.put("item-transactions", "true");
|
||||
DEFAULT_VALUES.put("item-drops", "true");
|
||||
DEFAULT_VALUES.put("item-pickups", "true");
|
||||
DEFAULT_VALUES.put("hopper-transactions", "true");
|
||||
DEFAULT_VALUES.put("player-interactions", "true");
|
||||
DEFAULT_VALUES.put("player-messages", "true");
|
||||
DEFAULT_VALUES.put("player-commands", "true");
|
||||
DEFAULT_VALUES.put("player-sessions", "true");
|
||||
DEFAULT_VALUES.put("username-changes", "true");
|
||||
DEFAULT_VALUES.put("worldedit", "true");
|
||||
|
||||
HEADERS.put("donation-key", new String[] { "# CoreProtect is donationware. For more information, visit our project page." });
|
||||
HEADERS.put("use-mysql", new String[] { "# MySQL is optional and not required.", "# If you prefer to use MySQL, enable the following and fill out the fields." });
|
||||
HEADERS.put("language", new String[] { "# If modified, will automatically attempt to translate languages phrases.", "# List of language codes: https://coreprotect.net/languages/" });
|
||||
HEADERS.put("check-updates", new String[] { "# If enabled, CoreProtect will check for updates when your server starts up.", "# If an update is available, you'll be notified via your server console.", });
|
||||
HEADERS.put("api-enabled", new String[] { "# If enabled, other plugins will be able to utilize the CoreProtect API.", });
|
||||
HEADERS.put("verbose", new String[] { "# If enabled, extra data is displayed during rollbacks and restores.", "# Can be manually triggered by adding \"#verbose\" to your rollback command." });
|
||||
HEADERS.put("default-radius", new String[] { "# If no radius is specified in a rollback or restore, this value will be", "# used as the radius. Set to \"0\" to disable automatically adding a radius." });
|
||||
HEADERS.put("max-radius", new String[] { "# The maximum radius that can be used in a command. Set to \"0\" to disable.", "# To run a rollback or restore without a radius, you can use \"r:#global\"." });
|
||||
HEADERS.put("rollback-items", new String[] { "# If enabled, items taken from containers (etc) will be included in rollbacks." });
|
||||
HEADERS.put("rollback-entities", new String[] { "# If enabled, entities, such as killed animals, will be included in rollbacks." });
|
||||
HEADERS.put("skip-generic-data", new String[] { "# If enabled, generic data, like zombies burning in daylight, won't be logged." });
|
||||
HEADERS.put("block-place", new String[] { "# Logs blocks placed by players." });
|
||||
HEADERS.put("block-break", new String[] { "# Logs blocks broken by players." });
|
||||
HEADERS.put("natural-break", new String[] { "# Logs blocks that break off of other blocks; for example, a sign or torch", "# falling off of a dirt block that a player breaks. This is required for", "# beds/doors to properly rollback." });
|
||||
HEADERS.put("block-movement", new String[] { "# Properly track block movement, such as sand or gravel falling." });
|
||||
HEADERS.put("pistons", new String[] { "# Properly track blocks moved by pistons." });
|
||||
HEADERS.put("block-burn", new String[] { "# Logs blocks that burn up in a fire." });
|
||||
HEADERS.put("block-ignite", new String[] { "# Logs when a block naturally ignites, such as from fire spreading." });
|
||||
HEADERS.put("explosions", new String[] { "# Logs explosions, such as TNT and Creepers." });
|
||||
HEADERS.put("entity-change", new String[] { "# Track when an entity changes a block, such as an Enderman destroying blocks." });
|
||||
HEADERS.put("entity-kills", new String[] { "# Logs killed entities, such as killed cows and enderman." });
|
||||
HEADERS.put("sign-text", new String[] { "# Logs text on signs. If disabled, signs will be blank when rolled back." });
|
||||
HEADERS.put("buckets", new String[] { "# Logs lava and water sources placed/removed by players who are using buckets." });
|
||||
HEADERS.put("leaf-decay", new String[] { "# Logs natural tree leaf decay." });
|
||||
HEADERS.put("tree-growth", new String[] { "# Logs tree growth. Trees are linked to the player who planted the sappling." });
|
||||
HEADERS.put("mushroom-growth", new String[] { "# Logs mushroom growth." });
|
||||
HEADERS.put("vine-growth", new String[] { "# Logs natural vine growth." });
|
||||
HEADERS.put("portals", new String[] { "# Logs when portals such as Nether portals generate naturally." });
|
||||
HEADERS.put("water-flow", new String[] { "# Logs water flow. If water destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
|
||||
HEADERS.put("lava-flow", new String[] { "# Logs lava flow. If lava destroys other blocks, such as torches,", "# this allows it to be properly rolled back." });
|
||||
HEADERS.put("liquid-tracking", new String[] { "# Allows liquid to be properly tracked and linked to players.", "# For example, if a player places water which flows and destroys torches,", "# it can all be properly restored by rolling back that single player." });
|
||||
HEADERS.put("item-transactions", new String[] { "# Track item transactions, such as when a player takes items from", "# a chest, furnace, or dispenser." });
|
||||
HEADERS.put("item-drops", new String[] { "# Logs items dropped by players." });
|
||||
HEADERS.put("item-pickups", new String[] { "# Logs items picked up by players." });
|
||||
HEADERS.put("hopper-transactions", new String[] { "# Track all hopper transactions, such as when a hopper removes items from a", "# chest, furnace, or dispenser." });
|
||||
HEADERS.put("player-interactions", new String[] { "# Track player interactions, such as when a player opens a door, presses", "# a button, or opens a chest. Player interactions can't be rolled back." });
|
||||
HEADERS.put("player-messages", new String[] { "# Logs messages that players send in the chat." });
|
||||
HEADERS.put("player-commands", new String[] { "# Logs all commands used by players." });
|
||||
HEADERS.put("player-sessions", new String[] { "# Logs the logins and logouts of players." });
|
||||
HEADERS.put("username-changes", new String[] { "# Logs when a player changes their Minecraft username." });
|
||||
HEADERS.put("worldedit", new String[] { "# Logs changes made via the plugin \"WorldEdit\" if it's in use on your server." });
|
||||
}
|
||||
|
||||
private void readValues() {
|
||||
this.HOVER_EVENTS = this.getBoolean("hover-events", true);
|
||||
this.DATABASE_LOCK = this.getBoolean("database-lock", true);
|
||||
this.HOPPER_FILTER_META = this.getBoolean("hopper-filter-meta", false);
|
||||
this.DONATION_KEY = this.getString("donation-key");
|
||||
this.MYSQL = this.getBoolean("use-mysql");
|
||||
this.PREFIX = this.getString("table-prefix");
|
||||
this.MYSQL_HOST = this.getString("mysql-host");
|
||||
this.MYSQL_PORT = this.getInt("mysql-port");
|
||||
this.MYSQL_DATABASE = this.getString("mysql-database");
|
||||
this.MYSQL_USERNAME = this.getString("mysql-username");
|
||||
this.MYSQL_PASSWORD = this.getString("mysql-password");
|
||||
this.LANGUAGE = this.getString("language");
|
||||
this.CHECK_UPDATES = this.getBoolean("check-updates");
|
||||
this.API_ENABLED = this.getBoolean("api-enabled");
|
||||
this.VERBOSE = this.getBoolean("verbose");
|
||||
this.DEFAULT_RADIUS = this.getInt("default-radius");
|
||||
this.MAX_RADIUS = this.getInt("max-radius");
|
||||
this.ROLLBACK_ITEMS = this.getBoolean("rollback-items");
|
||||
this.ROLLBACK_ENTITIES = this.getBoolean("rollback-entities");
|
||||
this.SKIP_GENERIC_DATA = this.getBoolean("skip-generic-data");
|
||||
this.BLOCK_PLACE = this.getBoolean("block-place");
|
||||
this.BLOCK_BREAK = this.getBoolean("block-break");
|
||||
this.NATURAL_BREAK = this.getBoolean("natural-break");
|
||||
this.BLOCK_MOVEMENT = this.getBoolean("block-movement");
|
||||
this.PISTONS = this.getBoolean("pistons");
|
||||
this.BLOCK_BURN = this.getBoolean("block-burn");
|
||||
this.BLOCK_IGNITE = this.getBoolean("block-ignite");
|
||||
this.EXPLOSIONS = this.getBoolean("explosions");
|
||||
this.ENTITY_CHANGE = this.getBoolean("entity-change");
|
||||
this.ENTITY_KILLS = this.getBoolean("entity-kills");
|
||||
this.SIGN_TEXT = this.getBoolean("sign-text");
|
||||
this.BUCKETS = this.getBoolean("buckets");
|
||||
this.LEAF_DECAY = this.getBoolean("leaf-decay");
|
||||
this.TREE_GROWTH = this.getBoolean("tree-growth");
|
||||
this.MUSHROOM_GROWTH = this.getBoolean("mushroom-growth");
|
||||
this.VINE_GROWTH = this.getBoolean("vine-growth");
|
||||
this.PORTALS = this.getBoolean("portals");
|
||||
this.WATER_FLOW = this.getBoolean("water-flow");
|
||||
this.LAVA_FLOW = this.getBoolean("lava-flow");
|
||||
this.LIQUID_TRACKING = this.getBoolean("liquid-tracking");
|
||||
this.ITEM_TRANSACTIONS = this.getBoolean("item-transactions");
|
||||
this.ITEM_DROPS = this.getBoolean("item-drops");
|
||||
this.ITEM_PICKUPS = this.getBoolean("item-pickups");
|
||||
this.HOPPER_TRANSACTIONS = this.getBoolean("hopper-transactions");
|
||||
this.PLAYER_INTERACTIONS = this.getBoolean("player-interactions");
|
||||
this.PLAYER_MESSAGES = this.getBoolean("player-messages");
|
||||
this.PLAYER_COMMANDS = this.getBoolean("player-commands");
|
||||
this.PLAYER_SESSIONS = this.getBoolean("player-sessions");
|
||||
this.USERNAME_CHANGES = this.getBoolean("username-changes");
|
||||
this.WORLDEDIT = this.getBoolean("worldedit");
|
||||
}
|
||||
|
||||
public static void init() throws IOException {
|
||||
parseConfig(loadFiles(ConfigFile.CONFIG));
|
||||
// pass variables to ConfigFile.parseConfig(ConfigFile.loadFiles());
|
||||
}
|
||||
|
||||
public static Config getGlobal() {
|
||||
return GLOBAL;
|
||||
}
|
||||
|
||||
// returns a world specific config if it exists, otherwise the global config
|
||||
public static Config getConfig(final World world) {
|
||||
Config ret = CONFIG_BY_WORLD.get(world);
|
||||
if (ret == null) {
|
||||
ret = CONFIG_BY_WORLD_NAME.getOrDefault(world.getName(), GLOBAL);
|
||||
CONFIG_BY_WORLD.put(world, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Config() {
|
||||
this.config = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public void setDefaults(final Config defaults) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
private String get(final String key, final String dfl) {
|
||||
String configured = this.config.get(key);
|
||||
if (configured == null) {
|
||||
if (dfl != null) {
|
||||
return dfl;
|
||||
}
|
||||
if (this.defaults == null) {
|
||||
configured = DEFAULT_VALUES.get(key);
|
||||
}
|
||||
else {
|
||||
configured = this.defaults.config.getOrDefault(key, DEFAULT_VALUES.get(key));
|
||||
}
|
||||
}
|
||||
return configured;
|
||||
}
|
||||
|
||||
private boolean getBoolean(final String key) {
|
||||
final String configured = this.get(key, null);
|
||||
return configured != null && configured.startsWith("t");
|
||||
}
|
||||
|
||||
private boolean getBoolean(final String key, final boolean dfl) {
|
||||
final String configured = this.get(key, null);
|
||||
return configured == null ? dfl : configured.startsWith("t");
|
||||
}
|
||||
|
||||
private int getInt(final String key) {
|
||||
return this.getInt(key, 0);
|
||||
}
|
||||
|
||||
private int getInt(final String key, final int dfl) {
|
||||
String configured = this.get(key, null);
|
||||
|
||||
if (configured == null) {
|
||||
return dfl;
|
||||
}
|
||||
|
||||
configured = configured.replaceAll("[^0-9]", "");
|
||||
|
||||
return configured.isEmpty() ? 0 : Integer.parseInt(configured);
|
||||
}
|
||||
|
||||
private String getString(final String key) {
|
||||
final String configured = this.get(key, null);
|
||||
return configured == null ? "" : configured;
|
||||
}
|
||||
|
||||
public void clearConfig() {
|
||||
this.config.clear();
|
||||
}
|
||||
|
||||
public void loadDefaults() {
|
||||
this.clearConfig();
|
||||
this.readValues();
|
||||
}
|
||||
|
||||
public void load(final InputStream in) throws IOException {
|
||||
// if we fail reading, we will not corrupt our current config.
|
||||
final Map<String, String> newConfig = new LinkedHashMap<>(this.config.size());
|
||||
ConfigFile.load(in, newConfig, false);
|
||||
|
||||
this.clearConfig();
|
||||
this.config.putAll(newConfig);
|
||||
|
||||
this.readValues();
|
||||
}
|
||||
|
||||
private static Map<String, byte[]> loadFiles(String fileName) throws IOException {
|
||||
final CoreProtect plugin = CoreProtect.getInstance();
|
||||
final File configFolder = plugin.getDataFolder();
|
||||
if (!configFolder.exists()) {
|
||||
configFolder.mkdirs();
|
||||
}
|
||||
|
||||
final Map<String, byte[]> map = new HashMap<>();
|
||||
final File globalFile = new File(configFolder, fileName);
|
||||
|
||||
if (globalFile.exists()) {
|
||||
// we always add options to the global config
|
||||
final byte[] data = Files.readAllBytes(globalFile.toPath());
|
||||
map.put("config", data);
|
||||
|
||||
// can't modify GLOBAL, we're likely off-main here
|
||||
final Config temp = new Config();
|
||||
temp.load(new ByteArrayInputStream(data));
|
||||
temp.addMissingOptions(globalFile);
|
||||
}
|
||||
else {
|
||||
final Config temp = new Config();
|
||||
temp.loadDefaults();
|
||||
temp.addMissingOptions(globalFile);
|
||||
}
|
||||
|
||||
for (final File worldConfigFile : configFolder.listFiles((File file) -> file.getName().endsWith(".yml"))) {
|
||||
final String name = worldConfigFile.getName();
|
||||
if (name.equals(ConfigFile.CONFIG) || name.equals(ConfigFile.LANGUAGE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
map.put(name.substring(0, name.length() - ".yml".length()), Files.readAllBytes(worldConfigFile.toPath()));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
// this should only be called on the main thread
|
||||
private static void parseConfig(final Map<String, byte[]> data) {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
// we call reloads asynchronously
|
||||
// for now this solution is good enough to ensure we only modify on the main thread
|
||||
final CompletableFuture<Void> complete = new CompletableFuture<>();
|
||||
|
||||
Bukkit.getScheduler().runTask(CoreProtect.getInstance(), () -> {
|
||||
try {
|
||||
parseConfig(data);
|
||||
}
|
||||
catch (final Throwable thr) {
|
||||
if (thr instanceof ThreadDeath) {
|
||||
throw (ThreadDeath) thr;
|
||||
}
|
||||
complete.completeExceptionally(thr);
|
||||
return;
|
||||
}
|
||||
complete.complete(null);
|
||||
});
|
||||
|
||||
complete.join();
|
||||
return;
|
||||
}
|
||||
|
||||
CONFIG_BY_WORLD_NAME.clear();
|
||||
CONFIG_BY_WORLD.clear();
|
||||
|
||||
// we need to load global first since it is used for config defaults
|
||||
final byte[] defaultData = data.get("config");
|
||||
if (defaultData != null) {
|
||||
try {
|
||||
GLOBAL.load(new ByteArrayInputStream(defaultData));
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new RuntimeException(ex); // shouldn't happen
|
||||
}
|
||||
}
|
||||
else {
|
||||
GLOBAL.loadDefaults();
|
||||
}
|
||||
|
||||
for (final Map.Entry<String, byte[]> entry : data.entrySet()) {
|
||||
final String worldName = entry.getKey();
|
||||
if (worldName.equals("config")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final byte[] fileData = entry.getValue();
|
||||
final Config config = new Config();
|
||||
config.setDefaults(GLOBAL);
|
||||
|
||||
try {
|
||||
config.load(new ByteArrayInputStream(fileData));
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new RuntimeException(ex); // shouldn't happen
|
||||
}
|
||||
|
||||
CONFIG_BY_WORLD_NAME.put(worldName, config);
|
||||
}
|
||||
}
|
||||
|
||||
public void addMissingOptions(final File file) throws IOException {
|
||||
final boolean writeHeader = !file.exists() || file.length() == 0;
|
||||
try (final FileOutputStream fout = new FileOutputStream(file, true)) {
|
||||
OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(fout), StandardCharsets.UTF_8);
|
||||
if (writeHeader) {
|
||||
out.append(DEFAULT_FILE_HEADER);
|
||||
out.append(LINE_SEPARATOR);
|
||||
}
|
||||
|
||||
for (final Map.Entry<String, String> entry : DEFAULT_VALUES.entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
final String defaultValue = entry.getValue();
|
||||
|
||||
final String configuredValue = this.config.get(key);
|
||||
|
||||
if (configuredValue != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] header = HEADERS.get(key);
|
||||
|
||||
if (header != null) {
|
||||
out.append(LINE_SEPARATOR);
|
||||
for (final String headerLine : header) {
|
||||
out.append(headerLine);
|
||||
out.append(LINE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
out.append(key);
|
||||
out.append(": ");
|
||||
out.append(defaultValue);
|
||||
out.append(LINE_SEPARATOR);
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
214
src/main/java/net/coreprotect/config/ConfigFile.java
Normal file
214
src/main/java/net/coreprotect/config/ConfigFile.java
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
package net.coreprotect.config;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.language.Language;
|
||||
import net.coreprotect.language.Phrase;
|
||||
|
||||
public class ConfigFile extends Config {
|
||||
|
||||
public static final String CONFIG = "config.yml";
|
||||
public static final String LANGUAGE = "language.yml";
|
||||
public static final String LANGUAGE_CACHE = ".language";
|
||||
|
||||
private static final TreeMap<String, String> DEFAULT_VALUES = new TreeMap<>();
|
||||
private static final TreeMap<String, String> USER_VALUES = new TreeMap<>();
|
||||
private static final String DEFAULT_FILE_HEADER = "# CoreProtect Language File (en)";
|
||||
private final HashMap<String, String> lang;
|
||||
|
||||
public static void init(String fileName) throws IOException {
|
||||
for (Phrase phrase : Phrase.values()) {
|
||||
DEFAULT_VALUES.put(phrase.name(), phrase.getPhrase());
|
||||
USER_VALUES.put(phrase.name(), phrase.getUserPhrase());
|
||||
}
|
||||
|
||||
boolean isCache = fileName.startsWith(".");
|
||||
loadFiles(fileName, isCache);
|
||||
}
|
||||
|
||||
public ConfigFile() {
|
||||
this.lang = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public void load(final InputStream in, String fileName, boolean isCache) throws IOException {
|
||||
// if we fail reading, we will not corrupt our current config.
|
||||
final Map<String, String> newConfig = new LinkedHashMap<>(this.lang.size());
|
||||
ConfigFile.load(in, newConfig, true);
|
||||
|
||||
this.lang.clear();
|
||||
this.lang.putAll(newConfig);
|
||||
|
||||
for (final Entry<String, String> entry : this.lang.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
if (DEFAULT_VALUES.containsKey(key) && value.length() > 0 && (!isCache || DEFAULT_VALUES.get(key).equals(USER_VALUES.get(key)))) {
|
||||
Phrase phrase = Phrase.valueOf(key);
|
||||
if (!isCache) {
|
||||
Language.setUserPhrase(phrase, value);
|
||||
}
|
||||
|
||||
Language.setTranslatedPhrase(phrase, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this function will close in
|
||||
public static void load(final InputStream in, final Map<String, String> config, boolean forceCase) throws IOException {
|
||||
try (final InputStream in0 = in) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
|
||||
if (line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int split = line.indexOf(':');
|
||||
|
||||
if (split == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = line.substring(0, split).trim();
|
||||
String value = line.substring(split + 1).trim();
|
||||
|
||||
// Strip out single and double quotes from the start/end of the value
|
||||
if (value.length() >= 2 && value.startsWith("'") && value.endsWith("'")) {
|
||||
value = value.replaceAll("^'|'$", "");
|
||||
value = value.replace("''", "'");
|
||||
value = value.replace("\\'", "'");
|
||||
value = value.replace("\\\\", "\\");
|
||||
}
|
||||
else if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
|
||||
value = value.replaceAll("^\"|\"$", "");
|
||||
value = value.replace("\\\"", "\"");
|
||||
value = value.replace("\\\\", "\\");
|
||||
}
|
||||
|
||||
if (forceCase) {
|
||||
key = key.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
config.put(key, value);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, byte[]> loadFiles(String fileName, boolean isCache) throws IOException {
|
||||
final CoreProtect plugin = CoreProtect.getInstance();
|
||||
final File configFolder = plugin.getDataFolder();
|
||||
if (!configFolder.exists()) {
|
||||
configFolder.mkdirs();
|
||||
}
|
||||
|
||||
final Map<String, byte[]> map = new HashMap<>();
|
||||
final File globalFile = new File(configFolder, fileName);
|
||||
|
||||
if (globalFile.exists()) {
|
||||
// we always add options to the global config
|
||||
final byte[] data = Files.readAllBytes(globalFile.toPath());
|
||||
map.put("config", data);
|
||||
|
||||
final ConfigFile temp = new ConfigFile();
|
||||
temp.load(new ByteArrayInputStream(data), fileName, isCache);
|
||||
temp.addMissingOptions(globalFile);
|
||||
}
|
||||
else {
|
||||
final ConfigFile temp = new ConfigFile();
|
||||
temp.addMissingOptions(globalFile);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMissingOptions(final File file) throws IOException {
|
||||
if (file.getName().startsWith(".")) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean writeHeader = !file.exists() || file.length() == 0;
|
||||
try (final FileOutputStream fout = new FileOutputStream(file, true)) {
|
||||
OutputStreamWriter out = new OutputStreamWriter(new BufferedOutputStream(fout), StandardCharsets.UTF_8);
|
||||
if (writeHeader) {
|
||||
out.append(DEFAULT_FILE_HEADER);
|
||||
out.append(Config.LINE_SEPARATOR);
|
||||
}
|
||||
|
||||
for (final Entry<String, String> entry : DEFAULT_VALUES.entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
final String defaultValue = entry.getValue().replaceAll("\"", "\\\\\"");
|
||||
|
||||
final String configuredValue = this.lang.get(key);
|
||||
if (configuredValue != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out.append(Config.LINE_SEPARATOR);
|
||||
out.append(key);
|
||||
out.append(": ");
|
||||
out.append("\"" + defaultValue + "\"");
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void modifyLine(String fileName, String oldLine, String newLine) {
|
||||
try {
|
||||
Path path = Paths.get(ConfigHandler.path + fileName);
|
||||
List<String> lines = Files.readAllLines(path);
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (lines.get(i).equalsIgnoreCase(oldLine)) {
|
||||
if (newLine.length() > 0) {
|
||||
lines.set(i, newLine);
|
||||
}
|
||||
else {
|
||||
lines.remove(i);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.size() > 0) {
|
||||
String lastLine = lines.get(lines.size() - 1); // append the final line to prevent a line separator from being added
|
||||
Files.write(path, (lines.remove(lines.size() - 1).isEmpty() ? lines : lines), StandardCharsets.UTF_8);
|
||||
Files.write(path, lastLine.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
|
||||
lines.clear();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetCache(String cacheName, String fileName) throws IOException {
|
||||
File file = new File(CoreProtect.getInstance().getDataFolder(), cacheName);
|
||||
if (file.length() > 0) {
|
||||
new FileOutputStream(file).close();
|
||||
init(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
408
src/main/java/net/coreprotect/config/ConfigHandler.java
Normal file
408
src/main/java/net/coreprotect/config/ConfigHandler.java
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
package net.coreprotect.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.consumer.Consumer;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Database;
|
||||
import net.coreprotect.database.statement.UserStatement;
|
||||
import net.coreprotect.language.Phrase;
|
||||
import net.coreprotect.model.BlockGroup;
|
||||
import net.coreprotect.patch.Patch;
|
||||
import net.coreprotect.spigot.SpigotAdapter;
|
||||
import net.coreprotect.utility.Chat;
|
||||
import net.coreprotect.utility.Color;
|
||||
import net.coreprotect.utility.Util;
|
||||
|
||||
public class ConfigHandler extends Queue {
|
||||
public static int SERVER_VERSION = 0;
|
||||
public static final int EDITION_VERSION = 2;
|
||||
public static final String EDITION_BRANCH = Util.getBranch();
|
||||
public static final String EDITION_NAME = Util.getPluginName();
|
||||
public static final String JAVA_VERSION = "1.8";
|
||||
public static final String SPIGOT_VERSION = "1.14";
|
||||
public static String path = "plugins/CoreProtect/";
|
||||
public static String sqlite = "database.db";
|
||||
public static String host = "127.0.0.1";
|
||||
public static int port = 3306;
|
||||
public static String database = "database";
|
||||
public static String username = "root";
|
||||
public static String password = "";
|
||||
public static String prefix = "co_";
|
||||
public static final boolean isSpigot = Util.isSpigot();
|
||||
public static final boolean isPaper = Util.isPaper();
|
||||
public static volatile boolean serverRunning = false;
|
||||
public static volatile boolean converterRunning = false;
|
||||
public static volatile boolean purgeRunning = false;
|
||||
public static volatile boolean worldeditEnabled = false;
|
||||
public static volatile boolean databaseReachable = true;
|
||||
public static volatile int worldId = 0;
|
||||
public static volatile int materialId = 0;
|
||||
public static volatile int blockdataId = 0;
|
||||
public static volatile int entityId = 0;
|
||||
public static volatile int artId = 0;
|
||||
|
||||
private static <K, V> Map<K, V> syncMap() {
|
||||
return Collections.synchronizedMap(new HashMap<>());
|
||||
}
|
||||
|
||||
public static Map<String, Integer> worlds = syncMap();
|
||||
public static Map<Integer, String> worldsReversed = syncMap();
|
||||
public static Map<String, Integer> materials = syncMap();
|
||||
public static Map<Integer, String> materialsReversed = syncMap();
|
||||
public static Map<String, Integer> blockdata = syncMap();
|
||||
public static Map<Integer, String> blockdataReversed = syncMap();
|
||||
public static Map<String, Integer> entities = syncMap();
|
||||
public static Map<Integer, String> entitiesReversed = syncMap();
|
||||
public static Map<String, Integer> art = syncMap();
|
||||
public static Map<Integer, String> artReversed = syncMap();
|
||||
public static Map<String, int[]> rollbackHash = syncMap();
|
||||
public static Map<String, Boolean> inspecting = syncMap();
|
||||
public static Map<String, Boolean> blacklist = syncMap();
|
||||
public static Map<String, Integer> loggingChest = syncMap();
|
||||
public static Map<String, Integer> loggingItem = syncMap();
|
||||
public static ConcurrentHashMap<String, List<Object>> transactingChest = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<String, Boolean> hopperAbort = new ConcurrentHashMap<>();
|
||||
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
|
||||
public static Map<String, Integer> lookupType = syncMap();
|
||||
public static Map<String, Object[]> lookupThrottle = syncMap();
|
||||
public static Map<String, Object[]> teleportThrottle = syncMap();
|
||||
public static Map<String, Integer> lookupPage = syncMap();
|
||||
public static Map<String, String> lookupCommand = syncMap();
|
||||
public static Map<String, List<Object>> lookupBlist = syncMap();
|
||||
public static Map<String, List<Object>> lookupElist = syncMap();
|
||||
public static Map<String, List<String>> lookupEUserlist = syncMap();
|
||||
public static Map<String, List<String>> lookupUlist = syncMap();
|
||||
public static Map<String, List<Integer>> lookupAlist = syncMap();
|
||||
public static Map<String, Integer[]> lookupRadius = syncMap();
|
||||
public static Map<String, String> lookupTime = syncMap();
|
||||
public static Map<String, Integer> lookupRows = syncMap();
|
||||
public static Map<String, String> uuidCache = syncMap();
|
||||
public static Map<String, String> uuidCacheReversed = syncMap();
|
||||
public static Map<String, Integer> playerIdCache = syncMap();
|
||||
public static Map<Integer, String> playerIdCacheReversed = syncMap();
|
||||
public static Map<String, List<Object>> lastRollback = syncMap();
|
||||
public static Map<String, Boolean> activeRollbacks = syncMap();
|
||||
public static Map<UUID, Object[]> entityBlockMapper = syncMap();
|
||||
public static ConcurrentHashMap<String, String> language = new ConcurrentHashMap<>();
|
||||
public static List<String> databaseTables = new ArrayList<>();
|
||||
|
||||
private static void checkPlayers(Connection connection) {
|
||||
ConfigHandler.playerIdCache.clear();
|
||||
ConfigHandler.playerIdCacheReversed.clear();
|
||||
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if (ConfigHandler.playerIdCache.get(player.getName().toLowerCase(Locale.ROOT)) == null) {
|
||||
UserStatement.loadId(connection, player.getName(), player.getUniqueId().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadBlacklist() {
|
||||
try {
|
||||
ConfigHandler.blacklist.clear();
|
||||
String blacklist = ConfigHandler.path + "blacklist.txt";
|
||||
boolean exists = (new File(blacklist)).exists();
|
||||
if (exists) {
|
||||
RandomAccessFile blfile = new RandomAccessFile(blacklist, "rw");
|
||||
long blc = blfile.length();
|
||||
if (blc > 0) {
|
||||
while (blfile.getFilePointer() < blfile.length()) {
|
||||
String blacklistUser = blfile.readLine().replaceAll(" ", "").toLowerCase(Locale.ROOT);
|
||||
if (blacklistUser.length() > 0) {
|
||||
ConfigHandler.blacklist.put(blacklistUser, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
blfile.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadConfig() {
|
||||
try {
|
||||
Config.init();
|
||||
ConfigFile.init(ConfigFile.LANGUAGE); // load user phrases
|
||||
ConfigFile.init(ConfigFile.LANGUAGE_CACHE); // load translation cache
|
||||
|
||||
// Enforce "co_" table prefix if using SQLite.
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
Config.getGlobal().PREFIX = "co_";
|
||||
}
|
||||
|
||||
ConfigHandler.host = Config.getGlobal().MYSQL_HOST;
|
||||
ConfigHandler.port = Config.getGlobal().MYSQL_PORT;
|
||||
ConfigHandler.database = Config.getGlobal().MYSQL_DATABASE;
|
||||
ConfigHandler.username = Config.getGlobal().MYSQL_USERNAME;
|
||||
ConfigHandler.password = Config.getGlobal().MYSQL_PASSWORD;
|
||||
ConfigHandler.prefix = Config.getGlobal().PREFIX;
|
||||
|
||||
ConfigHandler.loadBlacklist(); // Load the blacklist file if it exists.
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadDatabase() {
|
||||
if (!Config.getGlobal().MYSQL) {
|
||||
try {
|
||||
File tempFile = File.createTempFile("CoreProtect_" + System.currentTimeMillis(), ".tmp");
|
||||
tempFile.setExecutable(true);
|
||||
|
||||
boolean canExecute = false;
|
||||
try {
|
||||
canExecute = tempFile.canExecute();
|
||||
}
|
||||
catch (Exception exception) {
|
||||
// execute access denied by security manager
|
||||
}
|
||||
|
||||
if (!canExecute) {
|
||||
File tempFolder = new File("cache");
|
||||
boolean exists = tempFolder.exists();
|
||||
if (!exists) {
|
||||
tempFolder.mkdir();
|
||||
}
|
||||
System.setProperty("java.io.tmpdir", "cache");
|
||||
}
|
||||
|
||||
tempFile.delete();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (ConfigHandler.serverRunning) {
|
||||
Consumer.resetConnection = true;
|
||||
}
|
||||
Database.createDatabaseTables(ConfigHandler.prefix, false);
|
||||
}
|
||||
|
||||
public static void loadTypes(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,material FROM " + ConfigHandler.prefix + "material_map";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
ConfigHandler.materials.clear();
|
||||
ConfigHandler.materialsReversed.clear();
|
||||
materialId = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
String material = rs.getString("material");
|
||||
ConfigHandler.materials.put(material, id);
|
||||
ConfigHandler.materialsReversed.put(id, material);
|
||||
if (id > materialId) {
|
||||
materialId = id;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
|
||||
query = "SELECT id,data FROM " + ConfigHandler.prefix + "blockdata_map";
|
||||
rs = statement.executeQuery(query);
|
||||
ConfigHandler.blockdata.clear();
|
||||
ConfigHandler.blockdataReversed.clear();
|
||||
blockdataId = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
String data = rs.getString("data");
|
||||
ConfigHandler.blockdata.put(data, id);
|
||||
ConfigHandler.blockdataReversed.put(id, data);
|
||||
if (id > blockdataId) {
|
||||
blockdataId = id;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
|
||||
query = "SELECT id,art FROM " + ConfigHandler.prefix + "art_map";
|
||||
rs = statement.executeQuery(query);
|
||||
ConfigHandler.art.clear();
|
||||
ConfigHandler.artReversed.clear();
|
||||
artId = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
String art = rs.getString("art");
|
||||
ConfigHandler.art.put(art, id);
|
||||
ConfigHandler.artReversed.put(id, art);
|
||||
if (id > artId) {
|
||||
artId = id;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
|
||||
query = "SELECT id,entity FROM " + ConfigHandler.prefix + "entity_map";
|
||||
rs = statement.executeQuery(query);
|
||||
ConfigHandler.entities.clear();
|
||||
ConfigHandler.entitiesReversed.clear();
|
||||
entityId = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
String entity = rs.getString("entity");
|
||||
ConfigHandler.entities.put(entity, id);
|
||||
ConfigHandler.entitiesReversed.put(id, entity);
|
||||
if (id > entityId) {
|
||||
entityId = id;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadWorlds(Statement statement) {
|
||||
try {
|
||||
String query = "SELECT id,world FROM " + ConfigHandler.prefix + "world";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
ConfigHandler.worlds.clear();
|
||||
ConfigHandler.worldsReversed.clear();
|
||||
worldId = 0;
|
||||
|
||||
while (rs.next()) {
|
||||
int id = rs.getInt("id");
|
||||
String world = rs.getString("world");
|
||||
ConfigHandler.worlds.put(world, id);
|
||||
ConfigHandler.worldsReversed.put(id, world);
|
||||
if (id > worldId) {
|
||||
worldId = id;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
|
||||
List<World> worlds = Bukkit.getServer().getWorlds();
|
||||
for (World world : worlds) {
|
||||
String worldname = world.getName();
|
||||
if (ConfigHandler.worlds.get(worldname) == null) {
|
||||
int id = worldId + 1;
|
||||
ConfigHandler.worlds.put(worldname, id);
|
||||
ConfigHandler.worldsReversed.put(id, worldname);
|
||||
worldId = id;
|
||||
Queue.queueWorldInsert(id, worldname);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkDatabaseLock(Statement statement) {
|
||||
try {
|
||||
if (Config.getGlobal().DATABASE_LOCK) {
|
||||
boolean locked = true;
|
||||
boolean lockMessage = false;
|
||||
int unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
int waitTime = unixtimestamp + 15;
|
||||
while (locked) {
|
||||
locked = false;
|
||||
unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
int checkTime = unixtimestamp - 15;
|
||||
String query = "SELECT * FROM " + ConfigHandler.prefix + "database_lock WHERE rowid='1' AND status='1' AND time >= '" + checkTime + "' LIMIT 1";
|
||||
ResultSet rs = statement.executeQuery(query);
|
||||
while (rs.next()) {
|
||||
if (unixtimestamp < waitTime) {
|
||||
if (!lockMessage) {
|
||||
Chat.sendConsoleMessage("[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_1));
|
||||
lockMessage = true;
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
else {
|
||||
Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_2));
|
||||
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_3));
|
||||
Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_4));
|
||||
return false;
|
||||
}
|
||||
|
||||
locked = true;
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean performInitialization(boolean startup) {
|
||||
try {
|
||||
BukkitAdapter.loadAdapter();
|
||||
SpigotAdapter.loadAdapter();
|
||||
BlockGroup.initialize();
|
||||
|
||||
ConfigHandler.loadConfig(); // Load (or create) the configuration file.
|
||||
ConfigHandler.loadDatabase(); // Initialize MySQL and create tables if necessary.
|
||||
|
||||
Connection connection = Database.getConnection(true, 0);
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
ConfigHandler.checkPlayers(connection);
|
||||
ConfigHandler.loadWorlds(statement); // Load world ID's into memory.
|
||||
ConfigHandler.loadTypes(statement); // Load material ID's into memory.
|
||||
|
||||
// Initialize WorldEdit logging
|
||||
if (Util.checkWorldEdit()) {
|
||||
PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||
Plugin worldEditPlugin = pluginManager.getPlugin("WorldEdit");
|
||||
if (worldEditPlugin != null && worldEditPlugin.isEnabled()) {
|
||||
Util.loadWorldEdit();
|
||||
}
|
||||
}
|
||||
else if (ConfigHandler.worldeditEnabled) {
|
||||
Util.unloadWorldEdit();
|
||||
}
|
||||
|
||||
ConfigHandler.serverRunning = true; // Set as running before patching
|
||||
boolean validVersion = Patch.versionCheck(statement); // Minor upgrades & version check
|
||||
boolean databaseLock = true;
|
||||
if (startup) {
|
||||
// Check that database isn't already in use
|
||||
databaseLock = ConfigHandler.checkDatabaseLock(statement);
|
||||
}
|
||||
|
||||
statement.close();
|
||||
connection.close();
|
||||
|
||||
return validVersion && databaseLock;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue