diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java b/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java index fa72a257323..a4074169afd 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/Towny.java @@ -42,6 +42,7 @@ import com.palmergames.bukkit.towny.object.Translation; import com.palmergames.bukkit.towny.object.WorldCoord; import com.palmergames.bukkit.towny.object.metadata.MetadataLoader; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.permissions.TownyPerms; import com.palmergames.bukkit.towny.regen.TownyRegenAPI; import com.palmergames.bukkit.towny.scheduling.TaskScheduler; @@ -236,6 +237,9 @@ public void loadFoundation(boolean reload) { // Initialize the special log4j hook logger. TownyLogger.initialize(); + // Initialize the ResidentModeHandler. + ResidentModeHandler.initialize(); + // Clear all objects from the TownyUniverse class. townyUniverse.clearAllObjects(); @@ -682,46 +686,60 @@ public void resetCache(Player player) { getCache(player).resetAndUpdate(WorldCoord.parseWorldCoord(player)); } + /** + * @deprecated since 0.100.4.6, use {@link ResidentModeHandler#toggleModes(Player, String[], boolean)} instead. + * @param player Player to act upon. + * @param modes String[] of mode names to toggle. + * @param notify whether to notify the player of their modes afterwards. + */ + @Deprecated public void setPlayerMode(Player player, String[] modes, boolean notify) { if (player == null) return; Resident resident = TownyUniverse.getInstance().getResident(player.getName()); - if (resident != null) - resident.setModes(modes, notify); + if (resident == null) + return; + + ResidentModeHandler.toggleModes(resident, modes, notify, false); } /** * Remove ALL current modes (and set the defaults) * - * @param player - player, whose modes are to be reset (all removed). + * @deprecated since 0.100.4.6, use {@link ResidentModeHandler#clearModes(Player))} instead. + * @param player Player, whose modes are to be reset (all removed). */ + @Deprecated public void removePlayerMode(Player player) { Resident resident = TownyUniverse.getInstance().getResident(player.getName()); if (resident != null) - resident.clearModes(); + ResidentModeHandler.clearModes(resident, false); } /** * Remove ALL current modes. * + * @deprecated since 0.100.4.6, use {@link ResidentModeHandler#clearModes(Player)} instead. * @param player - player, whose modes are to be reset (all removed). */ + @Deprecated public void removePlayerModes(Player player) { Resident resident = TownyUniverse.getInstance().getResident(player.getName()); - if (resident != null) - resident.resetModes(new String[0], true); - } + ResidentModeHandler.clearModes(resident, false); + } /** * Fetch a list of all the players current modes. * + * @deprecated since 0.100.4.6, use {@link ResidentModeHandler#getModes(Player)} instead. * @param player - player, whose modes are to be listed, taken. * @return list of modes */ + @Deprecated public List getPlayerMode(Player player) { return getPlayerMode(player.getName()); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/ResidentCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/ResidentCommand.java index 88cf7da2cdc..1ed9e63653c 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/ResidentCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/ResidentCommand.java @@ -10,7 +10,6 @@ import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.TownyCommandAddonAPI.CommandType; import com.palmergames.bukkit.towny.confirmations.Confirmation; -import com.palmergames.bukkit.towny.exceptions.NoPermissionException; import com.palmergames.bukkit.towny.exceptions.TownyException; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.SpawnType; @@ -19,6 +18,7 @@ import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.Translator; import com.palmergames.bukkit.towny.object.jail.UnJailReason; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.permissions.PermissionNodes; import com.palmergames.bukkit.towny.tasks.CooldownTimerTask; import com.palmergames.bukkit.towny.tasks.CooldownTimerTask.CooldownType; @@ -68,43 +68,6 @@ public class ResidentCommand extends BaseCommand implements CommandExecutor { "list" ); - private static final List residentToggleTabCompletes = Arrays.asList( - "pvp", - "fire", - "mobs", - "explosion", - "adminbypass", - "bedspawn", - "plotborder", - "constantplotborder", - "townborder", - "ignoreplots", - "ignoreotherchannels", - "bordertitles", - "townclaim", - "townunclaim", - "plotgroup", - "map", - "spy", - "reset", - "clear", - "infotool" - ); - - private static final List residentModeTabCompletes = Arrays.asList( - "map", - "townclaim", - "townunclaim", - "plotborder", - "constantplotborder", - "townborder", - "ignoreplots", - "ignoreotherchannels", - "reset", - "clear", - "infotool" - ); - private static final List residentConsoleTabCompletes = Arrays.asList( "?", "help", @@ -129,14 +92,17 @@ public class ResidentCommand extends BaseCommand implements CommandExecutor { "mobs", "explosion" ); - - private static final List residentToggleModes = new ArrayList<>(residentToggleTabCompletes).stream() - .filter(str -> !residentToggleChoices.contains(str)) - .collect(Collectors.toList()); - private static final List residentToggleModesUnionToggles = Stream.concat( - new ArrayList<>(residentToggleModes).stream(), - BaseCommand.setOnOffCompletes.stream() + private static final List residentToggleModeTabCompletes = ResidentModeHandler.getValidModeNames(); + + private static final List residentSetModeTabCompletesWithClearAndReset = Stream.concat( + Arrays.asList("reset", "clear").stream(), + new ArrayList<>(residentToggleModeTabCompletes).stream() + ).collect(Collectors.toList()); + + private static final List residentCompleteToggleChoices = Stream.concat( + new ArrayList<>(residentToggleChoices).stream(), + new ArrayList<>(residentToggleModeTabCompletes).stream() ).collect(Collectors.toList()); public ResidentCommand(Towny instance) { @@ -191,16 +157,9 @@ public List onTabComplete(CommandSender sender, Command command, String break; case "toggle": if (args.length == 2) { - return NameUtil.filterByStart(TownyCommandAddonAPI.getTabCompletes(CommandType.RESIDENT_TOGGLE, residentToggleTabCompletes), args[1]); + return NameUtil.filterByStart(TownyCommandAddonAPI.getTabCompletes(CommandType.RESIDENT_TOGGLE, residentCompleteToggleChoices), args[1]); } else if (args.length == 3 && residentToggleChoices.contains(args[1].toLowerCase(Locale.ROOT))) { return NameUtil.filterByStart(BaseCommand.setOnOffCompletes, args[2]); - } else if (args.length >= 3) { - String prevArg = args[args.length - 2].toLowerCase(Locale.ROOT); - if (residentToggleModes.contains(prevArg)) { - return NameUtil.filterByStart(residentToggleModesUnionToggles, args[args.length - 1]); - } else if (BaseCommand.setOnOffCompletes.contains(prevArg)) { - return NameUtil.filterByStart(residentToggleModes, args[args.length - 1]); - } } break; case "set": @@ -212,7 +171,10 @@ public List onTabComplete(CommandSender sender, Command command, String switch (args[1].toLowerCase(Locale.ROOT)) { case "mode": - return NameUtil.filterByStart(residentModeTabCompletes, args[args.length - 1]); + if (args.length == 3) + return NameUtil.filterByStart(residentSetModeTabCompletesWithClearAndReset, args[2]); + else + return NameUtil.filterByStart(residentToggleModeTabCompletes, args[args.length - 1]); case "perm": return permTabComplete(StringMgmt.remArgs(args, 2)); case "about": @@ -430,8 +392,14 @@ private void residentToggle(Player player, String[] newSplit) throws TownyExcept } // Check if we're reseting before trying for nodes. - if (newSplit[0].equalsIgnoreCase("reset") || newSplit[0].equalsIgnoreCase("clear")) { - plugin.removePlayerMode(player); + if (newSplit[0].equalsIgnoreCase("clear")) { + checkPermOrThrow(resident.getPlayer(), PermissionNodes.TOWNY_COMMAND_RESIDENT_SET_MODE_CLEAR.getNode()); + ResidentModeHandler.clearModes(resident, false); + return; + } + + if (newSplit[0].equalsIgnoreCase("reset")) { + ResidentModeHandler.resetModes(resident, false); return; } TownyPermission perm = resident.getPermissions(); @@ -441,14 +409,7 @@ private void residentToggle(Player player, String[] newSplit) throws TownyExcept choice = BaseCommand.parseToggleChoice(newSplit[1]); } - // Special case chat spy - if (StringMgmt.containsIgnoreCase(Arrays.asList(newSplit), "spy")) { - checkPermOrThrow(player, PermissionNodes.TOWNY_CHAT_SPY.getNode()); - - resident.toggleMode(newSplit, true); - return; - - } else if (newSplit[0].equalsIgnoreCase("pvp")) { + if (newSplit[0].equalsIgnoreCase("pvp")) { checkPermOrThrow(player, PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_PVP.getNode()); Town town = resident.getTownOrNull(); @@ -481,8 +442,7 @@ private void residentToggle(Player player, String[] newSplit) throws TownyExcept TownyCommandAddonAPI.getAddonCommand(CommandType.RESIDENT_TOGGLE, newSplit[0]).execute(player, "resident", newSplit); return; } else { - - resident.toggleMode(newSplit, true); + ResidentModeHandler.toggleMode(resident, newSplit[0].toLowerCase(Locale.ROOT), true); return; } @@ -545,7 +505,7 @@ public void residentSet(Player player, String[] split) throws TownyException { checkPermOrThrow(player, PermissionNodes.TOWNY_COMMAND_RESIDENT_SET_PERM.getNode()); TownCommand.setTownBlockPermissions(player, resident, resident.getPermissions(), StringMgmt.remFirstArg(split), true); } - case "mode" -> setMode(player, StringMgmt.remFirstArg(split)); + case "mode" -> setMode(resident, StringMgmt.remFirstArg(split)); case "about" -> setAbout(player, String.join(" ", StringMgmt.remFirstArg(split)), resident); default -> { if (TownyCommandAddonAPI.hasCommand(CommandType.RESIDENT_SET, split[0])) { @@ -559,31 +519,26 @@ public void residentSet(Player player, String[] split) throws TownyException { resident.save(); } - private void setMode(Player player, String[] split) throws NoPermissionException { - checkPermOrThrow(player, PermissionNodes.TOWNY_COMMAND_RESIDENT_SET_MODE.getNode()); - + private void setMode(Resident resident, String[] split) throws TownyException { if (split.length == 0) { - HelpMenu.RESIDENT_SET_MODE.send(player); + HelpMenu.RESIDENT_SET_MODE.send(resident.getPlayer()); return; } if (split[0].equalsIgnoreCase("clear")) { - plugin.removePlayerModes(player); + checkPermOrThrow(resident.getPlayer(), PermissionNodes.TOWNY_COMMAND_RESIDENT_SET_MODE_CLEAR.getNode()); + ResidentModeHandler.clearModes(resident, true); return; } if (split[0].equalsIgnoreCase("reset")) { - plugin.removePlayerMode(player); + ResidentModeHandler.resetModes(resident, true); return; } - List list = Arrays.asList(split); - if (list.contains("spy")) - checkPermOrThrow(player, PermissionNodes.TOWNY_CHAT_SPY.getNode()); - - plugin.setPlayerMode(player, split, true); + ResidentModeHandler.toggleModes(resident, split, true, false); } - + private void setAbout(Player player, String about, Resident resident) throws TownyException { checkPermOrThrow(player, PermissionNodes.TOWNY_COMMAND_RESIDENT_SET_ABOUT.getNode()); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyCommand.java index 1c0848f0308..a91939f6302 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyCommand.java @@ -27,6 +27,7 @@ import com.palmergames.bukkit.towny.object.TownyObject; import com.palmergames.bukkit.towny.object.TownyWorld; import com.palmergames.bukkit.towny.object.gui.SelectionGUI; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.permissions.PermissionNodes; import com.palmergames.bukkit.towny.utils.NameUtil; import com.palmergames.bukkit.towny.utils.ResidentUtil; @@ -274,10 +275,7 @@ else if (split.length > 1 && split[1].equalsIgnoreCase("hud")) } case "spy": { catchConsole(sender); - checkPermOrThrow(sender, PermissionNodes.TOWNY_CHAT_SPY.getNode()); - - Resident resident = getResidentOrThrow(player); - resident.toggleMode(split, true); + ResidentModeHandler.toggleMode(getResidentOrThrow(player), "spy", true); break; } default: { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java index e79b4175317..7a06fb66fa4 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/db/TownyDatabaseHandler.java @@ -37,6 +37,7 @@ import com.palmergames.bukkit.towny.object.Translation; import com.palmergames.bukkit.towny.object.WorldCoord; import com.palmergames.bukkit.towny.object.metadata.DataFieldIO; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.object.jail.Jail; import com.palmergames.bukkit.towny.object.jail.UnJailReason; import com.palmergames.bukkit.towny.regen.PlotBlockData; @@ -429,7 +430,7 @@ public boolean removeTown(@NotNull Town town, @NotNull DeleteTownEvent.Cause cau town.getAccount().removeAccount(); for (Resident resident : toSave) { - resident.clearModes(false); + ResidentModeHandler.resetModes(resident, false); resident.removeTown(true); } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/ResidentModesInitializeEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/ResidentModesInitializeEvent.java new file mode 100644 index 00000000000..0bc9ffadbdf --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/ResidentModesInitializeEvent.java @@ -0,0 +1,36 @@ +package com.palmergames.bukkit.towny.event; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +import com.palmergames.bukkit.towny.exceptions.TownyException; +import com.palmergames.bukkit.towny.object.resident.mode.AbstractResidentMode; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; + +public class ResidentModesInitializeEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + public ResidentModesInitializeEvent() { + super(!Bukkit.isPrimaryThread()); + } + + /** + * Registers a new ResidentMode. + * @param mode The ResidentMode you want to register. + * @throws TownyException - If a mode with this name is already registered. + */ + public void registerMode(@NotNull AbstractResidentMode mode) throws TownyException { + ResidentModeHandler.registerMode(mode); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java index a9455bfa192..fedd971792b 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java @@ -185,7 +185,7 @@ public void onPlayerQuit(PlayerQuitEvent event) { // Don't set last online if the player was vanished. if (!event.getPlayer().getMetadata("vanished").stream().anyMatch(MetadataValue::asBoolean)) resident.setLastOnline(System.currentTimeMillis()); - resident.clearModes(); + resident.clearModes(false); resident.save(); if (TownyTimerHandler.isTeleportWarmupRunning()) { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java index e53cdc9e33c..b2fc7ffad4f 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java @@ -7,13 +7,11 @@ import com.palmergames.bukkit.towny.TownyMessaging; import com.palmergames.bukkit.towny.TownySettings; import com.palmergames.bukkit.towny.TownyUniverse; -import com.palmergames.bukkit.towny.command.BaseCommand; import com.palmergames.bukkit.towny.confirmations.Confirmation; import com.palmergames.bukkit.towny.event.DeleteTownEvent; import com.palmergames.bukkit.towny.event.TownAddResidentEvent; import com.palmergames.bukkit.towny.event.TownRemoveResidentEvent; import com.palmergames.bukkit.towny.event.TownyObjectFormattedNameEvent; -import com.palmergames.bukkit.towny.event.resident.ResidentToggleModeEvent; import com.palmergames.bukkit.towny.event.town.TownPreRemoveResidentEvent; import com.palmergames.bukkit.towny.exceptions.AlreadyRegisteredException; import com.palmergames.bukkit.towny.exceptions.EmptyTownException; @@ -28,9 +26,9 @@ import com.palmergames.bukkit.towny.object.jail.Jail; import com.palmergames.bukkit.towny.object.metadata.BooleanDataField; import com.palmergames.bukkit.towny.object.metadata.CustomDataField; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.permissions.TownyPerms; import com.palmergames.bukkit.towny.scheduling.ScheduledTask; -import com.palmergames.bukkit.towny.tasks.SetDefaultModes; import com.palmergames.bukkit.towny.tasks.TeleportWarmupTimerTask; import com.palmergames.bukkit.towny.utils.CombatUtil; import com.palmergames.bukkit.towny.utils.MetaDataUtil; @@ -54,7 +52,6 @@ import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -70,7 +67,6 @@ public class Resident extends TownyObject implements InviteReceiver, EconomyHand private String title = ""; private String surname = ""; private String about = TownySettings.getDefaultResidentAbout(); - private final List modes = new ArrayList<>(); private transient Confirmation confirmation; private final transient List receivedInvites = new ArrayList<>(); private transient EconomyAccount account; @@ -566,69 +562,33 @@ public boolean isAdmin() { } public List getModes() { - return Collections.unmodifiableList(modes); + return ResidentModeHandler.getResidentModesNames(this); } public boolean hasMode(String mode) { - return this.modes.contains(mode.toLowerCase(Locale.ROOT)); + return getModes().contains(mode.toLowerCase(Locale.ROOT)); } - - public void toggleMode(String[] newModes, boolean notify) { - - /* - * Toggle any modes passed to us on/off. - */ - for (int i = 0; i < newModes.length; i++) { - String mode = newModes[i].toLowerCase(Locale.ROOT); - - Optional choice = Optional.empty(); - if (i + 1 < newModes.length) { - String bool = newModes[i + 1].toLowerCase(Locale.ROOT); - if (BaseCommand.setOnOffCompletes.contains(bool)) { - choice = Optional.of(bool.equalsIgnoreCase("on")); - i++; - } - } - - boolean modeEnabled = this.modes.contains(mode); - - ResidentToggleModeEvent event = new ResidentToggleModeEvent(this, mode); - if (BukkitTools.isEventCancelled(event)) { - TownyMessaging.sendErrorMsg(this, event.getCancelMessage()); - continue; - } - - if (choice.orElse(!modeEnabled)) { - if (!modeEnabled) { - this.modes.add(mode); - } - } else { - this.modes.remove(mode); - } - } - - /* - * If we have toggled all modes off we need to set their defaults. - */ - if (this.modes.isEmpty()) { - clearModes(); - return; - } - - if (notify) - TownyMessaging.sendMsg(this, Translatable.of("msg_modes_set").append(StringMgmt.join(getModes(), ","))); + /** + * @deprecated since 0.100.4.6. Use {@link ResidentModeHandler#toggleModes(Resident, String[], boolean)} instead. + * + * @param newModes + * @param notify + */ + @Deprecated + public void toggleMode(String[] newModes, boolean notify) { + ResidentModeHandler.toggleModes(this, newModes, notify, false); } - - public void setModes(String[] modes, boolean notify) { - - this.modes.clear(); - this.toggleMode(modes, false); - - if (notify) - TownyMessaging.sendMsg(this, Translatable.of("msg_modes_set").append(StringMgmt.join(getModes(), ","))); - + /** + * @deprecated since 0.100.4.6. Use {@link ResidentModeHandler#toggleModes(Resident, String[], boolean)} instead. + * + * @param newModes + * @param notify + */ + @Deprecated + public void setModes(String[] modes, boolean notify) { + ResidentModeHandler.toggleModes(this, modes, notify, false); } public void clearModes() { @@ -636,12 +596,7 @@ public void clearModes() { } public void clearModes(boolean notify) { - - this.modes.clear(); - if (notify) - TownyMessaging.sendMsg(this, (Translatable.of("msg_modes_set"))); - - Towny.getPlugin().getScheduler().runAsyncLater(new SetDefaultModes(this.getName(), notify), 1); + ResidentModeHandler.clearModes(this, notify); } /** @@ -651,12 +606,7 @@ public void clearModes(boolean notify) { * @param notify - If notifications should be sent */ public void resetModes(String[] modes, boolean notify) { - - if (modes.length > 0) - this.toggleMode(modes, false); - - if (notify) - TownyMessaging.sendMsg(this, Translatable.of("msg_modes_set").append(StringMgmt.join(getModes(), ","))); + ResidentModeHandler.resetModes(this, notify); } @Nullable diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/AbstractResidentMode.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/AbstractResidentMode.java new file mode 100644 index 00000000000..13b665d478e --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/AbstractResidentMode.java @@ -0,0 +1,24 @@ +package com.palmergames.bukkit.towny.object.resident.mode; + +import com.palmergames.bukkit.towny.object.Resident; + +public abstract class AbstractResidentMode { + + String name; + String permissionNode; + + public AbstractResidentMode(String name, String permissionNode) { + this.name = name; + this.permissionNode = permissionNode; + } + + protected String name() { + return name; + } + + protected String permissionNode() { + return permissionNode; + } + + protected abstract void toggle(Resident resident); +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/BorderResidentMode.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/BorderResidentMode.java new file mode 100644 index 00000000000..8669d28333a --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/BorderResidentMode.java @@ -0,0 +1,25 @@ +package com.palmergames.bukkit.towny.object.resident.mode; + +import java.util.HashSet; + +import com.palmergames.bukkit.towny.object.Resident; + +public class BorderResidentMode extends AbstractResidentMode { + + public BorderResidentMode(String name, String permissionNode) { + super(name, permissionNode); + } + + @Override + protected void toggle(Resident resident) { + if (ResidentModeHandler.hasMode(resident, this)) + ResidentModeHandler.removeMode(resident, this); + else { + for (AbstractResidentMode mode : new HashSet<>(ResidentModeHandler.getResidentModes(resident))) { + if (mode instanceof BorderResidentMode) + ResidentModeHandler.removeMode(resident, mode); + } + ResidentModeHandler.addMode(resident, this); + } + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ClaimingResidentMode.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ClaimingResidentMode.java new file mode 100644 index 00000000000..b542b2229be --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ClaimingResidentMode.java @@ -0,0 +1,25 @@ +package com.palmergames.bukkit.towny.object.resident.mode; + +import java.util.HashSet; + +import com.palmergames.bukkit.towny.object.Resident; + +public class ClaimingResidentMode extends AbstractResidentMode { + + public ClaimingResidentMode(String name, String permissionNode) { + super(name, permissionNode); + } + + @Override + protected void toggle(Resident resident) { + if (ResidentModeHandler.hasMode(resident, this)) + ResidentModeHandler.removeMode(resident, this); + else { + for (AbstractResidentMode mode : new HashSet<>(ResidentModeHandler.getResidentModes(resident))) { + if (mode instanceof ClaimingResidentMode) + ResidentModeHandler.removeMode(resident, mode); + } + ResidentModeHandler.addMode(resident, this); + } + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/GenericResidentMode.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/GenericResidentMode.java new file mode 100644 index 00000000000..c028f20725a --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/GenericResidentMode.java @@ -0,0 +1,18 @@ +package com.palmergames.bukkit.towny.object.resident.mode; + +import com.palmergames.bukkit.towny.object.Resident; + +public class GenericResidentMode extends AbstractResidentMode { + + public GenericResidentMode(String name, String permissionNode) { + super(name, permissionNode); + } + + @Override + protected void toggle(Resident resident) { + if (ResidentModeHandler.hasMode(resident, this)) + ResidentModeHandler.removeMode(resident, this); + else + ResidentModeHandler.addMode(resident, this); + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ResidentModeHandler.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ResidentModeHandler.java new file mode 100644 index 00000000000..90a82b221ae --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/resident/mode/ResidentModeHandler.java @@ -0,0 +1,312 @@ +package com.palmergames.bukkit.towny.object.resident.mode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.TownyMessaging; +import com.palmergames.bukkit.towny.TownyUniverse; +import com.palmergames.bukkit.towny.event.ResidentModesInitializeEvent; +import com.palmergames.bukkit.towny.event.resident.ResidentToggleModeEvent; +import com.palmergames.bukkit.towny.exceptions.NoPermissionException; +import com.palmergames.bukkit.towny.exceptions.TownyException; +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.Translatable; +import com.palmergames.bukkit.towny.permissions.PermissionNodes; +import com.palmergames.bukkit.util.BukkitTools; +import com.palmergames.util.StringMgmt; + +public class ResidentModeHandler { + + private static Map modes = new ConcurrentHashMap<>(); + private static Map> residentModesMap = new ConcurrentHashMap<>(); + + public static void initialize() { + modes.clear(); + residentModesMap.clear(); + + addMode(new GenericResidentMode("adminbypass", "")); // No permission so that admins can toggle it when they don't have admin powers. + addMode(new GenericResidentMode("bedspawn", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_BEDSPAWN.getNode())); + addMode(new GenericResidentMode("bordertitles", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_BORDERTITLES.getNode())); + addMode(new GenericResidentMode("ignoreotherchannels", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_IGNOREOTHERCHANNELS.getNode())); + addMode(new GenericResidentMode("ignoreplots", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_IGNOREPLOTS.getNode())); + addMode(new GenericResidentMode("infotool", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_INFOTOOL.getNode())); + addMode(new GenericResidentMode("map", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_MAP.getNode())); + addMode(new GenericResidentMode("plotgroup", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_PLOTGROUP.getNode())); + addMode(new GenericResidentMode("townborder", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNBORDER.getNode())); + addMode(new GenericResidentMode("spy", PermissionNodes.TOWNY_CHAT_SPY.getNode())); + + addMode(new BorderResidentMode("constantplotborder", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_CONSTANTPLOTBORDER.getNode())); + addMode(new BorderResidentMode("plotborder", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_PLOTBORDER.getNode())); + + addMode(new ClaimingResidentMode("townclaim", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNCLAIM.getNode())); + addMode(new ClaimingResidentMode("townunclaim", PermissionNodes.TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNUNCLAIM.getNode())); + + BukkitTools.fireEvent(new ResidentModesInitializeEvent()); + } + + /** + * Registers a new ResidentMode. Should not be used at all outside of the ResidentModesInitializeEvent. + * @param mode The ResidentMode to add. + * @throws TownyException if a mode with this name is already registered. + */ + public static void registerMode(@NotNull AbstractResidentMode mode) throws TownyException { + if (modes.containsKey(mode.name)) + throw new TownyException(); + addMode(mode); + } + + private static void addMode(AbstractResidentMode mode) { + if (modes.containsKey(mode.name)) + return; + modes.put(mode.name.toLowerCase(Locale.ROOT), mode); + } + + public static boolean isValidMode(String name) { + return modes.containsKey(name); + } + + public static boolean isValidMode(AbstractResidentMode mode) { + return modes.containsValue(mode); + } + + public static List getValidModeNames() { + return new ArrayList<>(modes.keySet()); + } + + @Nullable + public static AbstractResidentMode getMode(String name) { + return modes.get(name); + } + + public static Set getModes(Player player) { + try { + return residentModesMap.getOrDefault(getResident(player), new HashSet<>()); + } catch (TownyException e) {} + + return new HashSet<>(); + } + + public static Set getModes(Resident resident) { + return residentModesMap.getOrDefault(resident, new HashSet<>()); + } + + public static boolean hasMode(Resident resident, String name) { + return isValidMode(name) && hasMode(resident, getMode(name)); + } + + public static boolean hasMode(Resident resident, AbstractResidentMode mode) { + return isValidMode(mode) && residentModesMap.containsKey(resident) && residentModesMap.get(resident).contains(mode); + } + + /** + * Will clear a Player's modes and then apply all of the given named Modes. + * + * @param player Player to toggle modes on. + * @param names String[] of all modes to add to the Player. + * @param notify whether to notify the Player of their new modes. + */ + public static void toggleModes(Player player, String[] names, boolean notify) throws TownyException { + toggleModes(getResident(player), names, notify, false); + } + + /** + * Will clear a Resident's modes and then apply all of the given named Modes. + * + * @param resident Resident to toggle modes on. + * @param names String[] of all modes to add to the Resident. + * @param notify whether to notify the Resident of their new modes. + * @param clearModes whether a resident's nodes are cleared before toggling + * happens. + */ + public static void toggleModes(Resident resident, String[] names, boolean notify, boolean clearModes) { + if (clearModes) + clearModes(resident, false); + for (String mode : names) + try { + toggleMode(resident, mode, false); + } catch (TownyException e) { + if (resident.isOnline()) + TownyMessaging.sendErrorMsg(resident.getPlayer(), e.getMessage(resident.getPlayer())); + } + + if (notify && !getModes(resident).isEmpty()) + TownyMessaging.sendMsg(resident, Translatable.of("msg_modes_set").append(StringMgmt.join(getResidentModesNames(resident), ","))); + } + + /** + * Will attempt to toggle on or off, a named mode on a Player. + * + * @param player Player to toggle a mode on. + * @param name the String name of the {@link AbstractResidentMode} to toggle. + * @param notify whether to notify the Player of their mode changing. + * @throws TownyException thrown when a mode doesn't exist, the Player does not + * have permisson, or when the ResidentToggleModeEvent is + * cancelled, or the Player isn't a registered Resident. + */ + public static void toggleMode(Player player, String name, boolean notify) throws TownyException { + toggleMode(getResident(player), name, notify); + } + + /** + * Will attempt to toggle on or off, a named mode on a Resident. + * + * @param resident Resident to toggle a mode on. + * @param name the String name of the {@link AbstractResidentMode} to + * toggle. + * @param notify whether to notify the Resident of their mode changing. + * @throws TownyException thrown when a mode doesn't exist, the resident does + * not have permisson, or when the + * ResidentToggleModeEvent is cancelled. + */ + public static void toggleMode(Resident resident, String name, boolean notify) throws TownyException { + if (!isValidMode(name)) + throw new TownyException(Translatable.of("msg_err_mode_does_not_exist", name)); + + toggleMode(resident, getMode(name), notify); + } + + /** + * Will attempt to toggle on or off, a AbstractResidentMode on a Resident. + * + * @param resident Resident to toggle a mode on. + * @param mode {@link AbstractResidentMode} to toggle on or off. + * @param notify whether to notify the Resident of their mode changing. + * @throws TownyException thrown when a mode doesn't exist, the resident does + * not have permisson, or when the + * ResidentToggleModeEvent is cancelled. + */ + public static void toggleMode(Resident resident, AbstractResidentMode mode, boolean notify) throws TownyException { + if (!isValidMode(mode)) + throw new TownyException(Translatable.of("msg_err_mode_does_not_exist", mode.name)); + + if (!mode.permissionNode.isEmpty() && !resident.hasPermissionNode(mode.permissionNode) && isNotBecauseOfDefaultModes(resident, mode.name)) + throw new NoPermissionException(); + + BukkitTools.ifCancelledThenThrow(new ResidentToggleModeEvent(resident, mode.name)); + + mode.toggle(resident); + + if (notify) + TownyMessaging.sendMsg(resident, Translatable.of("msg_modes_set").append(StringMgmt.join(getResidentModesNames(resident), ","))); + } + + /** + * Default modes bypass the permission requirement, so that Admins can force + * players to have modes they cannot remove. + * + * @param resident Resident to test. + * @param name Mode name to test for. + * @return true if the player does not have the mode in their default modes. + */ + private static boolean isNotBecauseOfDefaultModes(Resident resident, String name) { + List defaultModes = Stream.of(getDefaultModes(resident).split(",")).collect(Collectors.toList()); + return !StringMgmt.containsIgnoreCase(defaultModes, name); + } + + /** + * Removes all modes from a Player. + * + * @param player Player to remove the modes from. + */ + public static void clearModes(Player player) { + try { + clearModes(getResident(player), false); + } catch (TownyException ignored) {} + } + + /** + * Removes all modes from a Resident. + * + * @param resident Resident to remove the modes from. + * @param notify whether to notify the Resident of their modes being cleared. + */ + public static void clearModes(Resident resident, boolean notify) { + if (!residentModesMap.containsKey(resident)) + return; + + residentModesMap.get(resident).clear(); + if (notify) + TownyMessaging.sendMsg(resident, (Translatable.of("msg_modes_set"))); + } + + /** + * Removes all modes from a Resident and then resets their modes to the Default Modes according to their permissions. + * + * @param resident Resident to reset. + * @param notify whether to notify the Resident of their modes after. + */ + public static void resetModes(Resident resident, boolean notify) { + if (residentModesMap.containsKey(resident)) + residentModesMap.get(resident).clear(); + + Towny.getPlugin().getScheduler().runAsyncLater(() -> applyDefaultModes(resident, notify), 1); + } + + public static void applyDefaultModes(Resident resident, boolean notify) { + // Is the player still available + if (resident == null || !resident.isOnline()) + return; + + try { + String modeString = getDefaultModes(resident); + if (modeString.isEmpty()) + return; + toggleModes(resident, modeString.split(","), notify, true); + } catch (NullPointerException ignored) {} + } + + protected static void addMode(Resident resident, AbstractResidentMode mode) { + if (!residentModesMap.containsKey(resident)) { + residentModesMap.put(resident, new HashSet<>(Arrays.asList(mode))); + return; + } + + Set modes = residentModesMap.get(resident); + modes.add(mode); + residentModesMap.put(resident, modes); + } + + protected static void removeMode(Resident resident, AbstractResidentMode mode) { + if (!residentModesMap.containsKey(resident) || !residentModesMap.get(resident).contains(mode)) + return; + + Set modes = residentModesMap.get(resident); + modes.remove(mode); + residentModesMap.put(resident, modes); + } + + public static List getResidentModesNames(Resident resident) { + if (!residentModesMap.containsKey(resident)) + return new ArrayList<>(); + + return residentModesMap.get(resident).stream().map(AbstractResidentMode::name).collect(Collectors.toUnmodifiableList()); + } + + protected static Set getResidentModes(Resident resident) { + return residentModesMap.getOrDefault(resident, new HashSet<>()); + } + + private static Resident getResident(Player player) throws TownyException { + Resident resident = TownyUniverse.getInstance().getResident(player.getUniqueId()); + if (resident == null) + throw new TownyException(String.format("The player with the name '%s' is not registered!", player.getName())); + return resident; + } + + private static String getDefaultModes(Resident resident) { + return TownyUniverse.getInstance().getPermissionSource().getPlayerPermissionStringNode(resident.getName(), PermissionNodes.TOWNY_DEFAULT_MODES.getNode()); + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/GroupManagerSource.java b/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/GroupManagerSource.java index 9c5c835d84e..f27dfcf8497 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/GroupManagerSource.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/GroupManagerSource.java @@ -3,6 +3,7 @@ import com.palmergames.bukkit.towny.Towny; import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.util.BukkitTools; import com.palmergames.bukkit.util.Colors; @@ -175,17 +176,7 @@ public void onGMUserEvent(GMUserEvent event) { return; } - Resident resident = TownyUniverse.getInstance().getResident(event.getUserName()); - if (resident != null) { - Player player = BukkitTools.getPlayerExact(resident.getName()); - - if (player != null) { - //setup default modes for this player. - String[] modes = getPlayerPermissionStringNode(player.getName(), PermissionNodes.TOWNY_DEFAULT_MODES.getNode()).split(","); - plugin.setPlayerMode(player, modes, false); - plugin.resetCache(player); - } - } + updateDefaultResidentModes(event.getUserName()); } @EventHandler(priority = EventPriority.HIGH) @@ -196,17 +187,9 @@ public void onGMGroupEvent(GMGroupEvent event) { Group group = event.getGroup(); // Update all players who are in this group. - for (Player toUpdate : BukkitTools.getOnlinePlayers()) { - if (toUpdate != null) { - if (group.toString().equals(getPlayerGroup(toUpdate))) { - //setup default modes - String[] modes = getPlayerPermissionStringNode(toUpdate.getName(), PermissionNodes.TOWNY_DEFAULT_MODES.getNode()).split(","); - plugin.setPlayerMode(toUpdate, modes, false); - plugin.resetCache(toUpdate); - } - } - } - + for (Player player : BukkitTools.getOnlinePlayers()) + if (player != null && group.toString().equals(getPlayerGroup(player))) + updateDefaultResidentModes(player.getName()); } } catch (IllegalArgumentException e) { // Not tracking this event type @@ -219,15 +202,9 @@ public void onGMSystemEvent(GMSystemEvent event) { try { if (PermissionEventEnums.GMSystem_Action.valueOf(event.getAction().name()) != null) { // Update all players. - for (Player toUpdate : BukkitTools.getOnlinePlayers()) { - if (toUpdate != null) { - //setup default modes - String[] modes = getPlayerPermissionStringNode(toUpdate.getName(), PermissionNodes.TOWNY_DEFAULT_MODES.getNode()).split(","); - plugin.setPlayerMode(toUpdate, modes, false); - plugin.resetCache(toUpdate); - } - } - + for (Player player : BukkitTools.getOnlinePlayers()) + if (player != null) + updateDefaultResidentModes(player.getName()); } } catch (IllegalArgumentException e) { // Not tracking this event type @@ -235,6 +212,13 @@ public void onGMSystemEvent(GMSystemEvent event) { } + private void updateDefaultResidentModes(String name) { + Resident resident = TownyUniverse.getInstance().getResident(name); + if (resident == null || !resident.isOnline()) + return; + ResidentModeHandler.applyDefaultModes(resident, false); + plugin.resetCache(resident.getPlayer()); + } } protected class PermissionEventEnums { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/PermissionNodes.java b/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/PermissionNodes.java index 24350373957..aaeeccad622 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/PermissionNodes.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/permissions/PermissionNodes.java @@ -265,18 +265,30 @@ public enum PermissionNodes { TOWNY_COMMAND_RESIDENT_SET("towny.command.resident.set.*"), TOWNY_COMMAND_RESIDENT_SET_PERM("towny.command.resident.set.perm"), TOWNY_COMMAND_RESIDENT_SET_MODE("towny.command.resident.set.mode"), + TOWNY_COMMAND_RESIDENT_SET_MODE_CLEAR("towny.command.resident.set.mode.clear"), TOWNY_COMMAND_RESIDENT_SET_ABOUT("towny.command.resident.set.about"), TOWNY_COMMAND_RESIDENT_TOGGLE("towny.command.resident.toggle.*"), + // Plot-permission-related TOWNY_COMMAND_RESIDENT_TOGGLE_PVP("towny.command.resident.toggle.pvp"), TOWNY_COMMAND_RESIDENT_TOGGLE_EXPLOSION("towny.command.resident.toggle.explosion"), TOWNY_COMMAND_RESIDENT_TOGGLE_FIRE("towny.command.resident.toggle.fire"), TOWNY_COMMAND_RESIDENT_TOGGLE_MOBS("towny.command.resident.toggle.mobs"), + // Generic Modes + TOWNY_COMMAND_RESIDENT_TOGGLE_BEDSPAWN("towny.command.resident.toggle.bedspawn"), + TOWNY_COMMAND_RESIDENT_TOGGLE_BORDERTITLES("towny.command.resident.toggle.bordertitles"), + TOWNY_COMMAND_RESIDENT_TOGGLE_IGNOREOTHERCHANNELS("towny.command.resident.toggle.ignoreotherchannels"), + TOWNY_COMMAND_RESIDENT_TOGGLE_IGNOREPLOTS("towny.command.resident.toggle.ignoreplots"), + TOWNY_COMMAND_RESIDENT_TOGGLE_INFOTOOL("towny.command.resident.toggle.infotool"), + TOWNY_COMMAND_RESIDENT_TOGGLE_MAP("towny.command.resident.toggle.map"), + TOWNY_COMMAND_RESIDENT_TOGGLE_PLOTGROUP("towny.command.resident.toggle.plotgroup"), + TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNBORDER("towny.command.resident.toggle.townborder"), + // Border Modes + TOWNY_COMMAND_RESIDENT_TOGGLE_CONSTANTPLOTBORDER("towny.command.resident.toggle.constantplotborder"), TOWNY_COMMAND_RESIDENT_TOGGLE_PLOTBORDER("towny.command.resident.toggle.plotborder"), + // Claiming Modes TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNCLAIM("towny.command.resident.toggle.townclaim"), - TOWNY_COMMAND_RESIDENT_TOGGLE_CONSTANTPLOTBORDER("towny.command.resident.toggle.constantplotborder"), - TOWNY_COMMAND_RESIDENT_TOGGLE_IGNOREPLOTS("towny.command.resident.toggle.ignoreplots"), - TOWNY_COMMAND_RESIDENT_TOGGLE_BORDERTITLES("towny.command.resident.toggle.bordertitles"), + TOWNY_COMMAND_RESIDENT_TOGGLE_TOWNUNCLAIM("towny.command.resident.toggle.townunclaim"), TOWNY_COMMAND_RESIDENT_FRIEND("towny.command.resident.friend"), TOWNY_COMMAND_RESIDENT_SPAWN("towny.command.resident.spawn"), diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/OnPlayerLogin.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/OnPlayerLogin.java index 89c15ae24b7..9862e0fcbe4 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/OnPlayerLogin.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/OnPlayerLogin.java @@ -14,6 +14,7 @@ import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.Translatable; +import com.palmergames.bukkit.towny.object.resident.mode.ResidentModeHandler; import com.palmergames.bukkit.towny.permissions.PermissionNodes; import com.palmergames.bukkit.towny.permissions.TownyPerms; import com.palmergames.bukkit.towny.utils.ResidentUtil; @@ -102,7 +103,7 @@ else if (nationHasPendingAllyInvites(nation)) ResidentUtil.outlawEnteredTown(resident, insideTown, player.getLocation()); //Schedule to setup default modes when the player has finished loading - plugin.getScheduler().runLater(player, new SetDefaultModes(player.getName(), false), 1); + plugin.getScheduler().runLater(player, () -> ResidentModeHandler.applyDefaultModes(resident, false), 1); if (TownyUpdateChecker.shouldShowNotification() && player.hasPermission(PermissionNodes.TOWNY_ADMIN_UPDATEALERTS.getNode())) { Audience audience = Towny.getAdventure().player(player); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/SetDefaultModes.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/SetDefaultModes.java deleted file mode 100644 index 87af2adbea4..00000000000 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/SetDefaultModes.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.palmergames.bukkit.towny.tasks; - -import com.palmergames.bukkit.towny.TownyUniverse; -import com.palmergames.bukkit.towny.object.Resident; -import com.palmergames.bukkit.towny.permissions.PermissionNodes; -import com.palmergames.bukkit.util.BukkitTools; - -import java.util.TimerTask; - -/** - * @author ElgarL - * - */ -public class SetDefaultModes extends TimerTask { - - protected String name; - protected boolean notify; - - public SetDefaultModes(String name, boolean notify) { - - this.name = name; - this.notify = notify; - } - - @Override - public void run() { - - // Is the player still available - if (!BukkitTools.isOnline(name)) - return; - - //setup default modes - try { - TownyUniverse townyUniverse = TownyUniverse.getInstance(); - String modeString = townyUniverse.getPermissionSource().getPlayerPermissionStringNode(name, PermissionNodes.TOWNY_DEFAULT_MODES.getNode()); - if (modeString.isEmpty()) { return; } - String[] modes = modeString.split(","); - Resident resident = townyUniverse.getResident(name); - - if (resident != null) - resident.setModes(modes, notify); - } catch (NullPointerException ignored) { - - } - - - } - -} \ No newline at end of file diff --git a/Towny/src/main/resources/lang/en-US.yml b/Towny/src/main/resources/lang/en-US.yml index 7bb6bc5afa8..ffc067bace5 100644 --- a/Towny/src/main/resources/lang/en-US.yml +++ b/Towny/src/main/resources/lang/en-US.yml @@ -2610,3 +2610,5 @@ msg_admin_eco_convert_online_players_warning: "Warning: It is recommended t msg_admin_eco_convert_x_accounts_found: "Found %s accounts to convert. Beginning conversion now." msg_admin_eco_convert_conversion_progress: "Account conversion in progress, %s complete..." msg_admin_eco_convert_success: "Economy conversion successful" + +msg_err_mode_does_not_exist: "The mode %s is not recognized." diff --git a/Towny/src/main/resources/plugin.yml b/Towny/src/main/resources/plugin.yml index 8cb8a224fe7..0c91a48eff3 100644 --- a/Towny/src/main/resources/plugin.yml +++ b/Towny/src/main/resources/plugin.yml @@ -652,6 +652,7 @@ permissions: default: false children: towny.command.resident.set.mode: true + towny.command.resident.set.mode.clear: true towny.command.resident.set.perm: true towny.command.resident.set.about: true @@ -661,14 +662,20 @@ permissions: children: towny.command.resident.toggle.explosion: true towny.command.resident.toggle.fire: true - towny.command.resident.toggle.map: true towny.command.resident.toggle.mobs: true - towny.command.resident.toggle.plotborder: true towny.command.resident.toggle.pvp: true - towny.command.resident.toggle.townclaim: true - towny.command.resident.toggle.constantplotborder: true - towny.command.resident.toggle.ignoreplots: true + towny.command.resident.toggle.bedspawn: true towny.command.resident.toggle.bordertitles: true + towny.command.resident.toggle.ignoreotherchannels: true + towny.command.resident.toggle.ignoreplots: true + towny.command.resident.toggle.infotool: true + towny.command.resident.toggle.map: true + towny.command.resident.toggle.plotgroup: true + towny.command.resident.toggle.constantplotborder: true + towny.command.resident.toggle.plotborder: true + towny.command.resident.toggle.townborder: true + towny.command.resident.toggle.townclaim: true + towny.command.resident.toggle.townunclaim: true # TownyAdmin command permissions towny.command.townyadmin.*: