diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java index d393b8357..88971fc94 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSettingsCommand.java @@ -1,17 +1,29 @@ package world.bentobox.bentobox.api.commands.admin; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; +import org.bukkit.ChatColor; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; +import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag.Mode; +import world.bentobox.bentobox.api.flags.Flag.Type; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.panels.builders.TabbedPanelBuilder; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.panels.settings.SettingsTab; import world.bentobox.bentobox.panels.settings.WorldDefaultSettingsTab; import world.bentobox.bentobox.util.Util; @@ -22,31 +34,56 @@ import world.bentobox.bentobox.util.Util; */ public class AdminSettingsCommand extends CompositeCommand { + private final List PROTECTION_FLAG_NAMES; private Island island; + private final List SETTING_FLAG_NAMES; + private List WORLD_SETTING_FLAG_NAMES; + private @NonNull Optional flag; + private boolean activeState; + private int rank; public AdminSettingsCommand(CompositeCommand islandCommand) { super(islandCommand, "settings", "flags", "options"); + // make constants + GameModeAddon gameMode = getPlugin().getIWM().getAddon(getWorld()).orElse(null); + PROTECTION_FLAG_NAMES = getPlugin().getFlagsManager().getFlags().stream() + .filter(f -> f.getType().equals(Type.PROTECTION)) + .filter(f -> f.getGameModes().isEmpty() || gameMode == null || f.getGameModes().contains(gameMode)) + .map(Flag::getID) + .collect(Collectors.toList()); + SETTING_FLAG_NAMES = getPlugin().getFlagsManager().getFlags().stream() + .filter(f -> f.getType().equals(Type.SETTING)) + .filter(f -> f.getGameModes().isEmpty() || gameMode == null || f.getGameModes().contains(gameMode)) + .map(Flag::getID) + .collect(Collectors.toList()); + WORLD_SETTING_FLAG_NAMES = getPlugin().getFlagsManager().getFlags().stream() + .filter(f -> f.getType().equals(Type.WORLD_SETTING)) + .filter(f -> f.getGameModes().isEmpty() || gameMode == null || f.getGameModes().contains(gameMode)) + .map(Flag::getID) + .collect(Collectors.toList()); } @Override public void setup() { setPermission("admin.settings"); - setOnlyPlayer(true); setParametersHelp("commands.admin.settings.parameters"); setDescription("commands.admin.settings.description"); } @Override public boolean canExecute(User user, String label, List args) { - if (args.size() > 1) { - // Show help - showHelp(this, user); - return false; - } if (args.isEmpty()) { // World settings return true; } + if (args.size() > 1) { + // Command + return checkSyntax(user, args); + } + return getIsland(user, args); + } + + private boolean getIsland(User user, List args) { // Get target player @Nullable UUID targetUUID = Util.getUUID(args.get(0)); if (targetUUID == null) { @@ -61,8 +98,111 @@ public class AdminSettingsCommand extends CompositeCommand { return true; } + /** + * Check that this command is correct to set a setting + * @param user - user + * @param args - args + * @return true if the syntax is correct + */ + private boolean checkSyntax(User user, List args) { + if (args.size() == 2) { + // Should be a world setting + // If world settings, then active/disabled, otherwise player flags + if (WORLD_SETTING_FLAG_NAMES.contains(args.get(0).toUpperCase(Locale.ENGLISH))) { + if (checkActiveDisabled(user, args.get(1))) { + flag = getPlugin().getFlagsManager().getFlag(args.get(0).toUpperCase(Locale.ENGLISH)); + return true; + } + } else { + this.showHelp(this, user); + return false; + } + } else if (args.size() > 2) { + // Get island + if (!getIsland(user, args)) { + return false; + } + + if (!SETTING_FLAG_NAMES.contains(args.get(1).toUpperCase(Locale.ENGLISH)) + && !PROTECTION_FLAG_NAMES.contains(args.get(1).toUpperCase(Locale.ENGLISH))) { + user.sendMessage("commands.admin.settings.unknown-flag", TextVariables.NAME, args.get(2)); + return false; + } + // Set flag + flag = getPlugin().getFlagsManager().getFlag(args.get(1).toUpperCase(Locale.ENGLISH)); + // Check settings + if (flag.isPresent()) { + if (flag.get().getType().equals(Type.SETTING)) { + return checkActiveDisabled(user, args.get(2)); + } else { + // Protection flag + return checkRank(user, String.join(" ", args.subList(2, args.size()))); + } + } + } + return false; + } + + + /** + * Check the rank given. + * @param user - user + * @param string - the rank given in the command line + * @return true if rank is valid + */ + private boolean checkRank(User user, String string) { + for (Entry en : getPlugin().getRanksManager().getRanks().entrySet()) { + if (en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK + && string.equalsIgnoreCase(ChatColor.stripColor(user.getTranslation(en.getKey())))) { + // We have a winner + rank = en.getValue(); + return true; + } + } + user.sendMessage("commands.admin.setrank.unknown-rank"); + return false; + } + + private boolean checkActiveDisabled(User user, String string) { + String active = ChatColor.stripColor(user.getTranslation("protection.panel.flag-item.setting-active")); + String disabled = ChatColor.stripColor(user.getTranslation("protection.panel.flag-item.setting-disabled")); + if (!string.equalsIgnoreCase(active) && !string.equalsIgnoreCase(disabled)) { + user.sendMessage("commands.admin.settings.unknown-setting", TextVariables.NAME, string); + return false; + } + activeState = string.equalsIgnoreCase(active); + return true; + } + @Override public boolean execute(User user, String label, List args) { + if (args.size() > 1) { + // Command line setting + flag.ifPresent(f -> { + switch (f.getType()) { + case PROTECTION: + island.setFlag(f, rank); + getIslands().save(island); + break; + case SETTING: + island.setSettingsFlag(f, activeState); + getIslands().save(island); + break; + case WORLD_SETTING: + f.setSetting(getWorld(), activeState); + break; + default: + break; + } + }); + user.sendMessage("general.success"); + return true; + } + // GUI requires in-game + if (!user.isPlayer()) { + user.sendMessage("general.errors.use-in-game"); + return false; + } getPlayers().setFlagsDisplayMode(user.getUniqueId(), Mode.EXPERT); if (args.isEmpty()) { new TabbedPanelBuilder() @@ -86,4 +226,45 @@ public class AdminSettingsCommand extends CompositeCommand { .build().openPanel(); return true; } + + @Override + public Optional> tabComplete(User user, String alias, List args) { + String active = ChatColor.stripColor(user.getTranslation("protection.panel.flag-item.setting-active")); + String disabled = ChatColor.stripColor(user.getTranslation("protection.panel.flag-item.setting-disabled")); + List options = new ArrayList<>(); + String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; + if (args.size() == 2) { + // Player names or world settings + options = Util.tabLimit(Util.getOnlinePlayerList(user), lastArg); + options.addAll(WORLD_SETTING_FLAG_NAMES); + } else if (args.size() == 3) { + // If world settings, then active/disabled, otherwise player flags + if (WORLD_SETTING_FLAG_NAMES.contains(args.get(1).toUpperCase(Locale.ENGLISH))) { + options = Arrays.asList(active, disabled); + } else { + // Flag IDs + options.addAll(PROTECTION_FLAG_NAMES); + options.addAll(SETTING_FLAG_NAMES); + } + } else if (args.size() == 4) { + // Get flag in previous argument + options = getPlugin().getFlagsManager().getFlag(args.get(2).toUpperCase(Locale.ENGLISH)).map(f -> { + switch (f.getType()) { + case PROTECTION: + return getPlugin().getRanksManager() + .getRanks().entrySet().stream() + .filter(en -> en.getValue() > RanksManager.BANNED_RANK && en.getValue() <= RanksManager.OWNER_RANK) + .map(Entry::getKey) + .map(user::getTranslation).collect(Collectors.toList()); + case SETTING: + return Arrays.asList(active, disabled); + default: + return Collections.emptyList(); + + } + }).orElse(Collections.emptyList()); + } + return Optional.of(Util.tabLimit(options, lastArg)); + + } } diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index d726abba8..a07be2d8a 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -273,8 +273,9 @@ commands: success: "&a Successfully set this location as the spawn point for this island." island-spawnpoint-changed: "&a [user] changed this island spawn point." settings: - parameters: "[player]" - description: "open system settings or island settings for player" + parameters: "[player]/[world flag] [flag/active/disable] [rank/active/disable]" + description: "open settings GUI or set settings" + unknown-setting: "&c Unknown setting" blueprint: parameters: "" description: "manipulate blueprints"