mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-12 13:54:22 +01:00
Now using JSON-based data for MySQL
Large number of changes to improve database functions.
This commit is contained in:
parent
6626a9a4b0
commit
cf792779f9
@ -7,8 +7,6 @@ import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
|
|||||||
import us.tastybento.bskyblock.commands.AdminCommand;
|
import us.tastybento.bskyblock.commands.AdminCommand;
|
||||||
import us.tastybento.bskyblock.commands.IslandCommand;
|
import us.tastybento.bskyblock.commands.IslandCommand;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.PlayersManager;
|
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
|
||||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||||
import us.tastybento.bskyblock.listeners.JoinLeaveListener;
|
import us.tastybento.bskyblock.listeners.JoinLeaveListener;
|
||||||
import us.tastybento.bskyblock.listeners.NetherPortals;
|
import us.tastybento.bskyblock.listeners.NetherPortals;
|
||||||
@ -16,7 +14,9 @@ import us.tastybento.bskyblock.listeners.PanelListenerManager;
|
|||||||
import us.tastybento.bskyblock.managers.AddonsManager;
|
import us.tastybento.bskyblock.managers.AddonsManager;
|
||||||
import us.tastybento.bskyblock.managers.CommandsManager;
|
import us.tastybento.bskyblock.managers.CommandsManager;
|
||||||
import us.tastybento.bskyblock.managers.FlagsManager;
|
import us.tastybento.bskyblock.managers.FlagsManager;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
import us.tastybento.bskyblock.managers.LocalesManager;
|
import us.tastybento.bskyblock.managers.LocalesManager;
|
||||||
|
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||||
import us.tastybento.bskyblock.managers.RanksManager;
|
import us.tastybento.bskyblock.managers.RanksManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +26,7 @@ import us.tastybento.bskyblock.managers.RanksManager;
|
|||||||
*/
|
*/
|
||||||
public class BSkyBlock extends JavaPlugin {
|
public class BSkyBlock extends JavaPlugin {
|
||||||
|
|
||||||
private static BSkyBlock plugin;
|
private static BSkyBlock instance;
|
||||||
|
|
||||||
// Databases
|
// Databases
|
||||||
private PlayersManager playersManager;
|
private PlayersManager playersManager;
|
||||||
@ -74,7 +74,7 @@ public class BSkyBlock extends JavaPlugin {
|
|||||||
ranksManager = new RanksManager(this);
|
ranksManager = new RanksManager(this);
|
||||||
|
|
||||||
// Load metrics
|
// Load metrics
|
||||||
metrics = new Metrics(plugin);
|
metrics = new Metrics(instance);
|
||||||
registerCustomCharts();
|
registerCustomCharts();
|
||||||
|
|
||||||
// Set up commands
|
// Set up commands
|
||||||
@ -87,29 +87,29 @@ public class BSkyBlock extends JavaPlugin {
|
|||||||
// at this point. Therefore, the 1 tick scheduler is required.
|
// at this point. Therefore, the 1 tick scheduler is required.
|
||||||
getServer().getScheduler().runTask(this, () -> {
|
getServer().getScheduler().runTask(this, () -> {
|
||||||
// Create the world if it does not exist
|
// Create the world if it does not exist
|
||||||
islandWorldManager = new IslandWorld(plugin);
|
islandWorldManager = new IslandWorld(instance);
|
||||||
|
|
||||||
getServer().getScheduler().runTask(plugin, () -> {
|
getServer().getScheduler().runTask(instance, () -> {
|
||||||
|
|
||||||
// Load Flags
|
// Load Flags
|
||||||
flagsManager = new FlagsManager(plugin);
|
flagsManager = new FlagsManager(instance);
|
||||||
|
|
||||||
// Load islands from database
|
// Load islands from database
|
||||||
islandsManager.load();
|
islandsManager.load();
|
||||||
|
|
||||||
localesManager = new LocalesManager(plugin);
|
localesManager = new LocalesManager(instance);
|
||||||
PlaceholderHandler.register(plugin);
|
PlaceholderHandler.register(instance);
|
||||||
|
|
||||||
// Register Listeners
|
// Register Listeners
|
||||||
registerListeners();
|
registerListeners();
|
||||||
|
|
||||||
// Load addons
|
// Load addons
|
||||||
addonsManager = new AddonsManager(plugin);
|
addonsManager = new AddonsManager(instance);
|
||||||
addonsManager.enableAddons();
|
addonsManager.enableAddons();
|
||||||
|
|
||||||
// Save islands & players data asynchronously every X minutes
|
// Save islands & players data asynchronously every X minutes
|
||||||
getSettings().setDatabaseBackupPeriod(10 * 60 * 20);
|
getSettings().setDatabaseBackupPeriod(10 * 60 * 20);
|
||||||
plugin.getServer().getScheduler().runTaskTimer(plugin, () -> {
|
instance.getServer().getScheduler().runTaskTimer(instance, () -> {
|
||||||
playersManager.save(true);
|
playersManager.save(true);
|
||||||
islandsManager.save(true);
|
islandsManager.save(true);
|
||||||
}, getSettings().getDatabaseBackupPeriod(), getSettings().getDatabaseBackupPeriod());
|
}, getSettings().getDatabaseBackupPeriod(), getSettings().getDatabaseBackupPeriod());
|
||||||
@ -193,11 +193,11 @@ public class BSkyBlock extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void setInstance(BSkyBlock plugin) {
|
private static void setInstance(BSkyBlock plugin) {
|
||||||
BSkyBlock.plugin = plugin;
|
BSkyBlock.instance = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BSkyBlock getInstance() {
|
public static BSkyBlock getInstance() {
|
||||||
return plugin;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,8 +15,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.database.managers.PlayersManager;
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add-on class for BSkyBlock. Extend this to create an add-on. The operation
|
* Add-on class for BSkyBlock. Extend this to create an add-on. The operation
|
||||||
|
@ -19,8 +19,8 @@ import org.bukkit.entity.Player;
|
|||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.Settings;
|
import us.tastybento.bskyblock.Settings;
|
||||||
import us.tastybento.bskyblock.api.events.command.CommandEvent;
|
import us.tastybento.bskyblock.api.events.command.CommandEvent;
|
||||||
import us.tastybento.bskyblock.database.managers.PlayersManager;
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,8 +9,8 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.api.addons.Addon;
|
import us.tastybento.bskyblock.api.addons.Addon;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handy config class to store and load Java POJOs as YAML configs
|
* Handy config class to store and load Java POJOs as YAML configs
|
||||||
|
@ -4,9 +4,10 @@ import java.beans.IntrospectionException;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
|
import us.tastybento.bskyblock.database.flatfile.ConfigHandler;
|
||||||
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple interface for tagging all classes containing ConfigEntries.
|
* Simple interface for tagging all classes containing ConfigEntries.
|
||||||
@ -21,7 +22,7 @@ public interface ISettings<T> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
default void saveSettings() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
|
default void saveSettings() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
|
||||||
// Get the handler
|
// Get the handler
|
||||||
AbstractDatabaseHandler<T> settingsHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(getInstance().getClass());
|
ConfigHandler<T> settingsHandler = (ConfigHandler<T>) new FlatFileDatabase().getConfig(getInstance().getClass());
|
||||||
// Load every field in the config class
|
// Load every field in the config class
|
||||||
settingsHandler.saveSettings(getInstance());
|
settingsHandler.saveSettings(getInstance());
|
||||||
}
|
}
|
||||||
@ -44,7 +45,7 @@ public interface ISettings<T> {
|
|||||||
dbConfig = dbhandler.loadObject(getUniqueId());
|
dbConfig = dbhandler.loadObject(getUniqueId());
|
||||||
}
|
}
|
||||||
// Get the handler
|
// Get the handler
|
||||||
AbstractDatabaseHandler<T> configHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(getInstance().getClass());
|
ConfigHandler<T> configHandler = (ConfigHandler<T> ) new FlatFileDatabase().getConfig(getInstance().getClass());
|
||||||
// Load every field in the config class
|
// Load every field in the config class
|
||||||
return configHandler.loadSettings(getUniqueId(), dbConfig);
|
return configHandler.loadSettings(getUniqueId(), dbConfig);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.api.panels.PanelItem;
|
import us.tastybento.bskyblock.api.panels.PanelItem;
|
||||||
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
|
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
|
||||||
import us.tastybento.bskyblock.managers.RanksManager;
|
|
||||||
|
|
||||||
public class Flag implements Comparable<Flag> {
|
public class Flag implements Comparable<Flag> {
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package us.tastybento.bskyblock.api.panels.builders;
|
package us.tastybento.bskyblock.api.panels.builders;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
@ -11,7 +11,7 @@ import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
|||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
||||||
import us.tastybento.bskyblock.commands.IslandCommand;
|
import us.tastybento.bskyblock.commands.IslandCommand;
|
||||||
import us.tastybento.bskyblock.database.managers.island.NewIsland;
|
import us.tastybento.bskyblock.managers.island.NewIsland;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /island create - Create an island.
|
* /island create - Create an island.
|
||||||
|
@ -10,8 +10,8 @@ import us.tastybento.bskyblock.Constants;
|
|||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
||||||
import us.tastybento.bskyblock.database.managers.island.NewIsland;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.managers.island.NewIsland;
|
||||||
|
|
||||||
public class IslandResetCommand extends CompositeCommand {
|
public class IslandResetCommand extends CompositeCommand {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package us.tastybento.bskyblock.database.managers;
|
package us.tastybento.bskyblock.database;
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
import java.beans.IntrospectionException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -7,8 +7,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that handles insert/select-operations into/from a database
|
* An abstract class that handles insert/select-operations into/from a database
|
||||||
*
|
*
|
||||||
@ -83,18 +81,4 @@ public abstract class AbstractDatabaseHandler<T> {
|
|||||||
*/
|
*/
|
||||||
public abstract boolean objectExists(String key);
|
public abstract boolean objectExists(String key);
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a file as settings
|
|
||||||
* @param instance
|
|
||||||
*/
|
|
||||||
public abstract void saveSettings(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a file as settings
|
|
||||||
* @param uniqueId - unique ID
|
|
||||||
* @param dbConfig - the database mirror of this object. It will be checked against what is loaded to see if any significant changes have been made
|
|
||||||
* @return Settings object
|
|
||||||
*/
|
|
||||||
public abstract T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException;
|
|
||||||
|
|
||||||
}
|
}
|
@ -2,9 +2,7 @@ package us.tastybento.bskyblock.database;
|
|||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
import us.tastybento.bskyblock.database.mysql.MySQLDatabase;
|
import us.tastybento.bskyblock.database.mysql.MySQLDatabase;
|
||||||
import us.tastybento.bskyblock.database.mysqljson.MySQLDatabaseJ;
|
|
||||||
|
|
||||||
public abstract class BSBDatabase {
|
public abstract class BSBDatabase {
|
||||||
|
|
||||||
@ -24,9 +22,7 @@ public abstract class BSBDatabase {
|
|||||||
|
|
||||||
public enum DatabaseType{
|
public enum DatabaseType{
|
||||||
FLATFILE(new FlatFileDatabase()),
|
FLATFILE(new FlatFileDatabase()),
|
||||||
MYSQL(new MySQLDatabase()),
|
MYSQL(new MySQLDatabase());
|
||||||
//JSON();
|
|
||||||
MYSQLJ(new MySQLDatabaseJ());
|
|
||||||
|
|
||||||
BSBDatabase database;
|
BSBDatabase database;
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package us.tastybento.bskyblock.database.flatfile;
|
||||||
|
|
||||||
|
import java.beans.IntrospectionException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class handles config settings saving and loading
|
||||||
|
*
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
* @param <T> Handles config files for Class <T>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ConfigHandler<T> extends FlatFileDatabaseHandler<T> {
|
||||||
|
|
||||||
|
public ConfigHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
||||||
|
super(plugin, type, databaseConnecter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveSettings(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
||||||
|
configFlag = true;
|
||||||
|
saveObject(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
|
||||||
|
if (dbConfig == null) {
|
||||||
|
return loadObject(uniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: compare the loaded with the database copy
|
||||||
|
|
||||||
|
return loadObject(uniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package us.tastybento.bskyblock.database.flatfile;
|
package us.tastybento.bskyblock.database.flatfile;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
public class FlatFileDatabase extends BSBDatabase{
|
public class FlatFileDatabase extends BSBDatabase{
|
||||||
|
|
||||||
@ -11,4 +11,13 @@ public class FlatFileDatabase extends BSBDatabase{
|
|||||||
return new FlatFileDatabaseHandler<>(BSkyBlock.getInstance(), type, new FlatFileDatabaseConnecter(BSkyBlock.getInstance(), null));
|
return new FlatFileDatabaseHandler<>(BSkyBlock.getInstance(), type, new FlatFileDatabaseConnecter(BSkyBlock.getInstance(), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the config
|
||||||
|
* @param type - config object type
|
||||||
|
* @return - the config handler
|
||||||
|
*/
|
||||||
|
public AbstractDatabaseHandler<?> getConfig(Class<?> type) {
|
||||||
|
return new ConfigHandler<>(BSkyBlock.getInstance(), type, new FlatFileDatabaseConnecter(BSkyBlock.getInstance(), null));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ import us.tastybento.bskyblock.Constants.GameType;
|
|||||||
import us.tastybento.bskyblock.api.configuration.ConfigComment;
|
import us.tastybento.bskyblock.api.configuration.ConfigComment;
|
||||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
||||||
import us.tastybento.bskyblock.api.configuration.StoreAt;
|
import us.tastybento.bskyblock.api.configuration.StoreAt;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.Adapter;
|
import us.tastybento.bskyblock.database.objects.adapters.Adapter;
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.AdapterInterface;
|
import us.tastybento.bskyblock.database.objects.adapters.AdapterInterface;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.util.Util;
|
||||||
@ -50,7 +50,7 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
|
|
||||||
private static final String DATABASE_FOLDER_NAME = "database";
|
private static final String DATABASE_FOLDER_NAME = "database";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private boolean configFlag;
|
protected boolean configFlag;
|
||||||
|
|
||||||
public FlatFileDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
public FlatFileDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
||||||
super(plugin, type, databaseConnecter);
|
super(plugin, type, databaseConnecter);
|
||||||
@ -264,15 +264,6 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#saveConfig(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void saveSettings(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
|
||||||
configFlag = true;
|
|
||||||
saveObject(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts T into the corresponding database-table
|
* Inserts T into the corresponding database-table
|
||||||
*
|
*
|
||||||
@ -525,18 +516,4 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#loadSettings(java.lang.String, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
|
|
||||||
if (dbConfig == null) {
|
|
||||||
return loadObject(uniqueId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: compare the loaded with the database copy
|
|
||||||
|
|
||||||
return loadObject(uniqueId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package us.tastybento.bskyblock.database.mysql;
|
package us.tastybento.bskyblock.database.mysql;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
|
import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
public class MySQLDatabase extends BSBDatabase{
|
public class MySQLDatabase extends BSBDatabase{
|
||||||
|
|
||||||
|
@ -1,42 +1,30 @@
|
|||||||
package us.tastybento.bskyblock.database.mysql;
|
package us.tastybento.bskyblock.database.mysql;
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.beans.PropertyDescriptor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Time;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
import us.tastybento.bskyblock.database.mysql.adapters.FlagAdapter;
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.Adapter;
|
import us.tastybento.bskyblock.database.mysql.adapters.LocationAdapter;
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.AdapterInterface;
|
import us.tastybento.bskyblock.database.mysql.adapters.PotionEffectTypeAdapter;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.database.mysql.adapters.WorldAdapter;
|
||||||
|
import us.tastybento.bskyblock.database.objects.DataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -52,47 +40,8 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
* Connection to the database
|
* Connection to the database
|
||||||
*/
|
*/
|
||||||
private Connection connection = null;
|
private Connection connection = null;
|
||||||
/**
|
|
||||||
* This hashmap maps Java types to MySQL SQL types because they are not the same
|
|
||||||
*/
|
|
||||||
private static final HashMap<String, String> MYSQL_MAPPING = new HashMap<>();
|
|
||||||
private static final String STRING_MAP = "VARCHAR(254)";
|
|
||||||
|
|
||||||
static {
|
private BSkyBlock plugin;
|
||||||
MYSQL_MAPPING.put(boolean.class.getTypeName(), "BOOL");
|
|
||||||
MYSQL_MAPPING.put(byte.class.getTypeName(), "TINYINT");
|
|
||||||
MYSQL_MAPPING.put(short.class.getTypeName(), "SMALLINT");
|
|
||||||
MYSQL_MAPPING.put(int.class.getTypeName(), "INTEGER");
|
|
||||||
MYSQL_MAPPING.put(long.class.getTypeName(), "BIGINT");
|
|
||||||
MYSQL_MAPPING.put(double.class.getTypeName(), "DOUBLE PRECISION");
|
|
||||||
MYSQL_MAPPING.put(Boolean.class.getTypeName(), "BOOL");
|
|
||||||
MYSQL_MAPPING.put(Byte.class.getTypeName(), "TINYINT");
|
|
||||||
MYSQL_MAPPING.put(Short.class.getTypeName(), "SMALLINT");
|
|
||||||
MYSQL_MAPPING.put(Integer.class.getTypeName(), "INTEGER");
|
|
||||||
MYSQL_MAPPING.put(Long.class.getTypeName(), "BIGINT");
|
|
||||||
MYSQL_MAPPING.put(Double.class.getTypeName(), "DOUBLE PRECISION");
|
|
||||||
MYSQL_MAPPING.put(BigDecimal.class.getTypeName(), "DECIMAL(13,0)");
|
|
||||||
MYSQL_MAPPING.put(String.class.getTypeName(), STRING_MAP);
|
|
||||||
MYSQL_MAPPING.put(Date.class.getTypeName(), "DATE");
|
|
||||||
MYSQL_MAPPING.put(Time.class.getTypeName(), "TIME");
|
|
||||||
MYSQL_MAPPING.put(Timestamp.class.getTypeName(), "TIMESTAMP");
|
|
||||||
MYSQL_MAPPING.put(UUID.class.getTypeName(), "VARCHAR(36)");
|
|
||||||
|
|
||||||
// Bukkit Mappings
|
|
||||||
MYSQL_MAPPING.put(Location.class.getTypeName(), STRING_MAP);
|
|
||||||
MYSQL_MAPPING.put(World.class.getTypeName(), STRING_MAP);
|
|
||||||
|
|
||||||
// Collections are stored as additional tables. The boolean indicates whether there
|
|
||||||
// is any data in it or not (maybe)
|
|
||||||
MYSQL_MAPPING.put(Set.class.getTypeName(), "BOOL");
|
|
||||||
MYSQL_MAPPING.put(Map.class.getTypeName(), "BOOL");
|
|
||||||
MYSQL_MAPPING.put(HashMap.class.getTypeName(), "BOOL");
|
|
||||||
MYSQL_MAPPING.put(ArrayList.class.getTypeName(), "BOOL");
|
|
||||||
|
|
||||||
// Enums
|
|
||||||
MYSQL_MAPPING.put(Enum.class.getTypeName(), STRING_MAP);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the connection to the database and creation of the initial database schema (tables) for
|
* Handles the connection to the database and creation of the initial database schema (tables) for
|
||||||
@ -101,8 +50,9 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
* @param type - the type of class to be stored in the database. Must inherit DataObject
|
* @param type - the type of class to be stored in the database. Must inherit DataObject
|
||||||
* @param databaseConnecter - authentication details for the database
|
* @param databaseConnecter - authentication details for the database
|
||||||
*/
|
*/
|
||||||
public MySQLDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
public MySQLDatabaseHandler(BSkyBlock plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
||||||
super(plugin, type, databaseConnecter);
|
super(plugin, type, databaseConnecter);
|
||||||
|
this.plugin = plugin;
|
||||||
connection = databaseConnecter.createConnection();
|
connection = databaseConnecter.createConnection();
|
||||||
// Check if the table exists in the database and if not, create it
|
// Check if the table exists in the database and if not, create it
|
||||||
createSchema();
|
createSchema();
|
||||||
@ -115,70 +65,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("CREATE TABLE IF NOT EXISTS `");
|
sql.append("CREATE TABLE IF NOT EXISTS `");
|
||||||
sql.append(dataObject.getCanonicalName());
|
sql.append(dataObject.getCanonicalName());
|
||||||
sql.append("` (");
|
sql.append("` (json JSON, uniqueId VARCHAR(255) GENERATED ALWAYS AS (json->\"$.uniqueId\"), UNIQUE INDEX i (uniqueId) )");
|
||||||
// Run through the fields of the class using introspection
|
|
||||||
for (Field field : dataObject.getDeclaredFields()) {
|
|
||||||
try {
|
|
||||||
// Get the description of the field
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
|
||||||
// Get default SQL mappings
|
|
||||||
// Get the write method for this field. This method will take an argument of the type of this field.
|
|
||||||
Method writeMethod = propertyDescriptor.getWriteMethod();
|
|
||||||
// The SQL column name is the name of the field
|
|
||||||
String columnName = field.getName();
|
|
||||||
// Get the mapping for this field from the hashmap
|
|
||||||
String typeName = propertyDescriptor.getPropertyType().getTypeName();
|
|
||||||
if (propertyDescriptor.getPropertyType().isEnum()) {
|
|
||||||
typeName = "Enum";
|
|
||||||
}
|
|
||||||
String mapping = MYSQL_MAPPING.get(typeName);
|
|
||||||
// If it exists, then create the SQL
|
|
||||||
if (mapping != null) {
|
|
||||||
// Note that the column name must be enclosed in `'s because it may include reserved words.
|
|
||||||
sql.append("`");
|
|
||||||
sql.append(columnName);
|
|
||||||
sql.append("` ");
|
|
||||||
sql.append(mapping);
|
|
||||||
sql.append(",");
|
|
||||||
// Create set and map tables if the type is a collection
|
|
||||||
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(Map.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(HashMap.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
|
||||||
// The ID in this table relates to the parent table and is unique
|
|
||||||
StringBuilder setSql = new StringBuilder();
|
|
||||||
setSql.append("CREATE TABLE IF NOT EXISTS `");
|
|
||||||
setSql.append(dataObject.getCanonicalName());
|
|
||||||
setSql.append(".");
|
|
||||||
setSql.append(field.getName());
|
|
||||||
setSql.append("` (uniqueId VARCHAR(36) NOT NULL, ");
|
|
||||||
// Get columns separated by commas
|
|
||||||
setSql.append(getCollectionColumnString(writeMethod,false,true));
|
|
||||||
// Close the SQL string
|
|
||||||
setSql.append(")");
|
|
||||||
// Execute the statement
|
|
||||||
try (PreparedStatement collections = connection.prepareStatement(setSql.toString())) {
|
|
||||||
collections.executeUpdate();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Getter or setter missing in data object. Cannot create schema! " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// The Java type is not in the hashmap, so we'll just guess that it can be stored in a string
|
|
||||||
// This should NOT be used in general because every type should be in the hashmap
|
|
||||||
sql.append(field.getName());
|
|
||||||
sql.append(" ");
|
|
||||||
sql.append(STRING_MAP);
|
|
||||||
sql.append(",");
|
|
||||||
plugin.getLogger().severe("Unknown type! Hoping it'll fit in a string!");
|
|
||||||
plugin.getLogger().severe(propertyDescriptor.getPropertyType().getTypeName());
|
|
||||||
}
|
|
||||||
} catch (IntrospectionException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Getter or setter missing in data object. Cannot create schema! " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For the main table for the class, the unique ID is the primary key
|
|
||||||
sql.append(" PRIMARY KEY (uniqueId))");
|
|
||||||
// Prepare and execute the database statements
|
// Prepare and execute the database statements
|
||||||
try (PreparedStatement pstmt = connection.prepareStatement(sql.toString())) {
|
try (PreparedStatement pstmt = connection.prepareStatement(sql.toString())) {
|
||||||
pstmt.executeUpdate();
|
pstmt.executeUpdate();
|
||||||
@ -187,596 +74,110 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Gets the GSON builder
|
||||||
*
|
private Gson getGSON() {
|
||||||
* Creates a comma-separated-String with the names of the variables in this
|
// excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose
|
||||||
* class
|
// enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys
|
||||||
* Not used in Flat File database.
|
GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
|
||||||
* @param usePlaceHolders
|
// Register adapters
|
||||||
* true, if PreparedStatement-placeholders ('?') should be used
|
builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ;
|
||||||
* instead of the names of the variables
|
builder.registerTypeAdapter(World.class, new WorldAdapter(plugin));
|
||||||
* @return a comma-separated-String with the names of the variables
|
builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin));
|
||||||
*/
|
builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter());
|
||||||
public String getColumns(boolean usePlaceHolders) {
|
// Keep null in the database
|
||||||
StringBuilder sb = new StringBuilder();
|
builder.serializeNulls();
|
||||||
|
// Allow characters like < or > without escaping them
|
||||||
boolean first = true;
|
builder.disableHtmlEscaping();
|
||||||
/* Iterate the column-names */
|
return builder.create();
|
||||||
for (Field f : dataObject.getDeclaredFields()) {
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
sb.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usePlaceHolders) {
|
|
||||||
sb.append("?");
|
|
||||||
} else {
|
|
||||||
sb.append("`" + f.getName() + "`");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string of columns separated by commas that represent the parameter types of this method
|
|
||||||
* this is used to get into parameters like HashMap<Location, Boolean> at runtime and find out Location
|
|
||||||
* and Boolean.
|
|
||||||
* @param writeMethod
|
|
||||||
* @param usePlaceHolders
|
|
||||||
* true, if PreparedStatement-placeholders ('?') should be used
|
|
||||||
* instead of the names of the variables
|
|
||||||
* @param createSchema if true contains the columns types
|
|
||||||
* @return Returns a string of columns separated by commas.
|
|
||||||
*/
|
|
||||||
private String getCollectionColumnString(Method writeMethod, boolean usePlaceHolders, boolean createSchema) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
List<String> cols = getCollentionColumnList(writeMethod, createSchema);
|
|
||||||
boolean first = true;
|
|
||||||
for (String col : cols) {
|
|
||||||
// Add commas
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
sb.append(", ");
|
|
||||||
}
|
|
||||||
// this is used if the string is going to be used to insert something so the value will replace the ?
|
|
||||||
if (usePlaceHolders) {
|
|
||||||
sb.append("?");
|
|
||||||
} else {
|
|
||||||
sb.append(col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of columns that represent the parameter types of this method
|
|
||||||
* @param method
|
|
||||||
* @param createSchema if true contains the columns types
|
|
||||||
* @return Returns a list of columns separated by commas.
|
|
||||||
*/
|
|
||||||
private List<String> getCollentionColumnList(Method method, boolean createSchema) {
|
|
||||||
List<String> columns = new ArrayList<>();
|
|
||||||
for (Entry<String,String> en : getCollectionColumnMap(method).entrySet()) {
|
|
||||||
StringBuilder col = new StringBuilder();
|
|
||||||
col.append(en.getKey());
|
|
||||||
if (createSchema) {
|
|
||||||
col.append(" ");
|
|
||||||
col.append(en.getValue());
|
|
||||||
}
|
|
||||||
columns.add(col.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a map of column names and their types
|
|
||||||
* @param method
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Map<String,String> getCollectionColumnMap(Method method) {
|
|
||||||
Map<String,String> columns = new LinkedHashMap<>();
|
|
||||||
// Get the return type
|
|
||||||
// This uses a trick to extract what the arguments are of the writeMethod of the field.
|
|
||||||
// In this way, we can deduce what type needs to be written at runtime.
|
|
||||||
Type[] genericParameterTypes = method.getGenericParameterTypes();
|
|
||||||
// There could be more than one argument, so step through them
|
|
||||||
for (Type genericParameterType : genericParameterTypes) {
|
|
||||||
// If the argument is a parameter, then do something - this should always be true if the parameter is a collection
|
|
||||||
if (genericParameterType instanceof ParameterizedType) {
|
|
||||||
// Get the actual type arguments of the parameter
|
|
||||||
Type[] parameters = ((ParameterizedType)genericParameterType).getActualTypeArguments();
|
|
||||||
//parameters[0] contains java.lang.String for method like "method(List<String> value)"
|
|
||||||
// Run through them one by one and create a SQL string
|
|
||||||
int index = 0;
|
|
||||||
for (Type type : parameters) {
|
|
||||||
// This is a request for column names.
|
|
||||||
String setMapping = MYSQL_MAPPING.get(type.getTypeName());
|
|
||||||
// This column name format is typeName_# where # is a number incremented from 0
|
|
||||||
columns.put("`" + type.getTypeName() + "_" + index + "`", setMapping != null ? setMapping : STRING_MAP);
|
|
||||||
// Increment the index so each column has a unique name
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
String createSelectQuery() {
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.append("SELECT ");
|
|
||||||
sb.append(getColumns(false));
|
|
||||||
sb.append(" FROM ");
|
|
||||||
sb.append("`");
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("`");
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String createInsertQuery() {
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
// Replace into is used so that any data in the table will be replaced with updated data
|
|
||||||
sb.append("REPLACE INTO ");
|
|
||||||
sb.append("`");
|
|
||||||
// The table name is the canonical name, so that add-ons can be sure of a unique table in the database
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("`");
|
|
||||||
sb.append("(");
|
|
||||||
sb.append(getColumns(false));
|
|
||||||
sb.append(")");
|
|
||||||
sb.append(" VALUES (");
|
|
||||||
sb.append(getColumns(true));
|
|
||||||
sb.append(")");
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String createDeleteQuery() {
|
|
||||||
return "DELETE FROM [table_name] WHERE uniqueId = ?";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts a <T> into the corresponding database-table
|
|
||||||
*
|
|
||||||
* @param instance <T> that should be inserted into the corresponding database-table. Must extend DataObject.
|
|
||||||
*/
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#insertObject(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void saveObject(T instance) throws SQLException,
|
public List<T> loadObjects() {
|
||||||
SecurityException, IllegalArgumentException,
|
|
||||||
InstantiationException, IllegalAccessException,
|
|
||||||
IntrospectionException, InvocationTargetException, NoSuchMethodException {
|
|
||||||
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(createInsertQuery())) {
|
|
||||||
// Get the uniqueId. As each class extends DataObject, it must have this method in it.
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
|
|
||||||
Method getUniqueId = propertyDescriptor.getReadMethod();
|
|
||||||
final String uniqueId = (String) getUniqueId.invoke(instance);
|
|
||||||
if (uniqueId.isEmpty()) {
|
|
||||||
throw new SQLException("uniqueId is blank");
|
|
||||||
}
|
|
||||||
// Create the insertion
|
|
||||||
int i = 0;
|
|
||||||
// Run through the fields in the class using introspection
|
|
||||||
for (Field field : dataObject.getDeclaredFields()) {
|
|
||||||
// Get the field's property descriptor
|
|
||||||
propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
|
||||||
// Get the read method for this field
|
|
||||||
Method method = propertyDescriptor.getReadMethod();
|
|
||||||
//sql += "`" + field.getName() + "` " + mapping + ",";
|
|
||||||
// Invoke the read method to obtain the value from the class - this is the value we need to store in the database
|
|
||||||
Object value = method.invoke(instance);
|
|
||||||
// Adapter Notation
|
|
||||||
Adapter adapterNotation = field.getAnnotation(Adapter.class);
|
|
||||||
if (adapterNotation != null && AdapterInterface.class.isAssignableFrom(adapterNotation.value())) {
|
|
||||||
// A conversion adapter has been defined
|
|
||||||
value = ((AdapterInterface<?,?>)adapterNotation.value().newInstance()).deserialize(value);
|
|
||||||
}
|
|
||||||
// Create set and map table inserts if this is a Collection
|
|
||||||
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(Map.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(HashMap.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
|
||||||
// Collection
|
|
||||||
// The table is cleared for this uniqueId every time the data is stored
|
|
||||||
StringBuilder clearTableSql = new StringBuilder();
|
|
||||||
clearTableSql.append("DELETE FROM `");
|
|
||||||
clearTableSql.append(dataObject.getCanonicalName());
|
|
||||||
clearTableSql.append(".");
|
|
||||||
clearTableSql.append(field.getName());
|
|
||||||
clearTableSql.append("` WHERE uniqueId = ?");
|
|
||||||
try (PreparedStatement collStatement = connection.prepareStatement(clearTableSql.toString())) {
|
|
||||||
collStatement.setString(1, uniqueId);
|
|
||||||
collStatement.execute();
|
|
||||||
}
|
|
||||||
// Insert into the table
|
|
||||||
StringBuilder setSql = new StringBuilder();
|
|
||||||
setSql.append("INSERT INTO `");
|
|
||||||
setSql.append(dataObject.getCanonicalName());
|
|
||||||
setSql.append(".");
|
|
||||||
setSql.append(field.getName());
|
|
||||||
setSql.append("` (uniqueId, ");
|
|
||||||
// Get the columns we are going to insert, just the names of them
|
|
||||||
setSql.append(getCollectionColumnString(propertyDescriptor.getWriteMethod(), false, false));
|
|
||||||
setSql.append(") ");
|
|
||||||
// Get all the ?'s for the columns
|
|
||||||
setSql.append("VALUES (?,");
|
|
||||||
setSql.append(getCollectionColumnString(propertyDescriptor.getWriteMethod(), true, false));
|
|
||||||
setSql.append(")");
|
|
||||||
// Prepare the statement
|
|
||||||
try (PreparedStatement collStatement = connection.prepareStatement(setSql.toString())) {
|
|
||||||
// Set the uniqueId
|
|
||||||
collStatement.setString(1, uniqueId);
|
|
||||||
// Do single dimension types (set and list)
|
|
||||||
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
|
||||||
//plugin.getLogger().info("DEBUG: set class for ");
|
|
||||||
// Loop through the set or list
|
|
||||||
// Note that we have no idea what type this is
|
|
||||||
Collection<?> collection = (Collection<?>)value;
|
|
||||||
Iterator<?> it = collection.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Object setValue = it.next();
|
|
||||||
//if (setValue instanceof UUID) {
|
|
||||||
// Serialize everything
|
|
||||||
setValue = serialize(setValue, setValue.getClass());
|
|
||||||
//}
|
|
||||||
// Set the value from ? to whatever it is
|
|
||||||
collStatement.setObject(2, setValue);
|
|
||||||
// Execute the SQL in the database
|
|
||||||
collStatement.execute();
|
|
||||||
}
|
|
||||||
} else if (propertyDescriptor.getPropertyType().equals(Map.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(HashMap.class)) {
|
|
||||||
// Loop through the map
|
|
||||||
Map<?,?> collection = (Map<?,?>)value;
|
|
||||||
Iterator<?> it = collection.entrySet().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<?,?> en = (Entry<?, ?>) it.next();
|
|
||||||
// Get the key and serialize it
|
|
||||||
Object key = serialize(en.getKey(), en.getKey().getClass());
|
|
||||||
// Get the value and serialize it
|
|
||||||
Object mapValue = serialize(en.getValue(), en.getValue().getClass());
|
|
||||||
// Write the objects into prepared statement
|
|
||||||
collStatement.setObject(2, key);
|
|
||||||
collStatement.setObject(3, mapValue);
|
|
||||||
// Write to database
|
|
||||||
collStatement.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Set value for the main insert. For collections, this is just a dummy value because the real values are in the
|
|
||||||
// additional table.
|
|
||||||
value = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the value is not a collection, it just needs to be serialized to go into the database.
|
|
||||||
value = serialize(value, propertyDescriptor.getPropertyType());
|
|
||||||
}
|
|
||||||
// Set the value in the main prepared statement and increment the location
|
|
||||||
// Note that with prepared statements, they count from 1, not 0, so the ++ goes on the front of i.
|
|
||||||
preparedStatement.setObject(++i, value);
|
|
||||||
}
|
|
||||||
// Add the statements to a batch
|
|
||||||
preparedStatement.addBatch();
|
|
||||||
// Execute
|
|
||||||
preparedStatement.executeBatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serializes values if required to go into a database.
|
|
||||||
* TODO: This method will need expanding to include additional Java types
|
|
||||||
* @param value
|
|
||||||
* @param clazz - the known class of value
|
|
||||||
* @return the object to write to the database
|
|
||||||
*/
|
|
||||||
private Object serialize(Object value, Class<? extends Object> clazz) {
|
|
||||||
//plugin.getLogger().info("DEBUG: serialize - class is " + clazz.getTypeName());
|
|
||||||
if (value == null) {
|
|
||||||
// If the value is null to start, return null as a string
|
|
||||||
return "null";
|
|
||||||
}
|
|
||||||
// Types that need to be serialized
|
|
||||||
// TODO - add others, like Date, Timestamp, etc.
|
|
||||||
if (clazz.equals(UUID.class)) {
|
|
||||||
value = value.toString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Bukkit Types
|
|
||||||
if (clazz.equals(Location.class)) {
|
|
||||||
// Serialize
|
|
||||||
value = Util.getStringLocation(((Location)value));
|
|
||||||
} else
|
|
||||||
if (clazz.equals(World.class)) {
|
|
||||||
// Serialize - get the name
|
|
||||||
value = ((World)value).getName();
|
|
||||||
} else
|
|
||||||
if (clazz.getSuperclass() != null && clazz.getSuperclass().equals(Enum.class)) {
|
|
||||||
//Custom enums are a child of the Enum class. Just get the names of each one.
|
|
||||||
value = ((Enum<?>)value).name();
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
// The value could become null from the above checks
|
|
||||||
return "null";
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a list of <T>s filled with values from the corresponding
|
|
||||||
* database-table
|
|
||||||
*
|
|
||||||
* @return List of <T>s filled with values from the corresponding
|
|
||||||
* database-table
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<T> loadObjects() throws SQLException,
|
|
||||||
SecurityException, IllegalArgumentException,
|
|
||||||
InstantiationException, IllegalAccessException,
|
|
||||||
IntrospectionException, InvocationTargetException, ClassNotFoundException {
|
|
||||||
|
|
||||||
try (Statement statement = connection.createStatement();
|
|
||||||
ResultSet resultSet = statement.executeQuery(createSelectQuery())) {
|
|
||||||
return createObjects(resultSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#selectObject(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public T loadObject(String uniqueId) throws InstantiationException,
|
|
||||||
IllegalAccessException, IllegalArgumentException,
|
|
||||||
InvocationTargetException, IntrospectionException, SQLException, SecurityException, ClassNotFoundException {
|
|
||||||
|
|
||||||
// Build the select query
|
|
||||||
StringBuilder query = new StringBuilder();
|
|
||||||
query.append("SELECT ");
|
|
||||||
query.append(getColumns(false));
|
|
||||||
query.append(" FROM `");
|
|
||||||
query.append(dataObject.getCanonicalName());
|
|
||||||
query.append("` WHERE uniqueId = ? LIMIT 1");
|
|
||||||
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(query.toString())) {
|
|
||||||
preparedStatement.setString(1, uniqueId);
|
|
||||||
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
|
||||||
// If there is a result, we only want/need the first one
|
|
||||||
List<T> result = createObjects(resultSet);
|
|
||||||
if (!result.isEmpty()) {
|
|
||||||
return result.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Creates a list of <T>s filled with values from the provided ResultSet
|
|
||||||
*
|
|
||||||
* @param resultSet
|
|
||||||
* ResultSet that contains the result of the
|
|
||||||
* database-select-query
|
|
||||||
*
|
|
||||||
* @return List of <T>s filled with values from the provided ResultSet
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private List<T> createObjects(ResultSet resultSet)
|
|
||||||
throws SecurityException, IllegalArgumentException,
|
|
||||||
SQLException, InstantiationException,
|
|
||||||
IllegalAccessException, IntrospectionException,
|
|
||||||
InvocationTargetException, ClassNotFoundException {
|
|
||||||
|
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
// The database can return multiple results in one go, e.g., all the islands in the database
|
StringBuilder sb = new StringBuilder();
|
||||||
// Run through them one by one
|
sb.append("SELECT `json` FROM `");
|
||||||
while (resultSet.next()) {
|
sb.append(dataObject.getCanonicalName());
|
||||||
// Create a new instance of this type
|
sb.append("`");
|
||||||
T instance = dataObject.newInstance();
|
try (Statement preparedStatement = connection.createStatement()) {
|
||||||
// Get the unique ID from the results
|
try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) {
|
||||||
String uniqueId = resultSet.getString("uniqueId");
|
// Load all the results
|
||||||
if (uniqueId == null) {
|
Gson gson = getGSON();
|
||||||
throw new SQLException("No unique ID in the results!");
|
while (resultSet.next()) {
|
||||||
}
|
list.add(gson.fromJson(resultSet.getString("json"), dataObject));
|
||||||
// Use introspection to run through all the fields in this type class
|
|
||||||
for (Field field : dataObject.getDeclaredFields()) {
|
|
||||||
/* We assume the table-column-names exactly match the variable-names of T */
|
|
||||||
Object value = resultSet.getObject(field.getName());
|
|
||||||
// Get the property descriptor of this type
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
|
||||||
// Get the write method for this field, because we are going to use it to write the value
|
|
||||||
// once we get the value from the database
|
|
||||||
Method method = propertyDescriptor.getWriteMethod();
|
|
||||||
// If the type is a Collection, then we need to deal with set and map tables
|
|
||||||
if (Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType())
|
|
||||||
|| Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
|
||||||
// Collection
|
|
||||||
// value is just of type boolean right now
|
|
||||||
StringBuilder setSql = new StringBuilder();
|
|
||||||
setSql.append("SELECT ");
|
|
||||||
// Get the columns, just the names of them, no ?'s or types
|
|
||||||
setSql.append(getCollectionColumnString(method, false, false));
|
|
||||||
setSql.append(" ");
|
|
||||||
setSql.append("FROM `");
|
|
||||||
setSql.append(dataObject.getCanonicalName());
|
|
||||||
setSql.append(".");
|
|
||||||
setSql.append(field.getName());
|
|
||||||
setSql.append("` ");
|
|
||||||
// We will need to fill in the ? later with the unique id of the class from the database
|
|
||||||
setSql.append("WHERE uniqueId = ?");
|
|
||||||
// Prepare the statement
|
|
||||||
try (PreparedStatement collStatement = connection.prepareStatement(setSql.toString())) {
|
|
||||||
// Set the unique ID
|
|
||||||
collStatement.setObject(1, uniqueId);
|
|
||||||
try (ResultSet collectionResultSet = collStatement.executeQuery()) {
|
|
||||||
|
|
||||||
//plugin.getLogger().info("DEBUG: collectionResultSet = " + collectionResultSet.toString());
|
|
||||||
// Do single dimension types (set and list)
|
|
||||||
if (Set.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
|
||||||
// Loop through the collection resultset
|
|
||||||
// Note that we have no idea what type this is
|
|
||||||
List<Type> collectionTypes = Util.getCollectionParameterTypes(method);
|
|
||||||
// collectionTypes should be only 1 long
|
|
||||||
Type setType = collectionTypes.get(0);
|
|
||||||
value = new HashSet<>();
|
|
||||||
while (collectionResultSet.next()) {
|
|
||||||
((Set<Object>) value).add(deserialize(collectionResultSet.getObject(1),Class.forName(setType.getTypeName())));
|
|
||||||
}
|
|
||||||
} else if (List.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
|
||||||
// Loop through the collection resultset
|
|
||||||
// Note that we have no idea what type this is
|
|
||||||
List<Type> collectionTypes = Util.getCollectionParameterTypes(method);
|
|
||||||
// collectionTypes should be only 1 long
|
|
||||||
Type setType = collectionTypes.get(0);
|
|
||||||
value = new ArrayList<>();
|
|
||||||
//plugin.getLogger().info("DEBUG: collection type argument = " + collectionTypes);
|
|
||||||
while (collectionResultSet.next()) {
|
|
||||||
// Add to the list
|
|
||||||
((List<Object>) value).add(deserialize(collectionResultSet.getObject(1),Class.forName(setType.getTypeName())));
|
|
||||||
}
|
|
||||||
} else if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType()) ||
|
|
||||||
HashMap.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
|
||||||
// Loop through the collection resultset
|
|
||||||
// Note that we have no idea what type this is
|
|
||||||
List<Type> collectionTypes = Util.getCollectionParameterTypes(method);
|
|
||||||
// collectionTypes should be 2 long
|
|
||||||
Type keyType = collectionTypes.get(0);
|
|
||||||
Type valueType = collectionTypes.get(1);
|
|
||||||
value = new HashMap<>();
|
|
||||||
while (collectionResultSet.next()) {
|
|
||||||
// Work through the columns
|
|
||||||
// Key
|
|
||||||
Object key = deserialize(collectionResultSet.getObject(1),Class.forName(keyType.getTypeName()));
|
|
||||||
Object mapValue = deserialize(collectionResultSet.getObject(2),Class.forName(valueType.getTypeName()));
|
|
||||||
((Map<Object,Object>) value).put(key,mapValue);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Set value for the main insert. For collections, this is just a dummy value because the real values are in the
|
|
||||||
// additional table.
|
|
||||||
value = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = deserialize(value, propertyDescriptor.getPropertyType());
|
|
||||||
}
|
}
|
||||||
// Adapter
|
|
||||||
// Check if there is an annotation on the field
|
|
||||||
Adapter adapterNotation = field.getAnnotation(Adapter.class);
|
|
||||||
if (adapterNotation != null && AdapterInterface.class.isAssignableFrom(adapterNotation.value())) {
|
|
||||||
// A conversion adapter has been defined
|
|
||||||
value = ((AdapterInterface<?,?>)adapterNotation.value().newInstance()).serialize(value);
|
|
||||||
}
|
|
||||||
// Write the value to the class
|
|
||||||
method.invoke(instance, value);
|
|
||||||
}
|
}
|
||||||
// Write the result into the list we are going to return
|
} catch (SQLException e) {
|
||||||
list.add(instance);
|
plugin.getLogger().severe(() -> "Could not load objects " + e.getMessage());
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Deserialize any values according to their class
|
|
||||||
* TODO: expand to include additional types
|
|
||||||
* @param value
|
|
||||||
* @param clazz
|
|
||||||
* @return the deserialized value
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
private Object deserialize(Object value, Class<? extends Object> clazz) {
|
|
||||||
if (value instanceof String && value.equals("null")) {
|
|
||||||
// If the value is null as a string, return null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Types that need to be deserialized
|
|
||||||
if (clazz.equals(UUID.class)) {
|
|
||||||
value = UUID.fromString((String)value);
|
|
||||||
}
|
|
||||||
// Bukkit Types
|
|
||||||
if (clazz.equals(Location.class)) {
|
|
||||||
// Get Location from String - may be null...
|
|
||||||
value = Util.getLocationString(((String)value));
|
|
||||||
}
|
|
||||||
if (clazz.equals(World.class)) {
|
|
||||||
// Get world by name - may be null...
|
|
||||||
value = plugin.getServer().getWorld((String)value);
|
|
||||||
}
|
|
||||||
// Enums
|
|
||||||
if (Enum.class.isAssignableFrom(clazz)) {
|
|
||||||
//Custom enums are a child of the Enum class.
|
|
||||||
// Find out the value
|
|
||||||
try {
|
|
||||||
Class<Enum> enumClass = (Class<Enum>)clazz;
|
|
||||||
value = Enum.valueOf(enumClass, (String)value);
|
|
||||||
} catch (Exception e) {
|
|
||||||
plugin.getLogger().severe("Could not deserialize enum! " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#deleteObject(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(T instance)
|
public T loadObject(String uniqueId) {
|
||||||
throws IllegalAccessException, IllegalArgumentException,
|
StringBuilder sb = new StringBuilder();
|
||||||
InvocationTargetException, IntrospectionException, SQLException, NoSuchMethodException, SecurityException {
|
sb.append("SELECT `json` FROM `");
|
||||||
// Delete this object from all tables
|
sb.append(dataObject.getCanonicalName());
|
||||||
// Try to connect to the database
|
sb.append("` WHERE uniqueId = ? LIMIT 1");
|
||||||
// Get the uniqueId. As each class extends DataObject, it must have this method in it.
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
||||||
Method getUniqueId = dataObject.getMethod("getUniqueId");
|
|
||||||
String uniqueId = (String) getUniqueId.invoke(instance);
|
|
||||||
//plugin.getLogger().info("DEBUG: Unique Id = " + uniqueId);
|
|
||||||
if (uniqueId.isEmpty()) {
|
|
||||||
throw new SQLException("uniqueId is blank");
|
|
||||||
}
|
|
||||||
// Delete from the main table
|
|
||||||
// First substitution is the table name
|
|
||||||
// deleteQuery is created in super from the createInsertQuery() method
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(createDeleteQuery().replace("[table_name]", "`" + dataObject.getCanonicalName() + "`"))) {
|
|
||||||
// Second is the unique ID
|
|
||||||
preparedStatement.setString(1, uniqueId);
|
preparedStatement.setString(1, uniqueId);
|
||||||
preparedStatement.addBatch();
|
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
||||||
preparedStatement.executeBatch();
|
while (resultSet.next()) {
|
||||||
}
|
// If there is a result, we only want/need the first one
|
||||||
|
Gson gson = getGSON();
|
||||||
// Delete from any sub tables created from the object
|
return gson.fromJson(resultSet.getString("json"), dataObject);
|
||||||
// Run through the fields in the class using introspection
|
|
||||||
for (Field field : dataObject.getDeclaredFields()) {
|
|
||||||
// Get the field's property descriptor
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
|
||||||
// Delete Collection tables
|
|
||||||
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(Map.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(HashMap.class) ||
|
|
||||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
|
||||||
// First substitution is the table name
|
|
||||||
try (PreparedStatement preparedStatement2 = connection.prepareStatement(createDeleteQuery().replace("[table_name]", "`" + dataObject.getCanonicalName() + "." + field.getName() + "`"))) {
|
|
||||||
// Second is the unique ID
|
|
||||||
preparedStatement2.setString(1, uniqueId);
|
|
||||||
preparedStatement2.addBatch();
|
|
||||||
// Execute
|
|
||||||
preparedStatement2.executeBatch();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.getLogger().severe(() -> "Could not load object " + uniqueId + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveObject(T instance) {
|
||||||
|
if (!(instance instanceof DataObject)) {
|
||||||
|
plugin.getLogger().severe(() -> "This class is not a DataObject: " + instance.getClass().getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
// Replace into is used so that any data in the table will be replaced with updated data
|
||||||
|
sb.append("INSERT INTO ");
|
||||||
|
sb.append("`");
|
||||||
|
// The table name is the canonical name, so that add-ons can be sure of a unique table in the database
|
||||||
|
sb.append(dataObject.getCanonicalName());
|
||||||
|
sb.append("` (json) VALUES (?) ON DUPLICATE KEY UPDATE json = ?");
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
||||||
|
Gson gson = getGSON();
|
||||||
|
String toStore = gson.toJson(instance);
|
||||||
|
preparedStatement.setString(1, toStore);
|
||||||
|
preparedStatement.setString(2, toStore);
|
||||||
|
preparedStatement.execute();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.getLogger().severe(() -> "Could not save object " + instance.getClass().getName() + " " + e.getMessage());
|
||||||
|
// Leave in for now until we know there are no particular issues
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteObject(T instance) {
|
||||||
|
if (!(instance instanceof DataObject)) {
|
||||||
|
plugin.getLogger().severe(() -> "This class is not a DataObject: " + instance.getClass().getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("DELETE FROM `");
|
||||||
|
sb.append(dataObject.getCanonicalName());
|
||||||
|
sb.append("` WHERE uniqueId = ?");
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
||||||
|
Method getUniqueId = dataObject.getMethod("getUniqueId");
|
||||||
|
String uniqueId = (String) getUniqueId.invoke(instance);
|
||||||
|
preparedStatement.setString(1, uniqueId);
|
||||||
|
preparedStatement.execute();
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().severe(() -> "Could not delete object " + instance.getClass().getName() + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#objectExists(java.lang.String)
|
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#objectExists(java.lang.String)
|
||||||
@ -785,7 +186,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
public boolean objectExists(String key) {
|
public boolean objectExists(String key) {
|
||||||
// Create the query to see if this key exists
|
// Create the query to see if this key exists
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
query.append("SELECT IF ( EXISTS( SELECT * FROM `");
|
query.append("SELECT IF ( EXISTS( SELECT * FROM `");
|
||||||
query.append(dataObject.getCanonicalName());
|
query.append(dataObject.getCanonicalName());
|
||||||
query.append("` WHERE `uniqueId` = ?), 1, 0)");
|
query.append("` WHERE `uniqueId` = ?), 1, 0)");
|
||||||
|
|
||||||
@ -802,18 +203,4 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSettings(T instance)
|
|
||||||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
|
||||||
// This method should not be used because configs are not stored in MySQL
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException,
|
|
||||||
IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
|
|
||||||
// This method should not be used because configs are not stored in MySQL
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package us.tastybento.bskyblock.database.mysql.adapters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
|
|
||||||
|
public class FlagAdapter extends TypeAdapter<Flag> {
|
||||||
|
|
||||||
|
private BSkyBlock plugin;
|
||||||
|
|
||||||
|
public FlagAdapter(BSkyBlock plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, Flag value) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.value(value.getID());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Flag read(JsonReader reader) throws IOException {
|
||||||
|
if (reader.peek() == JsonToken.NULL) {
|
||||||
|
reader.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return plugin.getFlagsManager().getFlagByID(reader.nextString());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package us.tastybento.bskyblock.database.mysql.adapters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
public class LocationAdapter extends TypeAdapter<Location> {
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
|
||||||
|
public LocationAdapter(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, Location location) throws IOException {
|
||||||
|
if (location == null) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.beginArray();
|
||||||
|
out.value(location.getWorld().getName());
|
||||||
|
out.value(location.getX());
|
||||||
|
out.value(location.getY());
|
||||||
|
out.value(location.getZ());
|
||||||
|
out.value(location.getYaw());
|
||||||
|
out.value(location.getPitch());
|
||||||
|
out.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location read(JsonReader in) throws IOException {
|
||||||
|
if (in.peek() == JsonToken.NULL) {
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
in.beginArray();
|
||||||
|
World world = plugin.getServer().getWorld(in.nextString());
|
||||||
|
double x = in.nextDouble();
|
||||||
|
double y = in.nextDouble();
|
||||||
|
double z = in.nextDouble();
|
||||||
|
float yaw = (float)in.nextDouble();
|
||||||
|
float pitch = (float)in.nextDouble();
|
||||||
|
in.endArray();
|
||||||
|
return new Location(world, x, y, z, yaw, pitch);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package us.tastybento.bskyblock.database.mysql.adapters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
public class WorldAdapter extends TypeAdapter<World> {
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
|
||||||
|
public WorldAdapter(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, World value) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.value(value.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World read(JsonReader reader) throws IOException {
|
||||||
|
if (reader.peek() == JsonToken.NULL) {
|
||||||
|
reader.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return plugin.getServer().getWorld(reader.nextString());
|
||||||
|
}
|
||||||
|
}
|
@ -1,88 +0,0 @@
|
|||||||
package us.tastybento.bskyblock.database.mysqljson;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
|
|
||||||
public class LocationAdapter implements JsonDeserializer<Location>, JsonSerializer<Location> {
|
|
||||||
|
|
||||||
public static final LocationAdapter INSTANCE = new LocationAdapter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Location deserialize( JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext ) throws JsonParseException {
|
|
||||||
|
|
||||||
if ( !json.isJsonObject() ) {
|
|
||||||
throw new JsonParseException( "not a JSON object" );
|
|
||||||
}
|
|
||||||
|
|
||||||
final JsonObject obj = (JsonObject) json;
|
|
||||||
final JsonElement world = obj.get( "world" );
|
|
||||||
final JsonElement x = obj.get( "x" );
|
|
||||||
final JsonElement y = obj.get( "y" );
|
|
||||||
final JsonElement z = obj.get( "z" );
|
|
||||||
final JsonElement yaw = obj.get( "yaw" );
|
|
||||||
final JsonElement pitch = obj.get( "pitch" );
|
|
||||||
|
|
||||||
if ( world == null || x == null || y == null || z == null || yaw == null || pitch == null ) {
|
|
||||||
throw new JsonParseException( "Malformed location json string!" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !world.isJsonPrimitive() || !((JsonPrimitive) world).isString() ) {
|
|
||||||
throw new JsonParseException( "world is not a string" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !x.isJsonPrimitive() || !((JsonPrimitive) x).isNumber() ) {
|
|
||||||
throw new JsonParseException( "x is not a number" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !y.isJsonPrimitive() || !((JsonPrimitive) y).isNumber() ) {
|
|
||||||
throw new JsonParseException( "y is not a number" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !z.isJsonPrimitive() || !((JsonPrimitive) z).isNumber() ) {
|
|
||||||
throw new JsonParseException( "z is not a number" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !yaw.isJsonPrimitive() || !((JsonPrimitive) yaw).isNumber() ) {
|
|
||||||
throw new JsonParseException( "yaw is not a number" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !pitch.isJsonPrimitive() || !((JsonPrimitive) pitch).isNumber() ) {
|
|
||||||
throw new JsonParseException( "pitch is not a number" );
|
|
||||||
}
|
|
||||||
|
|
||||||
World worldInstance = Bukkit.getWorld( world.getAsString() );
|
|
||||||
if (worldInstance == null) {
|
|
||||||
throw new IllegalArgumentException("Unknown/not loaded world");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Location( worldInstance, x.getAsDouble(), y.getAsDouble(), z.getAsDouble(), yaw.getAsFloat(), pitch.getAsFloat() );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize( Location location, Type type, JsonSerializationContext jsonSerializationContext ) {
|
|
||||||
|
|
||||||
final JsonObject obj = new JsonObject();
|
|
||||||
obj.addProperty( "world", location.getWorld().getName() );
|
|
||||||
obj.addProperty( "x", location.getX() );
|
|
||||||
obj.addProperty( "y", location.getY() );
|
|
||||||
obj.addProperty( "z", location.getZ() );
|
|
||||||
obj.addProperty( "yaw", location.getYaw() );
|
|
||||||
obj.addProperty( "pitch", location.getPitch() );
|
|
||||||
return obj;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
package us.tastybento.bskyblock.database.mysqljson;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
|
|
||||||
|
|
||||||
public class MySQLDatabaseConnecterJ implements DatabaseConnecter {
|
|
||||||
|
|
||||||
private String connectionUrl;
|
|
||||||
private DatabaseConnectionSettingsImpl dbSettings;
|
|
||||||
private Connection connection = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for MySQL database connections using the settings provided
|
|
||||||
* @param dbSettings
|
|
||||||
*/
|
|
||||||
public MySQLDatabaseConnecterJ(DatabaseConnectionSettingsImpl dbSettings) {
|
|
||||||
this.dbSettings = dbSettings;
|
|
||||||
try {
|
|
||||||
Class.forName("com.mysql.jdbc.Driver").newInstance();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Bukkit.getLogger().severe("Could not instantiate JDBC driver! " + e.getMessage());
|
|
||||||
}
|
|
||||||
// jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false
|
|
||||||
connectionUrl = "jdbc:mysql://" + dbSettings.getHost() + "/" + dbSettings.getDatabaseName() + "?autoReconnect=true&useSSL=false&allowMultiQueries=true";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Connection createConnection() {
|
|
||||||
try {
|
|
||||||
connection = DriverManager.getConnection(connectionUrl, dbSettings.getUsername(), dbSettings.getPassword());
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Bukkit.getLogger().severe("Could not connect to the database! " + e.getMessage());
|
|
||||||
}
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getConnectionUrl() {
|
|
||||||
return connectionUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUniqueId(String tableName) {
|
|
||||||
// Not used
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YamlConfiguration loadYamlFile(String string, String key) {
|
|
||||||
// Not used
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean uniqueIdExists(String tableName, String key) {
|
|
||||||
// Not used
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName,
|
|
||||||
Map<String, String> commentMap) {
|
|
||||||
// Not used
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,191 +0,0 @@
|
|||||||
package us.tastybento.bskyblock.database.mysqljson;
|
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Class that inserts a <T> into the corresponding database-table.
|
|
||||||
*
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
public class MySQLDatabaseHandlerJ<T> extends AbstractDatabaseHandler<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connection to the database
|
|
||||||
*/
|
|
||||||
private Connection connection = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the connection to the database and creation of the initial database schema (tables) for
|
|
||||||
* the class that will be stored.
|
|
||||||
* @param plugin - BSkyBlock plugin object
|
|
||||||
* @param type - the type of class to be stored in the database. Must inherit DataObject
|
|
||||||
* @param databaseConnecter - authentication details for the database
|
|
||||||
*/
|
|
||||||
public MySQLDatabaseHandlerJ(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
|
||||||
super(plugin, type, databaseConnecter);
|
|
||||||
connection = databaseConnecter.createConnection();
|
|
||||||
// Check if the table exists in the database and if not, create it
|
|
||||||
createSchema();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the table in the database if it doesn't exist already
|
|
||||||
*/
|
|
||||||
private void createSchema() {
|
|
||||||
StringBuilder sql = new StringBuilder();
|
|
||||||
sql.append("CREATE TABLE IF NOT EXISTS `");
|
|
||||||
sql.append(dataObject.getCanonicalName());
|
|
||||||
sql.append("` (json JSON, uniqueId VARCHAR(255) GENERATED ALWAYS AS (json->\"$.uniqueId\"), INDEX i (uniqueId) );");
|
|
||||||
// Prepare and execute the database statements
|
|
||||||
try (PreparedStatement pstmt = connection.prepareStatement(sql.toString())) {
|
|
||||||
pstmt.executeUpdate();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Problem trying to create schema for data object " + dataObject.getCanonicalName() + " " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> loadObjects() {
|
|
||||||
List<T> list = new ArrayList<>();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("SELECT `json` FROM `");
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("`");
|
|
||||||
try (Statement preparedStatement = connection.createStatement()) {
|
|
||||||
try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) {
|
|
||||||
// Load all the results
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
builder.registerTypeAdapter(Location.class, new LocationAdapter()) ;
|
|
||||||
Gson gson = builder.create();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
list.add(gson.fromJson(resultSet.getString("json"), dataObject));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Could not load objects " + e.getMessage());
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T loadObject(String uniqueId) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("SELECT `json` FROM `");
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("` WHERE uniqueId = ? LIMIT 1");
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
|
||||||
preparedStatement.setString(1, uniqueId);
|
|
||||||
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
|
||||||
while (resultSet.next()) {
|
|
||||||
// If there is a result, we only want/need the first one
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
builder.registerTypeAdapter(Location.class, new LocationAdapter()) ;
|
|
||||||
Gson gson = builder.create();
|
|
||||||
return gson.fromJson(resultSet.getString("json"), dataObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Could not load object " + uniqueId + " " + e.getMessage());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveObject(T instance) {
|
|
||||||
Bukkit.getLogger().severe(() -> "Saving object " + instance.getClass().getName());
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
// Replace into is used so that any data in the table will be replaced with updated data
|
|
||||||
sb.append("REPLACE INTO ");
|
|
||||||
sb.append("`");
|
|
||||||
// The table name is the canonical name, so that add-ons can be sure of a unique table in the database
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("` (json) VALUES (?)");
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
builder.registerTypeAdapter(Location.class, new LocationAdapter()) ;
|
|
||||||
Gson gson = builder.create();
|
|
||||||
preparedStatement.setString(1, gson.toJson(instance));
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe(() -> "Could not save object " + instance.getClass().getName() + " " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteObject(T instance) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("DELETE FROM `");
|
|
||||||
sb.append(dataObject.getCanonicalName());
|
|
||||||
sb.append("` WHERE uniqueId = ?");
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sb.toString())) {
|
|
||||||
Method getUniqueId = dataObject.getMethod("getUniqueId");
|
|
||||||
String uniqueId = (String) getUniqueId.invoke(instance);
|
|
||||||
preparedStatement.setString(1, uniqueId);
|
|
||||||
preparedStatement.executeQuery();
|
|
||||||
} catch (Exception e) {
|
|
||||||
plugin.getLogger().severe(() -> "Could not delete object " + instance.getClass().getName() + " " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#objectExists(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean objectExists(String key) {
|
|
||||||
// Create the query to see if this key exists
|
|
||||||
StringBuilder query = new StringBuilder();
|
|
||||||
query.append("SELECT IF ( EXISTS( SELECT * FROM `");
|
|
||||||
query.append(dataObject.getCanonicalName());
|
|
||||||
query.append("` WHERE `uniqueId` = ?), 1, 0)");
|
|
||||||
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(query.toString())) {
|
|
||||||
preparedStatement.setString(1, key);
|
|
||||||
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
|
||||||
if (resultSet.next()) {
|
|
||||||
return resultSet.getBoolean(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
plugin.getLogger().severe("Could not check if key exists in database! " + key + " " + e.getMessage());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveSettings(T instance)
|
|
||||||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
|
||||||
// This method should not be used because configs are not stored in MySQL
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T loadSettings(String uniqueId, T dbConfig) {
|
|
||||||
// This method should not be used because configs are not stored in MySQL
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package us.tastybento.bskyblock.database.mysqljson;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
|
||||||
import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
|
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
public class MySQLDatabaseJ extends BSBDatabase{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbstractDatabaseHandler<?> getHandler(Class<?> type) {
|
|
||||||
BSkyBlock plugin = BSkyBlock.getInstance();
|
|
||||||
return new MySQLDatabaseHandlerJ<>(plugin, type, new MySQLDatabaseConnecterJ(new DatabaseConnectionSettingsImpl(
|
|
||||||
plugin.getSettings().getDbHost(),
|
|
||||||
plugin.getSettings().getDbPort(),
|
|
||||||
plugin.getSettings().getDbName(),
|
|
||||||
plugin.getSettings().getDbUsername(),
|
|
||||||
plugin.getSettings().getDbPassword()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -7,24 +7,18 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSet.Builder;
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.api.events.IslandBaseEvent;
|
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent;
|
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent.IslandLockEvent;
|
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent.IslandUnlockEvent;
|
|
||||||
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
|
||||||
import us.tastybento.bskyblock.api.flags.Flag;
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.Adapter;
|
import us.tastybento.bskyblock.database.objects.adapters.Adapter;
|
||||||
import us.tastybento.bskyblock.database.objects.adapters.FlagSerializer;
|
import us.tastybento.bskyblock.database.objects.adapters.FlagSerializer;
|
||||||
@ -42,57 +36,71 @@ import us.tastybento.bskyblock.util.Util;
|
|||||||
*/
|
*/
|
||||||
public class Island implements DataObject {
|
public class Island implements DataObject {
|
||||||
|
|
||||||
private String uniqueId = "";
|
@Expose
|
||||||
|
private String uniqueId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
//// Island ////
|
//// Island ////
|
||||||
// The center of the island itself
|
// The center of the island itself
|
||||||
|
@Expose
|
||||||
private Location center;
|
private Location center;
|
||||||
|
|
||||||
// Island range
|
// Island range
|
||||||
|
@Expose
|
||||||
private int range;
|
private int range;
|
||||||
|
|
||||||
// Coordinates of the island area
|
// Coordinates of the island area
|
||||||
|
@Expose
|
||||||
private int minX;
|
private int minX;
|
||||||
|
@Expose
|
||||||
private int minZ;
|
private int minZ;
|
||||||
|
|
||||||
// Coordinates of minimum protected area
|
// Coordinates of minimum protected area
|
||||||
|
@Expose
|
||||||
private int minProtectedX;
|
private int minProtectedX;
|
||||||
|
@Expose
|
||||||
private int minProtectedZ;
|
private int minProtectedZ;
|
||||||
|
|
||||||
// Protection size
|
// Protection size
|
||||||
|
@Expose
|
||||||
private int protectionRange;
|
private int protectionRange;
|
||||||
|
|
||||||
// World the island is in
|
// World the island started in. This may be different from the island location
|
||||||
|
@Expose
|
||||||
private World world;
|
private World world;
|
||||||
|
|
||||||
// Display name
|
// Display name
|
||||||
private String name;
|
@Expose
|
||||||
|
private String name = "";
|
||||||
|
|
||||||
// Time parameters
|
// Time parameters
|
||||||
|
@Expose
|
||||||
private long createdDate;
|
private long createdDate;
|
||||||
|
@Expose
|
||||||
private long updatedDate;
|
private long updatedDate;
|
||||||
|
|
||||||
//// Team ////
|
//// Team ////
|
||||||
|
@Expose
|
||||||
private UUID owner;
|
private UUID owner;
|
||||||
|
|
||||||
|
@Expose
|
||||||
private Map<UUID, Integer> members = new HashMap<>();
|
private Map<UUID, Integer> members = new HashMap<>();
|
||||||
|
|
||||||
//// State ////
|
//// State ////
|
||||||
|
@Expose
|
||||||
private boolean locked = false;
|
private boolean locked = false;
|
||||||
|
@Expose
|
||||||
private boolean spawn = false;
|
private boolean spawn = false;
|
||||||
|
@Expose
|
||||||
private boolean purgeProtected = false;
|
private boolean purgeProtected = false;
|
||||||
|
|
||||||
//// Protection flags ////
|
//// Protection flags ////
|
||||||
@Adapter(FlagSerializer.class)
|
@Adapter(FlagSerializer.class)
|
||||||
|
@Expose
|
||||||
private Map<Flag, Integer> flags = new HashMap<>();
|
private Map<Flag, Integer> flags = new HashMap<>();
|
||||||
|
|
||||||
|
@Expose
|
||||||
private int levelHandicap;
|
private int levelHandicap;
|
||||||
|
@Expose
|
||||||
private Location spawnPoint;
|
private Location spawnPoint;
|
||||||
|
|
||||||
public Island() {}
|
public Island() {}
|
||||||
@ -126,7 +134,6 @@ public class Island implements DataObject {
|
|||||||
* @return true if successfully added
|
* @return true if successfully added
|
||||||
*/
|
*/
|
||||||
public boolean addToBanList(UUID targetUUID) {
|
public boolean addToBanList(UUID targetUUID) {
|
||||||
// TODO fire ban event
|
|
||||||
if (targetUUID != null) {
|
if (targetUUID != null) {
|
||||||
members.put(targetUUID, RanksManager.BANNED_RANK);
|
members.put(targetUUID, RanksManager.BANNED_RANK);
|
||||||
}
|
}
|
||||||
@ -247,15 +254,7 @@ public class Island implements DataObject {
|
|||||||
* @return the island display name or the owner's name if none is set
|
* @return the island display name or the owner's name if none is set
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if (name != null) {
|
return name;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
if (owner != null) {
|
|
||||||
OfflinePlayer player = Bukkit.getServer().getOfflinePlayer(owner);
|
|
||||||
name = player.getName();
|
|
||||||
return player.getName();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,7 +291,6 @@ public class Island implements DataObject {
|
|||||||
* @return rank integer
|
* @return rank integer
|
||||||
*/
|
*/
|
||||||
public int getRank(User user) {
|
public int getRank(User user) {
|
||||||
//Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId());
|
|
||||||
return members.getOrDefault(user.getUniqueId(), RanksManager.VISITOR_RANK);
|
return members.getOrDefault(user.getUniqueId(), RanksManager.VISITOR_RANK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,10 +351,6 @@ public class Island implements DataObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueId() {
|
public String getUniqueId() {
|
||||||
// Island's have UUID's that are randomly assigned if they do not exist
|
|
||||||
if (uniqueId.isEmpty()) {
|
|
||||||
uniqueId = UUID.randomUUID().toString();
|
|
||||||
}
|
|
||||||
return uniqueId;
|
return uniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,8 +396,7 @@ public class Island implements DataObject {
|
|||||||
* @return true if in the island space
|
* @return true if in the island space
|
||||||
*/
|
*/
|
||||||
public boolean inIslandSpace(int x, int z) {
|
public boolean inIslandSpace(int x, int z) {
|
||||||
//Bukkit.getLogger().info("DEBUG: center - " + center);
|
return x >= minX && x < minX + range*2 && z >= minZ && z < minZ + range*2;
|
||||||
return x >= minX && x < minX + range*2 && z >= minZ && z < minZ + range*2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean inIslandSpace(Location location) {
|
public boolean inIslandSpace(Location location) {
|
||||||
@ -439,7 +432,6 @@ public class Island implements DataObject {
|
|||||||
* @return true if allowed, false if not
|
* @return true if allowed, false if not
|
||||||
*/
|
*/
|
||||||
public boolean isAllowed(User user, Flag flag) {
|
public boolean isAllowed(User user, Flag flag) {
|
||||||
//Bukkit.getLogger().info("DEBUG: " + flag.getID() + " user score = " + getRank(user) + " flag req = "+ this.getFlagReq(flag));
|
|
||||||
return getRank(user) >= getFlag(flag);
|
return getRank(user) >= getFlag(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +479,6 @@ public class Island implements DataObject {
|
|||||||
* @return true if successful, otherwise false.
|
* @return true if successful, otherwise false.
|
||||||
*/
|
*/
|
||||||
public boolean removeFromBanList(UUID targetUUID) {
|
public boolean removeFromBanList(UUID targetUUID) {
|
||||||
// TODO fire unban event
|
|
||||||
members.remove(targetUUID);
|
members.remove(targetUUID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -543,24 +534,11 @@ public class Island implements DataObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locks/Unlocks the island. May be cancelled by
|
* Locks/Unlocks the island.
|
||||||
* {@link IslandLockEvent} or {@link IslandUnlockEvent}.
|
|
||||||
* @param locked - the lock state to set
|
* @param locked - the lock state to set
|
||||||
*/
|
*/
|
||||||
public void setLocked(boolean locked){
|
public void setLocked(boolean locked){
|
||||||
if(locked){
|
this.locked = locked;
|
||||||
// Lock the island
|
|
||||||
IslandBaseEvent event = IslandEvent.builder().island(this).reason(Reason.LOCK).build();
|
|
||||||
if(!event.isCancelled()){
|
|
||||||
this.locked = locked;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Unlock the island
|
|
||||||
IslandBaseEvent event = IslandEvent.builder().island(this).reason(Reason.UNLOCK).build();
|
|
||||||
if(!event.isCancelled()){
|
|
||||||
this.locked = locked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,8 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +20,19 @@ import us.tastybento.bskyblock.BSkyBlock;
|
|||||||
* @author tastybento
|
* @author tastybento
|
||||||
*/
|
*/
|
||||||
public class Players implements DataObject {
|
public class Players implements DataObject {
|
||||||
|
@Expose
|
||||||
private Map<Integer, Location> homeLocations = new HashMap<>();
|
private Map<Integer, Location> homeLocations = new HashMap<>();
|
||||||
|
@Expose
|
||||||
private String uniqueId;
|
private String uniqueId;
|
||||||
|
@Expose
|
||||||
private String playerName;
|
private String playerName;
|
||||||
|
@Expose
|
||||||
private int resetsLeft;
|
private int resetsLeft;
|
||||||
|
@Expose
|
||||||
private String locale = "";
|
private String locale = "";
|
||||||
|
@Expose
|
||||||
private int deaths;
|
private int deaths;
|
||||||
|
@Expose
|
||||||
private Map<Location, Long> kickedList = new HashMap<>();
|
private Map<Location, Long> kickedList = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,15 +73,6 @@ public class Players implements DataObject {
|
|||||||
* @return Location of this home or null if not available
|
* @return Location of this home or null if not available
|
||||||
*/
|
*/
|
||||||
public Location getHomeLocation(int number) {
|
public Location getHomeLocation(int number) {
|
||||||
/*
|
|
||||||
Bukkit.getLogger().info("DEBUG: getting home location " + number);
|
|
||||||
|
|
||||||
Bukkit.getLogger().info("DEBUG: " + homeLocations.toString());
|
|
||||||
for (Entry<Integer, Location> en : homeLocations.entrySet()) {
|
|
||||||
Bukkit.getLogger().info("DEBUG: " + en.getKey() + " ==> " + en.getValue());
|
|
||||||
if (number == en.getKey())
|
|
||||||
Bukkit.getLogger().info("DEBUG: key = number");
|
|
||||||
}*/
|
|
||||||
return homeLocations.get(number);
|
return homeLocations.get(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,6 @@ public class Players implements DataObject {
|
|||||||
* @param homeLocations the homeLocations to set
|
* @param homeLocations the homeLocations to set
|
||||||
*/
|
*/
|
||||||
public void setHomeLocations(Map<Integer, Location> homeLocations) {
|
public void setHomeLocations(Map<Integer, Location> homeLocations) {
|
||||||
//Bukkit.getLogger().info("DEBUG: " + homeLocations.toString());
|
|
||||||
this.homeLocations = homeLocations;
|
this.homeLocations = homeLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +165,7 @@ public class Players implements DataObject {
|
|||||||
* Set the uuid for this player object
|
* Set the uuid for this player object
|
||||||
* @param uuid - UUID
|
* @param uuid - UUID
|
||||||
*/
|
*/
|
||||||
public void setPlayerUUID(final UUID uuid) {
|
public void setPlayerUUID(UUID uuid) {
|
||||||
uniqueId = uuid.toString();
|
uniqueId = uuid.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.Constants;
|
import us.tastybento.bskyblock.Constants;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.database.managers.PlayersManager;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.managers.PlayersManager;
|
||||||
|
|
||||||
public class JoinLeaveListener implements Listener {
|
public class JoinLeaveListener implements Listener {
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ import us.tastybento.bskyblock.BSkyBlock;
|
|||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.api.flags.Flag;
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
import us.tastybento.bskyblock.api.flags.Flag.Type;
|
import us.tastybento.bskyblock.api.flags.Flag.Type;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for flag listeners. Provides common code.
|
* Abstract class for flag listeners. Provides common code.
|
||||||
|
@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package us.tastybento.bskyblock.database.managers.island;
|
package us.tastybento.bskyblock.managers;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -23,9 +23,10 @@ import org.bukkit.util.Vector;
|
|||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.Constants;
|
import us.tastybento.bskyblock.Constants;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.managers.island.IslandCache;
|
||||||
import us.tastybento.bskyblock.util.DeleteIslandChunks;
|
import us.tastybento.bskyblock.util.DeleteIslandChunks;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.util.Util;
|
||||||
import us.tastybento.bskyblock.util.teleport.SafeTeleportBuilder;
|
import us.tastybento.bskyblock.util.teleport.SafeTeleportBuilder;
|
||||||
@ -744,6 +745,7 @@ public class IslandsManager {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
plugin.getLogger().severe("Could not load islands to cache! " + e.getMessage());
|
plugin.getLogger().severe("Could not load islands to cache! " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
plugin.getLogger().info("DEBUG: islands loaded");
|
plugin.getLogger().info("DEBUG: islands loaded");
|
@ -1,4 +1,4 @@
|
|||||||
package us.tastybento.bskyblock.database.managers;
|
package us.tastybento.bskyblock.managers;
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
import java.beans.IntrospectionException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -19,13 +19,14 @@ import org.bukkit.entity.Player;
|
|||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.Constants;
|
import us.tastybento.bskyblock.Constants;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
|
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
import us.tastybento.bskyblock.database.BSBDatabase;
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
import us.tastybento.bskyblock.database.objects.Players;
|
import us.tastybento.bskyblock.database.objects.Players;
|
||||||
|
|
||||||
public class PlayersManager{
|
public class PlayersManager{
|
||||||
|
|
||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = false;
|
||||||
private BSkyBlock plugin;
|
private BSkyBlock plugin;
|
||||||
private BSBDatabase database;
|
private BSBDatabase database;
|
||||||
private AbstractDatabaseHandler<Players> handler;
|
private AbstractDatabaseHandler<Players> handler;
|
@ -0,0 +1,392 @@
|
|||||||
|
package us.tastybento.bskyblock.managers.island;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import com.google.common.collect.BiMap;
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.util.Util;
|
||||||
|
|
||||||
|
public class IslandCache {
|
||||||
|
private static final boolean DEBUG2 = false;
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
private BSkyBlock plugin = BSkyBlock.getInstance();
|
||||||
|
private BiMap<Location, Island> islandsByLocation;
|
||||||
|
/**
|
||||||
|
* Every player who is associated with an island is in this map.
|
||||||
|
*/
|
||||||
|
private HashMap<UUID, Island> islandsByUUID;
|
||||||
|
// 2D islandGrid of islands, x,z
|
||||||
|
private TreeMap<Integer, TreeMap<Integer, Island>> islandGrid = new TreeMap<>();
|
||||||
|
|
||||||
|
public IslandCache() {
|
||||||
|
islandsByLocation = HashBiMap.create();
|
||||||
|
islandsByUUID = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an island to the grid
|
||||||
|
* @param island
|
||||||
|
*/
|
||||||
|
public void addIsland(Island island) {
|
||||||
|
islandsByLocation.put(island.getCenter(), island);
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: owner = " + island.getOwner());
|
||||||
|
}
|
||||||
|
islandsByUUID.put(island.getOwner(), island);
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: island has " + island.getMemberSet().size() + " members");
|
||||||
|
}
|
||||||
|
for (UUID member: island.getMemberSet()) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: " + member);
|
||||||
|
}
|
||||||
|
islandsByUUID.put(member, island);
|
||||||
|
}
|
||||||
|
addToGrid(island);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPlayer(UUID playerUUID, Island teamIsland) {
|
||||||
|
islandsByUUID.put(playerUUID, teamIsland);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an island to the grid register
|
||||||
|
* @param newIsland
|
||||||
|
*/
|
||||||
|
private void addToGrid(Island newIsland) {
|
||||||
|
if (islandGrid.containsKey(newIsland.getMinX())) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: min x is in the grid :" + newIsland.getMinX());
|
||||||
|
}
|
||||||
|
TreeMap<Integer, Island> zEntry = islandGrid.get(newIsland.getMinX());
|
||||||
|
if (zEntry.containsKey(newIsland.getMinZ())) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: min z is in the grid :" + newIsland.getMinZ());
|
||||||
|
}
|
||||||
|
// Island already exists
|
||||||
|
Island conflict = islandGrid.get(newIsland.getMinX()).get(newIsland.getMinZ());
|
||||||
|
plugin.getLogger().warning("*** Duplicate or overlapping islands! ***");
|
||||||
|
plugin.getLogger().warning(
|
||||||
|
"Island at (" + newIsland.getCenter().getBlockX() + ", " + newIsland.getCenter().getBlockZ() + ") conflicts with ("
|
||||||
|
+ conflict.getCenter().getBlockX() + ", " + conflict.getCenter().getBlockZ() + ")");
|
||||||
|
if (conflict.getOwner() != null) {
|
||||||
|
plugin.getLogger().warning("Accepted island is owned by " + plugin.getPlayers().getName(conflict.getOwner()));
|
||||||
|
plugin.getLogger().warning(conflict.getOwner().toString() + ".yml");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warning("Accepted island is unowned.");
|
||||||
|
}
|
||||||
|
if (newIsland.getOwner() != null) {
|
||||||
|
plugin.getLogger().warning("Denied island is owned by " + plugin.getPlayers().getName(newIsland.getOwner()));
|
||||||
|
plugin.getLogger().warning(newIsland.getOwner().toString() + ".yml");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warning("Denied island is unowned and was just found in the islands folder. Skipping it...");
|
||||||
|
}
|
||||||
|
plugin.getLogger().warning("Recommend that the denied player file is deleted otherwise weird things can happen.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Add island
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: added island to grid at " + newIsland.getMinX() + "," + newIsland.getMinZ());
|
||||||
|
}
|
||||||
|
zEntry.put(newIsland.getMinZ(), newIsland);
|
||||||
|
islandGrid.put(newIsland.getMinX(), zEntry);
|
||||||
|
// plugin.getLogger().info("Debug: " + newIsland.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add island
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: added island to grid at " + newIsland.getMinX() + "," + newIsland.getMinZ());
|
||||||
|
}
|
||||||
|
TreeMap<Integer, Island> zEntry = new TreeMap<>();
|
||||||
|
zEntry.put(newIsland.getMinZ(), newIsland);
|
||||||
|
islandGrid.put(newIsland.getMinX(), zEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
islandsByLocation.clear();
|
||||||
|
islandsByUUID.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Island createIsland(Island island) {
|
||||||
|
islandsByLocation.put(island.getCenter(), island);
|
||||||
|
if (island.getOwner() != null) {
|
||||||
|
islandsByUUID.put(island.getOwner(), island);
|
||||||
|
}
|
||||||
|
addToGrid(island);
|
||||||
|
return island;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an island with no owner at location
|
||||||
|
* @param location - the location
|
||||||
|
*/
|
||||||
|
public Island createIsland(Location location){
|
||||||
|
return createIsland(location, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an island with owner. Note this does not create the schematic. It just creates the island data object.
|
||||||
|
* @param location - the location
|
||||||
|
* @param owner - the island owner UUID
|
||||||
|
*/
|
||||||
|
public Island createIsland(Location location, UUID owner){
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: adding island for " + owner + " at " + location);
|
||||||
|
}
|
||||||
|
Island island = new Island(location, owner, plugin.getSettings().getIslandProtectionRange());
|
||||||
|
islandsByLocation.put(location, island);
|
||||||
|
if (owner != null) {
|
||||||
|
islandsByUUID.put(owner, island);
|
||||||
|
}
|
||||||
|
addToGrid(island);
|
||||||
|
return island;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an island from the database. Does not remove blocks
|
||||||
|
* @param island
|
||||||
|
*/
|
||||||
|
public void deleteIslandFromCache(Island island) {
|
||||||
|
if (!islandsByLocation.remove(island.getCenter(), island)) {
|
||||||
|
plugin.getLogger().severe("Could not remove island from cache!");
|
||||||
|
}
|
||||||
|
Iterator<Entry<UUID, Island>> it = islandsByUUID.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entry<UUID, Island> en = it.next();
|
||||||
|
if (en.getValue().equals(island)) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove from grid
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: deleting island at " + island.getCenter());
|
||||||
|
}
|
||||||
|
if (island != null) {
|
||||||
|
int x = island.getMinX();
|
||||||
|
int z = island.getMinZ();
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: x = " + x + " z = " + z);
|
||||||
|
}
|
||||||
|
if (islandGrid.containsKey(x)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: x found");
|
||||||
|
}
|
||||||
|
TreeMap<Integer, Island> zEntry = islandGrid.get(x);
|
||||||
|
if (zEntry.containsKey(z)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: z found - deleting the island");
|
||||||
|
}
|
||||||
|
// Island exists - delete it
|
||||||
|
zEntry.remove(z);
|
||||||
|
islandGrid.put(x, zEntry);
|
||||||
|
} else {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: could not find z");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Island get(Location location) {
|
||||||
|
return islandsByLocation.get(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Island get(UUID uuid) {
|
||||||
|
return islandsByUUID.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the island for this player. If they are in a team, the team island is returned
|
||||||
|
* @param uuid - UUID
|
||||||
|
* @return Island
|
||||||
|
*/
|
||||||
|
public Island getIsland(UUID uuid){
|
||||||
|
return islandsByUUID.get(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the island at the x,z location or null if there is none.
|
||||||
|
* This includes the full island space, not just the protected area.
|
||||||
|
*
|
||||||
|
* @param x - x coordinate
|
||||||
|
* @param z - z coordinate
|
||||||
|
* @return Island or null
|
||||||
|
*/
|
||||||
|
public Island getIslandAt(int x, int z) {
|
||||||
|
if (DEBUG2) {
|
||||||
|
plugin.getLogger().info("DEBUG: getting island at " + x + "," + z);
|
||||||
|
plugin.getLogger().info("DEBUG: island grid is " + islandGrid.size());
|
||||||
|
}
|
||||||
|
Entry<Integer, TreeMap<Integer, Island>> en = islandGrid.floorEntry(x);
|
||||||
|
if (en != null) {
|
||||||
|
Entry<Integer, Island> ent = en.getValue().floorEntry(z);
|
||||||
|
if (ent != null) {
|
||||||
|
// Check if in the island range
|
||||||
|
Island island = ent.getValue();
|
||||||
|
if (island.inIslandSpace(x, z)) {
|
||||||
|
if (DEBUG2) {
|
||||||
|
plugin.getLogger().info("DEBUG: In island space");
|
||||||
|
}
|
||||||
|
return island;
|
||||||
|
}
|
||||||
|
if (DEBUG2) {
|
||||||
|
plugin.getLogger().info("DEBUG: not in island space");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the island at the location or null if there is none.
|
||||||
|
* This includes the full island space, not just the protected area
|
||||||
|
*
|
||||||
|
* @param location - the location
|
||||||
|
* @return Island object
|
||||||
|
*/
|
||||||
|
public Island getIslandAt(Location location) {
|
||||||
|
if (location == null) {
|
||||||
|
//plugin.getLogger().info("DEBUG: location is null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// World check
|
||||||
|
if (!Util.inWorld(location)) {
|
||||||
|
//plugin.getLogger().info("DEBUG: not in right world");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getIslandAt(location.getBlockX(), location.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the player's island location.
|
||||||
|
* Returns an island location OR a team island location
|
||||||
|
*
|
||||||
|
* @param playerUUID - the player's UUID
|
||||||
|
* @return Location of player's island or null if one does not exist
|
||||||
|
*/
|
||||||
|
public Location getIslandLocation(UUID playerUUID) {
|
||||||
|
if (hasIsland(playerUUID)) {
|
||||||
|
return getIsland(playerUUID).getCenter();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get name of the island owned by owner
|
||||||
|
* @param owner - the island owner
|
||||||
|
* @return Returns the name of owner's island, or the owner's name if there is none.
|
||||||
|
*/
|
||||||
|
public String getIslandName(UUID owner) {
|
||||||
|
String result = plugin.getPlayers().getName(owner);
|
||||||
|
if (islandsByUUID.containsKey(owner)) {
|
||||||
|
Island island = islandsByUUID.get(owner);
|
||||||
|
if (island.getName() != null && !island.getName().isEmpty()) {
|
||||||
|
result = island.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ChatColor.translateAlternateColorCodes('&', result) + ChatColor.RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Island> getIslands() {
|
||||||
|
return Collections.unmodifiableCollection(islandsByLocation.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<UUID> getMembers(UUID playerUUID) {
|
||||||
|
Island island = islandsByUUID.get(playerUUID);
|
||||||
|
if (island != null) {
|
||||||
|
return island.getMemberSet();
|
||||||
|
}
|
||||||
|
return new HashSet<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getTeamLeader(UUID playerUUID) {
|
||||||
|
if (islandsByUUID.containsKey(playerUUID)) {
|
||||||
|
return islandsByUUID.get(playerUUID).getOwner();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param playerUUID - the player's UUID
|
||||||
|
* @return true if player has island and owns it
|
||||||
|
*/
|
||||||
|
public boolean hasIsland(UUID playerUUID) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: checking if " + playerUUID + " has an island");
|
||||||
|
plugin.getLogger().info("DEBUG: islandsByUUID : " + islandsByUUID.toString());
|
||||||
|
|
||||||
|
if (!islandsByUUID.containsKey(playerUUID)) {
|
||||||
|
plugin.getLogger().info("DEBUG: player is not in islandsByUUID");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().info("DEBUG: owner = " + islandsByUUID.get(playerUUID).getOwner());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (islandsByUUID.containsKey(playerUUID) && islandsByUUID.get(playerUUID).getOwner() != null) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: checking for equals");
|
||||||
|
}
|
||||||
|
if (islandsByUUID.get(playerUUID).getOwner().equals(playerUUID)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: has island");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: doesn't have island");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayer(UUID playerUUID) {
|
||||||
|
Island island = islandsByUUID.get(playerUUID);
|
||||||
|
if (island != null) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: island found");
|
||||||
|
}
|
||||||
|
if (island.getOwner() != null && island.getOwner().equals(playerUUID)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: player is the owner of this island");
|
||||||
|
}
|
||||||
|
// Clear ownership and members
|
||||||
|
island.getMembers().clear();
|
||||||
|
island.setOwner(null);
|
||||||
|
}
|
||||||
|
island.removeMember(playerUUID);
|
||||||
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: removing reference to island by UUID");
|
||||||
|
}
|
||||||
|
islandsByUUID.remove(playerUUID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIslandName(UUID owner, String name) {
|
||||||
|
if (islandsByUUID.containsKey(owner)) {
|
||||||
|
Island island = islandsByUUID.get(owner);
|
||||||
|
island.setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return islandsByLocation.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,252 @@
|
|||||||
|
package us.tastybento.bskyblock.managers.island;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.api.events.IslandBaseEvent;
|
||||||
|
import us.tastybento.bskyblock.api.events.island.IslandEvent;
|
||||||
|
import us.tastybento.bskyblock.api.events.island.IslandEvent.Reason;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.island.builders.IslandBuilder;
|
||||||
|
import us.tastybento.bskyblock.island.builders.IslandBuilder.IslandType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and paste a new island
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class NewIsland {
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
private BSkyBlock plugin;
|
||||||
|
private Island island;
|
||||||
|
private final Player player;
|
||||||
|
private final Reason reason;
|
||||||
|
|
||||||
|
private NewIsland(Island oldIsland, Player player, Reason reason) {
|
||||||
|
super();
|
||||||
|
plugin = BSkyBlock.getInstance();
|
||||||
|
this.player = player;
|
||||||
|
this.reason = reason;
|
||||||
|
newIsland();
|
||||||
|
if (oldIsland != null) {
|
||||||
|
// Delete the old island
|
||||||
|
plugin.getIslands().deleteIsland(oldIsland, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the island that was created
|
||||||
|
*/
|
||||||
|
public Island getIsland() {
|
||||||
|
return island;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start building a new island
|
||||||
|
* @return New island builder object
|
||||||
|
*/
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a new island for a player using a schematic
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
private Island oldIsland;
|
||||||
|
private Player player;
|
||||||
|
private Reason reason;
|
||||||
|
|
||||||
|
public Builder oldIsland(Island oldIsland) {
|
||||||
|
this.oldIsland = oldIsland;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Builder player(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder reason(Reason reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Island build() throws IOException {
|
||||||
|
if (player != null) {
|
||||||
|
NewIsland newIsland = new NewIsland(oldIsland, player, reason);
|
||||||
|
return newIsland.getIsland();
|
||||||
|
}
|
||||||
|
throw new IOException("Insufficient parameters. Must have a schematic and a player");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an island.
|
||||||
|
*/
|
||||||
|
public void newIsland() {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: new island");
|
||||||
|
}
|
||||||
|
//long time = System.nanoTime();
|
||||||
|
final UUID playerUUID = player.getUniqueId();
|
||||||
|
/*
|
||||||
|
boolean firstTime = false;
|
||||||
|
if (!plugin.getPlayers().hasIsland(playerUUID)) {
|
||||||
|
firstTime = true;
|
||||||
|
}*/
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: finding island location");
|
||||||
|
}
|
||||||
|
Location next = getNextIsland();
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: found " + next);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the grid
|
||||||
|
island = plugin.getIslands().createIsland(next, playerUUID);
|
||||||
|
// Save the player so that if the server is reset weird things won't happen
|
||||||
|
//plugin.getPlayers().save(true);
|
||||||
|
//plugin.getIslands().save(true);
|
||||||
|
|
||||||
|
// Clear any old home locations (they should be clear, but just in case)
|
||||||
|
plugin.getPlayers().clearHomeLocations(playerUUID);
|
||||||
|
|
||||||
|
// Set the biome
|
||||||
|
//BiomesPanel.setIslandBiome(next, schematic.getBiome());
|
||||||
|
// Set home loction
|
||||||
|
plugin.getPlayers().setHomeLocation(playerUUID, next, 1);
|
||||||
|
|
||||||
|
// Fire event
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: firing event");
|
||||||
|
}
|
||||||
|
IslandBaseEvent event = IslandEvent.builder()
|
||||||
|
.involvedPlayer(player.getUniqueId())
|
||||||
|
.reason(reason)
|
||||||
|
.island(island)
|
||||||
|
.location(island.getCenter())
|
||||||
|
.build();
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: event cancelled status = " + event.isCancelled());
|
||||||
|
}
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
// Create island
|
||||||
|
new IslandBuilder(plugin, island)
|
||||||
|
.setPlayer(player)
|
||||||
|
.setChestItems(plugin.getSettings().getChestItems())
|
||||||
|
.setType(IslandType.ISLAND)
|
||||||
|
.build();
|
||||||
|
if (plugin.getSettings().isNetherGenerate() && plugin.getSettings().isNetherIslands() && plugin.getIslandWorldManager().getNetherWorld() != null) {
|
||||||
|
new IslandBuilder(plugin,island)
|
||||||
|
.setPlayer(player)
|
||||||
|
.setChestItems(plugin.getSettings().getChestItems())
|
||||||
|
.setType(IslandType.NETHER)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
if (plugin.getSettings().isEndGenerate() && plugin.getSettings().isEndIslands() && plugin.getIslandWorldManager().getEndWorld() != null) {
|
||||||
|
new IslandBuilder(plugin,island)
|
||||||
|
.setPlayer(player)
|
||||||
|
.setChestItems(plugin.getSettings().getChestItems())
|
||||||
|
.setType(IslandType.END)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
// Teleport player to their island
|
||||||
|
plugin.getIslands().homeTeleport(player);
|
||||||
|
// Fire exit event
|
||||||
|
Reason reasonDone = Reason.CREATED;
|
||||||
|
switch (reason) {
|
||||||
|
case CREATE:
|
||||||
|
reasonDone = Reason.CREATED;
|
||||||
|
break;
|
||||||
|
case RESET:
|
||||||
|
reasonDone = Reason.RESETTED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IslandEvent.builder()
|
||||||
|
.involvedPlayer(player.getUniqueId())
|
||||||
|
.reason(reasonDone)
|
||||||
|
.island(island)
|
||||||
|
.location(island.getCenter())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the location of next free island spot
|
||||||
|
* @return Location of island spot
|
||||||
|
*/
|
||||||
|
private Location getNextIsland() {
|
||||||
|
Location last = plugin.getIslands().getLast();
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: last = " + last);
|
||||||
|
// Find the next free spot
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last == null) {
|
||||||
|
last = new Location(plugin.getIslandWorldManager().getIslandWorld(), plugin.getSettings().getIslandXOffset() + plugin.getSettings().getIslandStartX(),
|
||||||
|
plugin.getSettings().getIslandHeight(), plugin.getSettings().getIslandZOffset() + plugin.getSettings().getIslandStartZ());
|
||||||
|
}
|
||||||
|
Location next = last.clone();
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: last 2 = " + last);
|
||||||
|
}
|
||||||
|
while (plugin.getIslands().isIsland(next)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: getting next loc");
|
||||||
|
}
|
||||||
|
next = nextGridLocation(next);
|
||||||
|
}
|
||||||
|
// Make the last next, last
|
||||||
|
last = next.clone();
|
||||||
|
if (DEBUG) {
|
||||||
|
plugin.getLogger().info("DEBUG: last 3 = " + last);
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the next free island spot based off the last known island Uses
|
||||||
|
* island_distance setting from the config file Builds up in a grid fashion
|
||||||
|
*
|
||||||
|
* @param lastIsland
|
||||||
|
* @return Location of next free island
|
||||||
|
*/
|
||||||
|
private Location nextGridLocation(final Location lastIsland) {
|
||||||
|
int x = lastIsland.getBlockX();
|
||||||
|
int z = lastIsland.getBlockZ();
|
||||||
|
Location nextPos = lastIsland;
|
||||||
|
if (x < z) {
|
||||||
|
if (-1 * x < z) {
|
||||||
|
nextPos.setX(nextPos.getX() + plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
nextPos.setZ(nextPos.getZ() + plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
if (x > z) {
|
||||||
|
if (-1 * x >= z) {
|
||||||
|
nextPos.setX(nextPos.getX() - plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
nextPos.setZ(nextPos.getZ() - plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
if (x <= 0) {
|
||||||
|
nextPos.setZ(nextPos.getZ() + plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
nextPos.setZ(nextPos.getZ() - plugin.getSettings().getIslandDistance()*2);
|
||||||
|
return nextPos;
|
||||||
|
}
|
||||||
|
}
|
@ -56,12 +56,12 @@ import us.tastybento.bskyblock.api.events.IslandBaseEvent;
|
|||||||
import us.tastybento.bskyblock.api.events.team.TeamEvent;
|
import us.tastybento.bskyblock.api.events.team.TeamEvent;
|
||||||
import us.tastybento.bskyblock.api.flags.Flag;
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
import us.tastybento.bskyblock.api.flags.FlagBuilder;
|
import us.tastybento.bskyblock.api.flags.FlagBuilder;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||||
import us.tastybento.bskyblock.listeners.flags.AbstractFlagListener;
|
import us.tastybento.bskyblock.listeners.flags.AbstractFlagListener;
|
||||||
import us.tastybento.bskyblock.lists.Flags;
|
import us.tastybento.bskyblock.lists.Flags;
|
||||||
import us.tastybento.bskyblock.managers.FlagsManager;
|
import us.tastybento.bskyblock.managers.FlagsManager;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
import us.tastybento.bskyblock.managers.RanksManager;
|
import us.tastybento.bskyblock.managers.RanksManager;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.util.Util;
|
||||||
|
|
||||||
|
@ -1,57 +1,81 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package us.tastybento.bskyblock.database.mysql;
|
package us.tastybento.bskyblock.database.mysql;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.inventory.ItemFactory;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import org.powermock.reflect.Whitebox;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.Settings;
|
||||||
|
import us.tastybento.bskyblock.api.flags.Flag;
|
||||||
|
import us.tastybento.bskyblock.database.mysql.MySQLDatabaseConnecter;
|
||||||
|
import us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Players;
|
||||||
|
import us.tastybento.bskyblock.lists.Flags;
|
||||||
|
|
||||||
/**
|
@RunWith(PowerMockRunner.class)
|
||||||
* @author ben
|
@PrepareForTest( { BSkyBlock.class })
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MySQLDatabaseHandlerTest {
|
public class MySQLDatabaseHandlerTest {
|
||||||
|
|
||||||
private static MySQLDatabaseHandler<MySQLDatabaseHandlerTestDataObject> handler;
|
private static MySQLDatabaseHandler<Island> handler;
|
||||||
private static MySQLDatabaseHandlerTestDataObject instance;
|
private static Island instance;
|
||||||
private static String UNIQUE_ID = "xyz";
|
private static String UNIQUE_ID = "xyz";
|
||||||
|
private static MySQLDatabaseConnecter dbConn;
|
||||||
|
private static World world;
|
||||||
|
@Mock
|
||||||
|
static BSkyBlock plugin = mock(BSkyBlock.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws java.lang.Exception
|
|
||||||
*/
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws Exception {
|
public static void setUpBeforeClass() throws Exception {
|
||||||
Server server = mock(Server.class);
|
Server server = mock(Server.class);
|
||||||
World world = mock(World.class);
|
world = mock(World.class);
|
||||||
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
when(server.getWorld("world")).thenReturn(world);
|
when(server.getWorld("world")).thenReturn(world);
|
||||||
when(server.getVersion()).thenReturn("BSB_Mocking");
|
when(server.getVersion()).thenReturn("BSB_Mocking");
|
||||||
|
|
||||||
|
PluginManager pluginManager = mock(PluginManager.class);
|
||||||
|
when(server.getPluginManager()).thenReturn(pluginManager);
|
||||||
|
|
||||||
|
ItemFactory itemFactory = mock(ItemFactory.class);
|
||||||
|
when(server.getItemFactory()).thenReturn(itemFactory);
|
||||||
|
|
||||||
Bukkit.setServer(server);
|
Bukkit.setServer(server);
|
||||||
|
|
||||||
BSkyBlock plugin = mock(BSkyBlock.class);
|
|
||||||
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
MySQLDatabaseConnecter dbConn = mock(MySQLDatabaseConnecter.class);
|
|
||||||
|
Whitebox.setInternalState(BSkyBlock.class, "instance", plugin);
|
||||||
|
|
||||||
|
Settings settings = mock(Settings.class);
|
||||||
|
|
||||||
|
when(plugin.getSettings()).thenReturn(settings);
|
||||||
|
when(settings.getDeathsMax()).thenReturn(10);
|
||||||
|
|
||||||
|
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
||||||
|
dbConn = mock(MySQLDatabaseConnecter.class);
|
||||||
Connection connection = mock(Connection.class);
|
Connection connection = mock(Connection.class);
|
||||||
when(dbConn.createConnection()).thenReturn(connection);
|
when(dbConn.createConnection()).thenReturn(connection);
|
||||||
PreparedStatement ps = mock(PreparedStatement.class);
|
PreparedStatement ps = mock(PreparedStatement.class);
|
||||||
@ -61,152 +85,74 @@ public class MySQLDatabaseHandlerTest {
|
|||||||
ResultSet rs = mock(ResultSet.class);
|
ResultSet rs = mock(ResultSet.class);
|
||||||
when(ps.executeQuery()).thenReturn(rs);
|
when(ps.executeQuery()).thenReturn(rs);
|
||||||
when(statement.executeQuery(Mockito.anyString())).thenReturn(rs);
|
when(statement.executeQuery(Mockito.anyString())).thenReturn(rs);
|
||||||
instance = new MySQLDatabaseHandlerTestDataObject();
|
instance = new Island();
|
||||||
instance.setUniqueId(UNIQUE_ID);
|
instance.setUniqueId(UNIQUE_ID);
|
||||||
handler = new MySQLDatabaseHandler<>(plugin, MySQLDatabaseHandlerTestDataObject.class, dbConn);
|
handler = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#getColumns(boolean)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testGetColumns() {
|
|
||||||
// This should be a list of 20 ?'s which related to the 20
|
|
||||||
assertEquals("?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?", handler.getColumns(true));
|
|
||||||
assertEquals("`uniqueId`, `center`, `range`, `minX`, `minZ`, `minProtectedX`, `minProtectedZ`, " +
|
|
||||||
"`protectionRange`, `world`, `name`, `createdDate`, `updatedDate`, `owner`, `members`, `locked`, " +
|
|
||||||
"`spawn`, `purgeProtected`, `flags`, `levelHandicap`, `spawnPoint`",
|
|
||||||
handler.getColumns(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#createSelectQuery()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreateSelectQuery() {
|
|
||||||
assertEquals("SELECT `uniqueId`, `center`, `range`, `minX`, `minZ`, `minProtectedX`, " +
|
|
||||||
"`minProtectedZ`, `protectionRange`, `world`, `name`, `createdDate`, `updatedDate`, " +
|
|
||||||
"`owner`, `members`, `locked`, `spawn`, `purgeProtected`, `flags`, `levelHandicap`, " +
|
|
||||||
"`spawnPoint` FROM `us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandlerTestDataObject`",
|
|
||||||
handler.createSelectQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#createInsertQuery()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreateInsertQuery() {
|
|
||||||
assertEquals("REPLACE INTO `us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandlerTestDataObject`(`uniqueId`, " +
|
|
||||||
"`center`, `range`, `minX`, `minZ`, `minProtectedX`, `minProtectedZ`, `protectionRange`, " +
|
|
||||||
"`world`, `name`, `createdDate`, `updatedDate`, `owner`, `members`, `locked`, `spawn`, " +
|
|
||||||
"`purgeProtected`, `flags`, `levelHandicap`, `spawnPoint`) " +
|
|
||||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
||||||
handler.createInsertQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#createDeleteQuery()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testCreateDeleteQuery() {
|
|
||||||
assertEquals("DELETE FROM [table_name] WHERE uniqueId = ?", handler.createDeleteQuery());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#loadObjects()}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testLoadObjects() {
|
|
||||||
try {
|
|
||||||
java.util.List<MySQLDatabaseHandlerTestDataObject> result = handler.loadObjects();
|
|
||||||
System.out.println("Size of result " + result.size());
|
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
|
||||||
| InvocationTargetException | ClassNotFoundException | SQLException | IntrospectionException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#loadObject(java.lang.String)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testLoadObject() {
|
|
||||||
try {
|
|
||||||
MySQLDatabaseHandlerTestDataObject obj = (MySQLDatabaseHandlerTestDataObject) handler.loadObject(UNIQUE_ID);
|
|
||||||
assertNull(obj);
|
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#saveObject(java.lang.Object)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testSaveObject() {
|
public void testSaveObject() {
|
||||||
try {
|
handler.saveObject(instance);
|
||||||
handler.saveObject(instance);
|
BSkyBlock plugin = mock(BSkyBlock.class);
|
||||||
} catch (SecurityException | IllegalArgumentException | InstantiationException | IllegalAccessException
|
Settings settings = mock(Settings.class);
|
||||||
| InvocationTargetException | NoSuchMethodException | SQLException | IntrospectionException e) {
|
when(plugin.getSettings()).thenReturn(settings);
|
||||||
// TODO Auto-generated catch block
|
when(settings.getDeathsMax()).thenReturn(10);
|
||||||
e.printStackTrace();
|
Players players = new Players();
|
||||||
}
|
players.setUniqueId(UUID.randomUUID().toString());
|
||||||
}
|
players.setDeaths(23);
|
||||||
|
Location location = mock(Location.class);
|
||||||
|
Mockito.when(location.getWorld()).thenReturn(world);
|
||||||
|
Mockito.when(location.getBlockX()).thenReturn(0);
|
||||||
|
Mockito.when(location.getBlockY()).thenReturn(0);
|
||||||
|
Mockito.when(location.getBlockZ()).thenReturn(0);
|
||||||
|
|
||||||
/**
|
players.setHomeLocation(location);
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#deleteObject(java.lang.Object)}.
|
players.setHomeLocation(location, 1);
|
||||||
*/
|
players.setHomeLocation(location, 2);
|
||||||
@Test
|
Map<Location, Long> map = new HashMap<>();
|
||||||
public void testDeleteObject() {
|
map.put(location, 324L);
|
||||||
try {
|
players.setKickedList(map);
|
||||||
handler.deleteObject(instance);
|
players.setLocale("sdfsd");
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
|
players.setPlayerName("name");
|
||||||
| SecurityException | IntrospectionException | SQLException e) {
|
players.setPlayerUUID(UUID.randomUUID());
|
||||||
// TODO Auto-generated catch block
|
players.setResetsLeft(3);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#objectExists(java.lang.String)}.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testObjectExits() {
|
|
||||||
// This right now is not tested properly
|
|
||||||
assertFalse(handler.objectExists(UNIQUE_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
MySQLDatabaseHandler<Players> h = new MySQLDatabaseHandler<>(plugin, Players.class, dbConn);
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#saveSettings(java.lang.Object)}.
|
h.saveObject(players);
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSaveSettings() {
|
|
||||||
try {
|
|
||||||
handler.saveSettings(instance);
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| IntrospectionException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
Island island = new Island();
|
||||||
* Test method for {@link us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandler#loadSettings(java.lang.String, java.lang.Object)}.
|
island.setUniqueId(UNIQUE_ID);
|
||||||
*/
|
island.setCenter(location);
|
||||||
@Test
|
Map<Flag, Integer> flags = new HashMap<>();
|
||||||
public void testLoadSettings() {
|
for (Flag fl : Flags.values()) {
|
||||||
try {
|
flags.put(fl, 100);
|
||||||
handler.loadSettings(UNIQUE_ID, instance);
|
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| ClassNotFoundException | IntrospectionException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
island.setFlags(flags);
|
||||||
|
island.setLevelHandicap(10);
|
||||||
|
island.setLocked(true);
|
||||||
|
Map<UUID, Integer> members = new HashMap<>();
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
members.put(UUID.randomUUID(), i);
|
||||||
|
}
|
||||||
|
island.setMembers(members);
|
||||||
|
island.setMinProtectedX(-100);
|
||||||
|
island.setMinProtectedZ(-300);
|
||||||
|
island.setMinX(-121);
|
||||||
|
island.setMinZ(-23423);
|
||||||
|
island.setName("ytasdgfsdfg");
|
||||||
|
island.setOwner(UUID.randomUUID());
|
||||||
|
island.setProtectionRange(100);
|
||||||
|
island.setPurgeProtected(true);
|
||||||
|
island.setRange(100);
|
||||||
|
island.setSpawn(true);
|
||||||
|
island.setSpawnPoint(location);
|
||||||
|
island.setWorld(world);
|
||||||
|
|
||||||
|
MySQLDatabaseHandler<Island> ih = new MySQLDatabaseHandler<>(plugin, Island.class, dbConn);
|
||||||
|
ih.saveObject(island);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
package us.tastybento.bskyblock.database.mysqljson;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.inventory.ItemFactory;
|
|
||||||
import org.bukkit.plugin.PluginManager;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.Settings;
|
|
||||||
import us.tastybento.bskyblock.database.mysql.MySQLDatabaseConnecter;
|
|
||||||
import us.tastybento.bskyblock.database.mysql.MySQLDatabaseHandlerTestDataObject;
|
|
||||||
|
|
||||||
@RunWith(PowerMockRunner.class)
|
|
||||||
public class MySQLDatabaseHandlerJTest {
|
|
||||||
|
|
||||||
private static MySQLDatabaseHandlerJ<MySQLDatabaseHandlerTestDataObject> handler;
|
|
||||||
private static MySQLDatabaseHandlerTestDataObject instance;
|
|
||||||
private static String UNIQUE_ID = "xyz";
|
|
||||||
private static MySQLDatabaseConnecter dbConn;
|
|
||||||
private static World world;
|
|
||||||
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void setUpBeforeClass() throws Exception {
|
|
||||||
Server server = mock(Server.class);
|
|
||||||
world = mock(World.class);
|
|
||||||
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
|
||||||
when(server.getWorld("world")).thenReturn(world);
|
|
||||||
when(server.getVersion()).thenReturn("BSB_Mocking");
|
|
||||||
|
|
||||||
PluginManager pluginManager = mock(PluginManager.class);
|
|
||||||
when(server.getPluginManager()).thenReturn(pluginManager);
|
|
||||||
|
|
||||||
ItemFactory itemFactory = mock(ItemFactory.class);
|
|
||||||
when(server.getItemFactory()).thenReturn(itemFactory);
|
|
||||||
|
|
||||||
Bukkit.setServer(server);
|
|
||||||
|
|
||||||
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
|
||||||
|
|
||||||
BSkyBlock plugin = mock(BSkyBlock.class);
|
|
||||||
when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
|
|
||||||
dbConn = mock(MySQLDatabaseConnecter.class);
|
|
||||||
Connection connection = mock(Connection.class);
|
|
||||||
when(dbConn.createConnection()).thenReturn(connection);
|
|
||||||
PreparedStatement ps = mock(PreparedStatement.class);
|
|
||||||
when(connection.prepareStatement(Mockito.anyString())).thenReturn(ps);
|
|
||||||
Statement statement = mock(Statement.class);
|
|
||||||
when(connection.createStatement()).thenReturn(statement);
|
|
||||||
ResultSet rs = mock(ResultSet.class);
|
|
||||||
when(ps.executeQuery()).thenReturn(rs);
|
|
||||||
when(statement.executeQuery(Mockito.anyString())).thenReturn(rs);
|
|
||||||
instance = new MySQLDatabaseHandlerTestDataObject();
|
|
||||||
instance.setUniqueId(UNIQUE_ID);
|
|
||||||
handler = new MySQLDatabaseHandlerJ<>(plugin, MySQLDatabaseHandlerTestDataObject.class, dbConn);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSaveObject() {
|
|
||||||
handler.saveObject(instance);
|
|
||||||
BSkyBlock plugin = mock(BSkyBlock.class);
|
|
||||||
Settings settings = mock(Settings.class);
|
|
||||||
when(plugin.getSettings()).thenReturn(settings);
|
|
||||||
when(settings.getDeathsMax()).thenReturn(10);
|
|
||||||
Players players = new Players();
|
|
||||||
players.setUniqueId(UUID.randomUUID().toString());
|
|
||||||
players.setDeaths(23);
|
|
||||||
Location location = mock(Location.class);
|
|
||||||
Mockito.when(location.getWorld()).thenReturn(world);
|
|
||||||
Mockito.when(location.getBlockX()).thenReturn(0);
|
|
||||||
Mockito.when(location.getBlockY()).thenReturn(0);
|
|
||||||
Mockito.when(location.getBlockZ()).thenReturn(0);
|
|
||||||
|
|
||||||
players.setHomeLocation(location);
|
|
||||||
players.setHomeLocation(location, 1);
|
|
||||||
players.setHomeLocation(location, 2);
|
|
||||||
Map<Location, Long> map = new HashMap<>();
|
|
||||||
map.put(location, 324L);
|
|
||||||
players.setKickedList(map);
|
|
||||||
players.setLocale("sdfsd");
|
|
||||||
players.setPlayerName("name");
|
|
||||||
players.setPlayerUUID(UUID.randomUUID());
|
|
||||||
players.setResetsLeft(3);
|
|
||||||
|
|
||||||
MySQLDatabaseHandlerJ<Players> h = new MySQLDatabaseHandlerJ<>(plugin, Players.class, dbConn);
|
|
||||||
h.saveObject(players);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -42,11 +42,11 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
|||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.Settings;
|
import us.tastybento.bskyblock.Settings;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||||
import us.tastybento.bskyblock.lists.Flags;
|
import us.tastybento.bskyblock.lists.Flags;
|
||||||
import us.tastybento.bskyblock.managers.FlagsManager;
|
import us.tastybento.bskyblock.managers.FlagsManager;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
import us.tastybento.bskyblock.managers.LocalesManager;
|
import us.tastybento.bskyblock.managers.LocalesManager;
|
||||||
|
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@ -33,11 +33,11 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
|
|||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||||
import us.tastybento.bskyblock.lists.Flags;
|
import us.tastybento.bskyblock.lists.Flags;
|
||||||
import us.tastybento.bskyblock.managers.FlagsManager;
|
import us.tastybento.bskyblock.managers.FlagsManager;
|
||||||
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||||
|
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
@PrepareForTest( { Flags.class })
|
@PrepareForTest( { Flags.class })
|
||||||
|
Loading…
Reference in New Issue
Block a user