Fixed bugs with MySQL saving and loading.

Added the adapter annotation to MySQL and fixed issues with empty
hashmaps causing null errors.

Added a flag serializer adapter for the protection flags so that flags
are saved and loaded correctly.

Renamed the Adapter notation class to be clearer about what it is doing.
This commit is contained in:
Tastybento 2018-02-04 12:53:17 -08:00
parent 83d0848429
commit fa1ccd0c99
12 changed files with 102 additions and 37 deletions

View File

@ -98,7 +98,6 @@ public class BSkyBlock extends JavaPlugin {
islandsManager.load();
localesManager = new LocalesManager(plugin);
//TODO localesManager.registerLocales(plugin);
// Register Listeners
registerListeners();

View File

@ -367,7 +367,6 @@ public class Settings implements ISettings<Settings> {
}
@Override
public Settings getInstance() {
// TODO Auto-generated method stub
return this;
}
/**

View File

@ -11,10 +11,16 @@ package us.tastybento.bskyblock.api.configuration;
public interface Adapter<S,V> {
/**
* Convert from to something
* @param from
* Serialize object
* @param object - object
* @return serialized object
*/
S convertFrom(Object from);
S serialize(Object object);
V convertTo(Object to);
/**
* Deserialize object
* @param object
* @return deserialized object
*/
V deserialize(Object object);
}

View File

@ -14,6 +14,7 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
* Simple interface for tagging all classes containing ConfigEntries.
*
* @author Poslovitch
* @author tastybento
* @param <T>
*/
public interface ISettings<T> {
@ -30,10 +31,10 @@ public interface ISettings<T> {
}
default void saveBackup() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
// Save backup in real database
// Save backup
@SuppressWarnings("unchecked")
AbstractDatabaseHandler<T> dbhandler = (AbstractDatabaseHandler<T>) BSBDatabase.getDatabase().getHandler(getInstance().getClass());
dbhandler.saveObject(getInstance());
AbstractDatabaseHandler<T> backupHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(getInstance().getClass());
backupHandler.saveObject(getInstance());
}
// --------------- Loader ------------------

View File

