diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 29ef672..f2488b7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,7 +4,7 @@ stages:
variables:
name: "UltimateStacker"
path: "/builds/$CI_PROJECT_PATH"
- version: "1.8.7"
+ version: "1.8.8"
build:
stage: build
diff --git a/pom.xml b/pom.xml
index 87a51ac..413c0ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,9 @@
com.songoda:songodaupdater
com.songoda:Lootables
+ com.zaxxer:HikariCP
+ org.slf4j:slf4j-api
+ org.slf4j:slf4j-nop
@@ -57,6 +60,10 @@
private
http://repo.songoda.com/artifactory/private/
+
+ CodeMC
+ https://repo.codemc.org/repository/maven-public
+
@@ -109,5 +116,15 @@
Clearlag
3.0.6
+
+ com.zaxxer
+ HikariCP
+ 3.2.0
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.23.1
+
diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java
index 0764209..efbe0ba 100644
--- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java
+++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java
@@ -1,6 +1,7 @@
package com.songoda.ultimatestacker;
import com.songoda.ultimatestacker.command.CommandManager;
+import com.songoda.ultimatestacker.database.*;
import com.songoda.ultimatestacker.entity.EntityStack;
import com.songoda.ultimatestacker.entity.EntityStackManager;
import com.songoda.ultimatestacker.hologram.Hologram;
@@ -13,7 +14,6 @@ import com.songoda.ultimatestacker.spawner.SpawnerStack;
import com.songoda.ultimatestacker.spawner.SpawnerStackManager;
import com.songoda.ultimatestacker.storage.Storage;
import com.songoda.ultimatestacker.storage.StorageRow;
-import com.songoda.ultimatestacker.storage.types.StorageMysql;
import com.songoda.ultimatestacker.storage.types.StorageYaml;
import com.songoda.ultimatestacker.tasks.StackingTask;
import com.songoda.ultimatestacker.utils.*;
@@ -33,6 +33,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -53,22 +54,22 @@ public class UltimateStacker extends JavaPlugin {
private StackingTask stackingTask;
private Hologram hologram;
+ private DatabaseConnector databaseConnector;
+ private DataMigrationManager dataMigrationManager;
+ private DataManager dataManager;
+
private EntityUtils entityUtils;
private List stackerHooks = new ArrayList<>();
private ServerVersion serverVersion = ServerVersion.fromPackageName(Bukkit.getServer().getClass().getPackage().getName());
- private Storage storage;
public static UltimateStacker getInstance() {
return INSTANCE;
}
public void onDisable() {
- this.saveToFile();
- this.storage.closeConnection();
- if (hologram != null)
- this.hologram.unloadHolograms();
+ this.dataManager.bulkUpdateSpawners(this.spawnerStackManager.getStacks());
ConsoleCommandSender console = Bukkit.getConsoleSender();
console.sendMessage(Methods.formatText("&a============================="));
@@ -137,31 +138,6 @@ public class UltimateStacker extends JavaPlugin {
this.entityStackManager = new EntityStackManager();
this.stackingTask = new StackingTask(this);
- checkStorage();
-
- Bukkit.getScheduler().runTaskLater(this, () -> {
- if (storage.containsGroup("spawners")) {
- for (StorageRow row : storage.getRowsByGroup("spawners")) {
- try {
- Location location = Methods.unserializeLocation(row.getKey());
-
- SpawnerStack stack = new SpawnerStack(
- location,
- row.get("amount").asInt());
-
- this.spawnerStackManager.addSpawner(stack);
- } catch (Exception e) {
- console.sendMessage("Failed to load spawner.");
- e.printStackTrace();
- }
- }
- }
-
- // Save data initially so that if the person reloads again fast they don't lose all their data.
- this.saveToFile();
- if (hologram != null)
- hologram.loadHolograms();
- }, 10);
PluginManager pluginManager = Bukkit.getPluginManager();
if (isServerVersionAtLeast(ServerVersion.V1_10))
pluginManager.registerEvents(new BreedListeners(this), this);
@@ -189,11 +165,68 @@ public class UltimateStacker extends JavaPlugin {
stackerHooks.add(new JobsHook());
}
- Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveToFile, 6000, 6000);
-
// Starting Metrics
new Metrics(this);
+ // Legacy Data
+ Bukkit.getScheduler().runTaskLater(this, () -> {
+ File folder = getDataFolder();
+ File dataFile = new File(folder, "data.yml");
+
+ if (dataFile.exists()) {
+ Storage storage = new StorageYaml(this);
+ if (storage.containsGroup("spawners")) {
+ for (StorageRow row : storage.getRowsByGroup("spawners")) {
+ try {
+ Location location = Methods.unserializeLocation(row.getKey());
+
+ SpawnerStack stack = new SpawnerStack(
+ location,
+ row.get("amount").asInt());
+
+ getDataManager().createSpawner(stack);
+ } catch (Exception e) {
+ console.sendMessage("Failed to load spawner.");
+ e.printStackTrace();
+ }
+ }
+ }
+ dataFile.delete();
+ }
+ }, 10);
+
+ // Database stuff, go!
+ try {
+ if (Setting.MYSQL_ENABLED.getBoolean()) {
+ String hostname = Setting.MYSQL_HOSTNAME.getString();
+ int port = Setting.MYSQL_PORT.getInt();
+ String database = Setting.MYSQL_DATABASE.getString();
+ String username = Setting.MYSQL_USERNAME.getString();
+ String password = Setting.MYSQL_PASSWORD.getString();
+ boolean useSSL = Setting.MYSQL_USE_SSL.getBoolean();
+
+ this.databaseConnector = new MySQLConnector(this, hostname, port, database, username, password, useSSL);
+ this.getLogger().info("Data handler connected using MySQL.");
+ } else {
+ this.databaseConnector = new SQLiteConnector(this);
+ this.getLogger().info("Data handler connected using SQLite.");
+ }
+ } catch (Exception ex) {
+ this.getLogger().severe("Fatal error trying to connect to database. Please make sure all your connection settings are correct and try again. Plugin has been disabled.");
+ Bukkit.getPluginManager().disablePlugin(this);
+ }
+
+ this.dataManager = new DataManager(this.databaseConnector, this);
+ this.dataMigrationManager = new DataMigrationManager(this.databaseConnector, this.dataManager);
+ this.dataMigrationManager.runMigrations();
+
+ Bukkit.getScheduler().runTaskLater(this, () -> {
+ this.dataManager.getSpawners((spawners) -> {
+ this.spawnerStackManager.addSpawners(spawners);
+ this.hologram.loadHolograms();
+ });
+ }, 20L);
+
console.sendMessage(Methods.formatText("&a============================="));
}
@@ -203,21 +236,6 @@ public class UltimateStacker extends JavaPlugin {
}
}
- private void checkStorage() {
- if (getConfig().getBoolean("Database.Activate Mysql Support")) {
- this.storage = new StorageMysql(this);
- } else {
- this.storage = new StorageYaml(this);
- }
- }
-
- private void saveToFile() {
- this.storage.closeConnection();
- checkStorage();
-
- storage.doSave();
- }
-
public void reload() {
this.locale = Locale.getLocale(getConfig().getString("System.Language Mode"));
this.locale.reloadMessages();
@@ -301,4 +319,12 @@ public class UltimateStacker extends JavaPlugin {
public EntityUtils getEntityUtils() {
return entityUtils;
}
+
+ public DatabaseConnector getDatabaseConnector() {
+ return databaseConnector;
+ }
+
+ public DataManager getDataManager() {
+ return dataManager;
+ }
}
diff --git a/src/main/java/com/songoda/ultimatestacker/database/DataManager.java b/src/main/java/com/songoda/ultimatestacker/database/DataManager.java
new file mode 100644
index 0000000..8f272af
--- /dev/null
+++ b/src/main/java/com/songoda/ultimatestacker/database/DataManager.java
@@ -0,0 +1,149 @@
+package com.songoda.ultimatestacker.database;
+
+import com.songoda.ultimatestacker.spawner.SpawnerStack;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.plugin.Plugin;
+
+import java.sql.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+public class DataManager {
+
+ private final DatabaseConnector databaseConnector;
+ private final Plugin plugin;
+
+ public DataManager(DatabaseConnector databaseConnector, Plugin plugin) {
+ this.databaseConnector = databaseConnector;
+ this.plugin = plugin;
+ }
+
+ /**
+ * @return the prefix to be used by all table names
+ */
+ public String getTablePrefix() {
+ return this.plugin.getDescription().getName().toLowerCase() + '_';
+ }
+
+ public void bulkUpdateSpawners(Collection spawnerStacks) {
+ this.databaseConnector.connect(connection -> {
+ String updateSpawner = "UPDATE " + this.getTablePrefix() + "spawners SET amount = ? WHERE world = ? AND x = ? AND y = ? and z = ?";
+ try (PreparedStatement statement = connection.prepareStatement(updateSpawner)) {
+ for (SpawnerStack spawnerStack : spawnerStacks) {
+ statement.setInt(1, spawnerStack.getAmount());
+
+ statement.setString(5, spawnerStack.getWorld().getName());
+ statement.setInt(6, spawnerStack.getX());
+ statement.setInt(7, spawnerStack.getY());
+ statement.setInt(8, spawnerStack.getZ());
+ statement.executeUpdate();
+ statement.addBatch();
+ }
+
+ statement.executeBatch();
+ }
+ });
+ }
+
+
+ public void updateSpawner(SpawnerStack spawnerStack) {
+ this.async(() -> this.databaseConnector.connect(connection -> {
+ String updateSpawner = "UPDATE " + this.getTablePrefix() + "spawners SET amount = ? WHERE world = ? AND x = ? AND y = ? and z = ?";
+ try (PreparedStatement statement = connection.prepareStatement(updateSpawner)) {
+ statement.setInt(1, spawnerStack.getAmount());
+
+ statement.setString(2, spawnerStack.getWorld().getName());
+ statement.setInt(3, spawnerStack.getX());
+ statement.setInt(4, spawnerStack.getY());
+ statement.setInt(5, spawnerStack.getZ());
+ statement.executeUpdate();
+ }
+ }));
+ }
+
+
+ public void createSpawner(SpawnerStack spawnerStack) {
+ this.async(() -> this.databaseConnector.connect(connection -> {
+ String createSpawner = "INSERT INTO " + this.getTablePrefix() + "spawners (amount, world, x, y, z) VALUES (?, ?, ?, ? , ?)";
+ try (PreparedStatement statement = connection.prepareStatement(createSpawner)) {
+ statement.setInt(1, spawnerStack.getAmount());
+
+ statement.setString(2, spawnerStack.getWorld().getName());
+ statement.setInt(3, spawnerStack.getX());
+ statement.setInt(4, spawnerStack.getY());
+ statement.setInt(5, spawnerStack.getZ());
+ statement.executeUpdate();
+ }
+ }));
+ }
+
+ public void deleteSpawner(SpawnerStack spawnerStack) {
+ this.async(() -> this.databaseConnector.connect(connection -> {
+ String deleteSpawner = "DELETE FROM " + this.getTablePrefix() + "spawners WHERE world = ? AND x = ? AND y = ? and z = ?";
+ try (PreparedStatement statement = connection.prepareStatement(deleteSpawner)) {
+ statement.setString(1, spawnerStack.getWorld().getName());
+ statement.setInt(2, spawnerStack.getX());
+ statement.setInt(3, spawnerStack.getY());
+ statement.setInt(4, spawnerStack.getZ());
+ statement.executeUpdate();
+ }
+ }));
+ }
+
+ public void getSpawners(Consumer