Fail fast if world is null when parsing locations.

This commit introduces a null check in the ConfigUtils `parseLocation`
method. If the world of a location string does not exist, the method now
throws an IllegalArgumentException, which allows callers to fail more
gracefully instead of having to resort to null checks.

Additionally, the parsing of exit warps, leaderboards, or linked class
chests is wrapped in try-catch statements that re-throw ConfigErrors
for better error reporting.

Fixes #421
This commit is contained in:
Andreas Troelsen 2019-12-31 20:40:51 +01:00
parent 01c56fdd6a
commit eed5117454
4 changed files with 20 additions and 5 deletions

View File

@ -14,6 +14,7 @@ These changes will (most likely) be included in the next version.
- It is no longer necessary to have recurrent waves for an arena to work. MobArena automatically creates a "catch all" recurrent wave in case the arena session reaches a wave number that isn't covered by any other wave definitions.
- Entities outside of the arena can no longer target players, pets, or monsters inside of the arena.
- Tab completion for `/ma kick` and `/ma restore` now uses actual player names instead of display names.
- If the world of an exit warp, leaderboard, or linked class chest is not available on (re)load, MobArena now throws a config error instead of failing silently later down the road.
- MobArena's internal version checker has been rewritten. It now uses the resource API of Spigot instead of DBO. It's also a lot more lightweight and caches results for up to one hour.
## [0.104] - 2019-08-08

View File

@ -382,8 +382,12 @@ public class ArenaMasterImpl implements ArenaMaster
loadClassLobbyPermissions(arenaClass, section);
// Check for class chests
Location cc = parseLocation(section, "classchest", null);
arenaClass.setClassChest(cc);
try {
Location cc = parseLocation(section, "classchest", null);
arenaClass.setClassChest(cc);
} catch (IllegalArgumentException e) {
throw new ConfigError("Failed to parse classchest location for class " + classname + " because: " + e.getMessage());
}
// Finally add the class to the classes map.
classes.put(lowercase, arenaClass);

View File

@ -4,6 +4,7 @@ import static com.garbagemule.MobArena.util.config.ConfigUtils.makeSection;
import static com.garbagemule.MobArena.util.config.ConfigUtils.parseLocation;
import static com.garbagemule.MobArena.util.config.ConfigUtils.setLocation;
import com.garbagemule.MobArena.ConfigError;
import com.garbagemule.MobArena.MAUtils;
import com.garbagemule.MobArena.MobArena;
import com.garbagemule.MobArena.framework.Arena;
@ -81,7 +82,12 @@ public class ArenaRegion
arenaWarp = parseLocation(coords, "arena", world);
lobbyWarp = parseLocation(coords, "lobby", world);
specWarp = parseLocation(coords, "spectator", world);
exitWarp = parseLocation(coords, "exit", null);
try {
exitWarp = parseLocation(coords, "exit", null);
} catch (IllegalArgumentException e) {
throw new ConfigError("Failed to parse exit warp for arena " + arena.configName() + " because: " + e.getMessage());
}
}
public void reloadLeaderboards() {
@ -89,7 +95,7 @@ public class ArenaRegion
try {
leaderboard = parseLocation(coords, "leaderboard", null);
} catch (IllegalArgumentException e) {
leaderboard = parseLocation(coords, "leaderboard", world);
throw new ConfigError("Failed to parse leaderboard location for arena " + arena.configName() + " because: " + e.getMessage());
}
if (leaderboard != null && leaderboard.getWorld() == null) {
leaderboard.setWorld(world);
@ -235,7 +241,7 @@ public class ArenaRegion
(z + radius >= p1.getBlockZ() && z - radius <= p2.getBlockZ()) &&
(y + radius >= p1.getBlockY() && y - radius <= p2.getBlockY()));
}
// Region expand
public void expandUp(int amount) {
int x = p2.getBlockX();

View File

@ -1,5 +1,6 @@
package com.garbagemule.MobArena.util.config;
import com.garbagemule.MobArena.ConfigError;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -119,6 +120,9 @@ public class ConfigUtils
throw new IllegalArgumentException("Expected location of type (x,y,z,yaw,pitch,world)");
}
world = Bukkit.getWorld(parts[5]);
if (world == null) {
throw new IllegalArgumentException("World " + parts[5] + " not found");
}
}
return new Location(world, x, y, z, yaw, pit);
}