Package com.forgeessentials.permissions.commands

Source Code of com.forgeessentials.permissions.commands.PermissionCommandParser

package com.forgeessentials.permissions.commands;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;

import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.permissions.PermissionContext;
import net.minecraftforge.permissions.PermissionsManager;

import org.apache.commons.lang3.StringUtils;

import com.forgeessentials.api.APIRegistry;
import com.forgeessentials.api.permissions.FEPermissions;
import com.forgeessentials.api.permissions.IPermissionsHelper;
import com.forgeessentials.api.permissions.Zone;
import com.forgeessentials.permissions.ModulePermissions;
import com.forgeessentials.util.OutputHandler;
import com.forgeessentials.util.UserIdent;
import com.forgeessentials.util.selections.WorldPoint;

@SuppressWarnings("unchecked")
public class PermissionCommandParser {

    public static final String PERM = "fe.perm";
    public static final String PERM_ALL = PERM + ".*";
    public static final String PERM_TEST = PERM + ".test";
    public static final String PERM_RELOAD = PERM + ".reload";
    public static final String PERM_SAVE = PERM + ".save";

    public static final String PERM_USER = PERM + ".user";
    public static final String PERM_USER_PERMS = PERM_USER + ".perms";
    public static final String PERM_USER_SPAWN = PERM_USER + ".spawn";
    public static final String PERM_USER_FIX = PERM_USER + ".fix";

    public static final String PERM_GROUP = PERM + ".group";
    public static final String PERM_GROUP_PERMS = PERM_GROUP + ".perms";
    public static final String PERM_GROUP_SPAWN = PERM_GROUP + ".spawn";
    public static final String PERM_GROUP_FIX = PERM_GROUP + ".fix";

    private static final String PERM_LIST = PERM + ".list";
    public static final String PERM_LIST_PERMS = PERM_LIST + ".perms";
    public static final String PERM_LIST_ZONES = PERM_LIST + ".zones";
    public static final String PERM_LIST_USERS = PERM_LIST + ".users";
    public static final String PERM_LIST_GROUPS = PERM_LIST + ".groups";

    enum PermissionAction {
        ALLOW, DENY, CLEAR, VALUE
    }

    private ICommandSender sender;
    private EntityPlayerMP senderPlayer;
    private Queue<String> args;
    private boolean tabCompleteMode = false;
    private List<String> tabComplete;

    public PermissionCommandParser(ICommandSender sender, String[] args, boolean tabCompleteMode)
    {
        this.sender = sender;
        this.args = new LinkedList<String>(Arrays.asList(args));
        this.senderPlayer = (sender instanceof EntityPlayerMP) ? (EntityPlayerMP) sender : null;
        this.tabCompleteMode = tabCompleteMode;
        if (tabCompleteMode)
        {
            try
            {
                parseMain();
            }
            catch (Exception e)
            {
            }
        }
        else
        {
            parseMain();
        }
    }

    public List<String> getTabCompleteList()
    {
        return tabComplete;
    }

    private void info(String message)
    {
        if (!tabCompleteMode)
            OutputHandler.chatConfirmation(sender, message);
    }

    private void warn(String message)
    {
        if (!tabCompleteMode)
            OutputHandler.chatWarning(sender, message);
    }

    private void error(String message)
    {
        if (!tabCompleteMode)
            OutputHandler.chatError(sender, message);
    }

    // Variables for auto-complete
    private static final String[] parseMainArgs = { "test", "user", "group", "global", "list", "reload", "save" }; // "export", "promote", "test" };
    private static final String[] parseListArgs = { "zones", "perms", "users", "groups" };
    private static final String[] parseUserArgs = { "zone", "allow", "deny", "clear", "true", "false", "value", "prefix", "suffix", "spawn", "perms", "group" };
    private static final String[] parseGroupArgs = { "zone", "allow", "deny", "clear", "true", "false", "value", "prefix", "suffix", "spawn", "perms",
            "priority", "include" };
    private static final String[] parseUserGroupArgs = { "add", "remove" };
    private static final String[] parseGroupIncludeArgs = { "add", "remove", "clear" };
    private static final String[] parseSpawnArgs = { "here", "clear", "bed" };

