diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/RestoreCommand.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/RestoreCommand.java index d9f80d7..1c82e0d 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/RestoreCommand.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Command/RestoreCommand.java @@ -148,7 +148,7 @@ private void listBackups(final @NotNull CommandSender sender, final @NotNull Str return; } } - ArrayList backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups(); + List backups = ((Minepacks) getMinepacksPlugin()).getDatabase().getBackups(); int pages = backups.size() / elementsPerPage + 1; page = Math.min(page, pages - 1); int offset = page * elementsPerPage, end = Math.min(offset + elementsPerPage, backups.size()); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/DatabaseBackend.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/DatabaseBackend.java new file mode 100644 index 0000000..63a7bce --- /dev/null +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/DatabaseBackend.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 GeorgH93 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend; + +import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback; +import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.InventorySerializer; +import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import lombok.Getter; +import lombok.Setter; + +public abstract class DatabaseBackend +{ + protected static final String START_UUID_UPDATE = "Start updating database to UUIDs ...", UUIDS_UPDATED = "Updated %d accounts to UUIDs."; + + protected final Minepacks plugin; + protected final boolean onlineUUIDs; + @Setter protected boolean asyncSave = true; + protected boolean useUUIDSeparators; + @Getter protected final InventorySerializer itsSerializer; + protected long maxAge; + + protected DatabaseBackend(final @NotNull Minepacks plugin) + { + this.plugin = plugin; + useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators(); + onlineUUIDs = plugin.getConfiguration().useOnlineUUIDs(); + maxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays(); + itsSerializer = new InventorySerializer(plugin.getLogger()); + } + + public @NotNull String getPlayerFormattedUUID(final @NotNull OfflinePlayer player) + { + return (useUUIDSeparators) ? player.getUniqueId().toString() : player.getUniqueId().toString().replace("-", ""); + } + + public void close() {} + + //region DB Functions + public abstract void updatePlayer(final @NotNull Player player); + + public abstract void saveBackpack(final @NotNull Backpack backpack); + + public void syncCooldown(final @NotNull Player player, long time) {} + + public void getCooldown(final @NotNull Player player, final @NotNull Callback callback) {} + + public abstract void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback callback); + //endregion +} \ No newline at end of file diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Files.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/Files.java similarity index 85% rename from Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Files.java rename to Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/Files.java index 42536d4..9870938 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Files.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/Files.java @@ -15,10 +15,11 @@ * along with this program. If not, see . */ -package at.pcgamingfreaks.Minepacks.Bukkit.Database; +package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend; import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback; import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.InventorySerializer; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.UUIDConverter; @@ -33,17 +34,17 @@ import java.io.FileOutputStream; import java.util.logging.Logger; -public class Files extends Database +public class Files extends DatabaseBackend { public static final String EXT = ".backpack", EXT_REGEX = "\\.backpack", FOLDER_NAME = "backpacks"; private final File saveFolder; - public Files(Minepacks plugin) + public Files(final @NotNull Minepacks plugin) { super(plugin); maxAge *= 24 * 3600000L; - saveFolder = new File(this.plugin.getDataFolder(), FOLDER_NAME); + saveFolder = new File(plugin.getDataFolder(), FOLDER_NAME); if(!saveFolder.exists()) { if(!saveFolder.mkdirs()) @@ -58,9 +59,9 @@ public Files(Minepacks plugin) } @Override - public void updatePlayer(Player player) + public void updatePlayer(final @NotNull Player player) { - // Files are stored with the users name or the uuid, there is no reason to update anything + // Files are stored with the users uuid, there is no reason to update anything } private void checkFiles() @@ -118,7 +119,7 @@ private String getFileName(OfflinePlayer player) // DB Functions @Override - public void saveBackpack(Backpack backpack) + public void saveBackpack(@NotNull Backpack backpack) { File save = new File(saveFolder, getFileName(backpack.getOwner())); try(FileOutputStream fos = new FileOutputStream(save)) @@ -134,7 +135,7 @@ public void saveBackpack(Backpack backpack) } @Override - protected void loadBackpack(final OfflinePlayer player, final Callback callback) + public void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback callback) { //TODO this needs to be done async! File save = new File(saveFolder, getFileName(player)); ItemStack[] itemStacks = readFile(itsSerializer, save, plugin.getLogger()); @@ -148,7 +149,7 @@ protected void loadBackpack(final OfflinePlayer player, final Callback } } - protected static @Nullable ItemStack[] readFile(@NotNull InventorySerializer itsSerializer, @NotNull File file, @NotNull Logger logger) + public static @Nullable ItemStack[] readFile(final @NotNull InventorySerializer itsSerializer, final @NotNull File file, final @NotNull Logger logger) { if(file.exists()) { diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/MySQL.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/MySQL.java similarity index 97% rename from Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/MySQL.java rename to Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/MySQL.java index d408e90..f849343 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/MySQL.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/MySQL.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package at.pcgamingfreaks.Minepacks.Bukkit.Database; +package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend; import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; import at.pcgamingfreaks.Database.ConnectionProvider.MySQLConnectionProvider; diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQL.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQL.java similarity index 93% rename from Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQL.java rename to Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQL.java index 985127a..f9a3a96 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQL.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQL.java @@ -15,12 +15,13 @@ * along with this program. If not, see . */ -package at.pcgamingfreaks.Minepacks.Bukkit.Database; +package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend; import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; import at.pcgamingfreaks.Database.DBTools; import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback; import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.BackupHandler; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.UUIDConverter; import at.pcgamingfreaks.Utils; @@ -32,10 +33,12 @@ import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; +import lombok.AllArgsConstructor; + import java.sql.*; import java.util.*; -public abstract class SQL extends Database +public abstract class SQL extends DatabaseBackend { private final ConnectionProvider dataSource; @@ -104,23 +107,17 @@ protected void loadSettings() @Override public void close() { - super.close(); Utils.blockThread(1); // Give the database some time to perform async operations dataSource.close(); } protected void checkUUIDs() { + @AllArgsConstructor class UpdateData // Helper class for fixing UUIDs { - int id; String uuid; - - public UpdateData(String uuid, int id) - { - this.id = id; - this.uuid = uuid; - } + final int id; } try(Connection connection = getConnection()) { @@ -262,17 +259,17 @@ protected void runStatement(final String query, final Object... args) // Plugin Functions @Override - public void updatePlayer(final Player player) + public void updatePlayer(final @NotNull Player player) { runStatementAsync(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player), player.getName()); } @Override - public void saveBackpack(final Backpack backpack) + public void saveBackpack(final @NotNull Backpack backpack) { final byte[] data = itsSerializer.serialize(backpack.getInventory()); final int id = backpack.getOwnerID(), usedSerializer = itsSerializer.getUsedSerializer(); - final String nameOrUUID = getPlayerFormattedUUID(backpack.getOwner()), name = backpack.getOwner().getName(); + final String uuid = getPlayerFormattedUUID(backpack.getOwner()), name = backpack.getOwner().getName(); Runnable runnable = () -> { try(Connection connection = getConnection()) @@ -281,7 +278,7 @@ public void saveBackpack(final Backpack backpack) { try(PreparedStatement ps = connection.prepareStatement(queryGetPlayerID)) { - ps.setString(1, nameOrUUID); + ps.setString(1, uuid); try(ResultSet rs = ps.executeQuery()) { if(rs.next()) @@ -293,7 +290,7 @@ public void saveBackpack(final Backpack backpack) else { plugin.getLogger().warning("Failed saving backpack for: " + name + " (Unable to get players ID from database)"); - writeBackup(name, nameOrUUID, usedSerializer, data); + BackupHandler.getInstance().writeBackup(name, uuid, usedSerializer, data); } } } @@ -307,14 +304,14 @@ public void saveBackpack(final Backpack backpack) { plugin.getLogger().warning("Failed to save backpack in database! Error: " + e.getMessage()); e.printStackTrace(); - writeBackup(name, nameOrUUID, usedSerializer, data); + BackupHandler.getInstance().writeBackup(name, uuid, usedSerializer, data); } }; if(asyncSave) Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable); else runnable.run(); } @Override - protected void loadBackpack(final OfflinePlayer player, final Callback callback) + public void loadBackpack(final @NotNull OfflinePlayer player, final @NotNull Callback callback) { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { try(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetBP)) @@ -360,14 +357,14 @@ protected void loadBackpack(final OfflinePlayer player, final Callback } @Override - public void syncCooldown(Player player, long cooldownTime) + public void syncCooldown(final @NotNull Player player, final long cooldownTime) { Timestamp ts = new Timestamp(cooldownTime); runStatementAsync(querySyncCooldown, ts, getPlayerFormattedUUID(player), ts); } @Override - public void getCooldown(final Player player, final Callback callback) + public void getCooldown(final @NotNull Player player, final @NotNull Callback callback) { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { try(Connection conn = getConnection(); PreparedStatement ps = conn.prepareStatement(queryGetCooldown)) diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQLite.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQLite.java similarity index 97% rename from Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQLite.java rename to Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQLite.java index eb58e5a..6101ef3 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/SQLite.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Backend/SQLite.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package at.pcgamingfreaks.Minepacks.Bukkit.Database; +package at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend; import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; import at.pcgamingfreaks.Database.ConnectionProvider.SQLiteConnectionProvider; @@ -107,7 +107,7 @@ protected void checkDB() } @Override - public void updatePlayer(final Player player) + public void updatePlayer(final @NotNull Player player) { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { runStatement(queryUpdatePlayerAdd, player.getName(), getPlayerFormattedUUID(player)); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/BackupHandler.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/BackupHandler.java new file mode 100644 index 0000000..169a371 --- /dev/null +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/BackupHandler.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2020 GeorgH93 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package at.pcgamingfreaks.Minepacks.Bukkit.Database; + +import at.pcgamingfreaks.ConsoleColor; +import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files; +import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; + +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +public final class BackupHandler +{ + @Setter(AccessLevel.PRIVATE) @Getter private static BackupHandler instance; + + private final Logger logger; + private final InventorySerializer itsSerializer; + private final boolean useUUIDSeparators; + private final File backupFolder; + + public BackupHandler(final @NotNull Minepacks plugin) + { + logger = plugin.getLogger(); + itsSerializer = new InventorySerializer(logger); + useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators(); + + backupFolder = new File(plugin.getDataFolder(), "backups"); + if(!backupFolder.exists() && !backupFolder.mkdirs()) plugin.getLogger().info("Failed to create backups folder."); + + setInstance(this); + } + + public void backup(final @NotNull Backpack backpack) + { + final String formattedUUID = (useUUIDSeparators) ? backpack.getOwner().getUniqueId().toString() : backpack.getOwner().getUniqueId().toString().replace("-", ""); + writeBackup(backpack.getOwner().getName(), formattedUUID, itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory())); + } + + public @Nullable ItemStack[] loadBackup(final String backupName) + { + File backup = new File(backupFolder, backupName + Files.EXT); + return Files.readFile(itsSerializer, backup, logger); + } + + public void writeBackup(@Nullable String userName, @NotNull String userIdentifier, final int usedSerializer, final @NotNull byte[] data) + { + if(userIdentifier.equalsIgnoreCase(userName)) userName = null; + if(userName != null) userIdentifier = userName + "_" + userIdentifier; + final File save = new File(backupFolder, userIdentifier + "_" + System.currentTimeMillis() + Files.EXT); + try(FileOutputStream fos = new FileOutputStream(save)) + { + fos.write(usedSerializer); + fos.write(data); + logger.info("Backup of the backpack has been created: " + save.getAbsolutePath()); + } + catch(Exception e) + { + logger.warning(ConsoleColor.RED + "Failed to write backup! Error: " + e.getMessage() + ConsoleColor.RESET); + } + } + + public List getBackups() + { + File[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT)); + if(files != null) + { + ArrayList backups = new ArrayList<>(files.length); + for(File file : files) + { + if(!file.isFile()) continue; + backups.add(file.getName().replaceAll(Files.EXT_REGEX, "")); + } + return backups; + } + return new ArrayList<>(); + } +} \ No newline at end of file diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Config.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Config.java index 583d2b5..d077520 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Config.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Config.java @@ -82,11 +82,16 @@ public int getAutoCleanupMaxInactiveDays() return getConfigE().getInt("Database.AutoCleanup.MaxInactiveDays", -1); } - public String getDatabaseType() + public @NotNull String getDatabaseTypeName() { return getConfigE().getString("Database.Type", "sqlite"); } + public @NotNull DatabaseType getDatabaseType() + { + return DatabaseType.fromName(getDatabaseTypeName()); + } + public void setDatabaseType(String type) { getConfigE().set("Database.Type", type); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Database.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Database.java index d8106af..0c55b7f 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Database.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Database.java @@ -21,6 +21,10 @@ import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; import at.pcgamingfreaks.Minepacks.Bukkit.API.Callback; import at.pcgamingfreaks.Minepacks.Bukkit.Backpack; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.MySQL; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite; import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.OnDisconnect; import at.pcgamingfreaks.Minepacks.Bukkit.Database.UnCacheStrategies.UnCacheStrategie; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; @@ -35,90 +39,85 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.io.FileOutputStream; -import java.util.ArrayList; +import lombok.Getter; + import java.util.Collection; -import java.util.Locale; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; -public abstract class Database implements Listener +public final class Database implements Listener { - protected static final String START_UUID_UPDATE = "Start updating database to UUIDs ...", UUIDS_UPDATED = "Updated %d accounts to UUIDs."; public static final String MESSAGE_UNKNOWN_DB_TYPE = ConsoleColor.RED + "Unknown database type \"%s\"!" + ConsoleColor.RESET; protected final Minepacks plugin; - protected final InventorySerializer itsSerializer; - protected final boolean onlineUUIDs, bungeeCordMode; - protected boolean useUUIDSeparators, asyncSave = true; - protected long maxAge; + private final boolean bungeeCordMode; + private final BackupHandler backupHandler; + @Getter private final DatabaseBackend backend; private final Map backpacks = new ConcurrentHashMap<>(); private final UnCacheStrategie unCacheStrategie; - private final File backupFolder; - public Database(Minepacks mp) + public Database(final @NotNull Minepacks plugin) { - plugin = mp; - itsSerializer = new InventorySerializer(plugin.getLogger()); - useUUIDSeparators = plugin.getConfiguration().getUseUUIDSeparators(); - onlineUUIDs = plugin.getConfiguration().useOnlineUUIDs(); + this.plugin = plugin; bungeeCordMode = plugin.getConfiguration().isBungeeCordModeEnabled(); - maxAge = plugin.getConfiguration().getAutoCleanupMaxInactiveDays(); unCacheStrategie = bungeeCordMode ? new OnDisconnect(this) : UnCacheStrategie.getUnCacheStrategie(this); - backupFolder = new File(this.plugin.getDataFolder(), "backups"); - if(!backupFolder.exists() && !backupFolder.mkdirs()) mp.getLogger().info("Failed to create backups folder."); - } + backupHandler = new BackupHandler(plugin); + backend = getDatabaseBackend(plugin); + if(!available()) return; - public void init() - { plugin.getServer().getPluginManager().registerEvents(this, plugin); } public void close() { HandlerList.unregisterAll(this); - asyncSave = false; + backend.setAsyncSave(false); backpacks.forEach((key, value) -> value.closeAll()); backpacks.clear(); unCacheStrategie.close(); + backend.close(); } - public static @Nullable Database getDatabase(Minepacks plugin) + public boolean available() + { + return backend != null; + } + + public static @Nullable ConnectionProvider getGlobalConnectionProvider(final @NotNull Logger logger) + { + /*if[STANDALONE] + plugin.getLogger().warning(ConsoleColor.RED + "The shared database connection option is not available in standalone mode!" + ConsoleColor.RESET); + return null; + else[STANDALONE]*/ + at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool(); + if(pool == null) + { + logger.warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET); + return null; + } + return pool.getConnectionProvider(); + /*end[STANDALONE]*/ + } + + protected static @Nullable DatabaseBackend getDatabaseBackend(Minepacks plugin) { try { - String dbType = plugin.getConfiguration().getDatabaseType().toLowerCase(Locale.ROOT); - ConnectionProvider connectionProvider = null; - if(dbType.equals("shared") || dbType.equals("external") || dbType.equals("global")) - { - /*if[STANDALONE] - plugin.getLogger().warning(ConsoleColor.RED + "The shared database connection option is not available in standalone mode!" + ConsoleColor.RESET); - return null; - else[STANDALONE]*/ - at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool(); - if(pool == null) - { - plugin.getLogger().warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET); - return null; - } - dbType = pool.getDatabaseType().toLowerCase(Locale.ROOT); - connectionProvider = pool.getConnectionProvider(); - /*end[STANDALONE]*/ - } - Database database; + DatabaseType dbType = plugin.getConfiguration().getDatabaseType(); + ConnectionProvider connectionProvider = dbType == DatabaseType.SHARED ? getGlobalConnectionProvider(plugin.getLogger()) : null; + if(connectionProvider != null) dbType = DatabaseType.fromName(connectionProvider.getDatabaseType()); + DatabaseBackend databaseBackend; switch(dbType) { - case "mysql": database = new MySQL(plugin, connectionProvider); break; - case "sqlite": database = new SQLite(plugin, connectionProvider); break; - case "flat": - case "file": - case "files": - database = new Files(plugin); break; - default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseType())); return null; + case MYSQL: databaseBackend = new MySQL(plugin, connectionProvider); break; + case SQLITE: databaseBackend = new SQLite(plugin, connectionProvider); break; + case FILES: databaseBackend = new Files(plugin); break; + default: plugin.getLogger().warning(String.format(MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseTypeName())); return null; } - database.init(); - return database; + //databaseBackend.init(); + return databaseBackend; } catch(IllegalStateException ignored) {} catch(Exception e) @@ -130,51 +129,17 @@ public void close() public void backup(@NotNull Backpack backpack) { - writeBackup(backpack.getOwner().getName(), getPlayerFormattedUUID(backpack.getOwner()), itsSerializer.getUsedSerializer(), itsSerializer.serialize(backpack.getInventory())); - } - - protected void writeBackup(@Nullable String userName, @NotNull String userIdentifier, final int usedSerializer, final @NotNull byte[] data) - { - if(userIdentifier.equalsIgnoreCase(userName)) userName = null; - if(userName != null) userIdentifier = userName + "_" + userIdentifier; - final File save = new File(backupFolder, userIdentifier + "_" + System.currentTimeMillis() + Files.EXT); - try(FileOutputStream fos = new FileOutputStream(save)) - { - fos.write(usedSerializer); - fos.write(data); - plugin.getLogger().info("Backup of the backpack has been created: " + save.getAbsolutePath()); - } - catch(Exception e) - { - plugin.getLogger().warning(ConsoleColor.RED + "Failed to write backup! Error: " + e.getMessage() + ConsoleColor.RESET); - } + backupHandler.backup(backpack); } public @Nullable ItemStack[] loadBackup(final String backupName) { - File backup = new File(backupFolder, backupName + Files.EXT); - return Files.readFile(itsSerializer, backup, plugin.getLogger()); + return backupHandler.loadBackup(backupName); } - public ArrayList getBackups() + public List getBackups() { - File[] files = backupFolder.listFiles((dir, name) -> name.endsWith(Files.EXT)); - if(files != null) - { - ArrayList backups = new ArrayList<>(files.length); - for(File file : files) - { - if(!file.isFile()) continue; - backups.add(file.getName().replaceAll(Files.EXT_REGEX, "")); - } - return backups; - } - return new ArrayList<>(); - } - - protected String getPlayerFormattedUUID(OfflinePlayer player) - { - return (useUUIDSeparators) ? player.getUniqueId().toString() : player.getUniqueId().toString().replace("-", ""); + return backupHandler.getBackups(); } public @NotNull Collection getLoadedBackpacks() @@ -270,20 +235,35 @@ public void onPlayerLoginEvent(PlayerJoinEvent event) updatePlayerAndLoadBackpack(event.getPlayer()); } - // DB Functions public void updatePlayerAndLoadBackpack(Player player) { updatePlayer(player); if(!bungeeCordMode) asyncLoadBackpack(player); } - public abstract void updatePlayer(Player player); + // DB Functions + public void updatePlayer(final @NotNull Player player) + { + backend.updatePlayer(player); + } - public abstract void saveBackpack(Backpack backpack); + public void saveBackpack(final @NotNull Backpack backpack) + { + backend.saveBackpack(backpack); + } - public void syncCooldown(Player player, long time) {} + public void syncCooldown(final @NotNull Player player, final long time) + { + backend.syncCooldown(player, time); + } - public void getCooldown(final Player player, final Callback callback) {} + public void getCooldown(final Player player, final Callback callback) + { + backend.getCooldown(player, callback); + } - protected abstract void loadBackpack(final OfflinePlayer player, final Callback callback); + protected void loadBackpack(final OfflinePlayer player, final Callback callback) + { + backend.loadBackpack(player, callback); + } } \ No newline at end of file diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/DatabaseType.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/DatabaseType.java new file mode 100644 index 0000000..e2e2240 --- /dev/null +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/DatabaseType.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 GeorgH93 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package at.pcgamingfreaks.Minepacks.Bukkit.Database; + +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public enum DatabaseType +{ + MYSQL, + SQLITE, + FILES, + SHARED, + UNKNOWN; + + public static @NotNull DatabaseType fromName(@NotNull String typeName) + { + typeName = typeName.toLowerCase(Locale.ENGLISH); + switch(typeName) + { + case "mysql": return MYSQL; + case "sqlite": return SQLITE; + case "files": case "file": case "flat": return FILES; + case "shared": case "external": case "global": return SHARED; + } + return UNKNOWN; + } +} \ No newline at end of file diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/FilesToSQLMigration.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/FilesToSQLMigration.java index d8a2955..42671eb 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/FilesToSQLMigration.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/FilesToSQLMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,8 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import org.intellij.lang.annotations.Language; @@ -35,7 +36,7 @@ public class FilesToSQLMigration extends ToSQLMigration private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks; private final File saveFolder; - protected FilesToSQLMigration(@NotNull Minepacks plugin, @NotNull Files oldDb, @NotNull String dbType, boolean global) throws Exception + protected FilesToSQLMigration(@NotNull Minepacks plugin, @NotNull Files oldDb, @NotNull DatabaseType dbType, boolean global) throws Exception { super(plugin, oldDb, dbType, global); saveFolder = new File(this.plugin.getDataFolder(), Files.FOLDER_NAME); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/Migration.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/Migration.java index 0a5372f..71b6907 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/Migration.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/Migration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import org.jetbrains.annotations.NotNull; @@ -26,9 +26,9 @@ public abstract class Migration { protected final Minepacks plugin; - protected final Database oldDb; + protected final DatabaseBackend oldDb; - protected Migration(@NotNull Minepacks plugin, @NotNull Database oldDb) + protected Migration(@NotNull Minepacks plugin, @NotNull DatabaseBackend oldDb) { this.plugin = plugin; this.oldDb = oldDb; diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationManager.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationManager.java index 73459e2..1d5066e 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationManager.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/MigrationManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +18,15 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; import at.pcgamingfreaks.ConsoleColor; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.*; +import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.*; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Reflection; import org.bukkit.event.HandlerList; -import java.util.Locale; - public class MigrationManager { private final Minepacks plugin; @@ -107,39 +108,25 @@ public Migration getMigrationPerformer(String targetDatabaseType) { try { - boolean global = false; - if(targetDatabaseType.toLowerCase(Locale.ROOT).equals("external") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("global") || targetDatabaseType.toLowerCase(Locale.ROOT).equals("shared")) + DatabaseType targetDbType = DatabaseType.fromName(targetDatabaseType); + ConnectionProvider cp = targetDbType == DatabaseType.SHARED ? Database.getGlobalConnectionProvider(plugin.getLogger()) : null; + boolean global = cp != null; + if(cp != null) targetDbType = DatabaseType.fromName(cp.getDatabaseType()); + DatabaseBackend oldBackend = plugin.getDatabase().getBackend(); + switch(targetDbType) { - /*if[STANDALONE] - plugin.getLogger().warning(ConsoleColor.RED + "The shared database connection option is not available in standalone mode!" + ConsoleColor.RESET); - return null; - else[STANDALONE]*/ - at.pcgamingfreaks.PluginLib.Database.DatabaseConnectionPool pool = at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool(); - if(pool == null) - { - plugin.getLogger().warning(ConsoleColor.RED + "The shared connection pool is not initialized correctly!" + ConsoleColor.RESET); - return null; - } - targetDatabaseType = pool.getDatabaseType().toLowerCase(Locale.ROOT); - global = true; - /*end[STANDALONE]*/ - } - switch(targetDatabaseType.toLowerCase(Locale.ROOT)) - { - case "flat": - case "file": - case "files": - if(!(plugin.getDatabase() instanceof SQL)) return null; - return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase()); - case "mysql": - if(plugin.getDatabase() instanceof MySQL) return null; - if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "mysql", global); - else return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), "mysql", global); - case "sqlite": - if(plugin.getDatabase() instanceof SQLite) return null; - if(plugin.getDatabase() instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) plugin.getDatabase(), "sqlite", global); - else return new FilesToSQLMigration(plugin, (Files) plugin.getDatabase(), "sqlite", global); - default: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE, plugin.getConfiguration().getDatabaseType())); return null; + case FILES: + if(!(oldBackend instanceof SQL)) return null; + return new SQLtoFilesMigration(plugin, (SQL) plugin.getDatabase().getBackend()); + case MYSQL: + if(oldBackend instanceof MySQL) return null; + if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.MYSQL, global); + else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.MYSQL, global); + case SQLITE: + if(oldBackend instanceof SQLite) return null; + if(oldBackend instanceof SQL) return new SQLtoSQLMigration(plugin, (SQL) oldBackend, DatabaseType.SQLITE, global); + else return new FilesToSQLMigration(plugin, (Files) oldBackend, DatabaseType.SQLITE, global); + default: plugin.getLogger().warning(String.format(Database.MESSAGE_UNKNOWN_DB_TYPE, targetDatabaseType)); return null; } } catch(Exception e) diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoFilesMigration.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoFilesMigration.java index 626157c..aec2f32 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoFilesMigration.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoFilesMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,8 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.Files; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.Files; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Reflection; diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoSQLMigration.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoSQLMigration.java index 665266d..8a41c21 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoSQLMigration.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/SQLtoSQLMigration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 GeorgH93 + * Copyright (C) 2020 GeorgH93 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,9 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import org.intellij.lang.annotations.Language; @@ -33,7 +34,7 @@ public class SQLtoSQLMigration extends ToSQLMigration { private final @Language("SQL") String queryInsertUsers, queryInsertBackpacks; - protected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NotNull String dbType, boolean global) throws Exception + protected SQLtoSQLMigration(@NotNull Minepacks plugin, @NotNull SQL oldDb, @NotNull DatabaseType dbType, boolean global) throws Exception { super(plugin, oldDb, dbType, global); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/ToSQLMigration.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/ToSQLMigration.java index b18ca45..53dd28f 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/ToSQLMigration.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Database/Migration/ToSQLMigration.java @@ -18,10 +18,12 @@ package at.pcgamingfreaks.Minepacks.Bukkit.Database.Migration; import at.pcgamingfreaks.Database.ConnectionProvider.ConnectionProvider; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.DatabaseBackend; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.MySQL; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQL; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.Backend.SQLite; import at.pcgamingfreaks.Minepacks.Bukkit.Database.Database; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.MySQL; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQL; -import at.pcgamingfreaks.Minepacks.Bukkit.Database.SQLite; +import at.pcgamingfreaks.Minepacks.Bukkit.Database.DatabaseType; import at.pcgamingfreaks.Minepacks.Bukkit.Minepacks; import at.pcgamingfreaks.Reflection; @@ -49,18 +51,15 @@ public abstract class ToSQLMigration extends Migration protected final SQL newDb; - protected ToSQLMigration(@NotNull Minepacks plugin, @NotNull Database oldDb, @NotNull String dbType, boolean global) + protected ToSQLMigration(@NotNull Minepacks plugin, @NotNull DatabaseBackend oldDb, @NotNull DatabaseType dbType, boolean global) { super(plugin, oldDb); - /*if[STANDALONE] - ConnectionProvider connectionProvider = null; - else[STANDALONE]*/ - ConnectionProvider connectionProvider = (global) ? at.pcgamingfreaks.PluginLib.Bukkit.PluginLib.getInstance().getDatabaseConnectionPool().getConnectionProvider() : null; - /*end[STANDALONE]*/ + ConnectionProvider connectionProvider = (global) ? Database.getGlobalConnectionProvider(plugin.getLogger()) : null; + switch(dbType) { - case "mysql": newDb = new MySQL(plugin, connectionProvider); break; - case "sqlite": + case MYSQL: newDb = new MySQL(plugin, connectionProvider); break; + case SQLITE: final File dbFile = new File(SQLite.getDbFile(plugin)); if(dbFile.exists()) dbFile.renameTo(new File(SQLite.getDbFile(plugin) + ".old_" + System.currentTimeMillis())); newDb = new SQLite(plugin, connectionProvider); diff --git a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Minepacks.java b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Minepacks.java index 6a270fa..68805f8 100644 --- a/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Minepacks.java +++ b/Minepacks/src/at/pcgamingfreaks/Minepacks/Bukkit/Minepacks.java @@ -186,8 +186,8 @@ private void load() updater.setChannel(config.getUpdateChannel()); lang.load(config); backpacksConfig.loadData(); - database = Database.getDatabase(this); - if(database == null) + database = new Database(this); + if(!database.available()) { new NoDatabaseWorker(this); return;