From 483d894c2013d411499e390614aea551c5f2d7b4 Mon Sep 17 00:00:00 2001 From: Jascha Starke Date: Sat, 25 Feb 2012 17:08:06 +0100 Subject: [PATCH] v0.9.5-beta: - configuration: disable remember of optional region - chain armor for creative player - prevent leave creative region flying - players.yml cleanup - update on region changes --- config.yml | 35 ++++-- plugin.yml | 5 +- .../minecraft/limitedcreative/BlackList.java | 6 + .../limitedcreative/Configuration.java | 80 +++++++++---- .../minecraft/limitedcreative/LCPlayer.java | 109 +++++++++++++----- .../minecraft/limitedcreative/Perms.java | 1 + .../regions/RegionListener.java | 14 ++- .../limitedcreative/store/PlayerOptions.java | 16 ++- .../minecraft/worldguard/CCommand.java | 1 + .../minecraft/worldguard/CListener.java | 34 +++++- .../minecraft/worldguard/CPlayer.java | 12 ++ .../worldguard/events/PlayerAreaEvent.java | 34 ++++++ .../events/PlayerChangedAreaEvent.java | 38 +++--- .../worldguard/events/PlayerSetAreaEvent.java | 67 +++++++++++ .../events/PlayerUpdateAreaEvent.java | 60 ++++++++++ 15 files changed, 431 insertions(+), 81 deletions(-) create mode 100644 src/de/jaschastarke/minecraft/worldguard/events/PlayerAreaEvent.java create mode 100644 src/de/jaschastarke/minecraft/worldguard/events/PlayerSetAreaEvent.java create mode 100644 src/de/jaschastarke/minecraft/worldguard/events/PlayerUpdateAreaEvent.java diff --git a/config.yml b/config.yml index fbbb036..d593bf5 100644 --- a/config.yml +++ b/config.yml @@ -2,12 +2,13 @@ # Limited Creative - Configuration # Full Default Configuration at: # https://github.com/possi/LimitedCreative/blob/master/config.yml +# +# (YAML-Syntax: http://en.wikipedia.org/wiki/YAML) # -------------------------------- store: # SeparatedInventoryEnabled # Use this option to disable the separated inventories feature, for the case you only need the other features. - # This option can only changed by reloading the plugin (not via ingame commands). # default: true enabled: true @@ -20,10 +21,27 @@ store: # UnsafeStore (for storing invalid enchants) # By default the new and upgrade-safe storage method for items is used. This method doesn't allow the use # of "invalid" enchants, like given by different plugins. Enable it, to allow invalid enchants (not recommended). - # This option can only changed by reloading the plugin (not via ingame commands). + # (May be removed with 1.2, as bukkit then allows unsafed enchants by default) # default: false unsafe: false + # CreativeArmor + # When set, all creative Player automatically wears the given items as Armor. So they are better seen by other + # Players. + armor: + # CreativeArmorEnabled + # When disabled, the players Armor isn't swapped + # default: true + enabled: true + + # CreativeArmor-Items + # Allows changing of the "Creative-Armor" to be wear when in creative mode + # *see Blacklist for details on Item-Types + head: CHAINMAIL_HELMET + chest: CHAINMAIL_CHESTPLATE + legs: CHAINMAIL_LEGGINGS + feet: CHAINMAIL_BOOTS + # InventoryFolder # The folder inside the datadir-folder (plugin/LimitedCreative) where the inventories are saved to. # By default the inventories are saved to "plugin/LimitedCreative/inventories". @@ -33,8 +51,7 @@ store: limit: # LimitsEnabled # Use this option to disable all drop/pvp/etc. preventions while in creative mode. While you also can get this - # by giving the "nolimit" permissions, using this option can save you CPU performance. This option can only changed - # by reloading the plugin (not via ingame commands). + # by giving the "nolimit" permissions, using this option can save you CPU performance. # default: true enabled: true @@ -88,7 +105,6 @@ limit: # data-value, all items/blocks of this material are blocked. # You also may add the special block "*" (better add quotes to don't break yml) which prevents the usage of ANY # item/block. - # This option can only changed by reloading the plugin (not via ingame commands). # default: [] use: [] @@ -96,7 +112,6 @@ limit: # Prevents destroying of the given blocks in creative mode (and only in creative). # You can use the technical name (see http://jd.bukkit.org/doxygen/d7/dd9/namespaceorg_1_1bukkit.html#ab7fa290bb19b9a830362aa88028ec80a) # or the id of the block/item (better use the id, if you're not sure). - # This option can only changed by reloading the plugin (not via ingame commands). # You may add the data separated with a colon e.g.: "WOOL:11" blocks blue wool. But be sure to put it in quotes, to # not break yml-configuration! Named data values aren't supported yet. If you don't add a data-value, all blocks # of this material are blocked. @@ -110,7 +125,6 @@ region: # RegionsEnabled # Enables the Feature for "creative-regions". This Feature is automatically disabled, if the required plugin # "WorldGuard" (http://dev.bukkit.org/server-mods/worldguard/) isn't found. - # This option can only changed by reloading the plugin (not via ingame commands). # default: true enabled: true @@ -119,6 +133,13 @@ region: # have no global permission to those commands # default: true optional: true + + # RegionRememberOptional + # Remembers if s.o. disables the region gamemode, so the region doesn't change his mode automatically if he enters + # the region again. + # Hint: Is very confusing, if MultiVerse "enforce gamemode" swaps your state. + # default: true + remember: true permissions: # PermissionsEnabled diff --git a/plugin.yml b/plugin.yml index a3ba3bc..56f8c48 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: LimitedCreative main: de.jaschastarke.minecraft.limitedcreative.Core -version: 0.9.5-dev +version: 0.9.5-beta softdepend: [WorldGuard, WorldEdit, MultiInv] dev-url: http://dev.bukkit.org/server-mods/limited-creative/ commands: @@ -19,6 +19,9 @@ permissions: limitedcreative.regions: description: Allows usage of the //region commands default: op + limitedcreative.regions.bypass: + description: Ignores the force of a gamemode, when region optional is disabled + default: false limitedcreative.switch_gamemode: description: Allows switching of own game mode to creative and back default: op diff --git a/src/de/jaschastarke/minecraft/limitedcreative/BlackList.java b/src/de/jaschastarke/minecraft/limitedcreative/BlackList.java index 0f77bf4..d1f963b 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/BlackList.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/BlackList.java @@ -5,6 +5,7 @@ import java.util.List; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.inventory.ItemStack; +import org.bukkit.material.MaterialData; abstract public class BlackList { @@ -36,6 +37,11 @@ abstract public class BlackList { public Some(Material material) { mat = material; } + public Some(MaterialData md) { + mat = md.getItemType(); + if (md.getData() != 0) + this.data = md.getData(); + } public boolean matches(Block block) { if (this.mat == null) return true; diff --git a/src/de/jaschastarke/minecraft/limitedcreative/Configuration.java b/src/de/jaschastarke/minecraft/limitedcreative/Configuration.java index 4800131..fed84c3 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/Configuration.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/Configuration.java @@ -23,10 +23,14 @@ import static de.jaschastarke.minecraft.utils.Util.copyFile; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.material.MaterialData; import de.jaschastarke.minecraft.limitedcreative.store.InvYamlStorage; import de.jaschastarke.minecraft.limitedcreative.store.PlayerInventoryStorage; @@ -38,7 +42,9 @@ public class Configuration { public enum Option { STORECREATIVE("store.creative", true), + CREATIVEARMOR("store.armor.enabled", true), REGION_OPTIONAL("region.optional", true), + REGION_REMEMBER("region.remember", true), BLOCKPICKUP("limit.pickup", true), BLOCKSIGN("limit.sign", true), BLOCKBUTTON("limit.button", false), @@ -151,6 +157,9 @@ public class Configuration { public boolean getRegionOptional() { return this.getBoolean(Option.REGION_OPTIONAL); } + public boolean getRegionRememberOptional() { + return this.getRegionOptional() && this.getBoolean(Option.REGION_REMEMBER); + } public String getLocale() { if (c.contains("locale") && c.getString("locale") != "none") @@ -187,40 +196,49 @@ public class Configuration { List list = new ArrayList(); if (s != null) { for (String m : s) { - int d = -1; if (m.equals("*")) { list.clear(); list.add(new BlackList.All()); break; } else { - if (m.contains(":")) { - String[] t = m.split(":"); - m = t[0]; - try { - d = Integer.parseInt(t[1]); - } catch (NumberFormatException ex) { - // TODO: try to find the data value by - if (d == -1) - plugin.warn(L("exception.config.materiak_data_not_found", t[1])); - } - } - Material e = null; - try { - e = Material.getMaterial(Integer.parseInt(m)); - } catch (NumberFormatException ex) { - e = Material.matchMaterial(m); - } - if (e == null) { - plugin.warn(L("exception.config.material_not_found", m)); - } else { - list.add(new BlackList.Some(e, d)); - } + MaterialData md = parseMaterial(m); + if (md != null) + list.add(new BlackList.Some(md)); } } } return list; } + private MaterialData parseMaterial(String m) { + int d = -1; + if (m.contains(":")) { + String[] t = m.split(":"); + m = t[0]; + try { + d = Integer.parseInt(t[1]); + } catch (NumberFormatException ex) { + // TODO: try to find the data value by + if (d == -1) + plugin.warn(L("exception.config.materiak_data_not_found", t[1])); + } + } + Material e = null; + try { + e = Material.getMaterial(Integer.parseInt(m)); + } catch (NumberFormatException ex) { + e = Material.matchMaterial(m); + } + if (e == null) { + plugin.warn(L("exception.config.material_not_found", m)); + return null; + } + if (d != -1) + return new MaterialData(e, (byte) d); + else + return new MaterialData(e); + } + private boolean _store_enabled = true; public void setTempStoreEnabled(boolean b) { _store_enabled = b; @@ -247,4 +265,20 @@ public class Configuration { public PlayerInventoryStorage getInvetoryStorage() { return new InvYamlStorage(new File(plugin.getDataFolder(), getInventoryFolder())); } + + public Map getCreativeArmor() { + if (c.contains("store.armor") && c.isConfigurationSection("store.armor")) { + ConfigurationSection sect = c.getConfigurationSection("store.armor"); + if (sect.getBoolean("enabled")) { + Map armor = new HashMap(); + for (Map.Entry entry : sect.getValues(false).entrySet()) { + MaterialData md = parseMaterial((String) entry.getValue()); + if (md != null) + armor.put(entry.getKey(), md); + } + return armor; + } + } + return null; + } } diff --git a/src/de/jaschastarke/minecraft/limitedcreative/LCPlayer.java b/src/de/jaschastarke/minecraft/limitedcreative/LCPlayer.java index bf4fdf6..136b9ce 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/LCPlayer.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/LCPlayer.java @@ -40,9 +40,12 @@ import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.material.Lever; +import org.bukkit.material.MaterialData; import de.jaschastarke.minecraft.utils.IPermission; +import de.jaschastarke.minecraft.worldguard.events.PlayerAreaEvent; import de.jaschastarke.minecraft.worldguard.events.PlayerChangedAreaEvent; public class LCPlayer { @@ -125,6 +128,8 @@ public class LCPlayer { return getOptionalRegionGameMode(region); } private GameMode getOptionalRegionGameMode(String region) { + if (!plugin.config.getRegionRememberOptional()) + return null; if (!options.containsKey("region_opt#"+region)) { options.put("region_opt#"+region, Players.getOptions().getOptionalRegionGameMode(getName(), region)); } @@ -137,6 +142,8 @@ public class LCPlayer { setOptionalRegionGameMode(region, gm); } public void setOptionalRegionGameMode(String region, GameMode gm) { + if (!plugin.config.getRegionRememberOptional()) + return; options.remove("region_opt#"+region); Core.debug(getName()+": set optional region game mode: "+region+" - " + gm); Players.getOptions().setOptionalRegionGameMode(getName(), region, gm); @@ -162,7 +169,7 @@ public class LCPlayer { Core.debug(getName() + " going into " + gm); if (isRegionGameMode()) { // change to the other gamemode as the area defines if (!isRegionGameMode(gm)) { // only when we are not switching to the mode the region allows - if (!plugin.config.getRegionOptional()) { + if (!plugin.config.getRegionOptional() && (!plugin.config.getPermissionsEnabled() || !hasPermission(Perms.REGIONS_BYPASS))) { getPlayer().sendMessage(ChatColor.RED + L("exception.region.not_optional", gm.toString().toLowerCase())); Core.debug("... denied"); return false; @@ -192,6 +199,7 @@ public class LCPlayer { } else { getInv().clear(); } + setCreativeArmor(); } else if (gm == GameMode.SURVIVAL) { if (getInv().isStored(GameMode.SURVIVAL)) getInv().load(GameMode.SURVIVAL); @@ -201,6 +209,22 @@ public class LCPlayer { return true; } + public void setCreativeArmor() { + Map armor = plugin.config.getCreativeArmor(); + if (armor != null) { + ItemStack[] is = new ItemStack[4]; + if (armor.containsKey("feet")) + is[0] = armor.get("feet").toItemStack(1); + if (armor.containsKey("legs")) + is[1] = armor.get("legs").toItemStack(1); + if (armor.containsKey("chest")) + is[2] = armor.get("chest").toItemStack(1); + if (armor.containsKey("head")) + is[3] = armor.get("head").toItemStack(1); + getPlayer().getInventory().setArmorContents(is); + } + } + public void onDropItem(PlayerDropItemEvent event) { Core.debug(getName() + " ("+getPlayer().getGameMode()+") drops items " + event.getItemDrop().getItemStack().getType()); if (getPlayer().getGameMode() == GameMode.CREATIVE) { @@ -332,15 +356,39 @@ public class LCPlayer { } } + private boolean checkSwitchFlight(PlayerMoveEvent event) { + if (event != null && getPlayer().getGameMode() == GameMode.CREATIVE && getFloatingHeight(event.getTo()) > plugin.config.getMaximumFloatingHeight()) { + // but not if he is too high + this.sendTimeoutMessage(L("blocked.survival_flying")); + + Location newloc = event.getTo().clone(); + newloc.setX(event.getFrom().getX()); + newloc.setY(event.getFrom().getY()); // well, otherwise flying high out of the region is possible + newloc.setZ(event.getFrom().getZ()); + event.setTo(newloc); + return false; + } + return true; + } + private boolean checkSwitchFlight(PlayerAreaEvent area_event) { + if (area_event instanceof PlayerChangedAreaEvent) { + if (!checkSwitchFlight(((PlayerChangedAreaEvent) area_event).getMoveEvent())) { + ((PlayerChangedAreaEvent) area_event).setCancelled(true); + return false; + } + } + return true; + } + /* * Attention: "Creative" stands for "the other gamemode". So true may mean, "be survival in creative world". */ - public void setRegionCreativeAllowed(boolean rcreative, PlayerChangedAreaEvent changearea_event) { - Core.debug(getName()+": changed region: "+rcreative+": " + (changearea_event == null ? "null" : changearea_event.toString())); + public void setRegionCreativeAllowed(boolean rcreative, PlayerAreaEvent area_event) { + Core.debug(getName()+": changed region: "+rcreative+": " + area_event); PlayerMoveEvent event = null; - if (changearea_event != null) - event = changearea_event.getMoveEvent(); + if (area_event instanceof PlayerChangedAreaEvent) + event = ((PlayerChangedAreaEvent) area_event).getMoveEvent(); GameMode CURRENT_GAMEMODE = getPlayer().getGameMode(); GameMode DEFAULT_GAMEMODE = plugin.com.getDefaultGameMode(event != null ? event.getTo().getWorld() : getPlayer().getWorld()); GameMode TEMPORARY_GAMEMODE = DEFAULT_GAMEMODE == GameMode.SURVIVAL ? GameMode.CREATIVE : GameMode.SURVIVAL; // the opposite @@ -351,13 +399,15 @@ public class LCPlayer { // 2. but the player is not in that mode // 3. and the player is not aware of that // result: change him to that mode - setRegionGameMode(TEMPORARY_GAMEMODE); // have to be set, before setGameMode - boolean isOptional = changearea_event != null ? - isOptionalRegionGameMode(changearea_event.getNewRegionHash(), CURRENT_GAMEMODE) : - isOptionalRegionGameMode(CURRENT_GAMEMODE); - if (!isOptional) { - getPlayer().setGameMode(TEMPORARY_GAMEMODE); + boolean isOptional = isOptionalRegionGameMode(area_event.getRegionHash(), CURRENT_GAMEMODE); + + if (isOptional || checkSwitchFlight(area_event)) { + setRegionGameMode(TEMPORARY_GAMEMODE); // have to be set, before setGameMode + + if (!isOptional) { + getPlayer().setGameMode(TEMPORARY_GAMEMODE); + } } } else if (!rcreative && getPlayer().getGameMode() == TEMPORARY_GAMEMODE && !isPermanentGameMode(TEMPORARY_GAMEMODE)) { Core.debug(getName()+": leaving creative area"); @@ -365,21 +415,12 @@ public class LCPlayer { // 2. but the player is in that mode // 3. and the player isn't global (permanent) in that mode // result: change him back to default mode - if (event != null && CURRENT_GAMEMODE == GameMode.CREATIVE && getFloatingHeight() > plugin.config.getMaximumFloatingHeight()) { - // but not if he is too high - this.sendTimeoutMessage(L("blocked.survival_flying")); - - Location newloc = event.getTo().clone(); - newloc.setX(event.getFrom().getX()); - newloc.setY(event.getFrom().getY()); // well, otherwise flying high out of the region is possible - newloc.setZ(event.getFrom().getZ()); - event.setTo(newloc); - } else { + if (checkSwitchFlight(area_event)) { setRegionGameMode(null); - if (event != null && event.getTo().getWorld() == event.getFrom().getWorld()) { + if (event == null || event.getTo().getWorld() == event.getFrom().getWorld()) { // do not enforce the game mode change, on world teleport, as multiverse may cancel the event afterwards // the world-change game-mode change is done by multiworld - event.getPlayer().setGameMode(DEFAULT_GAMEMODE); + getPlayer().setGameMode(DEFAULT_GAMEMODE); } } } else if (!rcreative && this.isRegionGameMode(TEMPORARY_GAMEMODE)) { @@ -389,9 +430,21 @@ public class LCPlayer { // 3. (because of else) we are not longer in that mode // result: advise him to not longer allowed to that region setRegionGameMode(null); - } else if (this.isRegionGameMode()) { - // TODO: Add check to switch to optional selected gamemode } + /** At the moment, in permanent game mode, it ignores all regions + else if (this.isRegionGameMode()) { + Core.debug(getName()+": entering creative area (while already in region gamemode)"); + // 1. the region allow "the other gamemode" + // 2. (inherit) the player is already in that mode + GameMode rgm = getOptionalRegionGameMode(area_event.getRegionHash()); + if (rgm != null && rgm != CURRENT_GAMEMODE) { + Core.debug(getName()+": switching to optional remembered gamemode"); + // 3. but he remembered optional want the other gamemode in that region + // * this inherits, that the option is allowed + // result: change to the optional remembered game mode + getPlayer().setGameMode(rgm); + } + }*/ } private Map timeout_msgs = new HashMap(); @@ -408,8 +461,12 @@ public class LCPlayer { getPlayer().sendMessage(msg); } } + public int getFloatingHeight() { - Block b = getPlayer().getLocation().getBlock(); + return getFloatingHeight(getPlayer().getLocation()); + } + public int getFloatingHeight(Location loc) { + Block b = loc.getBlock(); int steps = 0; while (b.getType() == Material.AIR) { steps++; diff --git a/src/de/jaschastarke/minecraft/limitedcreative/Perms.java b/src/de/jaschastarke/minecraft/limitedcreative/Perms.java index 6cafb55..72ffaa6 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/Perms.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/Perms.java @@ -22,6 +22,7 @@ import de.jaschastarke.minecraft.utils.IPermission; public enum Perms implements IPermission { CONFIG("config"), REGIONS("regions"), + REGIONS_BYPASS("regions_bypass"), GM("switch_gamemode"), GM_BACKONLY("switch_gamemode.backonly"), GM_SURVIVAL("switch_gamemode.survival"), diff --git a/src/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java b/src/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java index c11ef53..fb62fbf 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java @@ -14,7 +14,6 @@ import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.ItemSpawnEvent; -import org.bukkit.event.player.PlayerJoinEvent; import de.jaschastarke.minecraft.limitedcreative.Core; import de.jaschastarke.minecraft.limitedcreative.LCPlayer; @@ -23,6 +22,8 @@ import de.jaschastarke.minecraft.utils.Util; import de.jaschastarke.minecraft.worldguard.ApplicableRegions; import de.jaschastarke.minecraft.worldguard.CRegionManager; import de.jaschastarke.minecraft.worldguard.events.PlayerChangedAreaEvent; +import de.jaschastarke.minecraft.worldguard.events.PlayerSetAreaEvent; +import de.jaschastarke.minecraft.worldguard.events.PlayerUpdateAreaEvent; public class RegionListener implements Listener { private static Core plugin = WorldGuardIntegration.plugin; @@ -92,12 +93,17 @@ public class RegionListener implements Listener { @EventHandler public void onPlayerChangedArea(PlayerChangedAreaEvent event) { - Players.get(event.getPlayer()).setRegionCreativeAllowed(event.getNewRegionSet().allows(Flags.CREATIVE, event.getPlayer()), event); + Players.get(event.getPlayer()).setRegionCreativeAllowed(event.getRegionSet().allows(Flags.CREATIVE, event.getPlayer()), event); } @EventHandler - public void onPlayerLogin(PlayerJoinEvent event) { - Players.get(event.getPlayer()).setRegionCreativeAllowed(rm.getRegionSet(event.getPlayer().getLocation()).allows(Flags.CREATIVE, event.getPlayer()), null); + public void onPlayerSetArea(PlayerSetAreaEvent event) { + Players.get(event.getPlayer()).setRegionCreativeAllowed(event.getRegionSet().allows(Flags.CREATIVE, event.getPlayer()), event); + } + + @EventHandler + public void onPlayerUpdateArea(PlayerUpdateAreaEvent event) { + Players.get(event.getPlayer()).setRegionCreativeAllowed(event.getRegionSet().allows(Flags.CREATIVE, event.getPlayer()), event); } @EventHandler diff --git a/src/de/jaschastarke/minecraft/limitedcreative/store/PlayerOptions.java b/src/de/jaschastarke/minecraft/limitedcreative/store/PlayerOptions.java index 0672236..401c11e 100644 --- a/src/de/jaschastarke/minecraft/limitedcreative/store/PlayerOptions.java +++ b/src/de/jaschastarke/minecraft/limitedcreative/store/PlayerOptions.java @@ -35,10 +35,12 @@ public class PlayerOptions { } public void setRegionGameMode(String player, GameMode gm) { - if (gm == null) + if (gm == null) { store.set(player + ".region_gamemode", null); - else + cleanUp(player); + } else { store.set(player + ".region_gamemode", gm.name()); + } save(); } public GameMode getRegionGameMode(String player) { @@ -63,10 +65,18 @@ public class PlayerOptions { ConfigurationSection sect = store.contains(player+".region") ? store.getConfigurationSection(player+".region") : store.createSection(player+".region"); String mode = gm == null ? null : gm.name(); sect.set(region, mode); - if (sect.getKeys(true).size() == 0) + if (sect.getKeys(true).size() == 0) { store.set(sect.getCurrentPath(), null); + cleanUp(player); + } save(); } + + protected void cleanUp(String player) { + if (store.contains(player) && store.getConfigurationSection(player).getValues(true).size() == 0) { + store.set(player, null); + } + } protected void save() { try { diff --git a/src/de/jaschastarke/minecraft/worldguard/CCommand.java b/src/de/jaschastarke/minecraft/worldguard/CCommand.java index ff1837f..2fa2cec 100644 --- a/src/de/jaschastarke/minecraft/worldguard/CCommand.java +++ b/src/de/jaschastarke/minecraft/worldguard/CCommand.java @@ -177,6 +177,7 @@ public class CCommand implements CommandExecutor { sender.sendMessage(ChatColor.DARK_RED + e.getLocalizedMessage()); return; } + CPlayer.updateAll(); sender.sendMessage(L("command.worldguard.flag_set", flag.getName())); } diff --git a/src/de/jaschastarke/minecraft/worldguard/CListener.java b/src/de/jaschastarke/minecraft/worldguard/CListener.java index 9c6204a..08d5f35 100644 --- a/src/de/jaschastarke/minecraft/worldguard/CListener.java +++ b/src/de/jaschastarke/minecraft/worldguard/CListener.java @@ -21,12 +21,14 @@ import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; import de.jaschastarke.minecraft.worldguard.events.PlayerChangedAreaEvent; +import de.jaschastarke.minecraft.worldguard.events.PlayerSetAreaEvent; public class CListener implements Listener { private Interface com; @@ -43,11 +45,17 @@ public class CListener implements Listener { || event.getFrom().getBlockY() != event.getTo().getBlockY() || event.getFrom().getBlockZ() != event.getTo().getBlockZ()) { // he really moved, and not just looked around - if (com.getRegionManager().isDiffrentRegion(event.getPlayer(), event.getTo())) { - String current_hash = CPlayer.get(event.getPlayer()).getHash(); + String current_hash = CPlayer.get(event.getPlayer()).getHash(); + if (current_hash == null) { String new_hash = com.getRegionManager().getRegionsHash(event.getTo()); - Bukkit.getServer().getPluginManager().callEvent(new PlayerChangedAreaEvent(event, current_hash, new_hash)); + Bukkit.getServer().getPluginManager().callEvent(new PlayerSetAreaEvent(event.getPlayer(), new_hash, event.getTo())); CPlayer.get(event.getPlayer()).setHash(new_hash); + } else if (com.getRegionManager().isDiffrentRegion(event.getPlayer(), event.getTo())) { + String new_hash = com.getRegionManager().getRegionsHash(event.getTo()); + PlayerChangedAreaEvent areaevent = new PlayerChangedAreaEvent(event, current_hash, new_hash); + Bukkit.getServer().getPluginManager().callEvent(areaevent); + if (!areaevent.isCancelled()) + CPlayer.get(event.getPlayer()).setHash(new_hash); } } } @@ -59,11 +67,29 @@ public class CListener implements Listener { @EventHandler public void onPlayerLogin(PlayerJoinEvent event) { - CPlayer.get(event.getPlayer()).setHash(com.getRegionManager().getRegionsHash(event.getPlayer().getLocation())); + String new_hash = com.getRegionManager().getRegionsHash(event.getPlayer().getLocation()); + Bukkit.getServer().getPluginManager().callEvent(new PlayerSetAreaEvent(event.getPlayer(), new_hash)); + CPlayer.get(event.getPlayer()).setHash(new_hash); } @EventHandler public void onPlayerLogout(PlayerQuitEvent event) { CPlayer.remove(event.getPlayer()); } + + @EventHandler + public void onPlayerComamnd(PlayerCommandPreprocessEvent event) { + String[] cmd = event.getMessage().split(" "); + if (cmd.length >= 2) { + if (cmd[0].replaceAll("/", "").toLowerCase() == "region") { + String opt = cmd[1].toLowerCase(); + if (opt == "addowner" || opt == "addmember" || + opt == "removeowner" || opt == "remowner" || + opt == "removemember" || opt == "remmember" || + opt == "removemem" || opt == "remmem") { + CPlayer.clear(); + } + } + } + } } diff --git a/src/de/jaschastarke/minecraft/worldguard/CPlayer.java b/src/de/jaschastarke/minecraft/worldguard/CPlayer.java index 3913c58..3c2c674 100644 --- a/src/de/jaschastarke/minecraft/worldguard/CPlayer.java +++ b/src/de/jaschastarke/minecraft/worldguard/CPlayer.java @@ -20,8 +20,11 @@ package de.jaschastarke.minecraft.worldguard; import java.util.HashMap; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import de.jaschastarke.minecraft.worldguard.events.PlayerUpdateAreaEvent; + public class CPlayer { private static Map players = new HashMap(); @@ -45,4 +48,13 @@ public class CPlayer { public void setHash(String hash) { this.hash = hash; } + public static void clear() { + players.clear(); + } + + public static void updateAll() { + for (Map.Entry entry : players.entrySet()) { + Bukkit.getServer().getPluginManager().callEvent(new PlayerUpdateAreaEvent(entry.getKey(), entry.getValue().getHash())); + } + } } diff --git a/src/de/jaschastarke/minecraft/worldguard/events/PlayerAreaEvent.java b/src/de/jaschastarke/minecraft/worldguard/events/PlayerAreaEvent.java new file mode 100644 index 0000000..6ccfb3b --- /dev/null +++ b/src/de/jaschastarke/minecraft/worldguard/events/PlayerAreaEvent.java @@ -0,0 +1,34 @@ +/* + * Limited Creative - (Bukkit Plugin) + * Copyright (C) 2012 jascha@ja-s.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.jaschastarke.minecraft.worldguard.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; + +import de.jaschastarke.minecraft.worldguard.ApplicableRegions; + +@SuppressWarnings("serial") +public abstract class PlayerAreaEvent extends Event { + abstract public String getRegionHash(); + abstract public ApplicableRegions getRegionSet(); + abstract public Player getPlayer(); + + public String toString() { + return getClass().getSimpleName()+"["+getRegionHash()+"]"; + } +} diff --git a/src/de/jaschastarke/minecraft/worldguard/events/PlayerChangedAreaEvent.java b/src/de/jaschastarke/minecraft/worldguard/events/PlayerChangedAreaEvent.java index 7f602a9..62a7a27 100644 --- a/src/de/jaschastarke/minecraft/worldguard/events/PlayerChangedAreaEvent.java +++ b/src/de/jaschastarke/minecraft/worldguard/events/PlayerChangedAreaEvent.java @@ -18,7 +18,7 @@ package de.jaschastarke.minecraft.worldguard.events; import org.bukkit.entity.Player; -import org.bukkit.event.Event; +import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -27,10 +27,11 @@ import de.jaschastarke.minecraft.worldguard.ApplicableRegions; import de.jaschastarke.minecraft.worldguard.Interface; @SuppressWarnings("serial") -public class PlayerChangedAreaEvent extends Event { +public class PlayerChangedAreaEvent extends PlayerAreaEvent implements Cancellable { private PlayerMoveEvent event; private String _previous_hash; - private String _new_hash; + private String _hash; + private boolean _cancelled = false; public PlayerChangedAreaEvent(PlayerMoveEvent moveevent) { event = moveevent; @@ -38,7 +39,18 @@ public class PlayerChangedAreaEvent extends Event { public PlayerChangedAreaEvent(PlayerMoveEvent moveevent, String previous_hash, String new_hash) { event = moveevent; _previous_hash = previous_hash; - _new_hash = new_hash; + _hash = new_hash; + } + + @Override + public String getRegionHash() { + if (_hash == null) + _hash = Interface.getInstance().getRegionManager().getRegionsHash(event.getTo()); + return _hash; + } + @Override + public ApplicableRegions getRegionSet() { + return Interface.getInstance().getRegionManager().getRegionSet(event.getTo()); } public Player getPlayer() { @@ -52,27 +64,19 @@ public class PlayerChangedAreaEvent extends Event { public ApplicableRegions getPreviousRegionSet() { return Interface.getInstance().getRegionManager().getRegionSet(event.getFrom()); } - public ApplicableRegions getNewRegionSet() { - return Interface.getInstance().getRegionManager().getRegionSet(event.getTo()); - } public String getPreviousRegionHash() { if (_previous_hash == null) _previous_hash = Interface.getInstance().getRegionManager().getRegionsHash(event.getFrom()); return _previous_hash; } - public String getNewRegionHash() { - if (_new_hash == null) - _new_hash = Interface.getInstance().getRegionManager().getRegionsHash(event.getTo()); - return _new_hash; - } public PlayerMoveEvent getMoveEvent() { return event; } public String toString() { - return getClass().getSimpleName()+"["+getPreviousRegionHash()+" -> "+getNewRegionHash()+"]"; + return getClass().getSimpleName()+"["+getPreviousRegionHash()+" -> "+getRegionHash()+"]"; } private static final HandlerList handlers = new HandlerList(); @@ -84,4 +88,12 @@ public class PlayerChangedAreaEvent extends Event { public static HandlerList getHandlerList() { return handlers; } + @Override + public boolean isCancelled() { + return _cancelled; + } + @Override + public void setCancelled(boolean b) { + _cancelled = b; + } } diff --git a/src/de/jaschastarke/minecraft/worldguard/events/PlayerSetAreaEvent.java b/src/de/jaschastarke/minecraft/worldguard/events/PlayerSetAreaEvent.java new file mode 100644 index 0000000..078d476 --- /dev/null +++ b/src/de/jaschastarke/minecraft/worldguard/events/PlayerSetAreaEvent.java @@ -0,0 +1,67 @@ +/* + * Limited Creative - (Bukkit Plugin) + * Copyright (C) 2012 jascha@ja-s.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.jaschastarke.minecraft.worldguard.events; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import de.jaschastarke.minecraft.worldguard.ApplicableRegions; +import de.jaschastarke.minecraft.worldguard.Interface; + +@SuppressWarnings("serial") +public class PlayerSetAreaEvent extends PlayerAreaEvent { + private Player player; + private String hash; + private Location loc; + + public PlayerSetAreaEvent(Player player, String hash) { + this.player = player; + this.hash = hash; + } + public PlayerSetAreaEvent(Player player, String hash, Location location) { + this.player = player; + this.hash = hash; + this.loc = location; + } + + @Override + public String getRegionHash() { + return hash; + } + + @Override + public ApplicableRegions getRegionSet() { + return Interface.getInstance().getRegionManager().getRegionSet(loc != null ? loc : player.getLocation()); + } + + @Override + public Player getPlayer() { + return player; + } + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/de/jaschastarke/minecraft/worldguard/events/PlayerUpdateAreaEvent.java b/src/de/jaschastarke/minecraft/worldguard/events/PlayerUpdateAreaEvent.java new file mode 100644 index 0000000..951bedd --- /dev/null +++ b/src/de/jaschastarke/minecraft/worldguard/events/PlayerUpdateAreaEvent.java @@ -0,0 +1,60 @@ +/* + * Limited Creative - (Bukkit Plugin) + * Copyright (C) 2012 jascha@ja-s.de + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.jaschastarke.minecraft.worldguard.events; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +import de.jaschastarke.minecraft.worldguard.ApplicableRegions; +import de.jaschastarke.minecraft.worldguard.Interface; + +@SuppressWarnings("serial") +public class PlayerUpdateAreaEvent extends PlayerAreaEvent { + private String player; + private String hash; + + public PlayerUpdateAreaEvent(String player, String hash) { + this.player = player; + this.hash = hash; + } + @Override + public String getRegionHash() { + return hash; + } + + @Override + public ApplicableRegions getRegionSet() { + return Interface.getInstance().getRegionManager().getRegionSet(getPlayer().getLocation()); + } + + @Override + public Player getPlayer() { + return Bukkit.getServer().getPlayerExact(player); + } + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +}