From 2765e5f3abe12dcf3bbc8d32a3cd753386849e17 Mon Sep 17 00:00:00 2001 From: Tastybento Date: Sat, 6 Jan 2018 19:40:25 -0800 Subject: [PATCH] Fixed code according to comments on last commit. Reworked locales so they use a nice and pretty folder structure. Added the ability to define adapters to serialize certain data structures. Added the PotionType list adapter. Saving and loading of configs basically works. Known issues: 1. The config.yml is saved and loaded to/from the database folder 2. More error handling is required for the config loading. e.g., a list value with only one value in it is not read as a list. This could get tricky. 3. Comments are not saved (yet) --- .../us/tastybento/bskyblock/BSkyBlock.java | 7 +- .../us/tastybento/bskyblock/Constants.java | 7 +- .../us/tastybento/bskyblock/Settings.java | 20 +++-- .../bskyblock/api/addons/Addon.java | 51 +++++-------- .../api/commands/CompositeCommand.java | 4 - .../bskyblock/api/configuration/Adapter.java | 13 ++++ .../api/configuration/ConfigEntry.java | 10 +-- .../api/configuration/ISettings.java | 19 +++-- .../PotionEffectListAdpater.java | 34 +++++++++ .../configuration}/StoreAt.java | 2 +- .../tastybento/bskyblock/config/NotSetup.java | 76 ------------------- .../bskyblock/database/BSBDatabase.java | 4 +- .../flatfile/FlatFileDatabaseHandler.java | 62 +++++++++++---- .../database/managers/PlayersManager.java | 2 +- .../database/managers/island/IslandCache.java | 2 +- .../managers/island/IslandsManager.java | 4 +- .../database/managers/island/NewIsland.java | 14 +--- .../database/objects/DataObject.java | 4 +- .../bskyblock/database/objects/Island.java | 4 +- .../island/builders/IslandBuilder.java | 2 +- .../bskyblock/managers/AddonsManager.java | 4 +- .../bskyblock/managers/LocalesManager.java | 54 ++++++------- .../us/tastybento/bskyblock/util/Util.java | 31 +++----- 23 files changed, 210 insertions(+), 220 deletions(-) create mode 100644 src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java create mode 100644 src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java rename src/main/java/us/tastybento/bskyblock/{config => api/configuration}/StoreAt.java (91%) delete mode 100644 src/main/java/us/tastybento/bskyblock/config/NotSetup.java diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index 57e02e73a..9e59d1ae6 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -48,11 +48,10 @@ public class BSkyBlock extends JavaPlugin { @Override public void onEnable(){ plugin = this; - - // Load config - EXPERIMENTAL settings = new Settings(); + // Load config - EXPERIMENTAL try { - //config.saveConfig(); // works, but will wipe out comments + //settings.saveConfig(); -- doesn't work completely yet settings = settings.loadSettings(); getLogger().info("DEBUG: island distance = " + settings.getIslandDistance()); } catch (Exception e) { @@ -188,7 +187,7 @@ public class BSkyBlock extends JavaPlugin { @Override public String getValue() { - return BSBDatabase.getDatabase(plugin).toString(); + return BSBDatabase.getDatabase().toString(); } }); } diff --git a/src/main/java/us/tastybento/bskyblock/Constants.java b/src/main/java/us/tastybento/bskyblock/Constants.java index 4d98c9e6a..e278f0dd0 100644 --- a/src/main/java/us/tastybento/bskyblock/Constants.java +++ b/src/main/java/us/tastybento/bskyblock/Constants.java @@ -1,14 +1,15 @@ package us.tastybento.bskyblock; -import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType; - /** * All the plugin settings are here * @author Tastybento */ public class Constants { // ----------------- Constants ----------------- - + // Game Type BSKYBLOCK or ACIDISLAND + public enum GameType { + BSKYBLOCK, ACIDISLAND, BOTH + } /* public final static GameType GAMETYPE = GameType.ACIDISLAND; // The spawn command (Essentials spawn for example) diff --git a/src/main/java/us/tastybento/bskyblock/Settings.java b/src/main/java/us/tastybento/bskyblock/Settings.java index 3483068c9..8b2312389 100644 --- a/src/main/java/us/tastybento/bskyblock/Settings.java +++ b/src/main/java/us/tastybento/bskyblock/Settings.java @@ -9,12 +9,12 @@ import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffectType; +import us.tastybento.bskyblock.Constants.GameType; import us.tastybento.bskyblock.api.configuration.ConfigEntry; -import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType; import us.tastybento.bskyblock.api.configuration.ISettings; import us.tastybento.bskyblock.api.configuration.PotionEffectListAdpater; +import us.tastybento.bskyblock.api.configuration.StoreAt; import us.tastybento.bskyblock.api.flags.Flag; -import us.tastybento.bskyblock.config.StoreAt; import us.tastybento.bskyblock.database.BSBDatabase.DatabaseType; /** @@ -148,7 +148,7 @@ public class Settings implements ISettings { // Remove mobs private boolean removeMobsOnLogin; private boolean removeMobsOnIsland; - private List removeMobsWhitelist; + private List removeMobsWhitelist = new ArrayList<>(); private boolean makeIslandIfNone; private boolean immediateTeleportOnIsland; @@ -213,16 +213,16 @@ public class Settings implements ISettings { private List acidEffects = new ArrayList<>(Arrays.asList(PotionEffectType.CONFUSION, PotionEffectType.SLOW)); /* SCHEMATICS */ - private List companionNames; - private ItemStack[] chestItems; - private EntityType companionType; + private List companionNames = new ArrayList<>(); + private ItemStack[] chestItems = {}; + private EntityType companionType = EntityType.COW; private boolean useOwnGenerator; private HashMap limitedBlocks; private boolean teamJoinDeathReset; - private String uniqueId; + private String uniqueId = ""; /** * @return the uniqueId @@ -1112,5 +1112,11 @@ public class Settings implements ISettings { public void setTeamJoinDeathReset(boolean teamJoinDeathReset) { this.teamJoinDeathReset = teamJoinDeathReset; } + + @Override + public Settings getInstance() { + // TODO Auto-generated method stub + return this; + } } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java index 86a69ebdc..b44d2544a 100644 --- a/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java +++ b/src/main/java/us/tastybento/bskyblock/api/addons/Addon.java @@ -1,14 +1,13 @@ package us.tastybento.bskyblock.api.addons; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Logger; +import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -25,6 +24,7 @@ import us.tastybento.bskyblock.BSkyBlock; public abstract class Addon implements AddonInterface { private static final String ADDON_CONFIG_FILENAME = "config.yml"; + private static final boolean DEBUG = false; private boolean enabled; private AddonDescription description; private FileConfiguration config; @@ -146,53 +146,44 @@ public abstract class Addon implements AddonInterface { /** * Saves a resource contained in this add-on's jar file to the destination folder. - * @param resourcePath in jar file + * @param jarResource in jar file * @param destinationFolder on file system * @param replace - if true, will overwrite previous file - * @param prefix - if true, filename will be prefixed with the name of this addon + * @param noPath - if true, the resource's path will be ignored when saving */ - public void saveResource(String resourcePath, File destinationFolder, boolean replace, boolean prefix) { - if (resourcePath == null || resourcePath.equals("")) { + public void saveResource(String jarResource, File destinationFolder, boolean replace, boolean noPath) { + if (jarResource == null || jarResource.equals("")) { throw new IllegalArgumentException("ResourcePath cannot be null or empty"); } - resourcePath = resourcePath.replace('\\', '/'); + jarResource = jarResource.replace('\\', '/'); InputStream in = null; try { JarFile jar = new JarFile(file); - JarEntry config = jar.getJarEntry(resourcePath); + JarEntry config = jar.getJarEntry(jarResource); if (config != null) { in = jar.getInputStream(config); } if (in == null) { jar.close(); - throw new IllegalArgumentException("The embedded resource '" + resourcePath + "' cannot be found in " + jar.getName()); + throw new IllegalArgumentException("The embedded resource '" + jarResource + "' cannot be found in " + jar.getName()); } - File outFile = new File(destinationFolder, resourcePath); - //Bukkit.getLogger().info("DEBUG: outFile = " + outFile.getAbsolutePath()); - //Bukkit.getLogger().info("DEBUG: outFile name = " + outFile.getName()); - if (prefix) { - // Rename with addon prefix - outFile = new File(outFile.getParent(), getDescription().getName() + "-" + outFile.getName()); + + // There are two options, use the path of the resource or not + File outFile = new File(destinationFolder, jarResource); + if (noPath) { + outFile = new File(destinationFolder, outFile.getName()); } - int lastIndex = resourcePath.lastIndexOf('/'); - File outDir = new File(destinationFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0)); - //Bukkit.getLogger().info("DEBUG: outDir = " + outDir.getAbsolutePath()); - if (!outDir.exists()) { - outDir.mkdirs(); + // Make any dirs that need to be made + outFile.getParentFile().mkdirs(); + if (DEBUG) { + Bukkit.getLogger().info("DEBUG: outFile = " + outFile.getAbsolutePath()); + Bukkit.getLogger().info("DEBUG: outFile name = " + outFile.getName()); } - - if (!outFile.exists() || replace) { - OutputStream out = new FileOutputStream(outFile); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - out.close(); - in.close(); + java.nio.file.Files.copy(in, outFile.toPath()); } + in.close(); jar.close(); } catch (IOException ex) { ex.printStackTrace(); diff --git a/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java b/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java index 01eb1c0bb..10c6b7476 100644 --- a/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java +++ b/src/main/java/us/tastybento/bskyblock/api/commands/CompositeCommand.java @@ -352,10 +352,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi this.onlyPlayer = onlyPlayer; } - public void setparameters(String parameters) { - this.setParameters(parameters); - } - public void setParameters(String parameters) { this.parameters = parameters; } diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java b/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java new file mode 100644 index 000000000..f7016896b --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java @@ -0,0 +1,13 @@ +package us.tastybento.bskyblock.api.configuration; + + +public interface Adapter { + + /** + * Convert from to something + * @param from + */ + S convertFrom(Object from); + + V convertTo(Object to); +} diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigEntry.java b/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigEntry.java index b70592f11..cf138bc84 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigEntry.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigEntry.java @@ -5,6 +5,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import us.tastybento.bskyblock.Constants.GameType; + /** * * @@ -20,12 +22,6 @@ public @interface ConfigEntry { boolean experimental() default false; boolean needsReset() default false; GameType specificTo() default GameType.BOTH; - Class adapter() default NoAdapter.class; + Class adapter() default Adapter.class; - public class NoAdapter {} - - // Game Type BSKYBLOCK or ACIDISLAND - public enum GameType { - BSKYBLOCK, ACIDISLAND, BOTH - } } \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java b/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java index feb7ad017..a986b78bd 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java @@ -4,8 +4,9 @@ import java.beans.IntrospectionException; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; +import org.bukkit.Bukkit; + import us.tastybento.bskyblock.BSkyBlock; -import us.tastybento.bskyblock.Settings; import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase; import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; @@ -16,21 +17,25 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; * @param */ public interface ISettings { - + // ----------------Saver------------------- @SuppressWarnings("unchecked") - default void saveConfig(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException { + default void saveConfig() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException { // Get the handler - AbstractDatabaseHandler configHandler = (AbstractDatabaseHandler) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), instance.getClass()); + AbstractDatabaseHandler configHandler = (AbstractDatabaseHandler) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), getInstance().getClass()); // Load every field in the config class - configHandler.saveObject(instance); // The string parameter can be anything + Bukkit.getLogger().info("DEBUG: configHandler = " + configHandler); + Bukkit.getLogger().info("DEBUG: instance = " + getInstance()); + configHandler.saveObject(getInstance()); // The string parameter can be anything } // --------------- Loader ------------------ @SuppressWarnings("unchecked") - default Settings loadSettings() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, ClassNotFoundException, IntrospectionException, SQLException { + default T loadSettings() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, ClassNotFoundException, IntrospectionException, SQLException { // Get the handler - AbstractDatabaseHandler configHandler = (AbstractDatabaseHandler) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), Settings.class); + AbstractDatabaseHandler configHandler = (AbstractDatabaseHandler) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), getInstance().getClass()); // Load every field in the config class return configHandler.loadObject("config"); } + + T getInstance(); } diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java b/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java new file mode 100644 index 000000000..d79263028 --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java @@ -0,0 +1,34 @@ +package us.tastybento.bskyblock.api.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.potion.PotionEffectType; + +public class PotionEffectListAdpater implements Adapter, List> { + + @SuppressWarnings("unchecked") + @Override + public List convertFrom(Object from) { + List result = new ArrayList<>(); + if (from instanceof ArrayList) { + for (String type: (ArrayList)from) { + result.add(PotionEffectType.getByName(type)); + } + } + return result; + } + + @SuppressWarnings("unchecked") + @Override + public List convertTo(Object to) { + List result = new ArrayList<>(); + if (to instanceof ArrayList) { + for (PotionEffectType type: (ArrayList)to) { + result.add(type.getName()); + } + } + return result; + } + +} diff --git a/src/main/java/us/tastybento/bskyblock/config/StoreAt.java b/src/main/java/us/tastybento/bskyblock/api/configuration/StoreAt.java similarity index 91% rename from src/main/java/us/tastybento/bskyblock/config/StoreAt.java rename to src/main/java/us/tastybento/bskyblock/api/configuration/StoreAt.java index 7de893040..f6f63b03a 100644 --- a/src/main/java/us/tastybento/bskyblock/config/StoreAt.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/StoreAt.java @@ -1,4 +1,4 @@ -package us.tastybento.bskyblock.config; +package us.tastybento.bskyblock.api.configuration; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/us/tastybento/bskyblock/config/NotSetup.java b/src/main/java/us/tastybento/bskyblock/config/NotSetup.java deleted file mode 100644 index de214e540..000000000 --- a/src/main/java/us/tastybento/bskyblock/config/NotSetup.java +++ /dev/null @@ -1,76 +0,0 @@ -package us.tastybento.bskyblock.config; - -import java.util.List; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -import us.tastybento.bskyblock.BSkyBlock; - -/** - * This class runs when the config file is not set up enough, or is unsafe. - * It provides useful information to the admin on what is wrong. - * - * @author Tastybento - * @author Poslovitch - */ -public class NotSetup implements CommandExecutor{ - - public enum ConfigError { - DIFFERENT_WORLDNAME(0, 001), - DIFFERENT_ISLAND_DISTANCE(0, 002), - PROTECTION_RANGE_HIGHER_THAN_ISLAND_DISTANCE(1, 101), - UNKNOWN_LANGUAGE(2, 201), - NOT_CHUNK_ISLAND_DISTANCE(2, 202), - NOT_EVEN_PROTECTION_RANGE(2, 203), - PURGE_ISLAND_LEVEL_TOO_LOW(3, 301), - ISLAND_DISTANCE_TOO_LOW(3, 302), - PROTECTION_RANGE_TOO_LOW(3, 303), - ISLAND_HEIGHT_TOO_LOW(3, 304), - NETHER_SPAWN_RADIUS_TOO_LOW(3, 305), - NETHER_SPAWN_RADIUS_TOO_HIGH(3, 306); - - /* - * Priority: - * 0 - CRITICAL - * 1 - HIGH - * 2 - MEDIUM - * 3 - LOW - */ - private int priority; - private int id; - - ConfigError(int priority, int id){ - this.priority = priority; - this.id = id; - } - - public static ConfigError getById(int id){ - for(ConfigError e : ConfigError.values()){ - if(e.id == id) return e; - } - return null; - } - } - - private BSkyBlock plugin; - private List errors; - - /** - * Handles plugin operation if a critical config-related issue happened - * - * @param plugin - * @param errors - */ - public NotSetup(BSkyBlock plugin, List errors){ - this.plugin = plugin; - this.errors = errors; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - - return true; - } -} \ No newline at end of file diff --git a/src/main/java/us/tastybento/bskyblock/database/BSBDatabase.java b/src/main/java/us/tastybento/bskyblock/database/BSBDatabase.java index c11ca287e..27898644b 100755 --- a/src/main/java/us/tastybento/bskyblock/database/BSBDatabase.java +++ b/src/main/java/us/tastybento/bskyblock/database/BSBDatabase.java @@ -12,9 +12,9 @@ public abstract class BSBDatabase { * FLATFILE and MYSQL. Default is FLATFILE * @return Database type */ - public static BSBDatabase getDatabase(BSkyBlock plugin){ + public static BSBDatabase getDatabase(){ for(DatabaseType type : DatabaseType.values()){ - if(type == plugin.getSettings().getDatabaseType()) return type.database; + if(type == BSkyBlock.getInstance().getSettings().getDatabaseType()) return type.database; } return DatabaseType.FLATFILE.database; } diff --git a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java index 0d4189552..630b422a2 100644 --- a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java @@ -25,9 +25,10 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import us.tastybento.bskyblock.Constants; +import us.tastybento.bskyblock.Constants.GameType; +import us.tastybento.bskyblock.api.configuration.Adapter; import us.tastybento.bskyblock.api.configuration.ConfigEntry; -import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType; -import us.tastybento.bskyblock.config.StoreAt; +import us.tastybento.bskyblock.api.configuration.StoreAt; import us.tastybento.bskyblock.database.DatabaseConnecter; import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; import us.tastybento.bskyblock.util.Util; @@ -172,13 +173,35 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { storageLocation = configEntry.path(); } if (!configEntry.specificTo().equals(GameType.BOTH) && !configEntry.specificTo().equals(Constants.GAMETYPE)) { - Bukkit.getLogger().info(field.getName() + " not applicable to this game type"); + if (DEBUG) + Bukkit.getLogger().info(field.getName() + " not applicable to this game type"); + continue; + } + // TODO: Add handling of other ConfigEntry elements + if (!configEntry.adapter().equals(Adapter.class)) { + // A conversion adapter has been defined + Object value = config.get(storageLocation); + method.invoke(instance, ((Adapter)configEntry.adapter().newInstance()).convertFrom(value)); + if (DEBUG) { + plugin.getLogger().info("DEBUG: value = " + value); + plugin.getLogger().info("DEBUG: property type = " + propertyDescriptor.getPropertyType()); + plugin.getLogger().info("DEBUG: " + value.getClass()); + } + if (value != null && !value.getClass().equals(MemorySection.class)) { + method.invoke(instance, deserialize(value,propertyDescriptor.getPropertyType())); + } + // We are done here continue; } } // Look in the YAML Config to see if this field exists (it should) - if (config.contains(storageLocation)) { + if (config.contains(storageLocation)) { + // Check for null values + if (config.get(storageLocation) == null) { + method.invoke(instance, (Object)null); + continue; + } // Handle storage of maps. Check if this type is a Map if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) { // Note that we have no idea what type this is @@ -291,13 +314,6 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // Run through all the fields in the class that is being stored. EVERY field must have a get and set method for (Field field : dataObject.getDeclaredFields()) { - String storageLocation = field.getName(); - // Check if there is an annotation on the field - ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class); - // If there is a config path annotation then do something - if (configEntry != null && !configEntry.path().isEmpty()) { - storageLocation = configEntry.path(); - } // Get the property descriptor for this field PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject); // Get the read method, i.e., getXXXX(); @@ -305,14 +321,34 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // Invoke the read method to get the value. We have no idea what type of value it is. Object value = method.invoke(instance); + String storageLocation = field.getName(); + // Check if there is an annotation on the field + ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class); + // If there is a config path annotation then do something + if (configEntry != null) { + if (!configEntry.path().isEmpty()) { + storageLocation = configEntry.path(); + } + // TODO: add in game-specific saving + if (!configEntry.adapter().equals(Adapter.class)) { + // A conversion adapter has been defined + try { + config.set(storageLocation, ((Adapter)configEntry.adapter().newInstance()).convertTo(value)); + } catch (InstantiationException e) { + e.printStackTrace(); + } + // We are done here + continue; + } + } //plugin.getLogger().info("DEBUG: property desc = " + propertyDescriptor.getPropertyType().getTypeName()); // Depending on the vale type, it'll need serializing differenty // Check if this field is the mandatory UniqueId field. This is used to identify this instantiation of the class if (method.getName().equals("getUniqueId")) { - // If the object does not have a unique name assigned to it already, one is created at random + // If the object does not have a unique name assigned to it already, one is created at random //plugin.getLogger().info("DEBUG: uniqueId = " + value); String id = (String)value; - if (id.isEmpty()) { + if (value == null || id.isEmpty()) { id = databaseConnecter.getUniqueId(dataObject.getSimpleName()); // Set it in the class so that it will be used next time propertyDescriptor.getWriteMethod().invoke(instance, id); diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java index 2c3fc50c5..4d81d1348 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java @@ -40,7 +40,7 @@ public class PlayersManager{ @SuppressWarnings("unchecked") public PlayersManager(BSkyBlock plugin){ this.plugin = plugin; - database = BSBDatabase.getDatabase(plugin); + database = BSBDatabase.getDatabase(); // Set up the database handler to store and retrieve Players classes handler = (AbstractDatabaseHandler) database.getHandler(plugin, Players.class); playerCache = new HashMap<>(); diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java index 928a49199..9c4fa9bc1 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java @@ -135,7 +135,7 @@ public class IslandCache { public Island createIsland(Location location, UUID owner){ if (DEBUG) plugin.getLogger().info("DEBUG: adding island for " + owner + " at " + location); - Island island = new Island(plugin, location, owner, plugin.getSettings().getIslandProtectionRange()); + Island island = new Island(location, owner, plugin.getSettings().getIslandProtectionRange()); islandsByLocation.put(location, island); if (owner != null) islandsByUUID.put(owner, island); diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java index bd6890f6f..f6b517949 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java @@ -140,7 +140,7 @@ public class IslandsManager { @SuppressWarnings("unchecked") public IslandsManager(BSkyBlock plugin){ this.plugin = plugin; - database = BSBDatabase.getDatabase(plugin); + database = BSBDatabase.getDatabase(); // Set up the database handler to store and retrieve Island classes handler = (AbstractDatabaseHandler) database.getHandler(plugin, Island.class); islandCache = new IslandCache(); @@ -247,7 +247,7 @@ public class IslandsManager { public Island createIsland(Location location, UUID owner){ if (DEBUG) plugin.getLogger().info("DEBUG: adding island for " + owner + " at " + location); - return islandCache.createIsland(new Island(plugin, location, owner, plugin.getSettings().getIslandProtectionRange())); + return islandCache.createIsland(new Island(location, owner, plugin.getSettings().getIslandProtectionRange())); } /** diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/island/NewIsland.java b/src/main/java/us/tastybento/bskyblock/database/managers/island/NewIsland.java index f80997618..a104cbd35 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/island/NewIsland.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/island/NewIsland.java @@ -26,9 +26,9 @@ public class NewIsland { private final Player player; private final Reason reason; - private NewIsland(BSkyBlock plugin, Island oldIsland, Player player, Reason reason) { + private NewIsland(Island oldIsland, Player player, Reason reason) { super(); - this.plugin = plugin; + this.plugin = BSkyBlock.getInstance(); this.player = player; this.reason = reason; newIsland(); @@ -51,7 +51,7 @@ public class NewIsland { * @return New island builder object */ public static Builder builder(BSkyBlock plugin) { - return new Builder(plugin); + return new Builder(); } /** @@ -63,12 +63,6 @@ public class NewIsland { private Island oldIsland; private Player player; private Reason reason; - private BSkyBlock plugin; - - public Builder(BSkyBlock plugin) { - this.plugin = plugin; - } - public Builder oldIsland(Island oldIsland) { this.oldIsland = oldIsland; @@ -88,7 +82,7 @@ public class NewIsland { public Island build() throws IOException { if (player != null) { - NewIsland newIsland = new NewIsland(plugin, oldIsland, player, reason); + NewIsland newIsland = new NewIsland(oldIsland, player, reason); return newIsland.getIsland(); } throw new IOException("Insufficient parameters. Must have a schematic and a player"); diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/DataObject.java b/src/main/java/us/tastybento/bskyblock/database/objects/DataObject.java index ff97d66fe..30903bd4e 100644 --- a/src/main/java/us/tastybento/bskyblock/database/objects/DataObject.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/DataObject.java @@ -16,11 +16,11 @@ public interface DataObject { /** * @return the uniqueId */ - abstract String getUniqueId(); + String getUniqueId(); /** * @param uniqueId the uniqueId to set */ - abstract void setUniqueId(String uniqueId); + void setUniqueId(String uniqueId); } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index 1cf2c1451..8e702f1ab 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -103,14 +103,14 @@ public class Island implements DataObject { public Island() {} - public Island(BSkyBlock plugin, Location location, UUID owner, int protectionRange) { + public Island(Location location, UUID owner, int protectionRange) { this.members.add(owner); this.owner = owner; this.createdDate = System.currentTimeMillis(); this.updatedDate = System.currentTimeMillis(); this.world = location.getWorld(); this.center = location; - this.range = plugin.getSettings().getIslandProtectionRange(); + this.range = BSkyBlock.getInstance().getSettings().getIslandProtectionRange(); this.minX = center.getBlockX() - range; this.minZ = center.getBlockZ() - range; this.protectionRange = protectionRange; diff --git a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java index ae0d6c637..a4e017aba 100644 --- a/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java +++ b/src/main/java/us/tastybento/bskyblock/island/builders/IslandBuilder.java @@ -18,8 +18,8 @@ import org.bukkit.material.Chest; import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.Constants; +import us.tastybento.bskyblock.Constants.GameType; import us.tastybento.bskyblock.api.commands.User; -import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType; import us.tastybento.bskyblock.database.objects.Island; /** diff --git a/src/main/java/us/tastybento/bskyblock/managers/AddonsManager.java b/src/main/java/us/tastybento/bskyblock/managers/AddonsManager.java index da1e2ae80..026d1d8c7 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/AddonsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/AddonsManager.java @@ -31,6 +31,7 @@ import us.tastybento.bskyblock.api.events.addon.AddonEvent; public final class AddonsManager { private static final boolean DEBUG = false; + private static final String LOCALE_FOLDER = "locales"; private List addons; private List loader; private final Map> classes = new HashMap>(); @@ -132,10 +133,11 @@ public final class AddonsManager { addon.setDataFolder(new File(f.getParent(), addon.getDescription().getName())); addon.setAddonFile(f); + File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER + File.separator + addon.getDescription().getName()); // Obtain any locale files and save them for (String localeFile : listJarYamlFiles(jar, "locales")) { //plugin.getLogger().info("DEBUG: saving " + localeFile + " from jar"); - addon.saveResource(localeFile, plugin.getDataFolder(), false, true); + addon.saveResource(localeFile, localeDir, false, true); } plugin.getLocalesManager().loadLocales(addon.getDescription().getName()); diff --git a/src/main/java/us/tastybento/bskyblock/managers/LocalesManager.java b/src/main/java/us/tastybento/bskyblock/managers/LocalesManager.java index 10c52e361..41b23dcc4 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/LocalesManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/LocalesManager.java @@ -2,6 +2,7 @@ package us.tastybento.bskyblock.managers; import java.io.File; import java.io.FilenameFilter; +import java.io.InputStream; import java.util.HashMap; import java.util.Locale; @@ -22,7 +23,7 @@ public final class LocalesManager { public LocalesManager(BSkyBlock plugin) { this.plugin = plugin; - this.loadLocales(""); // Default + this.loadLocales("BSkyBlock"); // Default } /** @@ -49,45 +50,44 @@ public final class LocalesManager { */ public void loadLocales(String parent) { if (DEBUG) { - if (parent.isEmpty()) - plugin.getLogger().info("DEBUG: loading locale for BSkyBlock"); - else - plugin.getLogger().info("DEBUG: loading locale for " + parent); + plugin.getLogger().info("DEBUG: loading locale for " + parent); } // Describe the filter - we only want files that are correctly named FilenameFilter ymlFilter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { - // Do BSkyBlock files - if (parent.isEmpty()) { - if (name.toLowerCase().endsWith(".yml") && name.length() == 9) { - if (DEBUG) - plugin.getLogger().info("DEBUG: bsb locale filename = " + name); - return true; - } - return false; - } else { - // Addon locales - if (name.startsWith(parent) && name.toLowerCase().endsWith(".yml")) { - if (DEBUG) - plugin.getLogger().info("DEBUG: addon locale filename = " + name); - return true; - } - return false; - } + // Files must be 9 chars long + if (name.toLowerCase().endsWith(".yml") && name.length() == 9) { + if (DEBUG) + plugin.getLogger().info("DEBUG: bsb locale filename = " + name); + return true; + } + return false; } }; // Run through the files and store the locales - File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER); + File localeDir = new File(plugin.getDataFolder(), LOCALE_FOLDER + File.separator + parent); + if (DEBUG) + plugin.getLogger().info("DEBUG: localeDir = " + localeDir.getAbsolutePath()); // If the folder does not exist, then make it and fill with the locale files from the jar // If it does exist, then new files will NOT be written! if (!localeDir.exists()) { - localeDir.mkdir(); + localeDir.mkdirs(); FileLister lister = new FileLister(plugin); try { for (String name : lister.listJar(LOCALE_FOLDER)) { - plugin.saveResource(name,true); + // We cannot use Bukkit's saveResource, because we want it to go into a specific folder, so... + InputStream initialStream = plugin.getResource(name); + // Get the last part of the name + int lastIndex = name.lastIndexOf('/'); + File targetFile = new File(localeDir, name.substring(lastIndex >= 0 ? lastIndex : 0, name.length())); + if (DEBUG) + plugin.getLogger().info("DEBUG: targetFile = " + targetFile.getAbsolutePath()); + if (!targetFile.exists()) { + java.nio.file.Files.copy(initialStream, targetFile.toPath()); + } + initialStream.close(); } } catch (Exception e) { e.printStackTrace(); @@ -97,8 +97,8 @@ public final class LocalesManager { // Store all the locales available for (File language : localeDir.listFiles(ymlFilter)) { if (DEBUG) - plugin.getLogger().info("DEBUG: parent = " + parent + " language = " + language.getName().substring(parent.isEmpty() ? 0 : parent.length() + 1, language.getName().length() - 4)); - Locale localeObject = Locale.forLanguageTag(language.getName().substring(parent.isEmpty() ? 0 : parent.length() + 1, language.getName().length() - 4)); + plugin.getLogger().info("DEBUG: parent = " + parent + " language = " + language.getName().substring(0, language.getName().length() - 4)); + Locale localeObject = Locale.forLanguageTag(language.getName().substring(0, language.getName().length() - 4)); if (DEBUG) plugin.getLogger().info("DEBUG: locale country found = " + localeObject.getCountry()); if (languages.containsKey(localeObject)) { diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index 079ba2252..7334528b0 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -37,6 +37,7 @@ import us.tastybento.bskyblock.api.commands.User; public class Util { private static String serverVersion = null; + private static BSkyBlock plugin = BSkyBlock.getInstance(); /** * Returns the server version @@ -44,7 +45,7 @@ public class Util { */ public static String getServerVersion() { if (serverVersion == null) { - String serverPackageName = getPlugin().getServer().getClass().getPackage().getName(); + String serverPackageName = plugin.getServer().getClass().getPackage().getName(); serverVersion = serverPackageName.substring(serverPackageName.lastIndexOf('.') + 1); } return serverVersion; @@ -132,8 +133,8 @@ public class Util { @SuppressWarnings("deprecation") public static List getPlayerInHandItems(Player player) { List result = new ArrayList(2); - if (getPlugin().getServer().getVersion().contains("(MC: 1.7") - || getPlugin().getServer().getVersion().contains("(MC: 1.8")) { + if (plugin.getServer().getVersion().contains("(MC: 1.7") + || plugin.getServer().getVersion().contains("(MC: 1.8")) { if (player.getItemInHand() != null) result.add(player.getItemInHand()); return result; @@ -182,8 +183,8 @@ public class Util { */ @SuppressWarnings("deprecation") public static boolean playerIsHolding(Player player, Material type) { - if (getPlugin().getServer().getVersion().contains("(MC: 1.7") - || getPlugin().getServer().getVersion().contains("(MC: 1.8")) { + if (plugin.getServer().getVersion().contains("(MC: 1.7") + || plugin.getServer().getVersion().contains("(MC: 1.8")) { if (player.getItemInHand() != null && player.getItemInHand().getType().equals(type)) { return true; } @@ -206,13 +207,13 @@ public class Util { */ public static boolean inWorld(Location loc) { if (loc != null) { - if (loc.getWorld().equals(getPlugin().getIslandWorldManager().getIslandWorld())) { + if (loc.getWorld().equals(plugin.getIslandWorldManager().getIslandWorld())) { return true; } - if (getPlugin().getSettings().isNetherIslands() && loc.getWorld().equals(getPlugin().getIslandWorldManager().getNetherWorld())) { + if (plugin.getSettings().isNetherIslands() && loc.getWorld().equals(plugin.getIslandWorldManager().getNetherWorld())) { return true; } - if (getPlugin().getSettings().isEndIslands() && loc.getWorld().equals(getPlugin().getIslandWorldManager().getEndWorld())) { + if (plugin.getSettings().isEndIslands() && loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld())) { return true; } } @@ -317,7 +318,7 @@ public class Util { } public static void runCommand(final Player player, final String string) { - getPlugin().getServer().getScheduler().runTask(getPlugin(), new Runnable() { + plugin.getServer().getScheduler().runTask(plugin, new Runnable() { @Override public void run() { @@ -361,7 +362,7 @@ public class Util { // In ASkyBlock, liquid may be unsafe if (ground.isLiquid() || space1.isLiquid() || space2.isLiquid()) { // Check if acid has no damage - if (getPlugin().getSettings().getAcidDamage() > 0D) { + if (plugin.getSettings().getAcidDamage() > 0D) { // Bukkit.getLogger().info("DEBUG: acid"); return false; } else if (ground.getType().equals(Material.STATIONARY_LAVA) || ground.getType().equals(Material.LAVA) @@ -424,7 +425,7 @@ public class Util { String[] spl = perms.getPermission().split(perm + "."); if (spl.length > 1) { if (!NumberUtils.isDigits(spl[1])) { - getPlugin().getLogger().severe("Player " + player.getName() + " has permission: " + perms.getPermission() + " <-- the last part MUST be a number! Ignoring..."); + plugin.getLogger().severe("Player " + player.getName() + " has permission: " + perms.getPermission() + " <-- the last part MUST be a number! Ignoring..."); } else { permValue = Math.max(permValue, Integer.valueOf(spl[1])); @@ -440,12 +441,4 @@ public class Util { return permValue; } - /** - * @return the plugin - */ - public static BSkyBlock getPlugin() { - return BSkyBlock.getInstance(); - } - - }