🆙 Make Emulator Full MariaDB

- Swap mysql-connector-j → mariadb-java-client in pom.xml
- Changed JDBC URL to jdbc:mariadb://
Add all the HikariCP properties above (configurable via config.ini with sensible defaults)
- Fix the double-close in Database.dispose()
This commit is contained in:
duckietm
2026-04-07 11:00:04 +02:00
parent 0634c3d600
commit 75b73df8dc
3 changed files with 74 additions and 30 deletions
+5 -5
View File
@@ -6,7 +6,7 @@
<groupId>com.eu.habbo</groupId>
<artifactId>Habbo</artifactId>
<version>4.1.0</version>
<version>4.0.5</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -86,11 +86,11 @@
<version>2.11.0</version>
</dependency>
<!-- MySQL Connector -->
<!-- MariaDB Connector/J (native driver for MariaDB) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.5.1</version>
<scope>runtime</scope>
</dependency>
@@ -48,11 +48,11 @@ public class Database {
}
public void dispose() {
if (this.databasePool != null) {
this.databasePool.getDatabase().close();
// dataSource is the same instance returned by databasePool.getDatabase(),
// so close it exactly once.
if (this.dataSource != null && !this.dataSource.isClosed()) {
this.dataSource.close();
}
this.dataSource.close();
}
public HikariDataSource getDataSource() {
@@ -8,41 +8,85 @@ import org.slf4j.LoggerFactory;
class DatabasePool {
private final Logger log = LoggerFactory.getLogger(DatabasePool.class);
// Connection settings
private static final String DB_HOSTNAME_KEY = "db.hostname";
private static final String DB_PORT_KEY = "db.port";
private static final String DB_PASSWORD_KEY = "db.password";
private static final String DB_NAME_KEY = "db.database";
private static final String DB_USER_KEY = "db.username";
private static final String DB_PARAMS_KEY = "db.params";
// Pool sizing
private static final String DB_POOL_MAX_SIZE = "db.pool.maxsize";
private static final String DB_POOL_MIN_SIZE = "db.pool.minsize";
private static final String DB_HOSTNAME_KEY = "db.hostname";
private static final String DB_PORT_KEY = "db.port";
private static final String DB_PASSWORD_KEY = "db.password";
private static final String DB_NAME_KEY = "db.database";
private static final String DB_USER_KEY = "db.username";
private static final String DB_PARAMS_KEY = "db.params";
// Pool tuning (all overridable via config.ini; sensible MariaDB defaults apply otherwise)
private static final String DB_POOL_CONNECTION_TIMEOUT = "db.pool.connection_timeout_ms";
private static final String DB_POOL_IDLE_TIMEOUT = "db.pool.idle_timeout_ms";
private static final String DB_POOL_MAX_LIFETIME = "db.pool.max_lifetime_ms";
private static final String DB_POOL_LEAK_THRESHOLD = "db.pool.leak_detection_ms";
private static final String DB_POOL_VALIDATION_TIMEOUT = "db.pool.validation_timeout_ms";
private HikariDataSource database;
private static DatabasePool instance;
DatabasePool() {
}
public static synchronized DatabasePool getInstance() {
if (instance == null) {
instance = new DatabasePool();
}
return instance;
}
public boolean getStoragePooling(ConfigurationManager config) {
try {
HikariConfig databaseConfiguration = new HikariConfig();
// Pool sizing
databaseConfiguration.setMaximumPoolSize(config.getInt(DB_POOL_MAX_SIZE, 50));
databaseConfiguration.setMinimumIdle(config.getInt(DB_POOL_MIN_SIZE, 10));
databaseConfiguration.setJdbcUrl("jdbc:mysql://" + config.getValue(DB_HOSTNAME_KEY, "localhost") + ":" + config.getValue(DB_PORT_KEY, "3306") + "/" + config.getValue(DB_NAME_KEY) + config.getValue(DB_PARAMS_KEY));
databaseConfiguration.addDataSourceProperty("serverName", config.getValue(DB_HOSTNAME_KEY, "localhost"));
databaseConfiguration.addDataSourceProperty("port", config.getValue(DB_PORT_KEY, "3306"));
databaseConfiguration.addDataSourceProperty("databaseName", config.getValue(DB_NAME_KEY));
databaseConfiguration.addDataSourceProperty("user", config.getValue(DB_USER_KEY));
databaseConfiguration.addDataSourceProperty("password", config.getValue(DB_PASSWORD_KEY));
// Pool timeouts (milliseconds)
databaseConfiguration.setConnectionTimeout(config.getInt(DB_POOL_CONNECTION_TIMEOUT, 10_000));
databaseConfiguration.setIdleTimeout(config.getInt(DB_POOL_IDLE_TIMEOUT, 600_000));
databaseConfiguration.setMaxLifetime(config.getInt(DB_POOL_MAX_LIFETIME, 1_800_000));
databaseConfiguration.setValidationTimeout(config.getInt(DB_POOL_VALIDATION_TIMEOUT, 5_000));
// Leak detection: 0 disables it. Default 20s helps locate connections
// that weren't closed in a try-with-resources block.
int leakThreshold = config.getInt(DB_POOL_LEAK_THRESHOLD, 20_000);
if (leakThreshold > 0) {
databaseConfiguration.setLeakDetectionThreshold(leakThreshold);
}
// Use the MariaDB Connector/J native protocol instead of the Oracle MySQL driver.
databaseConfiguration.setJdbcUrl("jdbc:mariadb://"
+ config.getValue(DB_HOSTNAME_KEY, "localhost") + ":"
+ config.getValue(DB_PORT_KEY, "3306") + "/"
+ config.getValue(DB_NAME_KEY)
+ config.getValue(DB_PARAMS_KEY));
databaseConfiguration.setUsername(config.getValue(DB_USER_KEY));
databaseConfiguration.setPassword(config.getValue(DB_PASSWORD_KEY));
// Prepared-statement caching. Without these, Hikari's cache is off entirely
// and every prepareStatement() call re-parses on the server side.
databaseConfiguration.addDataSourceProperty("cachePrepStmts", "true");
databaseConfiguration.addDataSourceProperty("prepStmtCacheSize", "500");
databaseConfiguration.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
databaseConfiguration.addDataSourceProperty("useServerPrepStmts", "true");
// Bulk write throughput: rewrites batched INSERTs into a single multi-value
// INSERT statement. Huge win for item/room/inventory persistence paths.
databaseConfiguration.addDataSourceProperty("rewriteBatchedStatements", "true");
// Cut per-connection round-trips.
databaseConfiguration.addDataSourceProperty("cacheServerConfiguration", "true");
databaseConfiguration.addDataSourceProperty("useLocalSessionState", "true");
databaseConfiguration.addDataSourceProperty("cacheResultSetMetadata", "true");
databaseConfiguration.addDataSourceProperty("elideSetAutoCommits", "true");
databaseConfiguration.addDataSourceProperty("maintainTimeStats", "false");
databaseConfiguration.setPoolName("HabboHikariPool");
log.info("INITIALIZING DATABASE SERVER: " + config.getValue(DB_HOSTNAME_KEY));
log.info("ON PORT: " + config.getValue(DB_PORT_KEY));
log.info("HABBO DATABASE: " + config.getValue(DB_NAME_KEY));
log.info("USING DRIVER: MariaDB Connector/J");
this.database = new HikariDataSource(databaseConfiguration);
} catch (Exception e) {
@@ -58,4 +102,4 @@ class DatabasePool {
}
return database;
}
}
}