This commit is contained in:
Intelli committed 2026-10-18 12:29:19 -06:00
1 parent 38b6d87220
commit 2d484dffff
1 file changed
+83 -69
@@ -65,11 +65,21 @@ import net.coreprotect.utility.VersionUtils;
public class ConfigHandler extends Queue { public class ConfigHandler extends Queue {
public enum CacheType { public enum CacheType {
MATERIALS(ReferenceKind.MATERIAL), MATERIALS(
BLOCKDATA(ReferenceKind.BLOCK_DATA), ReferenceKind.MATERIAL
ART(ReferenceKind.ART), ),
ENTITIES(ReferenceKind.ENTITY), BLOCKDATA(
WORLDS(ReferenceKind.WORLD); ReferenceKind.BLOCK_DATA
),
ART(
ReferenceKind.ART
),
ENTITIES(
ReferenceKind.ENTITY
),
WORLDS(
ReferenceKind.WORLD
);
private final ReferenceKind kind; private final ReferenceKind kind;
@@ -145,13 +155,11 @@ public class ConfigHandler extends Queue {
return Collections.synchronizedMap(new HashMap<>(values)); return Collections.synchronizedMap(new HashMap<>(values));
} }
private static IdentifierCache loadIdentifierCache(Statement statement, String table, String valueColumn) private static IdentifierCache loadIdentifierCache(Statement statement, String table, String valueColumn) throws SQLException {
throws SQLException {
Map<String, Integer> values = new HashMap<>(); Map<String, Integer> values = new HashMap<>();
Map<Integer, String> reversed = new HashMap<>(); Map<Integer, String> reversed = new HashMap<>();
int maximumId = 0; int maximumId = 0;
try (ResultSet resultSet = statement try (ResultSet resultSet = statement.executeQuery("SELECT id," + valueColumn + " FROM " + ConfigHandler.prefix + table)) {
.executeQuery("SELECT id," + valueColumn + " FROM " + ConfigHandler.prefix + table)) {
while (resultSet.next()) { while (resultSet.next()) {
int id = resultSet.getInt("id"); int id = resultSet.getInt("id");
String value = resultSet.getString(valueColumn); String value = resultSet.getString(valueColumn);
@@ -183,8 +191,7 @@ public class ConfigHandler extends Queue {
private final IntSupplier maximum; private final IntSupplier maximum;
private final IntConsumer maximumSetter; private final IntConsumer maximumSetter;
private IdentifierStore(ReferenceKind kind, Supplier<Map<String, Integer>> values, Supplier<Map<Integer, String>> reversed, IntSupplier maximum, private IdentifierStore(ReferenceKind kind, Supplier<Map<String, Integer>> values, Supplier<Map<Integer, String>> reversed, IntSupplier maximum, IntConsumer maximumSetter) {
IntConsumer maximumSetter) {
this.kind = kind; this.kind = kind;
this.values = values; this.values = values;
this.reversed = reversed; this.reversed = reversed;
@@ -213,8 +220,7 @@ public class ConfigHandler extends Queue {
Integer storedId = names.get(value); Integer storedId = names.get(value);
String storedValue = identifiers.get(id); String storedValue = identifiers.get(id);
if ((storedId != null && storedId != id) || (storedValue != null && !storedValue.equals(value))) { if ((storedId != null && storedId != id) || (storedValue != null && !storedValue.equals(value))) {
throw new IllegalStateException("CoreProtect " + kind.name().toLowerCase(Locale.ROOT) + " identifier " + id + "='" + value throw new IllegalStateException("CoreProtect " + kind.name().toLowerCase(Locale.ROOT) + " identifier " + id + "='" + value + "' conflicts with cached " + storedId + "='" + storedValue + "'");
+ "' conflicts with cached " + storedId + "='" + storedValue + "'");
} }
return true; return true;
} }
@@ -301,7 +307,8 @@ public class ConfigHandler extends Queue {
if (!batch.commit()) { if (!batch.commit()) {
throw new IllegalStateException("Unable to initialize ClickHouse player records"); throw new IllegalStateException("Unable to initialize ClickHouse player records");
} }
} catch (Exception exception) { }
catch (Exception exception) {
throw new IllegalStateException("Unable to initialize ClickHouse player records", exception); throw new IllegalStateException("Unable to initialize ClickHouse player records", exception);
} }
return; return;
@@ -335,8 +342,7 @@ public class ConfigHandler extends Queue {
} }
public static boolean isBlacklisted(String user, String object) { public static boolean isBlacklisted(String user, String object) {
if (ConfigHandler.blacklist.containsKey(object) if (ConfigHandler.blacklist.containsKey(object) || ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT))) {
|| ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT))) {
return true; return true;
} }
return isFilterBlacklisted(user, object); return isFilterBlacklisted(user, object);
@@ -372,13 +378,14 @@ public class ConfigHandler extends Queue {
String[] blSplit = blLine.split(BLACKLIST_FILTER_SEPARATOR); String[] blSplit = blLine.split(BLACKLIST_FILTER_SEPARATOR);
if (blSplit.length == 1) { if (blSplit.length == 1) {
ConfigHandler.blacklist.put(blLine, true); ConfigHandler.blacklist.put(blLine, true);
} else { }
ConfigHandler.FilteredBlacklist.computeIfAbsent(blSplit[0], k -> new HashSet<>()) else {
.add(blSplit[1]); ConfigHandler.FilteredBlacklist.computeIfAbsent(blSplit[0], k -> new HashSet<>()).add(blSplit[1]);
} }
} }
} }
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
} }
} }
@@ -387,8 +394,7 @@ public class ConfigHandler extends Queue {
File configFolder = new File(ConfigHandler.path); File configFolder = new File(ConfigHandler.path);
File configFile = new File(configFolder, ConfigFile.CONFIG); File configFile = new File(configFolder, ConfigFile.CONFIG);
File[] existingFiles = configFolder.listFiles(); File[] existingFiles = configFolder.listFiles();
duckDBFallbackAllowed = !configFile.exists() duckDBFallbackAllowed = !configFile.exists() && (!configFolder.exists() || (existingFiles != null && existingFiles.length == 0));
&& (!configFolder.exists() || (existingFiles != null && existingFiles.length == 0));
Config.init(); Config.init();
ConfigFile.init(ConfigFile.LANGUAGE); // load user phrases ConfigFile.init(ConfigFile.LANGUAGE); // load user phrases
@@ -400,7 +406,8 @@ public class ConfigHandler extends Queue {
if (global.hasOption("use-mysql") && global.MYSQL != ConfigHandler.databaseType.isMySQL()) { if (global.hasOption("use-mysql") && global.MYSQL != ConfigHandler.databaseType.isMySQL()) {
Chat.sendConsoleMessage(Color.YELLOW + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_TYPE_OVERRIDE)); Chat.sendConsoleMessage(Color.YELLOW + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_TYPE_OVERRIDE));
} }
} else { }
else {
ConfigHandler.databaseType = global.MYSQL ? DatabaseType.MYSQL : DatabaseType.SQLITE; ConfigHandler.databaseType = global.MYSQL ? DatabaseType.MYSQL : DatabaseType.SQLITE;
} }
global.MYSQL = ConfigHandler.databaseType.isMySQL(); global.MYSQL = ConfigHandler.databaseType.isMySQL();
@@ -449,15 +456,16 @@ public class ConfigHandler extends Queue {
try { try {
if (preparedClickHouse != null) { if (preparedClickHouse != null) {
Database.installClickHouseDatabase(preparedClickHouse); Database.installClickHouseDatabase(preparedClickHouse);
} else { }
else {
initializeDatabase(); initializeDatabase();
} }
if (!migrationActivation && Database.hasIncompleteMigrationMarker()) { if (!migrationActivation && Database.hasIncompleteMigrationMarker()) {
throw new IllegalStateException( throw new IllegalStateException("Database contains an incomplete CoreProtect migration and cannot be activated");
"Database contains an incomplete CoreProtect migration and cannot be activated");
} }
ConfigHandler.databaseReachable = true; ConfigHandler.databaseReachable = true;
} catch (Exception exception) { }
catch (Exception exception) {
Database.closeConnection(); Database.closeConnection();
ConfigHandler.databaseReachable = false; ConfigHandler.databaseReachable = false;
if (exception instanceof RuntimeException) { if (exception instanceof RuntimeException) {
@@ -471,11 +479,10 @@ public class ConfigHandler extends Queue {
if (ConfigHandler.databaseType.isClickHouse()) { if (ConfigHandler.databaseType.isClickHouse()) {
try { try {
Config global = Config.getGlobal(); Config global = Config.getGlobal();
ClickHouseJdbcConfig config = new ClickHouseJdbcConfig(global.CLICKHOUSE_HOST, global.CLICKHOUSE_PORT, ClickHouseJdbcConfig config = new ClickHouseJdbcConfig(global.CLICKHOUSE_HOST, global.CLICKHOUSE_PORT, global.CLICKHOUSE_DATABASE, global.CLICKHOUSE_USERNAME, global.CLICKHOUSE_PASSWORD, global.CLICKHOUSE_TLS);
global.CLICKHOUSE_DATABASE, global.CLICKHOUSE_USERNAME, global.CLICKHOUSE_PASSWORD,
global.CLICKHOUSE_TLS);
Database.initializeClickHouse(config, ConfigHandler.prefix); Database.initializeClickHouse(config, ConfigHandler.prefix);
} catch (Exception exception) { }
catch (Exception exception) {
throw new IllegalStateException("Failed to initialize ClickHouse", exception); throw new IllegalStateException("Failed to initialize ClickHouse", exception);
} }
return; return;
@@ -489,7 +496,8 @@ public class ConfigHandler extends Queue {
boolean canExecute = false; boolean canExecute = false;
try { try {
canExecute = tempFile.canExecute(); canExecute = tempFile.canExecute();
} catch (Exception exception) { }
catch (Exception exception) {
// execute access denied by security manager // execute access denied by security manager
} }
@@ -507,39 +515,40 @@ public class ConfigHandler extends Queue {
if (ConfigHandler.databaseType.isDuckDB() && duckDBFallbackAllowed) { if (ConfigHandler.databaseType.isDuckDB() && duckDBFallbackAllowed) {
try { try {
DuckDBNativeSupport.verifyAvailable(); DuckDBNativeSupport.verifyAvailable();
} catch (Throwable failure) { }
catch (Throwable failure) {
if (!DuckDBNativeSupport.isNativeUnavailable(failure)) { if (!DuckDBNativeSupport.isNativeUnavailable(failure)) {
throw new IllegalStateException("Unable to verify DuckDB on this system. For native-library extraction or loading errors, check free space and permissions in the JVM temporary directory. " throw new IllegalStateException("Unable to verify DuckDB on this system. For native-library extraction or loading errors, check free space and permissions in the JVM temporary directory. " + "To select another directory, add -Djava.io.tmpdir=/absolute/path/to/cache before -jar and fully restart the server. " + "The directory must already exist, have sufficient space, and permit writing and native-library loading.", failure);
+ "To select another directory, add -Djava.io.tmpdir=/absolute/path/to/cache before -jar and fully restart the server. "
+ "The directory must already exist, have sufficient space, and permit writing and native-library loading.", failure);
} }
DatabaseConfigWriter.persistDatabaseType(DatabaseType.SQLITE); DatabaseConfigWriter.persistDatabaseType(DatabaseType.SQLITE);
ConfigHandler.databaseType = DatabaseType.SQLITE; ConfigHandler.databaseType = DatabaseType.SQLITE;
Config global = Config.getGlobal(); Config global = Config.getGlobal();
global.DATABASE_TYPE = DatabaseType.SQLITE.name().toLowerCase(Locale.ROOT); global.DATABASE_TYPE = DatabaseType.SQLITE.name().toLowerCase(Locale.ROOT);
global.MYSQL = false; global.MYSQL = false;
Chat.sendConsoleMessage(Color.YELLOW + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_FALLBACK, Chat.sendConsoleMessage(Color.YELLOW + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_FALLBACK, DatabaseType.DUCKDB.getDisplayName(), DatabaseType.SQLITE.getDisplayName()));
DatabaseType.DUCKDB.getDisplayName(), DatabaseType.SQLITE.getDisplayName())); }
} finally { finally {
duckDBFallbackAllowed = false; duckDBFallbackAllowed = false;
} }
} }
Class.forName(ConfigHandler.databaseType.isDuckDB() ? "org.duckdb.DuckDBDriver" : "org.sqlite.JDBC"); Class.forName(ConfigHandler.databaseType.isDuckDB() ? "org.duckdb.DuckDBDriver" : "org.sqlite.JDBC");
} catch (Exception e) { }
catch (Exception e) {
throw new IllegalStateException("Failed to initialize " + ConfigHandler.databaseType.getDisplayName(), e); throw new IllegalStateException("Failed to initialize " + ConfigHandler.databaseType.getDisplayName(), e);
} }
} else { }
else {
HikariConfig config = new HikariConfig(); HikariConfig config = new HikariConfig();
try { try {
Class.forName("com.mysql.cj.jdbc.Driver"); Class.forName("com.mysql.cj.jdbc.Driver");
config.setDriverClassName("com.mysql.cj.jdbc.Driver"); config.setDriverClassName("com.mysql.cj.jdbc.Driver");
} catch (Exception e) { }
catch (Exception e) {
config.setDriverClassName("com.mysql.jdbc.Driver"); config.setDriverClassName("com.mysql.jdbc.Driver");
} }
config.setJdbcUrl( config.setJdbcUrl("jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
"jdbc:mysql://" + ConfigHandler.host + ":" + ConfigHandler.port + "/" + ConfigHandler.database);
config.setUsername(ConfigHandler.username); config.setUsername(ConfigHandler.username);
config.setPassword(ConfigHandler.password); config.setPassword(ConfigHandler.password);
config.setMaximumPoolSize(ConfigHandler.maximumPoolSize); config.setMaximumPoolSize(ConfigHandler.maximumPoolSize);
@@ -579,7 +588,8 @@ public class ConfigHandler extends Queue {
ConfigHandler.materialsReversed = syncMap(cache.reversed); ConfigHandler.materialsReversed = syncMap(cache.reversed);
materialId = cache.maximumId; materialId = cache.maximumId;
return true; return true;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -592,7 +602,8 @@ public class ConfigHandler extends Queue {
ConfigHandler.blockdataReversed = syncMap(cache.reversed); ConfigHandler.blockdataReversed = syncMap(cache.reversed);
blockdataId = cache.maximumId; blockdataId = cache.maximumId;
return true; return true;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -605,7 +616,8 @@ public class ConfigHandler extends Queue {
ConfigHandler.artReversed = syncMap(cache.reversed); ConfigHandler.artReversed = syncMap(cache.reversed);
artId = cache.maximumId; artId = cache.maximumId;
return true; return true;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -618,7 +630,8 @@ public class ConfigHandler extends Queue {
ConfigHandler.entitiesReversed = syncMap(cache.reversed); ConfigHandler.entitiesReversed = syncMap(cache.reversed);
entityId = cache.maximumId; entityId = cache.maximumId;
return true; return true;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -643,9 +656,9 @@ public class ConfigHandler extends Queue {
* Reloads an identifier cache when multi-server cache refresh is permitted. * Reloads an identifier cache when multi-server cache refresh is permitted.
* *
* @param type * @param type
* The type of cache to reload * The type of cache to reload
* @param name * @param name
* The name to look up after reload * The name to look up after reload
* @return The ID if found after reload, or -1 if not found * @return The ID if found after reload, or -1 if not found
*/ */
public static synchronized int reloadAndGetId(CacheType type, String name) { public static synchronized int reloadAndGetId(CacheType type, String name) {
@@ -812,7 +825,8 @@ public class ConfigHandler extends Queue {
return false; return false;
} }
} }
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -879,11 +893,7 @@ public class ConfigHandler extends Queue {
locked = false; locked = false;
unixtimestamp = (int) (System.currentTimeMillis() / 1000L); unixtimestamp = (int) (System.currentTimeMillis() / 1000L);
int checkTime = unixtimestamp - 15; int checkTime = unixtimestamp - 15;
String query = "SELECT * FROM " + ConfigHandler.prefix String query = "SELECT * FROM " + ConfigHandler.prefix + "database_lock WHERE rowid='1' AND (status='" + Database.DATABASE_LOCK_MIGRATION_INCOMPLETE + "' OR (status='" + Database.DATABASE_LOCK_ACTIVE + "' AND time >= '" + checkTime + "')) LIMIT 1";
+ "database_lock WHERE rowid='1' AND (status='"
+ Database.DATABASE_LOCK_MIGRATION_INCOMPLETE
+ "' OR (status='" + Database.DATABASE_LOCK_ACTIVE + "' AND time >= '" + checkTime
+ "')) LIMIT 1";
ResultSet rs = statement.executeQuery(query); ResultSet rs = statement.executeQuery(query);
while (rs.next()) { while (rs.next()) {
if (unixtimestamp < waitTime) { if (unixtimestamp < waitTime) {
@@ -892,13 +902,11 @@ public class ConfigHandler extends Queue {
lockMessage = true; lockMessage = true;
} }
Thread.sleep(1000); Thread.sleep(1000);
} else { }
Chat.sendConsoleMessage( else {
Color.RED + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_2)); Chat.sendConsoleMessage(Color.RED + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_2));
Chat.sendConsoleMessage( Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_3));
Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_3)); Chat.sendConsoleMessage(Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_4));
Chat.sendConsoleMessage(
Color.GREY + "[CoreProtect] " + Phrase.build(Phrase.DATABASE_LOCKED_4));
return false; return false;
} }
@@ -907,7 +915,8 @@ public class ConfigHandler extends Queue {
rs.close(); rs.close();
} }
} }
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
} }
@@ -927,9 +936,11 @@ public class ConfigHandler extends Queue {
if (startup) { if (startup) {
ListenerHandler.registerNetworking(); // Register channels for networking API ListenerHandler.registerNetworking(); // Register channels for networking API
} }
} catch (CancellationException e) { }
catch (CancellationException e) {
throw e; throw e;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
return false; return false;
} }
@@ -951,7 +962,8 @@ public class ConfigHandler extends Queue {
if (worldEditPlugin != null && worldEditPlugin.isEnabled()) { if (worldEditPlugin != null && worldEditPlugin.isEnabled()) {
VersionUtils.loadWorldEdit(); VersionUtils.loadWorldEdit();
} }
} else if (ConfigHandler.worldeditEnabled) { }
else if (ConfigHandler.worldeditEnabled) {
VersionUtils.unloadWorldEdit(); VersionUtils.unloadWorldEdit();
} }
@@ -968,7 +980,8 @@ public class ConfigHandler extends Queue {
statement.close(); statement.close();
return validVersion && databaseLock; return validVersion && databaseLock;
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
} }
@@ -979,7 +992,8 @@ public class ConfigHandler extends Queue {
try { try {
Database.closeConnection(); Database.closeConnection();
ListenerHandler.unregisterNetworking(); // Unregister channels for networking API ListenerHandler.unregisterNetworking(); // Unregister channels for networking API
} catch (Exception e) { }
catch (Exception e) {
ErrorReporter.report(e); ErrorReporter.report(e);
} }
} }