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.
This commit is contained in:
tastybento 2018-07-14 11:14:51 -07:00
parent 2b024d035b
commit ec0a6bdd73
5 changed files with 28 additions and 21 deletions

View File

@ -317,6 +317,10 @@ public class BSkyBlock extends JavaPlugin {
getLogger().info(() -> string); getLogger().info(() -> string);
} }
public void logDebug(Object object) {
getLogger().info(() -> "DEBUG: " + object);
}
public void logError(String error) { public void logError(String error) {
getLogger().severe(() -> error); getLogger().severe(() -> error);
} }

View File

@ -162,17 +162,18 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
// collectionTypes should be 2 long // collectionTypes should be 2 long
Type keyType = collectionTypes.get(0); Type keyType = collectionTypes.get(0);
Type valueType = collectionTypes.get(1); Type valueType = collectionTypes.get(1);
// TODO: this may not work with all keys. Further serialization may be required.
Map<Object,Object> value = new HashMap<>(); Map<Object,Object> value = new HashMap<>();
if (config.getConfigurationSection(storageLocation) != null) { if (config.getConfigurationSection(storageLocation) != null) {
for (String key : config.getConfigurationSection(storageLocation).getKeys(false)) { 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 // 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())); Object mapKey = deserialize(key,Class.forName(keyType.getTypeName()));
if (mapKey == null) { if (mapKey == null) {
continue; 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); value.put(mapKey, mapValue);
} }
} }
@ -341,7 +342,9 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
Map<Object, Object> result = new HashMap<>(); Map<Object, Object> result = new HashMap<>();
for (Entry<Object, Object> object : ((Map<Object,Object>)value).entrySet()) { for (Entry<Object, Object> object : ((Map<Object,Object>)value).entrySet()) {
// Serialize all key and values // 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 // Save the list in the config file
config.set(storageLocation, result); config.set(storageLocation, result);

View File

@ -69,8 +69,7 @@ public class Util {
* Converts a serialized location to a Location. Returns null if string is * Converts a serialized location to a Location. Returns null if string is
* empty * empty
* *
* @param s * @param s - serialized location in format "world:x:y:z:y:p"
* - serialized location in format "world:x:y:z"
* @return Location * @return Location
*/ */
public static Location getLocationString(final String s) { public static Location getLocationString(final String s) {
@ -83,12 +82,13 @@ public class Util {
if (w == null) { if (w == null) {
return null; return null;
} }
double x = Double.parseDouble(parts[1]); // Parse string as double just in case
double y = Double.parseDouble(parts[2]); int x = (int) Double.parseDouble(parts[1]);
double z = Double.parseDouble(parts[3]); 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 yaw = Float.intBitsToFloat(Integer.parseInt(parts[4]));
final float pitch = Float.intBitsToFloat(Integer.parseInt(parts[5])); 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; return null;
} }
@ -96,19 +96,16 @@ public class Util {
/** /**
* Converts a location to a simple string representation * Converts a location to a simple string representation
* If location is null, returns empty string * If location is null, returns empty string
* Only stores block ints. Inverse function returns block centers
* *
* @param l - the location * @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) { public static String getStringLocation(final Location l) {
if (l == null || l.getWorld() == null) { if (l == null || l.getWorld() == null) {
return ""; return "";
} }
return l.getWorld().getName() + ":" + format(l.getX()) + ":" + format(l.getY()) + ":" + format(l.getZ()) + ":" + Float.floatToIntBits(l.getYaw()) + ":" + Float.floatToIntBits(l.getPitch()); return l.getWorld().getName() + ":" + l.getBlockX() + ":" + l.getBlockY() + ":" + l.getBlockZ() + ":" + Float.floatToIntBits(l.getYaw()) + ":" + Float.floatToIntBits(l.getPitch());
}
private static String format(double num) {
return String.valueOf(Math.round(num * 100D) / 100D);
} }
/** /**

View File

@ -57,6 +57,9 @@ public class UtilTest {
when(location.getX()).thenReturn(500D); when(location.getX()).thenReturn(500D);
when(location.getY()).thenReturn(600D); when(location.getY()).thenReturn(600D);
when(location.getZ()).thenReturn(700D); 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.getYaw()).thenReturn(10F);
when(location.getPitch()).thenReturn(20F); when(location.getPitch()).thenReturn(20F);
@ -100,11 +103,11 @@ public class UtilTest {
assertNull(Util.getLocationString(null)); assertNull(Util.getLocationString(null));
assertNull(Util.getLocationString("")); assertNull(Util.getLocationString(""));
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()); assertEquals(world, result.getWorld());
assertTrue(result.getX() == 500D); assertTrue(result.getX() == 500.5D);
assertTrue(result.getY() == 600D); assertTrue(result.getY() == 600D);
assertTrue(result.getZ() == 700D); assertTrue(result.getZ() == 700.5D);
assertTrue(result.getYaw() == 10F); assertTrue(result.getYaw() == 10F);
assertTrue(result.getPitch() == 20F); assertTrue(result.getPitch() == 20F);
} }
@ -118,7 +121,7 @@ public class UtilTest {
when(location.getWorld()).thenReturn(null); when(location.getWorld()).thenReturn(null);
assertEquals("", Util.getStringLocation(location)); assertEquals("", Util.getStringLocation(location));
when(location.getWorld()).thenReturn(world); 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));
} }
/** /**