From c9f99e0903b336bee0cde314adf14fe39d9e9447 Mon Sep 17 00:00:00 2001 From: sk89q Date: Mon, 20 Jun 2011 19:23:03 -0700 Subject: [PATCH] Added /stoplag or /halt-activity to cease all intensive operations (such as fire spread, water flow, mob spawning, etc.) and to remove mobs (except wolves) and item drops proactively for those situations when you (or someone else) messes up really badly. --- .../bukkit/ConfigurationManager.java | 1 + .../bukkit/WorldGuardBlockListener.java | 60 +++++++++++++++++ .../bukkit/WorldGuardEntityListener.java | 11 ++++ .../bukkit/WorldGuardPlayerListener.java | 34 ++++++++-- .../worldguard/bukkit/WorldGuardPlugin.java | 1 + .../bukkit/WorldGuardWorldListener.java | 66 +++++++++++++++++++ .../bukkit/commands/ToggleCommands.java | 51 ++++++++++++++ src/main/resources/plugin.yml | 4 ++ 8 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java diff --git a/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java b/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java index 73dc412c..0239f3bb 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/ConfigurationManager.java @@ -60,6 +60,7 @@ public class ConfigurationManager { public boolean suppressTickSyncWarnings; public boolean useRegionsScheduler; + public boolean activityHaltToggle = false; /** * Construct the object. diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java index 0a63b543..83c070b2 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java @@ -74,6 +74,8 @@ public void registerEvents() { pm.registerEvent(Event.Type.REDSTONE_CHANGE, this, Priority.High, plugin); pm.registerEvent(Event.Type.SNOW_FORM, this, Priority.High, plugin); pm.registerEvent(Event.Type.LEAVES_DECAY, this, Priority.High, plugin); + pm.registerEvent(Event.Type.BLOCK_FORM, this, Priority.High, plugin); + pm.registerEvent(Event.Type.BLOCK_SPREAD, this, Priority.High, plugin); } /** @@ -191,6 +193,11 @@ public void onBlockFromTo(BlockFromToEvent event) { ConfigurationManager cfg = plugin.getGlobalStateManager(); WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + if (wcfg.simulateSponge && isWater) { int ox = blockTo.getX(); int oy = blockTo.getY(); @@ -273,6 +280,11 @@ public void onBlockIgnite(BlockIgniteEvent event) { ConfigurationManager cfg = plugin.getGlobalStateManager(); WorldConfiguration wcfg = cfg.get(world); + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + boolean isFireSpread = cause == IgniteCause.SPREAD; if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) { @@ -367,6 +379,11 @@ public void onBlockBurn(BlockBurnEvent event) { ConfigurationManager cfg = plugin.getGlobalStateManager(); WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + if (wcfg.disableFireSpread) { event.setCancelled(true); return; @@ -418,6 +435,11 @@ public void onBlockPhysics(BlockPhysicsEvent event) { ConfigurationManager cfg = plugin.getGlobalStateManager(); WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + int id = event.getChangedTypeId(); if (id == 13 && wcfg.noPhysicsGravel) { @@ -600,6 +622,13 @@ public void onSnowForm(SnowFormEvent event) { return; } + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.SNOW_FALL, event.getBlock().getLocation())) { event.setCancelled(true); @@ -612,8 +641,39 @@ public void onLeavesDecay(LeavesDecayEvent event) { return; } + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + if (!plugin.getGlobalRegionManager().allows(DefaultFlag.LEAF_DECAY, event.getBlock().getLocation())) { event.setCancelled(true); } } + + /** + * Called when a block is formed based on world conditions. + */ + public void onBlockForm(BlockFormEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + } + + /** + * Called when a block spreads based on world conditions. + */ + public void onBlockSpread(BlockSpreadEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + } } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java index 1d39993a..24bab734 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java @@ -426,6 +426,11 @@ public void onEntityExplode(EntityExplodeEvent event) { } } } else if (ent instanceof TNTPrimed) { + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + if (wcfg.blockTNT) { event.setCancelled(true); return; @@ -462,6 +467,12 @@ public void onCreatureSpawn(CreatureSpawnEvent event) { } ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + event.setCancelled(true); + return; + } + WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld()); //CreatureType creaType = (CreatureType) CreatureType.valueOf(event.getMobType().toString()); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index 4a474075..1783e685 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -20,13 +20,14 @@ import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector; import java.util.Iterator; +import java.util.logging.Logger; + import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; +import org.bukkit.entity.*; import org.bukkit.event.Event; import org.bukkit.event.Event.Priority; import org.bukkit.event.Event.Result; @@ -49,6 +50,11 @@ */ public class WorldGuardPlayerListener extends PlayerListener { + /** + * Logger for messages. + */ + private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + private WorldGuardPlugin plugin; /** @@ -111,6 +117,26 @@ public void onPlayerJoin(PlayerJoinEvent event) { ConfigurationManager cfg = plugin.getGlobalStateManager(); WorldConfiguration wcfg = cfg.get(player.getWorld()); + if (cfg.activityHaltToggle) { + player.sendMessage(ChatColor.YELLOW + + "Intensive server activity has been HALTED."); + + int removed = 0; + + for (Entity entity : player.getWorld().getEntities()) { + if (entity instanceof Item + || (entity instanceof LivingEntity && !(entity instanceof Tameable))) { + entity.remove(); + removed++; + } + } + + if (removed > 10) { + logger.info("WG Halt-Act: " + removed + " entities (>10) auto-removed from " + + player.getWorld().toString()); + } + } + if (wcfg.fireSpreadDisableToggle) { player.sendMessage(ChatColor.YELLOW + "Fire spread is currently globally disabled for this world."); @@ -241,7 +267,7 @@ public void onPlayerMove(PlayerMoveEvent event) { } } } - + /** * Called when a player left clicks air. * @@ -291,7 +317,7 @@ private void handleBlockLeftClick(PlayerInteractEvent event) { } } - /** + /** * Called when a player right clicks air. * * @param event diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java index 841418c6..76ab2598 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java @@ -138,6 +138,7 @@ public void onEnable() { (new WorldGuardBlockListener(this)).registerEvents(); (new WorldGuardEntityListener(this)).registerEvents(); (new WorldGuardWeatherListener(this)).registerEvents(); + (new WorldGuardWorldListener(this)).registerEvents(); flagStateManager = new FlagStateManager(this); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java new file mode 100644 index 00000000..97202bf6 --- /dev/null +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardWorldListener.java @@ -0,0 +1,66 @@ +// $Id$ +/* + * Copyright (C) 2010 sk89q + * All rights reserved. +*/ +package com.sk89q.worldguard.bukkit; + +import org.bukkit.entity.*; +import org.bukkit.event.Event; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.WorldListener; +import org.bukkit.plugin.PluginManager; + +import java.util.logging.Logger; + +public class WorldGuardWorldListener extends WorldListener { + + /** + * Logger for messages. + */ + private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard"); + + private WorldGuardPlugin plugin; + + /** + * Construct the object; + * + * @param plugin + */ + public WorldGuardWorldListener(WorldGuardPlugin plugin) { + this.plugin = plugin; + } + + /** + * Register events. + */ + public void registerEvents() { + PluginManager pm = plugin.getServer().getPluginManager(); + + pm.registerEvent(Event.Type.CHUNK_LOAD, this, Event.Priority.Normal, plugin); + } + + /** + * Called when a chunk is loaded. + */ + public void onChunkLoad(ChunkLoadEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + + if (cfg.activityHaltToggle) { + int removed = 0; + + for (Entity entity : event.getChunk().getEntities()) { + if (entity instanceof Item + || (entity instanceof LivingEntity && !(entity instanceof Tameable))) { + entity.remove(); + removed++; + } + } + + if (removed > 50) { + logger.info("WG Halt-Act: " + removed + " entities (>50) auto-removed from " + + event.getChunk().toString()); + } + } + } +} diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java index c7b12375..fad855a1 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/ToggleCommands.java @@ -19,12 +19,14 @@ package com.sk89q.worldguard.bukkit.commands; +import com.sk89q.worldguard.bukkit.ConfigurationManager; import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.command.CommandSender; import com.sk89q.minecraft.util.commands.*; import com.sk89q.worldguard.bukkit.WorldConfiguration; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import org.bukkit.entity.*; public class ToggleCommands { @@ -87,4 +89,53 @@ public static void allowFire(CommandContext args, WorldGuardPlugin plugin, wcfg.fireSpreadDisableToggle = false; } + + @Command(aliases = {"halt-activity"}, + usage = "", desc = "Attempts to cease as much activity in order to stop lag", + flags = "c", min = 0, max = 0) + @CommandPermissions({"worldguard.halt-activity"}) + public static void stopLag(CommandContext args, WorldGuardPlugin plugin, + CommandSender sender) throws CommandException { + + ConfigurationManager configManager = plugin.getGlobalStateManager(); + + configManager.activityHaltToggle = !args.hasFlag('c'); + + if (configManager.activityHaltToggle) { + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.YELLOW + + "ALL intensive server activity halted."); + } + + plugin.getServer().broadcastMessage(ChatColor.YELLOW + + "ALL intensive server activity halted by " + + plugin.toName(sender) + "."); + + for (World world : plugin.getServer().getWorlds()) { + int removed = 0; + + for (Entity entity : world.getEntities()) { + if (entity instanceof Item + || (entity instanceof LivingEntity && !(entity instanceof Tameable))) { + entity.remove(); + removed++; + } + } + + if (removed > 10) { + sender.sendMessage("" + removed + " entities (>10) auto-removed from " + + world.toString()); + } + } + + } else { + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.YELLOW + + "ALL intensive server activity no longer halted."); + } + + plugin.getServer().broadcastMessage(ChatColor.YELLOW + + "ALL intensive server activity is now allowed."); + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0572cd2c..3b1ccd5b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,6 +8,10 @@ commands: allowfire: description: Re-enables fire spread if he has been disabled with /stopfire usage: / + halt-activity: + aliases: [stoplag, haltactivity] + description: Attempts to stop all intensive operations (toggle) + usage: / [-c] god: description: Enable god mode usage: / [player]