Defensive code around null worlds

When a world is not loaded it becomes null in Bukkit so that any
references to that world will be null. If an admin removes a game mode,
then the island data was instantly becoming useless and quarantined.
This change leaves the files as-is so that if the game mode is put back,
the world is still viable.

As for home locations that are stored in the Player object, they are
removed so they do not cause errors.
This commit is contained in:
tastybento 2019-02-07 19:18:46 -08:00
parent 2599839fad
commit f7f47e8f44
6 changed files with 32 additions and 3 deletions

View File

@ -58,6 +58,8 @@ public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
list.add(getGson().fromJson(new FileReader(file), dataObject));
} catch (FileNotFoundException e) {
plugin.logError("Could not load file '" + file.getName() + "': File not found.");
} catch (Exception e) {
plugin.logError("Could not load objects " + file.getName() + " " + e.getMessage());
}
}
return list;
@ -78,6 +80,8 @@ public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
result = getGson().fromJson(new FileReader(new File(plugin.getDataFolder(), fileName)), dataObject);
} catch (FileNotFoundException e) {
plugin.logError("Could not load file '" + fileName + "': File not found.");
} catch (Exception e) {
plugin.logError("Could not load objects " + fileName + " " + e.getMessage());
}
return result;

View File

@ -92,6 +92,8 @@ public class MariaDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
}
}
}
} catch (Exception e) {
plugin.logError("Could not load objects " + e.getMessage());
}
} catch (SQLException e) {
plugin.logError("Could not load objects " + e.getMessage());
@ -113,6 +115,8 @@ public class MariaDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
Gson gson = getGson();
return gson.fromJson(resultSet.getString("json"), dataObject);
}
} catch (Exception e) {
plugin.logError("Could not load object " + uniqueId + " " + e.getMessage());
}
} catch (SQLException e) {
plugin.logError("Could not load object " + uniqueId + " " + e.getMessage());

View File

@ -68,7 +68,11 @@ public class MongoDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
// The deprecated serialize option does not have a viable alternative without involving a huge amount of custom code
String json = JSON.serialize(document);
json = json.replaceFirst(MONGO_ID, UNIQUEID);
try {
list.add(gson.fromJson(json, dataObject));
} catch (Exception e) {
plugin.logError("Could not load object :" + e.getMessage());
}
}
return list;
}

View File

@ -129,6 +129,8 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
}
}
}
} catch (Exception e) {
plugin.logError("Could not load objects " + e.getMessage());
}
} catch (SQLException e) {
plugin.logError("Could not load objects " + e.getMessage());
@ -150,6 +152,8 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
Gson gson = getGson();
return gson.fromJson(resultSet.getString("json"), dataObject);
}
} catch (Exception e) {
plugin.logError("Could not load object " + uniqueId + " " + e.getMessage());
}
} catch (SQLException e) {
plugin.logError("Could not load object " + uniqueId + " " + e.getMessage());

View File

@ -72,6 +72,8 @@ public class Players implements DataObject {
* @return Location of this home or null if not available
*/
public Location getHomeLocation(World world, int number) {
// Remove any lost worlds/locations
homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
return homeLocations.entrySet().stream()
.filter(en -> Util.sameWorld(en.getKey().getWorld(), world) && en.getValue() == number)
.map(Map.Entry::getKey)
@ -84,6 +86,8 @@ public class Players implements DataObject {
* @return List of home locations
*/
public Map<Location, Integer> getHomeLocations(World world) {
// Remove any lost worlds/locations
homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
return homeLocations.entrySet().stream().filter(e -> Util.sameWorld(e.getKey().getWorld(),world))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
@ -92,6 +96,8 @@ public class Players implements DataObject {
* @return the homeLocations
*/
public Map<Location, Integer> getHomeLocations() {
// Remove any lost worlds/locations
homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
return homeLocations;
}
@ -100,6 +106,8 @@ public class Players implements DataObject {
*/
public void setHomeLocations(Map<Location, Integer> homeLocations) {
this.homeLocations = homeLocations;
// Remove any lost worlds/locations
homeLocations.keySet().removeIf(l -> l == null || l.getWorld() == null);
}
/**

View File

@ -10,9 +10,9 @@ import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.World;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;
@ -43,7 +43,12 @@ public class IslandCache {
*/
public boolean addIsland(@NonNull Island island) {
if (island.getCenter() == null || island.getWorld() == null) {
return false;
/* Special handling - return true.
The island will not be quarantined, but just not loaded
This can occur when a gamemode is removed temporarily from the server
TODO: have an option to remove these when the purge command is added
*/
return true;
}
if (addToGrid(island)) {
islandsByLocation.put(island.getCenter(), island);