    private void parseMain()
    {
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseMainArgs);
            return;
        }
        if (args.isEmpty())
        {
            info("/feperm " + StringUtils.join(parseMainArgs, "|") + ": Displays help for the subcommands");
        }
        else
        {
            switch (args.remove().toLowerCase())
            {
            case "save":
                ModulePermissions.permissionHelper.save();
                info("Permissions saved!");
                break;
            case "reload":
                if (ModulePermissions.permissionHelper.load())
                    info("Successfully reloaded permissions");
                else
                    error("Error while reloading permissions");
                break;
            case "test":
                parseTest();
                break;
            case "list":
                parseList();
                break;
            case "user":
                parseUser();
                break;
            case "group":
                parseGroup();
                break;
            case "global":
                parseGlobal();
                break;
            default:
                error("Unknown command argument");
                break;
            }
        }
    }

    // ------------------------------------------------------------
    // -- Listings
    // ------------------------------------------------------------

    private void parseList()
    {
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseListArgs);
            return;
        }
        if (args.isEmpty())
        {
            info("/feperm list " + StringUtils.join(parseListArgs, "|") + " : List the specified objects");
        }
        else
        {
            String arg = args.remove().toLowerCase();
            switch (arg)
            {
            case "zones":
                listZones();
                break;
            case "perms":
                listPermissions();
                break;
            case "users":
                listUsers();
                break;
            case "groups":
                listGroups();
                break;
            default:
                error("Unknown command argument");
                break;
            }
        }
    }

    private void listZones()
    {
        if (senderPlayer == null)
        {
            error(FEPermissions.MSG_NO_CONSOLE_COMMAND);
            return;
        }
        WorldPoint wp = new WorldPoint(senderPlayer);
        info("Zones at position " + wp.toString());
        for (Zone zone : APIRegistry.perms.getZonesAt(wp))
        {
            info("  #" + zone.getId() + " " + zone.toString());
        }
    }

    private void listPermissions()
    {
        if (senderPlayer == null)
        {
            error(FEPermissions.MSG_NO_CONSOLE_COMMAND);
            return;
        }
        listUserPermissions(new UserIdent(senderPlayer));
    }

    private void listUserPermissions(UserIdent ident)
    {
        if (tabCompleteMode)
            return;

        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_LIST_PERMS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }

        info(ident.getUsernameOrUUID() + " permissions:");

        Map<Zone, Map<String, String>> userPerms = ModulePermissions.permissionHelper.enumUserPermissions(ident);
        for (Entry<Zone, Map<String, String>> zone : userPerms.entrySet())
        {
            boolean printedZone = false;
            for (Entry<String, String> perm : zone.getValue().entrySet())
            {
                if (perm.getKey().startsWith(FEPermissions.GROUP))
                    continue;
                if (!printedZone)
                {
                    warn("Zone #" + zone.getKey().getId() + " " + zone.getKey().toString());
                    printedZone = true;
                }
                info("  " + perm.getKey() + " = " + perm.getValue());
            }
        }

        for (String group : APIRegistry.perms.getPlayerGroups(ident))
        {
            Map<Zone, Map<String, String>> groupPerms = ModulePermissions.permissionHelper.enumGroupPermissions(group, false);
            if (!groupPerms.isEmpty())
            {
                boolean printedGroup = false;
                for (Entry<Zone, Map<String, String>> zone : groupPerms.entrySet())
                {
                    boolean printedZone = false;
                    for (Entry<String, String> perm : zone.getValue().entrySet())
                    {
                        if (perm.getKey().equals(FEPermissions.GROUP) || perm.getKey().equals(FEPermissions.GROUP_ID)
                                || perm.getKey().equals(FEPermissions.GROUP_PRIORITY) || perm.getKey().equals(FEPermissions.PREFIX)
                                || perm.getKey().equals(FEPermissions.SUFFIX))
                            continue;
                        if (!printedGroup)
                        {
                            warn("Group " + group);
                            printedGroup = true;
                        }
                        if (!printedZone)
                        {
                            warn("  Zone #" + zone.getKey().getId() + " " + zone.getKey().toString());
                            printedZone = true;
                        }
                        info("    " + perm.getKey() + " = " + perm.getValue());
                    }
                }
            }
        }
    }

    private void listGroups()
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_LIST_GROUPS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        info("Groups:");
        for (String group : APIRegistry.perms.getServerZone().getGroups())
        {
            info(" - " + group);
        }
    }

    private void listUsers()
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_LIST_USERS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        info("Known players:");
        for (UserIdent ident : APIRegistry.perms.getServerZone().getKnownPlayers())
        {
            info(" - " + ident.getUsernameOrUUID());
        }
        info("Online players:");
        for (Object player : MinecraftServer.getServer().getConfigurationManager().playerEntityList)
        {
            if (player instanceof EntityPlayerMP)
                info(" - " + ((EntityPlayerMP) player).getCommandSenderName());
        }
    }

    private void parseTest()
    {
        if (args.isEmpty())
        {
            error("Missing permission argument!");
            return;
        }
        if (senderPlayer == null)
        {
            error(FEPermissions.MSG_NO_CONSOLE_COMMAND);
            return;
        }
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_TEST))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (tabCompleteMode)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseUserArgs);
            for (Zone zone : APIRegistry.perms.getZones())
            {
                if (CommandBase.doesStringStartWith(args.peek(), zone.getName()))
                    tabComplete.add(zone.getName());
            }
            for (String perm : ModulePermissions.permissionHelper.enumRegisteredPermissions())
            {
                if (CommandBase.doesStringStartWith(args.peek(), perm))
                    tabComplete.add(perm);
            }
            return;
        }

        String permissionNode = args.remove();
        String result = APIRegistry.perms.getPermissionProperty(senderPlayer, permissionNode);
        if (result == null)
        {
            error("Permission does not exist");
        }
        else
        {
            info(permissionNode + " = " + result);
        }
    }

    // ------------------------------------------------------------
    // -- User
    // ------------------------------------------------------------

    private void parseUser()
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_USER))
        {
            error(FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            info("Possible usage:");
            info("/p user <player> : Display user info");
            info("/p user <player> zone <zone> ... : Work with zones");
            info("/p user <player> perms : List player's permissions");
            info("/p user <player> group add|remove <group>: Player's group settings");
            info("/p user <player> allow|deny|clear <perms> : Set permissions");
            info("/p user <player> value <perm> <value> : Set permission property");
            info("/p user <player> spawn : Set player spawn");
            return;
        }

        // Auto-complete player name
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = new ArrayList<String>();
            for (UserIdent knownPlayerIdent : APIRegistry.perms.getServerZone().getKnownPlayers())
            {
                if (CommandBase.doesStringStartWith(args.peek(), knownPlayerIdent.getUsernameOrUUID()))
                    tabComplete.add(knownPlayerIdent.getUsernameOrUUID());
            }
            for (EntityPlayerMP player : (List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
            {
                if (CommandBase.doesStringStartWith(args.peek(), player.getGameProfile().getName()))
                    tabComplete.add(player.getGameProfile().getName());
            }
            return;
        }

        String playerName = args.remove();
        UserIdent ident;
        if (playerName.equalsIgnoreCase("_ME_"))
        {
            if (senderPlayer == null)
            {
                error("_ME_ cannot be used in console.");
                return;
            }
            ident = new UserIdent(senderPlayer);
        }
        else
        {
            ident = new UserIdent(playerName);
            if (!ident.hasUUID())
            {
                error(String.format("Player %s not found. playername will be used, but may be inaccurate.", ident.getUsername()));
            }
        }

        parseUserInner(ident, null);
    }

    private void parseUserInner(UserIdent ident, Zone zone)
    {
        // Display help or player info
        if (args.isEmpty())
        {
            if (zone == null)
            {
                info(String.format("Groups for player %s:", ident.getUsernameOrUUID()));
                for (String group : APIRegistry.perms.getPlayerGroups(ident))
                {
                    info("  " + group);
                }
            }
            else
            {
                info("Possible usage:");
                info("/p ... group add|remove <group>: Player's group settings");
                info("/p ... allow|deny|clear <perms> : Set permissions");
                info("/p ... value <perm> <value> : Set permission property");
                info("/p ... spawn : Set player spawn");
            }
            return;
        }

        // TAB-complete command
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseUserArgs);
            if (zone != null)
                tabComplete.remove("zone");
            return;
        }

        String cmd = args.remove().toLowerCase();

        if (cmd.equals("zone"))
        {
            if (zone != null)
            {
                error(String.format("Zone already set!"));
                return;
            }
            if (args.isEmpty())
            {
                error(String.format("Expected zone identifier."));
                return;
            }
            String zoneId = args.remove();
            try
            {
                int intId = Integer.parseInt(zoneId);
                if (intId < 1)
                {
                    error(String.format("Zone ID must be greater than 0!"));
                    return;
                }
                zone = APIRegistry.perms.getZoneById(intId);
                if (zone == null)
                {
                    error(String.format("No zone by the ID %s exists!", zoneId));
                    return;
                }
            }
            catch (NumberFormatException e)
            {
                if (senderPlayer == null)
                {
                    error("Cannot identify zones by name from console!");
                    return;
                }
                zone = APIRegistry.perms.getWorldZone(senderPlayer.dimension).getAreaZone(zoneId);
                if (zone == null)
                {
                    error(String.format("No zone by the name %s exists!", zoneId));
                    return;
                }
            }
            parseUserInner(ident, zone);
            return;
        }

        // Set default zone
        if (zone == null)
            zone = APIRegistry.perms.getServerZone();

        // Parse command
        switch (cmd)
        {
        case "group":
            parseUserGroup(ident);
            break;
        case "perms":
            listUserPermissions(ident);
            break;
        case "prefix":
            parseUserPrefixSuffix(ident, zone, false);
            break;
        case "suffix":
            parseUserPrefixSuffix(ident, zone, true);
            break;
        case "spawn":
            parseUserSpawn(ident, zone);
            break;
        case "true":
        case "allow":
            parseUserPermissions(ident, zone, PermissionAction.ALLOW);
            break;
        case "false":
        case "deny":
            parseUserPermissions(ident, zone, PermissionAction.DENY);
            break;
        case "clear":
            parseUserPermissions(ident, zone, PermissionAction.CLEAR);
            break;
        case "value":
            parseUserPermissions(ident, zone, PermissionAction.VALUE);
            break;
        default:
            break;
        }
    }

    private void parseUserPrefixSuffix(UserIdent ident, Zone zone, boolean isSuffix)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_USER_FIX))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (tabCompleteMode)
            return;
        String fixName = isSuffix ? "suffix" : "prefix";
        if (args.isEmpty())
        {
            String fix = zone.getPlayerPermission(ident, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX);
            if (fix == null || fix.isEmpty())
                fix = "empty";
            info(String.format("%s's %s is %s", ident.getUsernameOrUUID(), fixName, fix));
        }
        else
        {
            String fix = args.remove();
            if (fix.equalsIgnoreCase("clear"))
            {
                info(String.format("%s's %s cleared", ident.getUsernameOrUUID(), fixName));
                zone.clearPlayerPermission(ident, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX);
            }
            else
            {
                info(String.format("%s's %s set to %s", ident.getUsernameOrUUID(), fixName, fix));
                zone.setPlayerPermissionProperty(ident, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX, fix);
            }
        }
    }

    private void parseUserPermissions(UserIdent ident, Zone zone, PermissionAction type)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_USER_PERMS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            error("Missing permission argument!");
            return;
        }
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = completePermission(args.peek());
            return;
        }

        // Apply permissions
        while (!args.isEmpty())
        {
            String permissionNode = args.remove();
            String msg = null, value = null;
            if (type == PermissionAction.VALUE)
            {
                if (args.isEmpty())
                {
                    error("Need to specify value");
                    return;
                }
                value = StringUtils.join(args, ' ');
                args.clear();
            }
            switch (type)
            {
            case ALLOW:
                zone.setPlayerPermission(ident, permissionNode, true);
                msg = "Allowed %s access to %s in zone %s";
                break;
            case DENY:
                zone.setPlayerPermission(ident, permissionNode, false);
                msg = "Denied %s access to %s in zone %s";
                break;
            case CLEAR:
                zone.clearPlayerPermission(ident, permissionNode);
                msg = "Cleared %s's acces to %s in zone %s";
                break;
            case VALUE:
                zone.setPlayerPermissionProperty(ident, permissionNode, value);
                info(String.format("Set %s for %s to %s in zone %s", permissionNode, ident.getUsernameOrUUID(), value, zone.getName()));
                break;
            }
            if (msg != null)
                info(String.format(msg, ident.getUsernameOrUUID(), permissionNode, zone.getName()));
        }
    }

    private void parseUserSpawn(UserIdent ident, Zone zone)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_USER_SPAWN))
        {
            throw new CommandException(FEPermissions.MSG_NO_COMMAND_PERM);
        }
        if (args.isEmpty())
        {
            info("/feperm user " + ident.getUsernameOrUUID() + " spawn (here|bed|clear|<x> <y> <z> <dim>) [zone] : Set spawn");
            return;
        }
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseSpawnArgs);
            return;
        }

        String loc = args.remove().toLowerCase();
        WorldPoint point = null;
        boolean isBed = false;
        switch (loc)
        {
        case "here":
            point = new WorldPoint(senderPlayer);
            break;
        case "bed":
            isBed = true;
            break;
        case "clear":
            break;
        default:
            if (args.size() < 3)
                throw new CommandException("Too few arguments!");
            try
            {
                int x = CommandBase.parseInt(sender, loc);
                int y = CommandBase.parseInt(sender, args.remove());
                int z = CommandBase.parseInt(sender, args.remove());
                int dimension = CommandBase.parseInt(sender, args.remove());
                point = new WorldPoint(dimension, x, y, z);
            }
            catch (NumberFormatException e)
            {
                error("Invalid location argument");
                return;
            }
            break;
        }

        if (isBed)
        {
            zone.setPlayerPermissionProperty(ident, FEPermissions.SPAWN, "bed");
            info(String.format("Set spawn for user %s to be bed-location in zone %s", ident.getUsernameOrUUID(), zone.getName()));
        }
        else if (point == null)
        {
            zone.clearPlayerPermission(ident, FEPermissions.SPAWN);
            info(String.format("Cleared spawn-rule for user %s in zone %s", ident.getUsernameOrUUID(), zone.getName()));
        }
        else
        {
            zone.setPlayerPermissionProperty(ident, FEPermissions.SPAWN, point.toString());
            info(String.format("Set spawn for user %s to %s in zone %s", ident.getUsernameOrUUID(), point.toString(), zone.getName()));
        }
    }

    private void parseUserGroup(UserIdent ident)
    {
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseUserGroupArgs);
            return;
        }
        if (args.isEmpty())
        {
            info(String.format("Groups for player %s (without includes):", ident.getUsernameOrUUID()));
            for (String g : APIRegistry.perms.getStoredPlayerGroups(ident))
            {
                info("  " + g);
            }
        }
        else
        {
            String mode = args.remove().toLowerCase();
            if (!mode.equals("add") && !mode.equals("remove") && !mode.equals("set"))
            {
                error("Syntax error. Please try this instead:");
                error("/p user <player> group add|set|remove <GROUP>");
                return;
            }

            if (tabCompleteMode && args.size() == 1)
            {
                tabComplete = new ArrayList<String>();
                for (String group : APIRegistry.perms.getServerZone().getGroups())
                {
                    if (CommandBase.doesStringStartWith(args.peek(), group))
                        tabComplete.add(group);
                }
                return;
            }
            if (args.isEmpty())
            {
                error("Usage: /p user <player> group " + mode + " <group-name>");
            }
            else
            {
                String group = args.remove();
                if (!APIRegistry.perms.groupExists(group))
                {
                    error(String.format("Group %s not found.", group));
                    return;
                }
                switch (mode)
                {
                case "add":
                    APIRegistry.perms.addPlayerToGroup(ident, group);
                    info(String.format("Player %s added to group %s", ident.getUsernameOrUUID(), group));
                    break;
                case "remove":
                    APIRegistry.perms.removePlayerFromGroup(ident, group);
                    info(String.format("Player %s removed from group %s", ident.getUsernameOrUUID(), group));
                    break;
                case "set":
                    for (String g : APIRegistry.perms.getStoredPlayerGroups(ident))
                    {
                        APIRegistry.perms.removePlayerFromGroup(ident, g);
                    }
                    APIRegistry.perms.addPlayerToGroup(ident, group);
                    info(String.format("Set %s's group to %s", ident.getUsernameOrUUID(), group));
                    break;
                }
            }
        }
    }

    // ------------------------------------------------------------
    // -- Group
    // ------------------------------------------------------------

    private void parseGroup()
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            info("Possible usage:");
            info("/p group <group> : Display group info");
            info("/p group <group> zone <zone> ... : Work with zones");
            info("/p group <group> create : Create a new group");
            info("/p group <group> perms : List group's permissions");
            info("/p group <group> allow|deny|clear <perms> : Set permissions");
            info("/p group <group> value <perm> <value> : Set permission property");
            info("/p group <group> spawn : Set group spawn");
            return;
        }

        // Auto-complete group name
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = new ArrayList<String>();
            for (String group : APIRegistry.perms.getServerZone().getGroups())
            {
                if (CommandBase.doesStringStartWith(args.peek(), group))
                    tabComplete.add(group);
            }
            return;
        }

        String group = args.remove();
        if (!APIRegistry.perms.groupExists(group))
        {
            if (tabCompleteMode && args.size() == 1)
            {
                tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, "create");
                return;
            }
            if (args.isEmpty())
            {
                info(String.format("Group %s does not exist", group));
            }
            else
            {
                String groupArg = args.remove();
                if (groupArg.equalsIgnoreCase("create"))
                {
                    APIRegistry.perms.createGroup(group);
                    info(String.format("Created group %s", group));
                }
                else
                {
                    error(String.format("Group %s does not exist", group));
                }
            }
            return;
        }

        parseGroupInner(group, null);
    }

    private void parseGlobal()
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            info("Possible usage:");
            info("/p global : Display global-group info");
            info("/p global zone <zone> ... : Work with zones");
            info("/p global perms : List global permissions");
            info("/p global allow|deny|clear <perms> : Set permissions");
            info("/p global value <perm> <value> : Set permission property");
            info("/p global spawn : Set global spawn");
            return;
        }

        parseGroupInner(IPermissionsHelper.GROUP_DEFAULT, null);
    }

    private void parseGroupInner(String group, Zone zone)
    {
        // Display help or player info
        if (args.isEmpty())
        {
            if (zone == null)
            {
                info("Group " + group + ":");
                // info("  ID    : " + group.getId());
                // info("  prio  : " + group.getPriority());
                // info("  prefix: " + group.getPrefix());
                // info("  suffix: " + group.getSuffix());
            }
            else
            {
                info("Possible usage:");
                if (!APIRegistry.perms.isSystemGroup(group))
                    info("/p ... group add|remove <group>: Player's group settings");
                info("/p ... allow|deny|clear <perms> : Set permissions");
                info("/p ... value <perm> <value> : Set permission property");
                info("/p ... spawn : Set player spawn");
            }
            return;
        }

        // TAB-complete command
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseGroupArgs);
            if (zone != null)
                tabComplete.remove("zone");
            return;
        }

        String cmd = args.remove().toLowerCase();

        if (cmd.equals("zone"))
        {
            if (zone != null)
            {
                error(String.format("Zone already set!"));
                return;
            }
            if (args.isEmpty())
            {
                error(String.format("Expected zone identifier."));
                return;
            }
            if (tabCompleteMode && args.size() == 1)
            {
                tabComplete = new ArrayList<>();
                for (Zone z : APIRegistry.perms.getZones())
                {
                    if (CommandBase.doesStringStartWith(args.peek(), z.getName()))
                        tabComplete.add(z.getName());
                }
                return;
            }
            String zoneId = args.remove();
            try
            {
                int intId = Integer.parseInt(zoneId);
                if (intId < 1)
                {
                    error(String.format("Zone ID must be greater than 0!"));
                    return;
                }
                zone = APIRegistry.perms.getZoneById(intId);
                if (zone == null)
                {
                    error(String.format("No zone by the ID %s exists!", zoneId));
                    return;
                }
            }
            catch (NumberFormatException e)
            {
                if (senderPlayer == null)
                {
                    error("Cannot identify zones by name from console!");
                    return;
                }
                zone = APIRegistry.perms.getWorldZone(senderPlayer.dimension).getAreaZone(zoneId);
                if (zone == null)
                {
                    error(String.format("No zone by the name %s exists!", zoneId));
                    return;
                }
            }
            parseGroupInner(group, zone);
            return;
        }

        // Set default zone
        if (zone == null)
            zone = APIRegistry.perms.getServerZone();

        switch (cmd)
        {
        // case "users":
        // listGroupUsers(group);
        // break;
        // case "perms":
        // listGroupPermissions(group);
        // break;
        case "prefix":
            parseGroupPrefixSuffix(group, zone, false);
            break;
        case "suffix":
            parseGroupPrefixSuffix(group, zone, true);
            break;
        case "spawn":
            parseGroupSpawn(group, zone);
            break;
        case "priority":
            parseGroupPriority(group);
            break;
        case "include":
            parseGroupInclude(group);
            break;
        case "true":
        case "allow":
            parseGroupPermissions(group, zone, PermissionAction.ALLOW);
            break;
        case "false":
        case "deny":
            parseGroupPermissions(group, zone, PermissionAction.DENY);
            break;
        case "clear":
            parseGroupPermissions(group, zone, PermissionAction.CLEAR);
            break;
        case "value":
            parseGroupPermissions(group, zone, PermissionAction.VALUE);
            break;
        default:
            break;
        }
    }

    private void parseGroupPrefixSuffix(String group, Zone zone, boolean isSuffix)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP_FIX))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (tabCompleteMode)
            return;
        String fixName = isSuffix ? "suffix" : "prefix";
        if (args.isEmpty())
        {
            String fix = APIRegistry.perms.getServerZone().getGroupPermission(group, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX);
            if (fix == null || fix.isEmpty())
                fix = "empty";
            info(String.format("%s's %s is %s", group, fixName, fix));
        }
        else
        {
            String fix = args.remove();
            if (fix.equalsIgnoreCase("clear"))
            {
                info(String.format("%s's %s cleared", group, fixName));
                APIRegistry.perms.getServerZone().clearGroupPermission(group, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX);
            }
            else
            {
                info(String.format("%s's %s set to %s", group, fixName, fix));
                APIRegistry.perms.getServerZone().setGroupPermissionProperty(group, isSuffix ? FEPermissions.SUFFIX : FEPermissions.PREFIX, fix);
            }
        }
    }

    private void parseGroupPermissions(String group, Zone zone, PermissionAction type)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP_PERMS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            error("Missing permission argument!");
            return;
        }
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = completePermission(args.peek());
            return;
        }

        // Apply permissions
        while (!args.isEmpty())
        {
            String permissionNode = args.remove();
            String msg = null, value = null;
            if (type == PermissionAction.VALUE)
            {
                if (args.isEmpty())
                {
                    error("Need to specify value");
                    return;
                }
                value = StringUtils.join(args, ' ');
                args.clear();
            }
            switch (type)
            {
            case ALLOW:
                zone.setGroupPermission(group, permissionNode, true);
                msg = "Allowed %s access to %s in zone %s";
                break;
            case DENY:
                zone.setGroupPermission(group, permissionNode, false);
                msg = "Denied %s access to %s in zone %s";
                break;
            case CLEAR:
                zone.clearGroupPermission(group, permissionNode);
                msg = "Cleared %s's acces to %s in zone %s";
                break;
            case VALUE:
                zone.setGroupPermissionProperty(group, permissionNode, value);
                info(String.format("Set %s for group %s to %s in zone %s", permissionNode, group, value, zone.getName()));
                break;
            }
            if (msg != null)
                info(String.format(msg, group, permissionNode, zone.getName()));
        }
    }

    private void parseGroupSpawn(String group, Zone zone)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP_SPAWN))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            info("/feperm group " + group + " spawn (here|bed|clear|<x> <y> <z> <dim>) [zone] : Set spawn");
            return;
        }
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseSpawnArgs);
            return;
        }

        String loc = args.remove().toLowerCase();
        WorldPoint point = null;
        boolean isBed = false;
        switch (loc)
        {
        case "here":
            point = new WorldPoint(senderPlayer);
            break;
        case "bed":
            isBed = true;
            break;
        case "clear":
            break;
        default:
            if (args.size() < 3)
                throw new CommandException("Too few arguments!");
            try
            {
                int x = CommandBase.parseInt(sender, loc);
                int y = CommandBase.parseInt(sender, args.remove());
                int z = CommandBase.parseInt(sender, args.remove());
                int dimension = CommandBase.parseInt(sender, args.remove());
                point = new WorldPoint(dimension, x, y, z);
            }
            catch (NumberFormatException e)
            {
                error("Invalid location argument");
                return;
            }
            break;
        }

        if (isBed)
        {
            zone.setGroupPermissionProperty(group, FEPermissions.SPAWN, "bed");
            info(String.format("Set spawn for group %s to be bed-location in zone %s", group, zone.getName()));
        }
        else if (point == null)
        {
            zone.clearGroupPermission(group, FEPermissions.SPAWN);
            info(String.format("Cleared spawn-rule for group %s in zone %s", group, zone.getName()));
        }
        else
        {
            zone.setGroupPermissionProperty(group, FEPermissions.SPAWN, point.toString());
            info(String.format("Set spawn for group %s to %s in zone %s", group, point.toString(), zone.getName()));
        }
    }

    private void parseGroupPriority(String group)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP_PERMS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }
        if (args.isEmpty())
        {
            info("/feperm group " + group + " priority <prio> : Set group priority");
        }
        String priorityValue = args.remove();
        try
        {
            APIRegistry.perms.setGroupPermissionProperty(group, FEPermissions.GROUP_PRIORITY, Integer.toString(Integer.parseInt(priorityValue)));
            info(String.format("Set priority for group %s to %s", group, priorityValue));
        }
        catch (NumberFormatException e)
        {
            error(String.format("The string %s is not a valid integer", priorityValue));
        }
    }

    private void parseGroupInclude(String group)
    {
        if (!tabCompleteMode && !PermissionsManager.checkPermission(new PermissionContext().setCommandSender(sender), PERM_GROUP_PERMS))
        {
            OutputHandler.chatError(sender, FEPermissions.MSG_NO_COMMAND_PERM);
            return;
        }

        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = CommandBase.getListOfStringsMatchingLastWord(new String[] { args.peek() }, parseGroupIncludeArgs);
            return;
        }

        // Get included groups
        String includedGroupsStr = APIRegistry.perms.getGroupPermissionProperty(group, FEPermissions.GROUP_INCLUDES);
        Set<String> includedGroups = new HashSet<String>();
        if (includedGroupsStr != null)
            for (String includedGroup : includedGroupsStr.split(","))
                if (!includedGroup.isEmpty())
                    includedGroups.add(includedGroup);

        if (args.isEmpty())
        {
            info("/feperm group " + group + " include add|remove <group>");
            info("/feperm group " + group + " include clear");
            info(String.format("Included groups for %s:", group));
            for (String includedGroup : includedGroups)
                info("  " + includedGroup);
            return;
        }

        String cmd = args.remove().toLowerCase();
        if (cmd.equals("clear"))
        {
            APIRegistry.perms.getServerZone().clearGroupPermission(group, FEPermissions.GROUP_INCLUDES);
            info(String.format("Cleared group-includes for group %s", group));
            return;
        }

        if (args.isEmpty())
        {
            error(FEPermissions.MSG_INVALID_SYNTAX);
            return;
        }

        // Auto-complete group name
        if (tabCompleteMode && args.size() == 1)
        {
            tabComplete = new ArrayList<String>();
            for (String g : APIRegistry.perms.getServerZone().getGroups())
            {
                if (CommandBase.doesStringStartWith(args.peek(), g))
                    tabComplete.add(g);
            }
            return;
        }

        String includeGroup = args.remove();

        switch (cmd)
        {
        case "add":
            includedGroups.add(includeGroup);
            info(String.format("Added group-include of %s to group %s", includeGroup, group));
            break;
        case "remove":
            includedGroups.remove(includeGroup);
            info(String.format("Removed group-include of %s to group %s", includeGroup, group));
            break;
        default:
            error(FEPermissions.MSG_INVALID_SYNTAX);
            return;
        }

        APIRegistry.perms.setGroupPermissionProperty(group, FEPermissions.GROUP_INCLUDES, StringUtils.join(includedGroups, ","));
    }

    // ------------------------------------------------------------
    // -- Utils
    // ------------------------------------------------------------

    private static List<String> completePermission(String permission)
    {
        Set<String> perms = new HashSet<String>();
        for (String perm : ModulePermissions.permissionHelper.enumRegisteredPermissions())
        {
            int nodeIndex = perm.indexOf('.', permission.length());
            if (nodeIndex >= 0)
                perm = perm.substring(0, nodeIndex);
            if (CommandBase.doesStringStartWith(permission, perm))
                perms.add(perm);
        }

        return new ArrayList<String>(perms);
    }

}
TOP

Related Classes of com.forgeessentials.permissions.commands.PermissionCommandParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.