diff --git a/Builder.xml b/Builder.xml index e8a7e38..6cbe5e1 100644 --- a/Builder.xml +++ b/Builder.xml @@ -11,7 +11,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/libs/WorldEdit.jar b/libs/WorldEdit.jar deleted file mode 100644 index 7be0f74..0000000 Binary files a/libs/WorldEdit.jar and /dev/null differ diff --git a/libs/worldedit-5.6.3.jar b/libs/worldedit-5.6.3.jar new file mode 100644 index 0000000..05d3087 Binary files /dev/null and b/libs/worldedit-5.6.3.jar differ diff --git a/plugin.yml b/plugin.yml index c2907b3..859195c 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: Zones main: com.zones.Zones -version: 3.0b2 +version: 3.0b3 author: 'Meaglin' authors: [ 'Mysteryman', 'GunterDW' ] depend: [ 'Vault' ] diff --git a/src/com/zones/ZoneManager.java b/src/com/zones/ZoneManager.java index 281c685..a08c5d1 100644 --- a/src/com/zones/ZoneManager.java +++ b/src/com/zones/ZoneManager.java @@ -11,12 +11,7 @@ import org.bukkit.entity.Player; -import com.zones.model.forms.ZoneCuboid; -import com.zones.model.forms.ZoneCylinder; -import com.zones.model.forms.ZoneNPoly; -import com.zones.model.forms.ZoneSphere; import com.zones.model.types.ZoneNormal; -import com.zones.persistence.Vertice; import com.zones.persistence.Zone; import com.zones.selection.ZoneSelection; import com.zones.world.WorldManager; @@ -53,7 +48,7 @@ public void cleanUp(WorldManager world) { public void load(WorldManager world) { cleanUp(world); try { - List zones = plugin.getMysqlDatabase().get(world.getWorldName()); + List zones = plugin.getMysqlDatabase().getWorld(world.getWorldName()); addZones(world, loadFromPersistentData(world, zones)); } catch(Exception e) { log.warning("[Zones] Error loading world " + world.getWorldName() + "."); @@ -89,36 +84,8 @@ public ZoneNormal loadFromPersistentData(WorldManager world, Zone zone) { return null; } temp.initialize(plugin, world, zone); - List vertices = zone.getVertices(); - - if(zone.getFormtype().equalsIgnoreCase("ZoneCuboid")) { - if (vertices.size() == 2) { - temp.setForm(new ZoneCuboid(vertices, zone.getMiny(), zone.getMaxy())); - } else { - log.info("[Zones] Missing zone vertex for cuboid zone id: " + zone.getId()); - return null; - } - } else if(zone.getFormtype().equalsIgnoreCase("ZoneNPoly")) { - if (vertices.size() > 2) { - temp.setForm(new ZoneNPoly(vertices, zone.getMiny() , zone.getMaxy())); - } else { - log.warning("[Zones] Bad data for zone: " + zone.getId()); - return null; - } - } else if(zone.getFormtype().equalsIgnoreCase("ZoneCylinder")) { - if (vertices.size() == 2) { - temp.setForm(new ZoneCylinder(vertices, zone.getMiny(), zone.getMaxy())); - } else { - log.info("[Zones] Missing zone vertex for Cylinder zone id: " + zone.getId()); - return null; - } - } else if(zone.getFormtype().equalsIgnoreCase("ZoneSphere")) { - if (vertices.size() == 1) { - temp.setForm(new ZoneSphere(vertices, zone.getMiny(), zone.getMaxy())); - } else { - log.info("[Zones] Missing zone vertex for Sphere zone id: " + zone.getId()); - return null; - } + if(!temp.loadForm()) { + return null; } } catch(Exception e) { log.warning("[Zones] Error loading zone " + zone.getId() + "."); diff --git a/src/com/zones/ZonesConfig.java b/src/com/zones/ZonesConfig.java index 4206be7..fcca600 100644 --- a/src/com/zones/ZonesConfig.java +++ b/src/com/zones/ZonesConfig.java @@ -43,6 +43,7 @@ public class ZonesConfig { public static final String PROTECTED_CANNOT_DEGRADE = ChatColor.RED + "You cannot remove this upgrade from the zone."; public static final String PROTECTED_ZONE_UPGRADED = ChatColor.GREEN + "Zone {zname} upgraded."; + public static final String PROTECTED_ZONE_DEGRADED = ChatColor.GREEN + "Zone {zname} degraded."; public static final String PROTECTED_CANNOT_UPGRADE = ChatColor.RED + "You cannot upgrade this zone."; public static final String PLAYER_CANT_USE_COMMAND_IN_ZONE = ChatColor.RED + "You cannot use this command in zone '{zname}' !"; diff --git a/src/com/zones/command/imports/WorldGuardImport.java b/src/com/zones/command/imports/WorldGuardImport.java index f9c1a62..8e085db 100644 --- a/src/com/zones/command/imports/WorldGuardImport.java +++ b/src/com/zones/command/imports/WorldGuardImport.java @@ -6,15 +6,22 @@ import org.bukkit.OfflinePlayer; import org.bukkit.World; +import org.bukkit.entity.EntityType; +import com.meaglin.json.JSONArray; import com.meaglin.json.JSONObject; import com.sk89q.worldedit.BlockVector2D; +import com.sk89q.worldedit.Location; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.StateFlag.State; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.zones.Zones; +import com.zones.model.settings.ZoneVar; import com.zones.persistence.Vertice; import com.zones.persistence.Zone; @@ -22,6 +29,9 @@ public class WorldGuardImport { public static List importAll(Zones plugin) { List zones = new ArrayList<>(); WorldGuardPlugin wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard"); + if(wg == null) { + return zones; + } for(World w : plugin.getServer().getWorlds()) { RegionManager m = wg.getRegionManager(w); for(Entry e : m.getRegions().entrySet()) { @@ -92,8 +102,200 @@ public static List importAll(Zones plugin) { user.put("access", defaultAccess); grouplist.put(group, user); } + parseFlags(z, r); + zones.add(z); } } return zones; } + + private static void parseFlags(Zone z, ProtectedRegion r) { + JSONObject settings = z.getConfig().getJSONObject("settings"); + for (Entry, Object> e : r.getFlags().entrySet()) { + switch (e.getKey().getName()) { + case "passthrough": // TODO: check + break; + // arbitrary + case "build": + break; + // deprecated + case "construct": + break; + case "pvp": + settings.put(ZoneVar.PLAYER_PVP_DAMAGE.getName(), r.getFlag(DefaultFlag.PVP) == State.ALLOW); + break; + case "mob-damage": // specific flag. + settings.put(ZoneVar.PLAYER_ENTITY_DAMAGE.getName(), r.getFlag(DefaultFlag.MOB_DAMAGE) == State.ALLOW); + break; + case "mob-spawning": + settings.put(ZoneVar.MOBS.getName(), r.getFlag(DefaultFlag.MOB_SPAWNING) == State.ALLOW); + break; + case "creeper-explosion": + settings.put(ZoneVar.CREEPER_EXPLOSION.getName(), r.getFlag(DefaultFlag.CREEPER_EXPLOSION) == State.ALLOW); + break; + case "enderdragon-block-damage": + break; // TODO: implement + case "ghast-fireball": + break; // TODO: implement + case "other-explosion": + break; // TODO: implement + case "sleep": + break; // TODO: implement + case "tnt": + settings.put(ZoneVar.DYNAMITE.getName(), r.getFlag(DefaultFlag.TNT) == State.ALLOW); + break; + case "lighter": + settings.put(ZoneVar.LIGHTER.getName(), r.getFlag(DefaultFlag.TNT) == State.ALLOW); + break; + case "fire-spread": + settings.put(ZoneVar.FIRE.getName(), r.getFlag(DefaultFlag.FIRE_SPREAD) == State.ALLOW); + break; + case "lava-fire": + settings.put(ZoneVar.FIRE.getName(), r.getFlag(DefaultFlag.LAVA_FIRE) == State.ALLOW); + break; + case "lightning": + settings.put(ZoneVar.LIGHTNING.getName(), r.getFlag(DefaultFlag.LIGHTNING) == State.ALLOW); + break; + case "chest-access": // specific flag. + break; + case "water-flow": + settings.put(ZoneVar.WATER.getName(), r.getFlag(DefaultFlag.WATER_FLOW) == State.ALLOW); + break; + case "lava-flow": + settings.put(ZoneVar.LAVA.getName(), r.getFlag(DefaultFlag.LAVA_FLOW) == State.ALLOW); + break; + case "use": // specific flag. + break; + case "vehicle-place": // specific flag. + break; + case "vehicle-destroy": // specific flag. + break; + case "pistons": // WHY THE FUDGE? + break; // TODO: implement + case "snow-fall": + settings.put(ZoneVar.SNOW_FALL.getName(), r.getFlag(DefaultFlag.SNOW_FALL) == State.ALLOW); + break; + case "snow-melt": + settings.put(ZoneVar.SNOW_MELT.getName(), r.getFlag(DefaultFlag.SNOW_MELT) == State.ALLOW); + break; + case "ice-form": + settings.put(ZoneVar.ICE_FORM.getName(), r.getFlag(DefaultFlag.ICE_FORM) == State.ALLOW); + break; + case "ice-melt": + settings.put(ZoneVar.ICE_MELT.getName(), r.getFlag(DefaultFlag.ICE_MELT) == State.ALLOW); + break; + case "mushroom-growth": + settings.put(ZoneVar.MUSHROOM_SPREAD.getName(), r.getFlag(DefaultFlag.MUSHROOMS) == State.ALLOW); + break; + case "leaf-decay": + settings.put(ZoneVar.LEAF_DECAY.getName(), r.getFlag(DefaultFlag.LEAF_DECAY) == State.ALLOW); + break; + case "grass-growth": + settings.put(ZoneVar.GRASS_GROWTH.getName(), r.getFlag(DefaultFlag.GRASS_SPREAD) == State.ALLOW); + break; + case "mycelium-spread": + settings.put(ZoneVar.MYCELIUM_SPREAD.getName(), r.getFlag(DefaultFlag.GRASS_SPREAD) == State.ALLOW); + break; + case "vine-growth": + settings.put(ZoneVar.VINES_GROWTH.getName(), r.getFlag(DefaultFlag.VINE_GROWTH) == State.ALLOW); + break; + case "soil-dry": + settings.put(ZoneVar.SOIL_DRY.getName(), r.getFlag(DefaultFlag.SOIL_DRY) == State.ALLOW); + break; + case "enderman-grief": + settings.put(ZoneVar.ENDER_GRIEFING.getName(), r.getFlag(DefaultFlag.ENDER_BUILD) == State.ALLOW); + break; + case "invincible": + break; // TODO: implement + case "exp-drops": + break; // TODO: implement + case "send-chat": + break; + case "receive-chat": + break; + case "entry": // specific flag. + break; + case "exit": // specific flag. + break; + case "item-drop": // specific flag. + break; + case "enderpearl": + settings.put(ZoneVar.ENDERPEARL.getName(), r.getFlag(DefaultFlag.ENDERPEARL) == State.ALLOW); + break; + case "entity-painting-destroy": // specific flag. + break; + case "entity-item-frame-destroy": // specific flag. + break; + case "potion-splash": + break; // TODO: implement + case "greeting": + settings.put(ZoneVar.ENTER_MESSAGE.getName(), r.getFlag(DefaultFlag.GREET_MESSAGE)); + break; + case "farewell": + settings.put(ZoneVar.LEAVE_MESSAGE.getName(), r.getFlag(DefaultFlag.FAREWELL_MESSAGE)); + break; + case "notify-enter": + settings.put(ZoneVar.NOTIFY.getName(), r.getFlag(DefaultFlag.NOTIFY_ENTER)); + break; + case "notify-leave": + settings.put(ZoneVar.NOTIFY.getName(), r.getFlag(DefaultFlag.NOTIFY_LEAVE)); + break; + case "deny-spawn": + JSONArray arr = new JSONArray(); + for(EntityType type : EntityType.values()) { + if(!r.getFlag(DefaultFlag.DENY_SPAWN).contains(type)) { + arr.add(type.name()); + } + } + settings.put(ZoneVar.ALLOWED_ANIMALS.getName(), arr); + settings.put(ZoneVar.ALLOWED_MOBS.getName(), arr); + break; + case "game-mode": + break; // TODO: implement + case "heal-delay": // We are not a very statefull plugin. + break; // TODO: implement + case "heal-amount": // We are not a very statefull plugin. + break; // TODO: implement + case "heal-min-health": // We are not a very statefull plugin. + break; // TODO: implement + case "heal-max-health": // We are not a very statefull plugin. + break; // TODO: implement + case "feed-delay": // We are not a very statefull plugin. + break; // TODO: implement + case "feed-amount": // We are not a very statefull plugin. + break; // TODO: implement + case "feed-min-hunger": // We are not a very statefull plugin. + break; // TODO: implement + case "feed-max-hunger": // We are not a very statefull plugin. + break; // TODO: implement + case "teleport": + break; // TODO: implement + case "spawn": + JSONObject obj = new JSONObject(); + Location loc = r.getFlag(DefaultFlag.SPAWN_LOC); + obj.put("world", loc.getWorld().getName()) + .put("x", loc.getPosition().getX()) + .put("y", loc.getPosition().getY()) + .put("z", loc.getPosition().getZ()) + .put("yaw", loc.getYaw()) + .put("pitch", loc.getPitch()); + settings.put(ZoneVar.SPAWN_LOCATION.getName(), obj); + break; + case "allow-shop": + break; // TODO: implement + case "buyable": + settings.put(ZoneVar.BUY_ALLOWED.getName(), r.getFlag(DefaultFlag.BUYABLE)); + break; + case "price": + settings.put(ZoneVar.BUY_PRICE.getName(), r.getFlag(DefaultFlag.PRICE)); + break; + case "blocked-cmds": + settings.put(ZoneVar.DENIED_COMMANDS.getName(), new JSONArray(r.getFlag(DefaultFlag.BLOCKED_CMDS))); + break; + case "allowed-cmds": + settings.put(ZoneVar.ALLOWED_COMMANDS.getName(), new JSONArray(r.getFlag(DefaultFlag.ALLOWED_CMDS))); + break; + } + } + } } diff --git a/src/com/zones/listeners/ZonesBlockListener.java b/src/com/zones/listeners/ZonesBlockListener.java index 76ef751..e2e3780 100644 --- a/src/com/zones/listeners/ZonesBlockListener.java +++ b/src/com/zones/listeners/ZonesBlockListener.java @@ -184,7 +184,7 @@ public void onBlockFade(BlockFadeEvent event) { Material mat = block.getType(); switch(mat) { - case SNOW: case ICE: break; + case SNOW: case ICE: case SOIL:break; default: return; } @@ -201,6 +201,11 @@ public void onBlockFade(BlockFadeEvent event) { event.setCancelled(true); } break; + case SOIL: + if(!wm.testFlag(event.getBlock(), ZoneVar.SOIL_DRY)) { + event.setCancelled(true); + } + break; } } @@ -211,6 +216,7 @@ public void onBlockSpread(org.bukkit.event.block.BlockSpreadEvent event) { case BROWN_MUSHROOM: case RED_MUSHROOM: case VINE: + case MYCEL: break; default: return; } @@ -234,6 +240,11 @@ public void onBlockSpread(org.bukkit.event.block.BlockSpreadEvent event) { event.setCancelled(true); } break; + case MYCEL: + if(!wm.testFlag(event.getBlock(), ZoneVar.MYCELIUM_SPREAD)) { + event.setCancelled(true); + } + break; } } diff --git a/src/com/zones/listeners/ZonesEntityListener.java b/src/com/zones/listeners/ZonesEntityListener.java index 54f1e74..0b34f77 100644 --- a/src/com/zones/listeners/ZonesEntityListener.java +++ b/src/com/zones/listeners/ZonesEntityListener.java @@ -100,6 +100,10 @@ public void onEntityDamage(EntityDamageEvent event) { sub = ZoneVar.PLAYER_CONTACT_DAMAGE; break; case ENTITY_ATTACK: + if(attacker instanceof Player) { + sub = ZoneVar.PLAYER_PVP_DAMAGE; + break; + } sub = ZoneVar.PLAYER_ENTITY_DAMAGE; break; case SUFFOCATION: @@ -130,6 +134,8 @@ public void onEntityDamage(EntityDamageEvent event) { sub = ZoneVar.PLAYER_VOID_DAMAGE; break; } + + // TODO: check for unknown types. if((sub == null && !wm.testFlag(defender.getLocation(), ZoneVar.HEALTH)) || !wm.canReceiveDamage((Player) defender, sub)) { event.setCancelled(true); diff --git a/src/com/zones/listeners/ZonesPlayerListener.java b/src/com/zones/listeners/ZonesPlayerListener.java index 29c082d..1a2ea2c 100644 --- a/src/com/zones/listeners/ZonesPlayerListener.java +++ b/src/com/zones/listeners/ZonesPlayerListener.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.List; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -34,6 +35,7 @@ import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerShearEntityEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; @@ -75,8 +77,7 @@ public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { break; } } - if(!contains - && !plugin.hasPermission(event.getPlayer(), "zones.override.command")) { + if(!contains && !plugin.hasPermission(event.getPlayer(), "zones.override.command")) { event.getPlayer().sendMessage(ZonesConfig.PLAYER_CANT_USE_COMMAND_IN_WORLD); event.setCancelled(true); return; @@ -269,12 +270,26 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { ZoneNormal aZone = wmfrom.getActiveZone(from); ZoneNormal bZone = wmto.getActiveZone(to); + if(event.getCause() == TeleportCause.ENDER_PEARL + && !wmto.getConfig().getFlagEnabledEnforced(ZoneVar.ENDERPEARL)) { + player.sendMessage(ChatColor.RED + "Enderpearls are disabled in this world."); + event.setCancelled(true); + return; + } + if(aZone != null) { if(!aZone.getFlag(ZoneVar.TELEPORT) && !aZone.canAdministrate(player)) { aZone.sendMarkupMessage(ZonesConfig.TELEPORT_INTO_ZONE_DISABLED, player); event.setCancelled(true); return; } + if(event.getCause() == TeleportCause.ENDER_PEARL + && aZone.hasSetting(ZoneVar.ENDERPEARL) + && !aZone.getFlag(ZoneVar.ENDERPEARL)) { + aZone.sendMarkupMessage(ChatColor.RED + "Cannot use an enderpearl inside {zname}.", player); + event.setCancelled(true); + return; + } } if(bZone != null) { if(!bZone.getFlag(ZoneVar.TELEPORT) && !bZone.canAdministrate(player)) { @@ -287,6 +302,13 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { event.setCancelled(false); return; } + if(event.getCause() == TeleportCause.ENDER_PEARL + && bZone.hasSetting(ZoneVar.ENDERPEARL) + && !bZone.getFlag(ZoneVar.ENDERPEARL)) { + bZone.sendMarkupMessage(ChatColor.RED + "Cannot use an enderpearl to teleport into {zname}.", player); + event.setCancelled(true); + return; + } if (wmto.getFlag(ZoneVar.BORDER) && wmto.getConfig().isEnforced(ZoneVar.BORDER) && wmto.getConfig().isOutsideBorder(to) @@ -297,6 +319,11 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { event.setCancelled(false); return; } + } else if(event.getCause() == TeleportCause.ENDER_PEARL + && !wmto.getConfig().getFlagEnabled(ZoneVar.ENDERPEARL)) { + player.sendMessage(ChatColor.RED + "Enderpearls are disabled in this world."); + event.setCancelled(true); + return; } else if (wmto.getFlag(ZoneVar.BORDER) && wmto.getConfig().isOutsideBorder(to) && (!wmto.getFlag(ZoneVar.BORDER_EXCEMPT_ADMIN) || plugin.hasPermission(wmto.getWorldName(), player, "zones.override.border")) diff --git a/src/com/zones/listeners/ZonesStoneProtectListener.java b/src/com/zones/listeners/ZonesStoneProtectListener.java index 90fdcd9..775139c 100644 --- a/src/com/zones/listeners/ZonesStoneProtectListener.java +++ b/src/com/zones/listeners/ZonesStoneProtectListener.java @@ -52,6 +52,7 @@ public void onBlockBreak(BlockBreakEvent event) { ZoneStone stone = (ZoneStone) zone; if(stone.isCenter(b)) { if(stone.canAdministrate(p)) { + stone.removeCenter(p, b); plugin.getZoneManager().delete(stone); stone.sendMarkupMessage(ZonesConfig.PROTECTED_ZONE_DELETED, p); return; @@ -62,8 +63,9 @@ public void onBlockBreak(BlockBreakEvent event) { } if(stone.isCenterUpgrade(b)) { if(stone.canAdministrate(p)) { - stone.removeUpgrade(b); - stone.sendMarkupMessage(ZonesConfig.PROTECTED_ZONE_DELETED, p); + stone.removeUpgrade(p, b); + stone.sendMarkupMessage(ZonesConfig.PROTECTED_ZONE_DEGRADED, p); + event.setCancelled(true); return; } stone.sendMarkupMessage(ZonesConfig.PROTECTED_CANNOT_DEGRADE, p); @@ -75,40 +77,61 @@ public void onBlockBreak(BlockBreakEvent event) { @EventHandler(priority=EventPriority.HIGHEST, ignoreCancelled=true) public void onBlockPlace(BlockPlaceEvent event) { - Block b = event.getBlock(); Player p = event.getPlayer(); - WorldManager wm = plugin.getWorldManager(b.getWorld()); + Block block = event.getBlock(); Player player = event.getPlayer(); + WorldManager wm = plugin.getWorldManager(block.getWorld()); if(!wm.getConfig().isEnabled(ZoneVar.PROTECT_STONE)) { return; } JSONObject val = wm.getConfig().getSetting(ZoneVar.PROTECT_STONE).getJSONObject("value"); - Material mat = b.getType(); + Material mat = block.getType(); if(!val.has(mat.name())) { return; } - if(!plugin.hasPermission(p, "zones.protectionstone." + mat.name())) { - p.sendMessage(ChatColor.RED + "You are not allowed to create a protectionstone area."); + if(!plugin.hasPermission(player, "zones.protectionstone." + mat.name())) { + player.sendMessage(ChatColor.RED + "You are not allowed to create a protectionstone area."); + event.setCancelled(true); return; } JSONObject obj = val.getJSONObject(mat.name()); - int minX = b.getX() - obj.getInt("radiusX"), maxX = b.getX() + obj.getInt("radiusX"), - minY = b.getY() - obj.getInt("radiusY"), maxY = b.getY() + obj.getInt("radiusY"), - minZ = b.getZ() - obj.getInt("radiusZ"), maxZ = b.getZ() + obj.getInt("radiusZ"); + int rx = obj.getInt("radiusX"), ry = obj.getInt("radiusY"), rz = obj.getInt("radiusZ"); + + int minX = block.getX() - rx, maxX = block.getX() + rx, + minY = block.getY() - ry, maxY = block.getY() + ry, + minZ = block.getZ() - rz, maxZ = block.getZ() + rz; List list = wm.getZones(minX - 1, maxX + 1, minY - 1, maxY + 1, minZ - 1, maxZ + 1); for(ZoneNormal zone : list) { - if(!zone.canAdministrate(p)) { - zone.sendMarkupMessage(ZonesConfig.PROTECTED_AREA_CONFLICTS, p); + if(!zone.canAdministrate(player)) { + zone.sendMarkupMessage(ZonesConfig.PROTECTED_AREA_CONFLICTS, player); event.setCancelled(true); return; } + if(zone instanceof ZoneStone) { + ZoneStone stone = (ZoneStone) zone; + if(stone.isNearCenter(block, 3)) { + if(!plugin.hasPermission(player, "zones.protectionstoneupgrade." + mat.name())) { + player.sendMessage(ChatColor.RED + "You are not allowed to upgrade a protectionstone area."); + event.setCancelled(true); + return; + } + if(!stone.canUpgrade(obj)) { + player.sendMessage(ChatColor.RED + "Upgrading this zone would conflict with an other zone."); + event.setCancelled(true); + return; + } + stone.addUpgrade(block, obj); + stone.sendMarkupMessage(ZonesConfig.PROTECTED_ZONE_UPGRADED, player); + return; + } + } } Zone zoneCfg = new Zone(); - zoneCfg.setName(p.getName() + "'s zone"); + zoneCfg.setName(player.getName() + "'s zone"); zoneCfg.setZonetype("ZoneNormal"); zoneCfg.setFormtype("ZoneCuboid"); - zoneCfg.setWorld(p.getWorld().getName()); + zoneCfg.setWorld(player.getWorld().getName()); zoneCfg.setSize(2); zoneCfg.getConfig().put("version", 1); zoneCfg.setMinY(minY); @@ -129,13 +152,16 @@ public void onBlockPlace(BlockPlaceEvent event) { JSONObject user = new JSONObject(); user.put("admin", true); user.put("access", "*"); - user.put("name", p.getName()); - user.put("uuid", p.getUniqueId().toString()); - zoneCfg.getConfig().getJSONObject("users").put(p.getUniqueId().toString(), user); + user.put("name", player.getName()); + user.put("uuid", player.getUniqueId().toString()); + zoneCfg.getConfig().getJSONObject("users").put(player.getUniqueId().toString(), user); zoneCfg.getConfig().put("center", (new JSONObject()) - .put("x", b.getX()) - .put("y", b.getY()) - .put("z", b.getZ()) + .put("x", block.getX()) + .put("y", block.getY()) + .put("z", block.getZ()) + .put("xChange", rx) + .put("yChange", ry) + .put("zChange", rz) ); zoneCfg.saveConfig(); diff --git a/src/com/zones/listeners/ZonesWeatherListener.java b/src/com/zones/listeners/ZonesWeatherListener.java index 17e2f40..3ce1bc7 100644 --- a/src/com/zones/listeners/ZonesWeatherListener.java +++ b/src/com/zones/listeners/ZonesWeatherListener.java @@ -4,6 +4,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.weather.LightningStrikeEvent; import com.zones.Zones; import com.zones.model.settings.ZoneVar; @@ -18,6 +19,14 @@ public ZonesWeatherListener(Zones plugin) { this.plugin = plugin; } + @EventHandler(ignoreCancelled = true) + public void onLightninghStrike(LightningStrikeEvent event) { + WorldManager wm = plugin.getWorldManager(event.getWorld()); + if(!wm.getConfig().getFlag(ZoneVar.LIGHTNING)) { + event.setCancelled(true); + } + } + @EventHandler(ignoreCancelled = true) public void onThunderChange(org.bukkit.event.weather.ThunderChangeEvent event) { if(!event.toThunderState()) { diff --git a/src/com/zones/model/ZoneBase.java b/src/com/zones/model/ZoneBase.java index 124189c..2a0ae32 100644 --- a/src/com/zones/model/ZoneBase.java +++ b/src/com/zones/model/ZoneBase.java @@ -18,8 +18,13 @@ import com.meaglin.json.JSONObject; import com.zones.Zones; import com.zones.backwardscompat.OldZoneVar; +import com.zones.model.forms.ZoneCuboid; +import com.zones.model.forms.ZoneCylinder; +import com.zones.model.forms.ZoneNPoly; +import com.zones.model.forms.ZoneSphere; import com.zones.model.settings.ZoneVar; import com.zones.model.settings.ZoneVarType; +import com.zones.persistence.Vertice; import com.zones.persistence.Zone; import com.zones.util.Point; import com.zones.world.WorldConfig; @@ -62,6 +67,45 @@ public final void initialize(Zones plugin, WorldManager worldManager, Zone persi } } + public boolean loadForm() { + Zone zone = getPersistence(); + List vertices = getPersistence().getVertices(); + + if(zone.getFormtype().equalsIgnoreCase("ZoneCuboid")) { + if (vertices.size() == 2) { + setForm(new ZoneCuboid(vertices, zone.getMiny(), zone.getMaxy())); + } else { + log.info("[Zones] Missing zone vertex for cuboid zone id: " + zone.getId()); + return false; + } + } else if(zone.getFormtype().equalsIgnoreCase("ZoneNPoly")) { + if (vertices.size() > 2) { + setForm(new ZoneNPoly(vertices, zone.getMiny() , zone.getMaxy())); + } else { + log.warning("[Zones] Bad data for zone: " + zone.getId()); + return false; + } + } else if(zone.getFormtype().equalsIgnoreCase("ZoneCylinder")) { + if (vertices.size() == 2) { + setForm(new ZoneCylinder(vertices, zone.getMiny(), zone.getMaxy())); + } else { + log.info("[Zones] Missing zone vertex for Cylinder zone id: " + zone.getId()); + return false; + } + } else if(zone.getFormtype().equalsIgnoreCase("ZoneSphere")) { + if (vertices.size() == 1) { + setForm(new ZoneSphere(vertices, zone.getMiny(), zone.getMaxy())); + } else { + log.info("[Zones] Missing zone vertex for Sphere zone id: " + zone.getId()); + return false; + } + } else { + log.info("[Zones] Unknown zoneForm " + zone.getFormtype() + " zone id: " + zone.getId()); + return false; + } + return true; + } + protected void onLoad(Zone persistence) { name = persistence.getName(); JSONObject cfg = getConfig(); diff --git a/src/com/zones/model/settings/ZoneVar.java b/src/com/zones/model/settings/ZoneVar.java index a758555..980c980 100644 --- a/src/com/zones/model/settings/ZoneVar.java +++ b/src/com/zones/model/settings/ZoneVar.java @@ -9,6 +9,7 @@ public enum ZoneVar { TELEPORT("TeleportEnabled", ZoneVarType.BOOLEAN, true) {}, + ENDERPEARL("EnderPearl", ZoneVarType.BOOLEAN, true), LIGHTER("LighterEnabled", ZoneVarType.BOOLEAN, true) {}, FIRE("FireEnabled", ZoneVarType.BOOLEAN, true) {}, @@ -24,6 +25,7 @@ public enum ZoneVar { HEALTH("HealthEnabled", ZoneVarType.BOOLEAN, true) {}, PLAYER_ENTITY_DAMAGE("PlayerEntityDamageEnabled", ZoneVarType.BOOLEAN, true), + PLAYER_PVP_DAMAGE("PlayerPVPDamageEnabled", ZoneVarType.BOOLEAN, true), PLAYER_FALL_DAMAGE("PlayerFallDamageEnabled", ZoneVarType.BOOLEAN, true), PLAYER_LAVA_DAMAGE("PlayerLavaDamageEnabled", ZoneVarType.BOOLEAN, true), PLAYER_SUFFOCATION_DAMAGE("PlayerSuffocationDamageEnabled", ZoneVarType.BOOLEAN, true), @@ -41,6 +43,7 @@ public enum ZoneVar { EXPLOSION_PROTECT_ENTITIES("ExplosionProtectEntites", ZoneVarType.BOOLEAN, false), EXPLOSION_PROTECTED_BLOCKS("ExplosionProtectedBlocks", ZoneVarType.MATERIALLIST, new JSONArray()), + SOIL_DRY("SoilDry", ZoneVarType.BOOLEAN, true), PHYSICS("PhysicsEnabled", ZoneVarType.BOOLEAN, true) {}, NOTIFY("NotifyEnabled", ZoneVarType.BOOLEAN, false) {}, CROP_PROTECTION("CropProtectionEnabled", ZoneVarType.BOOLEAN, false) {}, @@ -54,6 +57,7 @@ public enum ZoneVar { VINES_GROWTH("VinesGrowth", ZoneVarType.BOOLEAN, true) {}, GRASS_GROWTH("GrassGrowth", ZoneVarType.BOOLEAN, true) {}, TREE_GROWTH("TreeGrowth", ZoneVarType.BOOLEAN, true) {}, + MYCELIUM_SPREAD("MyceliumSpread", ZoneVarType.BOOLEAN, true) {}, PLACE_BLOCKS("ProtectedPlaceMaterials", ZoneVarType.MATERIALLIST, new JSONArray()) {}, BREAK_BLOCKS("ProtectedBreakMaterials", ZoneVarType.MATERIALLIST, new JSONArray()) {}, @@ -68,6 +72,9 @@ public enum ZoneVar { ENTER_MESSAGE("EnterMessage", ZoneVarType.STRING, "You've entered {zone}[{access}]") {}, LEAVE_MESSAGE("LeaveMessage", ZoneVarType.STRING, "You've left {zone}.") {}, + + LIGHTNING("LightningStrike", ZoneVarType.BOOLEAN, true), + RAIN("RainEnabled", ZoneVarType.BOOLEAN, ZoneVarScope.WORLD, true), RAIN_DIVIDER("RainDivider", ZoneVarType.INTEGER, ZoneVarScope.WORLD, 1), THUNDER("ThunderEnabled", ZoneVarType.BOOLEAN, ZoneVarScope.WORLD, true), @@ -89,6 +96,9 @@ public enum ZoneVar { .put("radiusX", 1) .put("radiusY", 1) .put("radiusZ", 1) + .put("radiusUpgradeX", 1) + .put("radiusUpgradeY", 1) + .put("radiusUpgradeZ", 1) )), SPAWN_LOCATION("SpawnLocation", ZoneVarType.LOCATION, ZoneVarScope.LOCAL, new JSONObject()) {}, diff --git a/src/com/zones/model/types/ZoneStone.java b/src/com/zones/model/types/ZoneStone.java index 16ead8b..b860e9a 100644 --- a/src/com/zones/model/types/ZoneStone.java +++ b/src/com/zones/model/types/ZoneStone.java @@ -1,9 +1,17 @@ package com.zones.model.types; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import com.meaglin.json.JSONObject; +import com.zones.model.ZoneForm; +import com.zones.persistence.Vertice; import com.zones.persistence.Zone; public class ZoneStone extends ZoneNormal { @@ -31,15 +39,85 @@ protected void onLoad(Zone persistence) { } } - public void addUpgrade(Block block) { + public void addUpgrade(Block block, JSONObject setting) { + int cx = setting.getInt("radiusUpgradeX"), cy = setting.getInt("radiusUpgradeY"), cz = setting.getInt("radiusUpgradeZ"); + getConfig().getJSONObject("centerUpgrades").put(blockToString(block), new JSONObject() - .put("x", block.getX()) - .put("y", block.getY()) - .put("z", block.getZ())); + .put("x", block.getX()) + .put("y", block.getY()) + .put("z", block.getZ()) + .put("xChange", cx) + .put("yChange", cy) + .put("zChange", cz) + ); + List vert = this.getPersistence().getVertices(); + vert.get(0).setX(vert.get(0).getX() - cx); + vert.get(0).setZ(vert.get(0).getZ() - cz); + + vert.get(1).setX(vert.get(1).getX() + cx); + vert.get(1).setZ(vert.get(1).getZ() + cz); + + getPersistence().setMinY(getPersistence().getMiny() - cy); + getPersistence().setMaxY(getPersistence().getMaxy() + cy); + loadForm(); // Reload form. } - public void removeUpgrade(Block block) { - getConfig().remove(blockToString(block)); + public void removeCenter(Player player, Block block) { + JSONObject c = getConfig().getJSONObject("centerUpgrades"); + for(String key : c.keySet()) { + JSONObject u = c.getJSONObject(key); + Block b = block.getWorld().getBlockAt(u.getInt("x"), u.getInt("y"), u.getInt("z")); + + giveOrDrop(player, new ItemStack(b.getType())); + b.setType(Material.AIR); + } + giveOrDrop(player, new ItemStack(block.getType())); + block.setType(Material.AIR); + } + + public void removeUpgrade(Player player, Block block) { +// JSONObject b = getConfig().getJSONObject("centerUpgrades").getJSONObject(blockToString(block)); + JSONObject c = getConfig().getJSONObject("centerUpgrades"); + JSONObject b = (JSONObject) c.remove(blockToString(block)); + int totalY = 0; + for(String key : c.keySet()) { + totalY += c.getJSONObject(key).getInt("yChange"); + } + totalY += getConfig().getJSONObject("center").getInt("yChange"); + int centerY = getConfig().getJSONObject("center").getInt("y"); + int lowY = centerY - totalY, highY = centerY + totalY; + if(lowY < 0) { + lowY = 0; + } + if(highY > 260) { + highY = 260; + } + getPersistence().setMinY(lowY); + getPersistence().setMaxY(highY); + + int cx = b.getInt("xChange"), cz = b.getInt("zChange"); + List vert = this.getPersistence().getVertices(); + vert.get(0).setX(vert.get(0).getX() + cx); + vert.get(0).setZ(vert.get(0).getZ() + cz); + + vert.get(1).setX(vert.get(1).getX() - cx); + vert.get(1).setZ(vert.get(1).getZ() - cz); + + giveOrDrop(player, new ItemStack(block.getType())); + block.setType(Material.AIR); + } + + public boolean canUpgrade(JSONObject setting) { + int cx = setting.getInt("radiusUpgradeX"), cy = setting.getInt("radiusUpgradeY"), cz = setting.getInt("radiusUpgradeZ"); + ZoneForm f = getForm(); + List zones = getWorldManager().getZones(f.getLowX() - cx, f.getHighX() + cx, f.getLowY() - cy, f.getHighY() + cy, f.getLowZ() - cz, f.getHighZ() + cz); + for(ZoneNormal zone : zones) { + if(zone.equals(this)) { // Skip self + continue; + } + return false; // Other zones, don't allow + } + return true; } public boolean isCenter(Block block) { @@ -68,93 +146,103 @@ public boolean isNearCenter(Block b, int range) { (b.getY() >= (y-range) && b.getY() <= (y+range)) && (b.getZ() >= (z-range) && b.getZ() <= (z+range)); } + + private void giveOrDrop(Player player, ItemStack stack) { + Map rest = player.getInventory().addItem(stack); + ItemStack drop = rest.get(0); + if(drop != null) { + player.getWorld().dropItem(player.getLocation(), drop); + } + } + + /* + public boolean isGovernor() { + return isGovernor; + } + + public boolean hasParent() { + return parent != null; + } + + private void tellParent(ZoneStone child) { + if(children == null) { + children = new ArrayList<>(); + } + isGovernor = true; + children.add(child); + } + + @Override + public JSONObject getSettings() { + return hasParent() ? parent.getSettings() : super.getSettings(); + } + + @Override + public boolean canModify(Player player, ZonesAccess.Rights right) { + return hasParent() ? parent.canModify(player, right) : super.canModify(player, right); + } -// public boolean isGovernor() { -// return isGovernor; -// } -// -// public boolean hasParent() { -// return parent != null; -// } -// -// private void tellParent(ZoneStone child) { -// if(children == null) { -// children = new ArrayList<>(); -// } -// isGovernor = true; -// children.add(child); -// } -// -// @Override -// public JSONObject getSettings() { -// return hasParent() ? parent.getSettings() : super.getSettings(); -// } -// -// @Override -// public boolean canModify(Player player, ZonesAccess.Rights right) { -// return hasParent() ? parent.canModify(player, right) : super.canModify(player, right); -// } -// -// @Override -// public ZonesAccess getAccess(String group) { -// return hasParent() ? parent.getAccess(group) : super.getAccess(group); -// } -// -// @Override -// public ZonesAccess getAccess(OfflinePlayer player) { -// return hasParent() ? parent.getAccess(player) : super.getAccess(player); -// } -// -// @Override -// protected boolean isAdmin(OfflinePlayer player) { -// return hasParent() ? parent.isAdmin(player) : super.isAdmin(player); -// } -// -// @Override -// public boolean isAdminUser(OfflinePlayer player) { -// return hasParent() ? parent.isAdminUser(player) : super.isAdminUser(player); -// } -// -// @Override -// protected String usersToString() { -// return hasParent() ? parent.usersToString() : super.usersToString(); -// } -// -// @Override -// protected String adminsToString() { -// return hasParent() ? parent.adminsToString() : super.adminsToString(); -// } -// -// @Override -// public void setAdmin(OfflinePlayer player, boolean isAdmin) { -// if(hasParent()) { -// parent.setAdmin(player, isAdmin); -// } else { -// super.setAdmin(player, isAdmin); -// } -// } -// -// @Override -// public ZonesAccess setUser(OfflinePlayer player, String access) { -// return hasParent() ? parent.setUser(player, access) : super.setUser(player, access); -// } -// -// @Override -// public ZonesAccess setGroup(String group, String access) { -// return hasParent() ? parent.setGroup(group, access) : super.setGroup(group, access); -// } -// -// @Override -// public void removeAdmin(JSONObject admin) { -// if(hasParent()) { -// parent.removeAdmin(admin); -// } else { -// super.removeAdmin(admin); -// } -// } -// -// @Override -// public JSONObject matchUser(String name) { -// return hasParent() ? parent.matchUser(name) : super.matchUser(name); -// } + @Override + public ZonesAccess getAccess(String group) { + return hasParent() ? parent.getAccess(group) : super.getAccess(group); + } + + @Override + public ZonesAccess getAccess(OfflinePlayer player) { + return hasParent() ? parent.getAccess(player) : super.getAccess(player); + } + + @Override + protected boolean isAdmin(OfflinePlayer player) { + return hasParent() ? parent.isAdmin(player) : super.isAdmin(player); + } + + @Override + public boolean isAdminUser(OfflinePlayer player) { + return hasParent() ? parent.isAdminUser(player) : super.isAdminUser(player); + } + + @Override + protected String usersToString() { + return hasParent() ? parent.usersToString() : super.usersToString(); + } + + @Override + protected String adminsToString() { + return hasParent() ? parent.adminsToString() : super.adminsToString(); + } + + @Override + public void setAdmin(OfflinePlayer player, boolean isAdmin) { + if(hasParent()) { + parent.setAdmin(player, isAdmin); + } else { + super.setAdmin(player, isAdmin); + } + } + + @Override + public ZonesAccess setUser(OfflinePlayer player, String access) { + return hasParent() ? parent.setUser(player, access) : super.setUser(player, access); + } + + @Override + public ZonesAccess setGroup(String group, String access) { + return hasParent() ? parent.setGroup(group, access) : super.setGroup(group, access); + } + + @Override + public void removeAdmin(JSONObject admin) { + if(hasParent()) { + parent.removeAdmin(admin); + } else { + super.removeAdmin(admin); + } + } + + @Override + public JSONObject matchUser(String name) { + return hasParent() ? parent.matchUser(name) : super.matchUser(name); + } + */ } diff --git a/src/com/zones/persistence/Database.java b/src/com/zones/persistence/Database.java index 11df0ad..04d52fb 100644 --- a/src/com/zones/persistence/Database.java +++ b/src/com/zones/persistence/Database.java @@ -30,10 +30,13 @@ public class Database { "`users` = ?, `settings` = ?, `minz` = ?, `maxz` = ?, size = ?, config = ? " + "WHERE id = ? LIMIT 1"; + public static final String UPDATE_VERTICE = ""; + public static final String DELETE_ZONE = "DELETE FROM `zones` WHERE id = ? LIMIT 1"; public static final String DELETE_VERTICE = "DELETE FROM `zones_vertices` WHERE id = ?"; public static final String SELECT_WORLD = "SELECT * FROM `zones` WHERE world = ? "; + public static final String SELECT_ZONES = "SELECT z.*, v.vertexorder as vertexorder, v.x as vertexx, v.y as vertexz FROM `zones` as z LEFT JOIN `zones_vertices` as v ON v.id = z.id WHERE world = ? ORDER BY z.id ASC, v.vertexorder ASC"; public static final String SELECT_VERTICE = "SELECT * FROM `zones_vertices` WHERE id = ? ORDER BY `vertexorder` ASC "; public static final String SELECT_ZONE = "SELECT * FROM `zones` WHERE id = ? LIMIT 1"; @@ -97,6 +100,54 @@ private Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } + public List getWorld(String world) { + Connection conn = null; + PreparedStatement st = null; + ResultSet rs = null; + List zones = new ArrayList(); + try { + conn = getConnection(); + st = conn.prepareStatement(SELECT_ZONES); + st.setString(1, world); + rs = st.executeQuery(); + Zone z = null; + while(rs.next()) { + if(z == null || z.getId() != rs.getInt("id")) { + if(z != null) { + zones.add(z); + } + z = new Zone(); + z.setId( rs.getInt("id")); + z.setName( rs.getString("name")); + z.setZonetype( rs.getString("zonetype")); + z.setFormtype( rs.getString("formtype")); + z.setWorld( rs.getString("world")); + z.setAdmins( rs.getString("admins")); + z.setUsers( rs.getString("users")); + z.setSettings( rs.getString("settings")); + z.setMinY( rs.getInt("minz")); + z.setMaxY( rs.getInt("maxz")); + z.setSize( rs.getInt("size")); + z.setConfig( rs.getString("config")); + } + z.addVertice(Vertice.from(z, rs)); + } + if(z != null) { + zones.add(z); + } + } catch(Exception e) { + Zones.log.warning("[Zones]Error loading zones of world " + world + ":"); + e.printStackTrace(); + } finally { + try{ + if(conn != null) conn.close(); + if(st != null) st.close(); + if(rs != null) rs.close(); + } catch(Exception e) {} + } + return zones; + } + public List get(String world) { Connection conn = null; PreparedStatement st = null; @@ -109,7 +160,7 @@ public List get(String world) { rs = st.executeQuery(); while(rs.next()) { Zone z = new Zone(); - z.setId( rs.getInt(1)); + z.setId( rs.getInt("id")); z.setName( rs.getString("name")); z.setZonetype( rs.getString("zonetype")); z.setFormtype( rs.getString("formtype")); diff --git a/src/com/zones/persistence/Vertice.java b/src/com/zones/persistence/Vertice.java index b07df9a..3c2f319 100644 --- a/src/com/zones/persistence/Vertice.java +++ b/src/com/zones/persistence/Vertice.java @@ -1,8 +1,12 @@ package com.zones.persistence; +import java.sql.ResultSet; +import java.sql.SQLException; + import javax.persistence.Column; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; + import com.avaje.ebean.validation.NotNull; @@ -27,6 +31,16 @@ public class Vertice { private int x; private int z; + + + public static Vertice from(Zone zone, ResultSet set) throws SQLException { + Vertice v = new Vertice(); + v.setZone(zone); + v.setVertexorder(set.getInt("vertexorder")); + v.setX(set.getInt("vertexx")); + v.setZ(set.getInt("vertexz")); + return v; + } public Zone getZone() { return zone; @@ -50,6 +64,7 @@ public int getZ() { public void setZone(Zone zone) { this.zone = zone; + this.id = zone.getId(); } public void setId(int id) { diff --git a/src/com/zones/persistence/Zone.java b/src/com/zones/persistence/Zone.java index 26a8726..8ff5054 100644 --- a/src/com/zones/persistence/Zone.java +++ b/src/com/zones/persistence/Zone.java @@ -147,10 +147,16 @@ public void setSettings(String settings) { } public void setMinY(int minz) { + if(minz < 0) { + minz = 0; + } this.miny = minz; } public void setMaxY(int maxz) { + if(maxz > 260) { + maxz = 260; + } this.maxy = maxz; } diff --git a/src/com/zones/world/WorldConfig.java b/src/com/zones/world/WorldConfig.java index 9fc49bb..b79c558 100644 --- a/src/com/zones/world/WorldConfig.java +++ b/src/com/zones/world/WorldConfig.java @@ -115,6 +115,31 @@ public boolean getFlag(ZoneVar var) { return settings.getJSONObject(var.getName()).getBoolean("value"); } + public boolean getFlagEnabledEnforced(ZoneVar var) { + if(!var.inScope(ZoneVarScope.WORLD)) { + return false; + } + JSONObject obj = settings.getJSONObject(var.getName()); + if(!obj.getBoolean("enabled")) { + return (boolean) var.getDefault(); + } + if(!obj.getBoolean("enforced")) { + return (boolean) var.getDefault(); + } + return obj.getBoolean("value"); + } + + public boolean getFlagEnabled(ZoneVar var) { + if(!var.inScope(ZoneVarScope.WORLD)) { + return false; + } + JSONObject obj = settings.getJSONObject(var.getName()); + if(!obj.getBoolean("enabled")) { + return (boolean) var.getDefault(); + } + return obj.getBoolean("value"); + } + public void setFlag(ZoneVar var, boolean set) { if(!var.inScope(ZoneVarScope.WORLD)) { return;