From ec0a6bdd73f6e2e85f747d02c5b73609a35e3313 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 14 Jul 2018 11:14:51 -0700 Subject: [PATCH] Fixed issue with dots in map keys for YAML saving YAML cannot handle dots in keys, so they need to be converted to something else. I chose :dot:. This issue occurred because location coordinates were saved with .'s in them. Actually, there is no real value in saving such accurate locations, so in addition to keeping the dot escape system (just in case), I changed locations to just save as ints and then when they are loaded, x and z have 0.5D added to them to center the location. This should be sufficient accuracy for any location storage and it also reduces the file size a lot. --- .../us/tastybento/bskyblock/BSkyBlock.java | 4 ++++ .../flatfile/FlatFileDatabaseHandler.java | 11 ++++++---- .../bskyblock/database/objects/Players.java | 2 +- .../us/tastybento/bskyblock/util/Util.java | 21 ++++++++----------- .../tastybento/bskyblock/util/UtilTest.java | 11 ++++++---- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index 21ecf7a87..3b229e1c4 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -317,6 +317,10 @@ public class BSkyBlock extends JavaPlugin { getLogger().info(() -> string); } + public void logDebug(Object object) { + getLogger().info(() -> "DEBUG: " + object); + } + public void logError(String error) { getLogger().severe(() -> error); } 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 34aa65db6..d46d94529 100644 --- a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java @@ -162,17 +162,18 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // collectionTypes should be 2 long Type keyType = collectionTypes.get(0); Type valueType = collectionTypes.get(1); - // TODO: this may not work with all keys. Further serialization may be required. Map value = new HashMap<>(); if (config.getConfigurationSection(storageLocation) != null) { for (String key : config.getConfigurationSection(storageLocation).getKeys(false)) { + // Map values can be null - it is allowed here + Object mapValue = deserialize(config.get(storageLocation + "." + key), Class.forName(valueType.getTypeName())); // Keys cannot be null - skip if they exist + // Convert any serialized dots back to dots + key = key.replaceAll(":dot:", "."); Object mapKey = deserialize(key,Class.forName(keyType.getTypeName())); if (mapKey == null) { continue; } - // Map values can be null - it is allowed here - Object mapValue = deserialize(config.get(storageLocation + "." + key), Class.forName(valueType.getTypeName())); value.put(mapKey, mapValue); } } @@ -341,7 +342,9 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { Map result = new HashMap<>(); for (Entry object : ((Map)value).entrySet()) { // Serialize all key and values - result.put(serialize(object.getKey()), serialize(object.getValue())); + String key = (String)serialize(object.getKey()); + key = key.replaceAll("\\.", ":dot:"); + result.put(key, serialize(object.getValue())); } // Save the list in the config file config.set(storageLocation, result); diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java index 183bf05e9..bcc1461dd 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java @@ -93,7 +93,7 @@ public class Players implements DataObject { return homeLocations.entrySet().stream().filter(e -> Util.sameWorld(e.getKey().getWorld(),world)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } - + /** * @return the homeLocations */ diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index 7262af753..f99a02b38 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -69,8 +69,7 @@ public class Util { * Converts a serialized location to a Location. Returns null if string is * empty * - * @param s - * - serialized location in format "world:x:y:z" + * @param s - serialized location in format "world:x:y:z:y:p" * @return Location */ public static Location getLocationString(final String s) { @@ -83,12 +82,13 @@ public class Util { if (w == null) { return null; } - double x = Double.parseDouble(parts[1]); - double y = Double.parseDouble(parts[2]); - double z = Double.parseDouble(parts[3]); + // Parse string as double just in case + int x = (int) Double.parseDouble(parts[1]); + int y = (int) Double.parseDouble(parts[2]); + int z = (int) Double.parseDouble(parts[3]); final float yaw = Float.intBitsToFloat(Integer.parseInt(parts[4])); final float pitch = Float.intBitsToFloat(Integer.parseInt(parts[5])); - return new Location(w, x, y, z, yaw, pitch); + return new Location(w, x + 0.5D, y, z + 0.5D, yaw, pitch); } return null; } @@ -96,19 +96,16 @@ public class Util { /** * Converts a location to a simple string representation * If location is null, returns empty string + * Only stores block ints. Inverse function returns block centers * * @param l - the location - * @return String of location + * @return String of location in format "world:x:y:z:y:p" */ public static String getStringLocation(final Location l) { if (l == null || l.getWorld() == null) { return ""; } - return l.getWorld().getName() + ":" + format(l.getX()) + ":" + format(l.getY()) + ":" + format(l.getZ()) + ":" + Float.floatToIntBits(l.getYaw()) + ":" + Float.floatToIntBits(l.getPitch()); - } - - private static String format(double num) { - return String.valueOf(Math.round(num * 100D) / 100D); + return l.getWorld().getName() + ":" + l.getBlockX() + ":" + l.getBlockY() + ":" + l.getBlockZ() + ":" + Float.floatToIntBits(l.getYaw()) + ":" + Float.floatToIntBits(l.getPitch()); } /** diff --git a/src/test/java/us/tastybento/bskyblock/util/UtilTest.java b/src/test/java/us/tastybento/bskyblock/util/UtilTest.java index 0414371c0..92e4c7175 100644 --- a/src/test/java/us/tastybento/bskyblock/util/UtilTest.java +++ b/src/test/java/us/tastybento/bskyblock/util/UtilTest.java @@ -57,6 +57,9 @@ public class UtilTest { when(location.getX()).thenReturn(500D); when(location.getY()).thenReturn(600D); when(location.getZ()).thenReturn(700D); + when(location.getBlockX()).thenReturn(500); + when(location.getBlockY()).thenReturn(600); + when(location.getBlockZ()).thenReturn(700); when(location.getYaw()).thenReturn(10F); when(location.getPitch()).thenReturn(20F); @@ -100,11 +103,11 @@ public class UtilTest { assertNull(Util.getLocationString(null)); assertNull(Util.getLocationString("")); assertNull(Util.getLocationString(" ")); - Location result = Util.getLocationString("world_name:500.0:600.0:700.0:1092616192:1101004800"); + Location result = Util.getLocationString("world_name:500:600:700.0:1092616192:1101004800"); assertEquals(world, result.getWorld()); - assertTrue(result.getX() == 500D); + assertTrue(result.getX() == 500.5D); assertTrue(result.getY() == 600D); - assertTrue(result.getZ() == 700D); + assertTrue(result.getZ() == 700.5D); assertTrue(result.getYaw() == 10F); assertTrue(result.getPitch() == 20F); } @@ -118,7 +121,7 @@ public class UtilTest { when(location.getWorld()).thenReturn(null); assertEquals("", Util.getStringLocation(location)); when(location.getWorld()).thenReturn(world); - assertEquals("world_name:500.0:600.0:700.0:1092616192:1101004800", Util.getStringLocation(location)); + assertEquals("world_name:500:600:700:1092616192:1101004800", Util.getStringLocation(location)); } /**