From 670908dc6a8ccf5f0a538350642043b5d25cdf27 Mon Sep 17 00:00:00 2001 From: Jascha Starke Date: Wed, 20 Mar 2013 17:11:32 +0100 Subject: [PATCH] Missing commit Cleanup (esp. Translation) Fixed modules late load (confrom config cmd) Optional GameMode per Region --- TODO.txt | 7 +- config.yml | 177 ------------------ plugin.yml | 78 -------- .../FeatureSwitchGameMode.java | 9 +- .../limitedcreative/MainCommand.java | 27 ++- .../limitedcreative/ModInventories.java | 4 +- .../minecraft/limitedcreative/ModRegions.java | 21 ++- .../regions/BlockListener.java | 35 +--- .../limitedcreative/regions/Flags.java | 2 + .../limitedcreative/regions/Listener.java | 96 ++++++++++ .../limitedcreative/regions/PlayerData.java | 17 +- .../regions/PlayerListener.java | 66 ++++--- .../limitedcreative/regions/RegionConfig.java | 40 ++++ .../regions/RegionListener.java | 86 +++------ .../regions/RegionPermissions.java | 3 + .../worldguard/PlayerRegionListener.java | 1 - src/main/resources/lang/messages.properties | 29 +-- 17 files changed, 289 insertions(+), 409 deletions(-) delete mode 100644 config.yml delete mode 100644 plugin.yml create mode 100644 src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Listener.java diff --git a/TODO.txt b/TODO.txt index a51cb2e..53e0377 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,4 @@ - - Region-Config? Where are the missing options? - - Region: permanent gamemode storage? (safemode, if not permanent: region!) maybe only if regionsset empty? - - remove config.yml and plugin.yml - cleanup localize-messages - - rework german localization \ No newline at end of file + - region command descriptions + - rework german localization + - fix DocComment formatting for config and permissions \ No newline at end of file diff --git a/config.yml b/config.yml deleted file mode 100644 index ba5498f..0000000 --- a/config.yml +++ /dev/null @@ -1,177 +0,0 @@ -# -------------------------------- -# 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. - # default: true - enabled: true - - # StoreCreative - # Should the creative-inventory also be stored on disk, when switching to survival? - # If disabled, the inventory gets cleared every time on switching to creative. - # default: true - creative: true - - # 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). - # (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". - # default: "inventories" - folder: "inventories" - - # SeparateAdventureInventory - # When true, your players get a separate inventory when switching to adventure gamemode (2). Otherwise - # they have the default survival inventory while in adventure gamemode. - adventure: false - -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. - # default: true - enabled: true - - # RemoveDrops - # When player not allowed to drop items, remove the item instead of putting it back to inventory/quickbar. - # You may disable this to get rid of the server.log-message: "Fetching addPacket for removed entity: CraftItem" - # default: true - remove_drops: true - - # BlockPickup - # Prevents the pickup of items while in creative mode - # default: false - pickup: false - - # RemovePickup - # Instead of blocking the pickup, you may want to disappear the item from world (good when destroying walls with - # signs or playing with minecarts). Only works when BlockPickup: false. - # The permission nolimit.pickup bypasses the removing. - # default: false - remove_pickup: true - - # BlockSign - # Prevents interacting with signs (right-click), while in creative mode, so trading becomes more difficult. - # Attention: this will also block useful signs, like Lifts. - # default: true - sign: true - - # BlockButtons - # When enabled also blocks usage of Buttons & Levers while in creative mode. - # default: false - button: false - - # BlockWorkbenches - # When enabled also blocks usage of workbenches like chests (so the creative player never can see his inventar). - # default: false - workbench: false - - # BlockDamageToMobs - # Prevents dealing damage to all creatures in creative (friendly sheeps as well as hostile creepers). - # default: false - damagemob: false - - # UseBlackList - # Prevents using or placing of the given blocks in creative mode (and only in creative). - # You can use the technical name (see http://jd.bukkit.org/doxygen/d6/d0e/enumorg_1_1bukkit_1_1Material.html) - # or the id of the block/item (better use the id, if you're not sure). - # To prevent Lava you need to add "LAVA_BUCKET", because lava-blocks aren't "placed", therefore Lava-Buckets are - # "used". - # You may add the data separated with a colon e.g.: "35:11" blocks blue wool. But be sure to put it in quotes, to - # not break yml-configuration! Also supporting Eggs (e.g: "MONSTER_EGG:56" blocks Ghasts-Eggs). If you don't add a - # 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. - # default: [exp_bottle, bedrock] - use: - - EXP_BOTTLE - - bedrock - - # BreakBlackList - # 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/d6/d0e/enumorg_1_1bukkit_1_1Material.html) - # or the id of the block/item (better use the id, if you're not sure). - # 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. - # You also may add the special block "*" (better add quotes to don't break yml) which prevents the breaking of any - # block. - # default: [bedrock] - break: - - bedrock - -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. - # default: true - enabled: true - - # RegionOptional - # Allows Players to use /lc creative|survival to switch between GameModes in creative-regions, even if they - # 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: false - remember: false - - -cmdblock: - # CommandBlockerEnabled - # Enables the feature for blocking certain commands in creative mode. - # default: true - enabled: true - - # CommandBlockerList - # Defines the list of commands that are blocked while in creative mode. The leading / isn't included. By default - # the list-item is treated as simple string as typed in by the user after the /. All commands starting with - # this string are blocked, even if more parameteres are entered by the user. - # If the first Char is ^ the entry is interpreted as a regular expression (including the ^ for begin of the string). - # Only use regular expressions if you know them. - # default: [] - commands: - # - logout - # - home - # - home second - # - ^chest (one|two|three) - # - ^(lc|limitedcreative) s(urvival)? - - -# Locale (Language) -# Uncomment the "locale: en_US"-Line, to override the locale which be used for localized messages. By default the -# System-Locale is used (selected by Java depending on LC_LANG-Environment-Variable -# default: none (Use System-Default Locale) -#locale: en_US \ No newline at end of file diff --git a/plugin.yml b/plugin.yml deleted file mode 100644 index e21f593..0000000 --- a/plugin.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: LimitedCreative -main: de.jaschastarke.minecraft.limitedcreative.Core -version: 1.4.0a -softdepend: [WorldGuard, WorldEdit, MultiInv] -dev-url: http://dev.bukkit.org/server-mods/limited-creative/ -commands: - limitedcreative: - description: "LimitedCreative: GameMode-Switch, Creative-Regions, Config" - aliases: lc - usage: / - displays LimitedCreative-Help - /region: - description: "LimitedCreative-Region-Command: configure creative regions" - aliases: lcregion - usage: / info|flag [#] - set/get region options -permissions: - limitedcreative.config: - description: Allows enabling/disabling of config options ingame - default: op - 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/adventure and back - default: op - limitedcreative.switch_gamemode.backonly: - description: Allows switching of own game mode to default of the not world he is in, but not back - default: false - limitedcreative.switch_gamemode.survival: - description: Allows switching of own game mode to survival, but not to creative/adventure - default: false - limitedcreative.switch_gamemode.creative: - description: Allows switching of own game mode to creative, but not to survival/adventure - default: false - limitedcreative.switch_gamemode.adventure: - description: Allows switching of own game mode to adventure, but not to creative/survival - default: false - limitedcreative.switch_gamemode.other: - description: Allows switching of other users game mode - default: op - limitedcreative.keepinventory: - description: Allows bypassing the inventory separation - default: false - limitedcreative.nolimit.drop: - description: Allows bypassing the "do not drop anything"-limitation - default: false - limitedcreative.nolimit.pickup: - description: Allows bypassing the "do not pickup anything"-limitation - default: false - limitedcreative.nolimit.chest: - description: Allows bypassing the "do not open a chest"-limitation - default: false - limitedcreative.nolimit.sign: - description: Allows bypassing the "do not interact with signs"-limitation - default: false - limitedcreative.nolimit.button: - description: Allows bypassing the "do not interact with buttons"-limitation - default: false - limitedcreative.nolimit.lever: - description: Allows bypassing the "do not interact with levers"-limitation - default: false - limitedcreative.nolimit.pvp: - description: Allows bypassing the "no pvp"-limitation - default: false - limitedcreative.nolimit.mob_damage: - description: Allows bypassing the "no dealing damage to creatures"-limitation - default: false - limitedcreative.nolimit.use: - description: Allows bypassing the "block place/item use"-limitation - default: false - limitedcreative.nolimit.break: - description: Allows bypassing the "block break"-limitation - default: false - limitedcreative.cmdblock.all: - description: Allowy bypassting the "command block"-limitation - default: op diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java index 5e05d89..4bc825a 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/FeatureSwitchGameMode.java @@ -85,7 +85,14 @@ public class FeatureSwitchGameMode extends CoreModule { if (!context.checkPermission(permission) && (wgm != tgm || !context.checkPermission(SwitchGameModePermissions.BACKONLY))) throw new MissingPermissionCommandException(permission); - target.setGameMode(tgm); + if (target.getGameMode() != tgm) { + target.setGameMode(tgm); + if (!context.isPlayer() || !target.equals(context.getPlayer())) { + context.response(context.getFormatter().getString("command.gamemode.changed", target.getName())); + } + } else { + context.response(context.getFormatter().getString("command.gamemode.no_change")); + } return true; } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/MainCommand.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/MainCommand.java index c1b1bcd..c8374be 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/MainCommand.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/MainCommand.java @@ -2,9 +2,15 @@ package de.jaschastarke.minecraft.limitedcreative; import de.jaschastarke.LocaleString; import de.jaschastarke.bukkit.lib.commands.BukkitCommand; +import de.jaschastarke.bukkit.lib.commands.CommandContext; import de.jaschastarke.bukkit.lib.commands.IHelpDescribed; +import de.jaschastarke.bukkit.lib.commands.IMethodCommandContainer; +import de.jaschastarke.bukkit.lib.commands.annotations.Description; +import de.jaschastarke.bukkit.lib.commands.annotations.IsCommand; +import de.jaschastarke.bukkit.lib.commands.annotations.NeedsPermission; import de.jaschastarke.maven.ArchiveDocComments; import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; +import de.jaschastarke.minecraft.lib.permissions.IPermission; /** * LimitedCreative: GameMode-Switch, Creative-Regions, Config and more @@ -12,7 +18,7 @@ import de.jaschastarke.minecraft.lib.permissions.IAbstractPermission; * @permission limitedcreative.command */ @ArchiveDocComments -public class MainCommand extends BukkitCommand implements IHelpDescribed { +public class MainCommand extends BukkitCommand implements IHelpDescribed, IMethodCommandContainer { private LimitedCreative plugin; public MainCommand() { @@ -51,4 +57,23 @@ public class MainCommand extends BukkitCommand implements IHelpDescribed { public String getPackageName() { return plugin.getName(); } + @Override + public IPermission getPermission(String subPerm) { + return Permissions.CONTAINER.getPermission(subPerm); + } + + @IsCommand("reload") + @Description(value = "command.config.reload", translate = true) + @NeedsPermission(value={"config"}) + public boolean doReload(final CommandContext context) { + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + plugin.onDisable(); + plugin.onEnable(); + context.response(context.getFormatter().getString("command.config.reload.success")); + } + }); + return true; + } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModInventories.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModInventories.java index 1351d32..0f07063 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModInventories.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModInventories.java @@ -48,7 +48,7 @@ public class ModInventories extends CoreModule { String incomp = Hooks.InventoryIncompatible.test(); if (incomp != null) { - getLog().warn(plugin.getLocale().trans("basic.conflict", incomp, this.getName())); + getLog().warn(plugin.getLocale().trans("inventory.warning.conflict", incomp, this.getName())); entry.initialState = ModuleState.NOT_INITIALIZED; } } @@ -56,7 +56,7 @@ public class ModInventories extends CoreModule { public void onEnable() { String incomp = Hooks.InventoryIncompatible.test(); if (incomp != null) { - throw new IllegalAccessError(plugin.getLocale().trans("basic.conflict", incomp, this.getName())); + throw new IllegalAccessError(plugin.getLocale().trans("inventory.warning.conflict", incomp, this.getName())); } super.onEnable(); storage = new InvYamlStorage(this, new File(plugin.getDataFolder(), config.getFolder())); diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java index 95b343f..3703582 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/ModRegions.java @@ -45,19 +45,20 @@ public class ModRegions extends CoreModule { config = plugin.getPluginConfig().registerSection(new RegionConfig(this, entry)); command = new RegionsCommand(this); - plugin.getCommandHandler().registerCommand(command); - plugin.getMainCommand().registerCommand(new AliasHelpedCommand(command, "region", new String[]{"r"})); listeners.registerEvents(new PlayerListener(this)); listeners.registerEvents(new BlockListener(this)); listeners.registerEvents(new RegionListener(this)); - listeners.registerEvents(new PlayerRegionListener(this)); + listeners.registerEvents(new PlayerRegionListener(this)); // Fires Custom-Events listen by RegionListener FlagList.addFlags(Flags.getList()); if (!config.getEnabled()) { entry.initialState = ModuleState.DISABLED; return; + } else if (!plugin.getServer().getPluginManager().isPluginEnabled("WorldGuard")) { + getLog().warn(plugin.getLocale().trans("region.warning.worldguard_not_found", getName())); + entry.initialState = ModuleState.NOT_INITIALIZED; } } @@ -67,10 +68,24 @@ public class ModRegions extends CoreModule { mgr = new CustomRegionManager(new File(plugin.getDataFolder(), "regions.yml"), this); wg = (WorldGuardPlugin) plugin.getServer().getPluginManager().getPlugin("WorldGuard"); + if (wg == null) + throw new IllegalAccessError("Missing Plugin WorldGuard"); + + plugin.getCommandHandler().registerCommand(command); + plugin.getMainCommand().registerCommand(new AliasHelpedCommand(command, "region", new String[]{"r"})); + pdata = new PlayerData(this); getLog().info(plugin.getLocale().trans("basic.loaded.module")); } + @Override + public void onDisable() { + super.onDisable(); + + plugin.getCommandHandler().removeCommand(command); + plugin.getMainCommand().removeCommand(command); + } + public RegionConfig getConfig() { return config; } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java index bfa09e4..534ca7d 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/BlockListener.java @@ -1,14 +1,12 @@ package de.jaschastarke.minecraft.limitedcreative.regions; import org.bukkit.GameMode; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; @@ -18,23 +16,10 @@ import org.bukkit.event.hanging.HangingBreakByEntityEvent; import de.jaschastarke.bukkit.lib.Utils; import de.jaschastarke.minecraft.limitedcreative.ModRegions; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager; -public class BlockListener implements Listener { - private ModRegions mod; - private CustomRegionManager rm; - +public class BlockListener extends Listener { public BlockListener(ModRegions mod) { - this.mod = mod; - rm = mod.getRegionManager(); - } - - private ApplicableRegions regionSet(Location loc) { - return rm.getRegionSet(loc); - } - private ApplicableRegions regionSet(Block block) { - return rm.getRegionSet(block); + super(mod); } @EventHandler @@ -54,8 +39,8 @@ public class BlockListener implements Listener { private void whenBlockBreak(Cancellable event, Block block, Player player) { boolean diffrent_region = rm.isDiffrentRegion(player, block.getLocation()); - - PlayerData.Data pdata = mod.getPlayerData(player); + + PlayerMeta pdata = new PlayerMeta(player); if (pdata.isActiveRegionGameMode() && diffrent_region) { // do not break outside of "gamemod-change-region" when in the region @@ -83,7 +68,7 @@ public class BlockListener implements Listener { if (event.isCancelled()) return; - PlayerData.Data pdata = mod.getPlayerData(event.getPlayer()); + PlayerMeta pdata = new PlayerMeta(event.getPlayer()); boolean diffrent_region = rm.isDiffrentRegion(event.getPlayer(), event.getBlock().getLocation()); if (pdata.isActiveRegionGameMode() && diffrent_region) { @@ -116,7 +101,7 @@ public class BlockListener implements Listener { if (mod.isDebug()) mod.getLog().debug("dest "+i+": "+dest.getType()); if (regionSet(dest).getFlag(Flags.GAMEMODE) != GameMode.CREATIVE) { - mod.getLog().warn(L("blocked.piston", source.getRelative(event.getDirection(), i - 1).getType().toString(), Utils.toString(source.getLocation()))); + mod.getLog().warn(L("blocked.region.piston", source.getRelative(event.getDirection(), i - 1).getType().toString(), Utils.toString(source.getLocation()))); event.setCancelled(true); break; } else if (dest.getType() == Material.AIR) { @@ -140,12 +125,12 @@ public class BlockListener implements Listener { mod.getLog().debug("dest "+dest.getType()); if (regionSet(source).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) { if (regionSet(dest).getFlag(Flags.GAMEMODE) != GameMode.CREATIVE) { - mod.getLog().warn(L("blocked.piston", source.getType().toString(), Utils.toString(source.getLocation()))); + mod.getLog().warn(L("blocked.region.piston", source.getType().toString(), Utils.toString(source.getLocation()))); event.setCancelled(true); } } else if (regionSet(dest).getFlag(Flags.GAMEMODE) == GameMode.CREATIVE) { // source isn't creative - mod.getLog().warn(L("blocked.piston_in", source.getType().toString(), Utils.toString(source.getLocation()))); + mod.getLog().warn(L("blocked.region.piston_in", source.getType().toString(), Utils.toString(source.getLocation()))); event.setCancelled(true); } } @@ -160,8 +145,4 @@ public class BlockListener implements Listener { event.setCancelled(true); } } - - private String L(String msg, Object... args) { - return mod.getPlugin().getLocale().trans(msg, args); - } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Flags.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Flags.java index 1c20af6..17dc201 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Flags.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Flags.java @@ -9,12 +9,14 @@ import com.sk89q.worldguard.protection.flags.StateFlag; public final class Flags { public static final StateFlag SPAWNDROPS = new StateFlag("spawndrops", true); + public static final StateFlag GAMEMODE_OPTIONAL = new StateFlag("gamemode-optional", false); public static final GameModeFlag GAMEMODE = new GameModeFlag("gamemode", RegionGroup.MEMBERS); public static List> getList() { return Arrays.asList(new Flag[]{ SPAWNDROPS, GAMEMODE, + GAMEMODE_OPTIONAL, }); } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Listener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Listener.java new file mode 100644 index 0000000..ca597b3 --- /dev/null +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/Listener.java @@ -0,0 +1,96 @@ +package de.jaschastarke.minecraft.limitedcreative.regions; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerInteractEvent; + +import de.jaschastarke.minecraft.limitedcreative.ModRegions; +import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; +import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager; + +abstract public class Listener implements org.bukkit.event.Listener { + protected ModRegions mod; + protected CustomRegionManager rm; + + public Listener(ModRegions mod) { + this.mod = mod; + rm = mod.getRegionManager(); + } + + /** + * The isCancelled in PlayerInteractEvent doesn't check useItemInHand, even this decides (when clicking on + * entity with e.g. a bucket) + * @param event + * @return The relevant "isCancelled" + */ + protected static boolean isCancelled(PlayerInteractEvent event) { + return event.useInteractedBlock() == Event.Result.DENY && event.useItemInHand() == Event.Result.DENY; + } + + protected ApplicableRegions regionSet(Location loc) { + return rm.getRegionSet(loc); + } + protected ApplicableRegions regionSet(Block block) { + return rm.getRegionSet(block); + } + + class PlayerMeta { + private Player player; + private PlayerData.Data pdata; + public PlayerMeta(Player player) { + this.player = player; + this.pdata = mod.getPlayerData(player); + } + + // Active Region GameMode + public GameMode getActiveRegionGameMode() { + return pdata.getActiveRegionGameMode(); + } + public boolean isActiveRegionGameMode() { + return getActiveRegionGameMode() != null; + } + public boolean isActiveRegionGameMode(GameMode gm) { + GameMode agm = getActiveRegionGameMode(); + return agm != null && agm.equals(gm); + } + public void storeActiveRegionGameMode(GameMode regionGameMode) { + pdata.storeActiveRegionGameMode(regionGameMode); + } + + // Optional GameMode + public void setOptionalRegionGameMode(GameMode gm) { + if (mod.getConfig().getRememberOptional()) + pdata.setOptionalRegionGameMode(getCurrentRegionHash(), gm); + else + pdata.setOptionalRegionGameMode(getCurrentRegionHash(), null); + } + private String getCurrentRegionHash() { + return mod.getRegionManager().getRegionsHash(player.getLocation()); + } + public GameMode getOptionalRegionGameMode(String regionHash) { + if (!mod.getConfig().getRememberOptional()) + return null; + return pdata.getOptionalRegionGameMode(regionHash); + } + + // Permanent GameMode + public void setPermanentGameMode(GameMode gm) { + if (mod.getConfig().getSafeMode()) + pdata.storePermanentGameMode(null); + else + pdata.storePermanentGameMode(gm); + } + public boolean isInPermanentGameMode(GameMode currentGameMode) { + if (mod.getConfig().getSafeMode()) + return false; + return pdata.getPermanentRegionGameMode() != null; + } + } + + protected String L(String msg, Object... args) { + return mod.getPlugin().getLocale().trans(msg, args); + } +} diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerData.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerData.java index f9fc210..2843f0d 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerData.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerData.java @@ -80,27 +80,20 @@ public class PlayerData { return player.get().getName(); } - public boolean isActiveRegionGameMode() { - return getActiveRegionGameMode() != null; - } - public boolean isActiveRegionGameMode(GameMode regionGameMode) { - return getActiveRegionGameMode() == regionGameMode; - } public GameMode getActiveRegionGameMode() { return getGameMode("region_gamemode"); } public void storeActiveRegionGameMode(GameMode regionGameMode) { getSect(n()).set("region_gamemode", regionGameMode); - } - public boolean isInPermanentGameMode(GameMode currentGameMode) { - return getPermanentRegionGameMode() == currentGameMode; - } - public void storePermanentGameMode(GameMode currentGameMode) { - getSect(n()).set("permanent_gamemode", currentGameMode); + cleanUp(); } public GameMode getPermanentRegionGameMode() { return getGameMode("permanent_gamemode"); } + public void storePermanentGameMode(GameMode currentGameMode) { + getSect(n()).set("permanent_gamemode", currentGameMode); + cleanUp(); + } public GameMode getOptionalRegionGameMode(String regionHash) { return getGameMode("optional_gamemode." + regionHash); } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java index 351291c..a4b9b14 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/PlayerListener.java @@ -1,37 +1,26 @@ package de.jaschastarke.minecraft.limitedcreative.regions; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Sign; -import org.bukkit.event.Event; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; +import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.InventoryHolder; import org.bukkit.material.Button; import org.bukkit.material.Lever; +import de.jaschastarke.minecraft.limitedcreative.Hooks; import de.jaschastarke.minecraft.limitedcreative.ModRegions; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager; -public class PlayerListener implements Listener { - private ModRegions mod; - private CustomRegionManager rm; - +public class PlayerListener extends Listener { public PlayerListener(ModRegions mod) { - this.mod = mod; - rm = mod.getRegionManager(); - } - - /** - * The isCancelled in PlayerInteractEvent doesn't check useItemInHand, even this decides (when clicking on - * entity with e.g. a bucket) - * @param event - * @return The relevant "isCancelled" - */ - private static boolean isCancelled(PlayerInteractEvent event) { - return event.useInteractedBlock() == Event.Result.DENY && event.useItemInHand() == Event.Result.DENY; + super(mod); } @EventHandler @@ -49,12 +38,12 @@ public class PlayerListener implements Listener { block.getState() instanceof Lever || block.getState() instanceof Button || block.getType() == Material.WORKBENCH || block.getType() == Material.ANVIL) { - PlayerData.Data pdata = mod.getPlayerData(event.getPlayer()); + PlayerMeta pmeta = new PlayerMeta(event.getPlayer()); boolean diffrent_region = rm.isDiffrentRegion(event.getPlayer(), block.getLocation()); - if (pdata.isActiveRegionGameMode() && diffrent_region) { + if (pmeta.isActiveRegionGameMode() && diffrent_region) { // do not break outside of "gamemod-change-region" when in the region - if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE, event.getPlayer()) != pdata.getActiveRegionGameMode()) { + if (rm.getRegionSet(block).getFlag(Flags.GAMEMODE, event.getPlayer()) != pmeta.getActiveRegionGameMode()) { event.getPlayer().sendMessage(L("blocked.outside_interact")); event.setCancelled(true); } @@ -68,7 +57,36 @@ public class PlayerListener implements Listener { } } - private String L(String msg, Object... args) { - return mod.getPlugin().getLocale().trans(msg, args); + private boolean isRegionOptional(Player player) { + return mod.getRegionManager().getRegionSet(player.getLocation()).allows(Flags.GAMEMODE_OPTIONAL, player); + } + + @EventHandler(priority = EventPriority.LOW) + public void onGameModeChange(PlayerGameModeChangeEvent event) { + Player player = event.getPlayer(); + PlayerMeta pmeta = new PlayerMeta(player); + GameMode gm = event.getNewGameMode(); + + if (mod.isDebug()) + mod.getLog().debug(player.getName() + " is changing to GameMode " + gm);; + if (Hooks.IsLoggedIn.test(player)) { // if authme is changing GameMode before going to teleport, this should be remembered + if (pmeta.isActiveRegionGameMode()) { // change to the other gamemode as the area defines + if (!pmeta.isActiveRegionGameMode(gm)) { // only when we are not switching to the mode the region allows + if (!mod.getPlugin().getPermManager().hasPermission(player, RegionPermissions.BYPASS) && !isRegionOptional(player)) { + player.sendMessage(ChatColor.RED + L("exception.region.not_optional", gm.toString().toLowerCase())); + mod.getLog().debug("... denied"); + event.setCancelled(true); + } else { + pmeta.setOptionalRegionGameMode(gm); + } + } else { + // we are changing to the mode the region defines, thats not permanent + pmeta.setOptionalRegionGameMode(null); + pmeta.setPermanentGameMode(null); + } + } else if (mod.getRegionManager().getRegionSet(player.getLocation()).getFlag(Flags.GAMEMODE, player) == null) { + pmeta.setPermanentGameMode(gm); // we are not in a region, so the mode change is permanent + } + } } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionConfig.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionConfig.java index 6333e96..6ae02dc 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionConfig.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionConfig.java @@ -1,5 +1,7 @@ package de.jaschastarke.minecraft.limitedcreative.regions; +import org.bukkit.configuration.ConfigurationSection; + import de.jaschastarke.bukkit.lib.configuration.Configuration; import de.jaschastarke.configuration.IConfigurationNode; import de.jaschastarke.configuration.IConfigurationSubGroup; @@ -36,6 +38,13 @@ public class RegionConfig extends Configuration implements IConfigurationSubGrou } } } + @Override + public void setValues(ConfigurationSection sect) { + super.setValues(sect); + // Config Upgrade + if (!sect.contains("rememberOptional") && sect.contains("remember")) + sect.set("rememberOptional", sect.getBoolean("remember")); + } @Override public String getName() { @@ -59,6 +68,37 @@ public class RegionConfig extends Configuration implements IConfigurationSubGrou public boolean getEnabled() { return config.getBoolean("enabled", true); } + + /** + * RegionRememberOptional + * + * Remembers if players disables the Region-GameMode (by switching in an optional region to World-Default-GameMode + * with /lc creative|survival). So when the player re-enters the region, he keep his GameMode which he left it in. + * Hint: This is very confusing, if MultiVerse "enforce gamemode" swaps your state (default). So better don't use + * with Multiverse. + * + * default: false + */ + @IsConfigurationNode(order = 200) + public boolean getRememberOptional() { + return config.getBoolean("rememberOptional", false); + } + + /** + * RegionSafeMode + * + * When a player leaves a region he always will get back to the World-GameMode, even if he entered the region already + * in the Region-GameMode. So its the opposite analog to RegionRememberOptional. + * That means: If a GM in creative-mode walks/flies through a creative-region in a survival world, he will get back + * to survival on leaving the region. + * + * default: false + */ + @IsConfigurationNode(order = 300) + public boolean getSafeMode() { + return config.getBoolean("safemode", false); + } + /** * RegionMaximumFallingHeight diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java index ce40e87..dbe7dbe 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionListener.java @@ -7,47 +7,24 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Item; import org.bukkit.entity.Player; -import org.bukkit.event.Event; import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; import org.bukkit.event.entity.ItemSpawnEvent; -import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; import de.jaschastarke.bukkit.lib.Utils; import de.jaschastarke.minecraft.limitedcreative.Hooks; import de.jaschastarke.minecraft.limitedcreative.ModRegions; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.ApplicableRegions; -import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.CustomRegionManager; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.events.PlayerAreaEvent; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.events.PlayerChangedAreaEvent; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.events.PlayerNewLocationAreaEvent; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.events.PlayerSetAreaEvent; import de.jaschastarke.minecraft.limitedcreative.regions.worldguard.events.PlayerUpdateAreaEvent; -public class RegionListener implements Listener { - private ModRegions mod; - private CustomRegionManager rm; - +public class RegionListener extends Listener { public RegionListener(ModRegions mod) { - this.mod = mod; - rm = mod.getRegionManager(); + super(mod); } - /** - * The isCancelled in PlayerInteractEvent doesn't check useItemInHand, even this decides (when clicking on - * entity with e.g. a bucket) - * @param event - * @return The relevant "isCancelled" - */ - public static boolean isCancelled(PlayerInteractEvent event) { - return event.useInteractedBlock() == Event.Result.DENY && event.useItemInHand() == Event.Result.DENY; - } - - private ApplicableRegions regionSet(Location loc) { - return rm.getRegionSet(loc); - } - public int getFloatingHeight(Player player) { return getFloatingHeight(player.getLocation()); } @@ -75,28 +52,29 @@ public class RegionListener implements Listener { } return true; } - private boolean checkSwitchFlight(PlayerAreaEvent area_event) { - if (area_event instanceof PlayerChangedAreaEvent) { - if (!checkSwitchFlight(((PlayerChangedAreaEvent) area_event).getMoveEvent())) { - ((PlayerChangedAreaEvent) area_event).setCancelled(true); + private boolean checkSwitchFlight(PlayerAreaEvent areaEvent) { + if (areaEvent instanceof PlayerChangedAreaEvent) { + if (!checkSwitchFlight(((PlayerChangedAreaEvent) areaEvent).getMoveEvent())) { + ((PlayerChangedAreaEvent) areaEvent).setCancelled(true); return false; } } return true; } - private void setRegionGameMode(GameMode region_gamemode, PlayerAreaEvent area_event) { - Player player = area_event.getPlayer(); - PlayerData.Data pdata = mod.getPlayerData(player); + private void setRegionGameMode(GameMode regionGameMode, PlayerAreaEvent areaEvent) { + Player player = areaEvent.getPlayer(); + PlayerMeta pmeta = new PlayerMeta(player); + if (mod.isDebug()) - mod.getLog().debug(player.getName()+": changed region: "+region_gamemode+": " + area_event); + mod.getLog().debug(player.getName()+": changed region: "+regionGameMode+": " + areaEvent); - PlayerMoveEvent event = null; - if (area_event instanceof PlayerChangedAreaEvent) - event = ((PlayerChangedAreaEvent) area_event).getMoveEvent(); - GameMode CURRENT_GAMEMODE = player.getGameMode(); - GameMode DEFAULT_GAMEMODE = Hooks.DefaultWorldGameMode.get(event != null ? event.getTo().getWorld() : player.getWorld()); + PlayerMoveEvent moveEvent = null; + if (areaEvent instanceof PlayerChangedAreaEvent) + moveEvent = ((PlayerChangedAreaEvent) areaEvent).getMoveEvent(); + GameMode currentGameMode = player.getGameMode(); + GameMode defaultGameMode = Hooks.DefaultWorldGameMode.get(moveEvent != null ? moveEvent.getTo().getWorld() : player.getWorld()); - if (region_gamemode != null && CURRENT_GAMEMODE != region_gamemode && !pdata.isActiveRegionGameMode(region_gamemode)) { + if (regionGameMode != null && currentGameMode != regionGameMode && !pmeta.isActiveRegionGameMode(regionGameMode)) { if (mod.isDebug()) mod.getLog().debug(player.getName()+": entering creative area"); // 1. the region allows "the other (temporary) gamemode" @@ -104,16 +82,16 @@ public class RegionListener implements Listener { // 3. and the player is not aware of that // result: change him to that mode - boolean isOptional = pdata.getOptionalRegionGameMode(area_event.getRegionHash()) == CURRENT_GAMEMODE; + boolean isOptional = pmeta.getOptionalRegionGameMode(areaEvent.getRegionHash()) == currentGameMode; - if (isOptional || checkSwitchFlight(area_event)) { - pdata.storeActiveRegionGameMode(region_gamemode); // have to be set, before setGameMode + if (isOptional || checkSwitchFlight(areaEvent)) { + pmeta.storeActiveRegionGameMode(regionGameMode); // have to be set, before setGameMode if (!isOptional) { - player.setGameMode(region_gamemode); + player.setGameMode(regionGameMode); } } - } else if (region_gamemode == null && player.getGameMode() != DEFAULT_GAMEMODE && !pdata.isInPermanentGameMode(CURRENT_GAMEMODE) && pdata.getActiveRegionGameMode() != null) { + } else if (regionGameMode == null && player.getGameMode() != defaultGameMode && !pmeta.isInPermanentGameMode(currentGameMode) && pmeta.getActiveRegionGameMode() != null) { if (mod.isDebug()) mod.getLog().debug(player.getName()+": leaving creative area"); // 1. the region doesn't allow "the other gamemode" @@ -121,22 +99,22 @@ public class RegionListener implements Listener { // 3. and the player isn't global (permanent) in that mode // 4. and the player isn't temporary in that mode (that means its maybe a world teleport, and the mode changes afterwards) // result: change him back to default mode - if (checkSwitchFlight(area_event)) { - pdata.storeActiveRegionGameMode(null); - player.setGameMode(DEFAULT_GAMEMODE); + if (checkSwitchFlight(areaEvent)) { + pmeta.storeActiveRegionGameMode(null); + player.setGameMode(defaultGameMode); } - } else if (region_gamemode == null && pdata.isActiveRegionGameMode()) { + } else if (regionGameMode == null && pmeta.isActiveRegionGameMode()) { if (mod.isDebug()) mod.getLog().debug(player.getName()+": leaving creative area (while already in default gamemode)"); // 1. the region doesn't allow "the other gamemode" // 2. but he thinks he is still allowed // 3. (because of else) we are not longer in that mode // result: advise him to not longer allowed to that region - pdata.storeActiveRegionGameMode(null); - } else if (region_gamemode == CURRENT_GAMEMODE && !pdata.isInPermanentGameMode(CURRENT_GAMEMODE)) { - if (!pdata.isActiveRegionGameMode(region_gamemode)) { + pmeta.storeActiveRegionGameMode(null); + } else if (regionGameMode == currentGameMode && !pmeta.isInPermanentGameMode(currentGameMode)) { + if (!pmeta.isActiveRegionGameMode(regionGameMode)) { // we have no information why we are already in this gamemode, so this may be because of an AuthMe change-and-teleport - pdata.storeActiveRegionGameMode(region_gamemode); + pmeta.storeActiveRegionGameMode(regionGameMode); } } } @@ -165,8 +143,4 @@ public class RegionListener implements Listener { event.setCancelled(true); } } - - private String L(String msg, Object... args) { - return mod.getPlugin().getLocale().trans(msg, args); - } } diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionPermissions.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionPermissions.java index 360b03a..9a8f990 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionPermissions.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/RegionPermissions.java @@ -23,6 +23,9 @@ final public class RegionPermissions extends SimplePermissionContainerNode imple return PermissionDefault.OP; } + /** + * Grants access to the /lcr command, which allows to define Limited Creatives region-flags + */ public static final RegionPermissions REGION = new RegionPermissions(Permissions.CONTAINER, "region"); /** diff --git a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/PlayerRegionListener.java b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/PlayerRegionListener.java index c9c3d8f..81caab3 100644 --- a/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/PlayerRegionListener.java +++ b/src/main/java/de/jaschastarke/minecraft/limitedcreative/regions/worldguard/PlayerRegionListener.java @@ -50,7 +50,6 @@ public class PlayerRegionListener implements Listener { || !event.getFrom().getWorld().equals(event.getTo().getWorld())) { // he really moved, and not just looked around String current_hash = mod.getPlayerData(event.getPlayer()).getHash(); - mod.getLog().debug(event.getPlayer().getName()+" "+current_hash); if (current_hash == null) { String new_hash = mod.getRegionManager().getRegionsHash(event.getTo()); Bukkit.getServer().getPluginManager().callEvent(new PlayerSetAreaEvent(mod.getRegionManager(), event.getPlayer(), new_hash, event.getTo())); diff --git a/src/main/resources/lang/messages.properties b/src/main/resources/lang/messages.properties index b43c9d9..40b931b 100644 --- a/src/main/resources/lang/messages.properties +++ b/src/main/resources/lang/messages.properties @@ -1,46 +1,29 @@ -basic.loaded.worldguard: Successfully loaded with WorldGuard-Integration -basic.loaded.no_worldguard: Successfully loaded (without WorldGuard) basic.loaded.module: Module loaded. -basic.feature.store: separated inventories -basic.feature.limit: creative restrictions -basic.feature.region: creative regions -basic.feature.gamemodecommands: GameMode Commands -basic.conflict: Due to conflict with the plugin {0}, the feature {1} is disabled -basic.warning.worldguard_not_found: WorldGuard isn't found, the feature {0} is disabled -# double single-quote '' because of MessageFormater to insert {0} -command.player: player +inventory.warning.conflict: Due to conflict with the plugin {0}, the feature {1} is disabled +region.warning.worldguard_not_found: WorldGuard isn't found, the feature {0} is disabled + command.general: LimitedCreative: GameMode-Switch, Creative-Regions, Config and more command.regions: LimitedCreative-Region-Command: configure creative regions command.switch.survival: Changes the game mode of a player to survival command.switch.creative: Changes the game mode of a player to creative command.switch.adventure: Changes the game mode of a player to adventure -command.config.overview: [setting] - empty for list of settings -command.config.settings: Available Settings: -command.config.reload: Reloads plugin (doesn't work on update!) +command.config.reload: Reloads configuration and re-initializes all active modules. +command.config.reload.success: The plugin was successfully reloaded. command.gamemode.changed: {0}'s game mode has been changed command.gamemode.no_change: Already in that game mode. -command.option.done: Option changed. + command.worldguard.alias: Alias for //region-command command.worldguard.unknown_flag: Unknown flag specified command.worldguard.available_flags: Available flags: command.worldguard.region_not_found: Could not find a region by that ID command.worldguard.world_not_found: Could not find a world by that name -command.worldguard.no_flag_given: You need to specify a flag to set -command.worldguard.no_integration: The worldguard-commands are not available, because worldguard wasn't found command.worldguard.flag_set: "The flag {0} was set" command.worldguard.additional_flags: Additional flags: cmdblock.blocked: This command is blocked while in creative mode. -exception.command.lackingpermission: You do not have access to this command -exception.command.toomuchparameter: Too much arguments given -exception.command.missingparameter: Not enough arguments given -exception.command.playernotfound: Player not found -exception.command.invalidoption: Unknown option -exception.config.savefail: Failed to write modified configuration to disk exception.config.material_not_found: (Config) Material with name/id "{0}" was not found. -exception.storage.load: Failed to load your Inventory. Ask your Admin to enable "UnsafeStorage" for LimitedCreative to allow invalid enchants on items exception.region.not_optional: You can not be {0} in that area blocked.chest: Access to chests is not allowed in creative mode