@ -9,7 +9,7 @@ public class PotionEffectListAdpater implements Adapter<List<PotionEffectType>,
@SuppressWarnings("unchecked")
@Override
public List<PotionEffectType> convertFrom(Object from) {
public List<PotionEffectType> serialize(Object from) {
List<PotionEffectType> result = new ArrayList<>();
if (from instanceof ArrayList) {
for (String type: (ArrayList<String>)from) {
@ -21,7 +21,7 @@ public class PotionEffectListAdpater implements Adapter<List<PotionEffectType>,
@SuppressWarnings("unchecked")
@Override
public List<String> convertTo(Object to) {
public List<String> deserialize(Object to) {
List<String> result = new ArrayList<>();
if (to instanceof ArrayList) {
for (PotionEffectType type: (ArrayList<PotionEffectType>)to) {

View File

@ -182,7 +182,7 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
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));
method.invoke(instance, ((Adapter<?,?>)configEntry.adapter().newInstance()).serialize(value));
if (DEBUG) {
plugin.getLogger().info("DEBUG: value = " + value);
plugin.getLogger().info("DEBUG: property type = " + propertyDescriptor.getPropertyType());
@ -355,7 +355,7 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
if (!configEntry.adapter().equals(Adapter.class)) {
// A conversion adapter has been defined
try {
config.set(storageLocation, ((Adapter<?,?>)configEntry.adapter().newInstance()).convertTo(value));
config.set(storageLocation, ((Adapter<?,?>)configEntry.adapter().newInstance()).deserialize(value));
} catch (InstantiationException e) {
e.printStackTrace();
}

View File

@ -37,6 +37,10 @@ public class IslandCache {
islandsByUUID = new HashMap<>();
}
/**
* Adds an island to the grid
* @param island
*/
public void addIsland(Island island) {
islandsByLocation.put(island.getCenter(), island);
if (DEBUG)

View File

@ -40,7 +40,6 @@ import us.tastybento.bskyblock.util.Util;
public class IslandsManager {
private static final boolean DEBUG = false;
private static final boolean DEBUG2 = false;
/**
* Checks if this location is safe for a player to teleport to. Used by
* warps and boat exits Unsafe is any liquid or air and also if there's no
@ -713,12 +712,14 @@ public class IslandsManager {
plugin.getLogger().info("DEBUG: loading grid");
for (Island island : handler.loadObjects()) {
if (DEBUG)
plugin.getLogger().info("DEBUG: addin island at "+ island.getCenter());
plugin.getLogger().info("DEBUG: adding island at "+ island.getCenter());
islandCache.addIsland(island);
}
} catch (Exception e) {
e.printStackTrace();
}
if (DEBUG)
plugin.getLogger().info("DEBUG: islands loaded");
}
/**

View File

@ -32,6 +32,8 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import us.tastybento.bskyblock.api.configuration.Adapter;
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
import us.tastybento.bskyblock.database.DatabaseConnecter;
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
import us.tastybento.bskyblock.util.Util;
@ -271,7 +273,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
if (DEBUG)
plugin.getLogger().info("DEBUG: collection columns = " + col);
}
return columns;
}
@ -414,6 +416,22 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
Object value = method.invoke(instance);
if (DEBUG)
plugin.getLogger().info("DEBUG: value = " + value);
// Adapter
// Check if there is an annotation on the field
ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class);
// If there is a config annotation then do something
if (configEntry != null) {
if (DEBUG)
plugin.getLogger().info("DEBUG: there is a configEntry");
if (!configEntry.adapter().equals(Adapter.class)) {
if (DEBUG)
plugin.getLogger().info("DEBUG: there is an adapter");
// A conversion adapter has been defined
value = ((Adapter<?,?>)configEntry.adapter().newInstance()).deserialize(value);
if (DEBUG)
plugin.getLogger().info("DEBUG: value now after deserialization = " + value);
}
}
// Create set and map table inserts if this is a Collection
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
propertyDescriptor.getPropertyType().equals(Map.class) ||
@ -465,6 +483,9 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
Iterator<?> it = collection.entrySet().iterator();
while (it.hasNext()) {
Entry<?,?> en = (Entry<?, ?>) it.next();
if (DEBUG)
plugin.getLogger().info("DEBUG: entry ket = " + en.getKey());
// Get the key and serialize it
Object key = serialize(en.getKey(), en.getKey().getClass());
if (DEBUG)
@ -668,10 +689,14 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
// 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 (DEBUG)
plugin.getLogger().info("DEBUG: propertyDescriptor.getPropertyType() = " + propertyDescriptor.getPropertyType());
// If the type is a Collection, then we need to deal with set and map tables
if (Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
if (Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType())
|| Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
// Collection
//plugin.getLogger().info("DEBUG: Collection");
if (DEBUG)
plugin.getLogger().info("DEBUG: Collection or Map");
// TODO Get the values from the subsidiary tables.
// value is just of type boolean right now
String setSql = "SELECT ";
@ -720,7 +745,8 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
//plugin.getLogger().info("DEBUG: collectionResultSet size = " + collectionResultSet.getFetchSize());
((List<Object>) value).add(deserialize(collectionResultSet.getObject(1),Class.forName(setType.getTypeName())));
}
} else if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
} else if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType()) ||
HashMap.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
if (DEBUG)
plugin.getLogger().info("DEBUG: Adding a map ");
// Loop through the collection resultset
@ -756,6 +782,22 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
plugin.getLogger().info("DEBUG: regular type");
value = deserialize(value, propertyDescriptor.getPropertyType());
}
// Adapter
// Check if there is an annotation on the field
ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class);
// If there is a config annotation then do something
if (configEntry != null) {
if (DEBUG)
plugin.getLogger().info("DEBUG: there is a configEntry");
if (!configEntry.adapter().equals(Adapter.class)) {
if (DEBUG)
plugin.getLogger().info("DEBUG: there is an adapter");
// A conversion adapter has been defined
value = ((Adapter<?,?>)configEntry.adapter().newInstance()).serialize(value);
if (DEBUG)
plugin.getLogger().info("DEBUG: value now after serialization = " + value);
}
}
if (DEBUG) {
plugin.getLogger().info("DEBUG: invoking method " + method.getName());
if (value == null) {
@ -914,12 +956,12 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
public void saveSettings(T instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
plugin.getLogger().severe("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 {
IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
plugin.getLogger().severe("This method should not be used because configs are not stored in MySQL");
return null;
}

View File

@ -20,21 +20,32 @@ import us.tastybento.bskyblock.api.flags.Flag;
public class FlagSerializer implements Adapter<HashMap<Flag, Integer>, HashMap<String, Integer>> {
@Override
public HashMap<Flag, Integer> convertFrom(Object from) {
public HashMap<Flag, Integer> serialize(Object object) {
HashMap<Flag, Integer> result = new HashMap<>();
MemorySection section = (MemorySection) from;
for (String key : section.getKeys(false)) {
Bukkit.getLogger().info("DEBUG: " + key + " = " + section.getInt(key));
result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(key), section.getInt(key));
if (object == null)
return result;
// For YAML
if (object instanceof MemorySection) {
MemorySection section = (MemorySection) object;
for (String key : section.getKeys(false)) {
Bukkit.getLogger().info("DEBUG: " + key + " = " + section.getInt(key));
result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(key), section.getInt(key));
}
} else {
for (Entry<String, Integer> en : ((HashMap<String, Integer>)object).entrySet()) {
result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(en.getKey()), en.getValue());
}
}
return result;
}
@Override
public HashMap<String, Integer> convertTo(Object to) {
public HashMap<String, Integer> deserialize(Object object) {
HashMap<String, Integer> result = new HashMap<>();
HashMap<Flag, Integer> flags = (HashMap<Flag, Integer>)to;
if (object == null)
return result;
HashMap<Flag, Integer> flags = (HashMap<Flag, Integer>)object;
for (Entry<Flag, Integer> en: flags.entrySet()) {
result.put(en.getKey().getID(), en.getValue());
}

View File

@ -89,8 +89,7 @@ public class Island implements DataObject {
public Island() {}
public Island(Location location, UUID owner, int protectionRange) {
this.owner = owner;
this.members.put(owner, RanksManager.OWNER_RANK);
setOwner(owner);
this.createdDate = System.currentTimeMillis();
this.updatedDate = System.currentTimeMillis();
this.world = location.getWorld();
@ -108,7 +107,8 @@ public class Island implements DataObject {
* @param playerUUID
*/
public void addMember(UUID playerUUID) {
members.put(playerUUID, RanksManager.MEMBER_RANK);
if (playerUUID != null)
members.put(playerUUID, RanksManager.MEMBER_RANK);
}
/**
@ -119,7 +119,8 @@ public class Island implements DataObject {
*/
public boolean addToBanList(UUID targetUUID) {
// TODO fire ban event
members.put(targetUUID, RanksManager.BANNED_RANK);
if (targetUUID != null)
members.put(targetUUID, RanksManager.BANNED_RANK);
return true;
}
@ -282,7 +283,7 @@ public class Island implements DataObject {
* @return rank integer
*/
public int getRank(User user) {
Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId());
//Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId());
return members.containsKey(user.getUniqueId()) ? members.get(user.getUniqueId()) : RanksManager.VISITOR_RANK;
}
@ -426,7 +427,7 @@ public class Island implements DataObject {
* @return true if allowed, false if not
*/
public boolean isAllowed(User user, Flag flag) {
Bukkit.getLogger().info("DEBUG: " + flag.getID() + " user score = " + getRank(user) + " flag req = "+ this.getFlagReq(flag));
//Bukkit.getLogger().info("DEBUG: " + flag.getID() + " user score = " + getRank(user) + " flag req = "+ this.getFlagReq(flag));
return (this.getRank(user) >= this.getFlagReq(flag)) ? true : false;
}
@ -601,6 +602,7 @@ public class Island implements DataObject {
*/
public void setOwner(UUID owner){
this.owner = owner;
if (owner == null) return;
// Defensive code: demote any previous owner
for (Entry<UUID, Integer> en : members.entrySet()) {
if (en.getValue().equals(RanksManager.OWNER_RANK)) {
@ -637,7 +639,7 @@ public class Island implements DataObject {
* @param rank
*/
public void setRank(User user, int rank) {
members.put(user.getUniqueId(), rank);
if (user.getUniqueId() != null) members.put(user.getUniqueId(), rank);
}
/**

View File

@ -19,7 +19,7 @@ public class FlagsManager {
public void registerFlag(Flag flag) {
//TODO all the security checks
plugin.getLogger().info("DEBUG: registering flag " + flag.getID());
//plugin.getLogger().info("DEBUG: registering flag " + flag.getID());
flags.add(flag);
// If there is a listener, register it into Bukkit.
flag.getListener().ifPresent(l -> plugin.getServer().getPluginManager().registerEvents(l, plugin));