summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2015-11-25 18:03:36 +0100
committerDico200 <dico.karssiens@gmail.com>2015-11-25 18:03:36 +0100
commit3bc7963a7a0a000fd5ae365bb5fabc59d22b189f (patch)
treeb3793fb5a719685716d683f9e15ed09c1315dff6
parent37d425bb6549b7070cce047069de3bc1db6b7572 (diff)
wrapper_player progress
-rw-r--r--wrapper_command.py270
1 files changed, 180 insertions, 90 deletions
diff --git a/wrapper_command.py b/wrapper_command.py
index 90eaf01..b2190ac 100644
--- a/wrapper_command.py
+++ b/wrapper_command.py
@@ -3,57 +3,56 @@ from helpers import *
root_commands = Command_dict() # {"command": command_object}
-def check_arguments(command, arguments):
- prev_required = True
- type_message_seen = False
- prev_arg = arguments[0] if len(arguments) > 0 else None
- for arg_info in arguments[1:]:
-
- if not prev_arg.required and arg_info.required:
- raise Argument_exception("Command: %s; There may not be required arguments after non-required arguments" % command)
-
- if prev_arg.type == Argument.MESSAGE:
- raise Argument_exception("Command: %s; An argument of type MESSAGE may not be followed by other arguments" % command)
-
- prev_arg = arg_info
-
-#--------------------------------------------------------------------------------------
-
-class Command_dict(dict):
- #{"cmd1" : cmd_object}
- def get_command_object(self, alias):
- for cmd_name, cmd_obj in self.iteritems():
- if alias == cmd_name or alias in cmd_obj.aliases:
- return cmd_obj
- raise KeyError("Subcommand '%s' was not found" % alias)
+class Command(object):
+ """
+ # Documentation to come.s
+ """
-#--------------------------------------------------------------------------------------
+ SENDER_ANY = 0
+ SENDER_PLAYER = 1
+ SENDER_CONSOLE = 2
-class Command(object):
+ ACTION_IGNORE = 3
+ ACTION_SYNTAXERROR = 4
+ ACTION_DISPLAYSYNTAX = 5
+ ACTION_DISPLAYHELP = 6
- def __init__(self,
+ def __init__(self,
command,
aliases = (),
- arguments = (
- Argument("target", Argument.string, "the player to teleport to"),
- Argument("second target", Argument.string, "the player to teleport", False),
- ),
- parent = None):
+ permission = None,
+ description = "Description",
+ type = Command.SENDER_ANY
+ no_arg_action = Command.ACTION_IGNORE
+ help_request_action = Command.ACTION_IGNORE
+ arguments = (),
+ parent = None,
+ ):
self.command = command.lower()
+ self.aliases = tuple(alias.lower() for alias in aliases)
+ self.permission = self.command if permission == None else permission
+ self.description = description
+ self.type = type
+ self.no_arg_action = no_arg_action
+ self.help_request_action = help_request_action
self.arguments = arguments
+ self.parent = parent
+ self.sub_commands = Command_dict()
- check_arguments(self.command, self.arguments)
+ # ---- Check if argument layout is valid ----
+ prev_arg = arguments[0] if len(arguments) > 0 else None
+ for arg_info in arguments[1:]:
- prev_required = True
- for arg_info in self.arguments:
- if not prev_required and arg_info.required:
- raise Argument_exception("Command: %s; There may not be required arguments after non-required arguments" % self.command)
+ if not prev_arg.required and arg_info.required:
+ raise Argument_exception("Command: %s; There may not be required arguments after non-required arguments" % command)
- self.aliases = tuple(alias.lower() for alias in aliases)
- self.parent = parent
- self.sub_commands = Command_dict()
+ if prev_arg.type == Argument.MESSAGE:
+ raise Argument_exception("Command: %s; An argument of type MESSAGE may not be followed by other arguments" % command)
+ prev_arg = arg_info
+
+ # ---- Add self to parent sub_commands ----
if self.parent == None:
root_commands[self.command] = self
else:
@@ -62,19 +61,29 @@ class Command(object):
parent_sub_commands = root_commands
parent_obj = None
for cmd_name in parent_route:
- parent_obj = parent_sub_commands.get_command_object(cmd_name)
+ parent_obj = parent_sub_commands[cmd_name]
parent_sub_commands = parent_obj.sub_commands
+
parent_obj.sub_commands[self.command] = self
- except command_exception, e:
- error("Error occurred while setting up command hierarchy. " + e.message + "\n" + trace())
+ except KeyError as e:
+ error("Error occurred while setting up command hierarchy: " + e.message + "\n" + trace())
def __call__(self, handler):
+ """
+ # To clarify: This function is called when you 'call' an instance of a class.
+ # This means, that Command() calls __init__() and Command()() calls __call__().
+ # This makes it possible to use class instances for decoration. The decorator is this function.
+ """
self.handler = handler
if parent == None:
@hook.command(self.command, self.aliases)
def run(sender, command, label, args):
+ """
+ # This function will take care of prefixing and colouring of messages in the future.
+ # So it's very much WIP.
+ """
try:
message = self.execute(sender, command, label, args)
except Command_exception as e:
@@ -90,30 +99,154 @@ class Command(object):
def execute(self, sender, command, label, args):
try:
- return self.sub_commands.get_command_object(args[0].lower()).execute(sender, command, label, args[1:])
+ return self.sub_commands[args[0].lower()].execute(sender, command, label, args[1:])
except (KeyError, IndexError):
self.execute_checks(sender, command, label, args)
def execute_checks(self, sender, command, label, args):
- #TODO
- scape = Command_scape(args, self.arguments)
+ # ---- Check sender type ----
+ Validate.is_true(self.type != Command.SENDER_CONSOLE, "That command can only be used by the console")
+ else:
+ Validate.is_true(self.type != Command.SENDER_PLAYER, "That command can only be used by players")
+
+ # ---- Check permission ----
+ Validate.is_authorized(sender, self.permission)
+
+ # ---- Check if a help message is expected ----
+ if len(args) == 0:
+ action = self.no_arg_action
+ elif args[0].lower() == "help":
+ action = self.help_request_action
+ else:
+ action = Command.ACTION_IGNORE
+
+ if action != Command.ACTION_IGNORE:
+ if action == Command.ACTION_SYNTAXERROR:
+ return "&cInvalid syntax, please try again."
+ if action == Command.ACTION_DISPLAYSYNTAX:
+ return self.syntax()
+ if action == Command.ACTION_DISPLAYHELP:
+ return self.help()
+
+ # ---- Set up passed arguments, prepare for handler call ----
+ if is_player(sender):
+ sender = py_players[sender]
+ scape = Command_scape(args, self.arguments, command, label)
if is_player(sender):
sender = py_players[sender]
return self.handler(sender, self, scape)
+ # @Command("hello") def on_hello_command(sender, command, scape/args)
def syntax(self):
return " ".join(tuple(arg_info.syntax() for arg_info in self.arguments))
-#--------------------------------------------------------------------------------------
+ def help(self):
+ syntax = self.syntax()
+ return syntax #WIP...
+
+class Argument():
+
+ """
+ # A more advanced implementation of amin and amax, though it doesn't do exactly the same.
+ # You can now pass a list of Argument objects which define what the argument represents.
+ # In the process of doing so, you can set an argument type, one of the ones mentioned below.
+ # For example, if Argument.PLAYER is given, the server will be searched for the given player, and
+ # they will be passed as the argument, instead of a string representing their name.
+ #
+ # Feel free to add your own argument types. If you want to make a change to the API to make it different,
+ # please don't do so on your own behalf.
+ """
+
+ STRING = 0
+ INTEGER = 1
+ FLOAT = 2
+ PLAYER = 3
+ OFFLINE_PLAYER = 4
+ MESSAGE = 5
+
+ def __init__(self, name, type, definition, required = True):
+ self.name = name
+ self.type = type
+ self.definition = definition
+ self.required = required
+
+ def syntax(self):
+ syntax = self.name
+ if self.type == Argument.MESSAGE:
+ syntax += "..."
+ return (("<%s>" if self.required else "[%s]") % syntax)
+
+class Validate():
+
+ """
+ # Much like what you often see in Java.
+ # Instead of having to check if a condition is met, and if not,
+ # sending the player a message and returning true,
+ # You can use one of these methods to check the condition, and
+ # pass a message if it's not met.
+ #
+ # For example:
+ # > if not sender.hasPermission("utils.smth"):
+ # noperm(sender)
+ # return True
+ #
+ # Can be replaced with:
+ # > Validate.is_authorized(sender, "utils.smth")
+ #
+ """
+
+ @staticmethod
+ def is_true(expression, fail_message):
+ if not expression:
+ raise Command_exception(fail_message)
+
+ @staticmethod
+ def not_none(obj, fail_message):
+ if obj == None:
+ raise Command_exception(fail_message)
+
+ @staticmethod
+ def is_authorized(player, permission, msg = "You do not have permission to use that command"):
+ if not player.hasPermission(permission):
+ raise Command_exception(msg)
+
+ @staticmethod
+ def is_player(sender):
+ if not is_player(sender):
+ raise Command_exception("That command can only be used by players")
+
+ @staticmethod
+ def is_console(sender):
+ if is_player(sender):
+ raise Command_exception("That command can only be used by the console")
+
+"""
+ # ---------- API classes ----------
+"""
+
+class Command_dict(dict):
+ #{"cmd1" : cmd_object}
+ def __getattr__(self, alias):
+ for cmd_name, cmd_obj in self.iteritems():
+ if alias == cmd_name or alias in cmd_obj.aliases:
+ return cmd_obj
+ raise KeyError("Subcommand '%s' was not found" % alias)
+
+class Command_exception(Exception):
+
+ def __init__(self, message):
+ self.message = message
class Command_scape(list):
- def __init__(self, args, arg_layout):
+ def __init__(self, args, arg_layout, command, label):
super(list, self).__init__()
self.raw = args
self.arg_layout = arg_layout
+ self.command = command
+ self.label = label
has_message = False
for i in range(len(arg_layout)):
@@ -182,51 +315,8 @@ class Command_scape(list):
def get_arg_layout(self):
return self.arg_layout
-#--------------------------------------------------------------------------------------
-
-class Command_exception(Exception):
-
- def __init__(self, message):
- self.message = message
-
class Argument_exception(Exception):
def __init__(self, message):
self.message = message
-#--------------------------------------------------------------------------------------
-
-class Argument():
-
- STRING = 0
- INTEGER = 1
- FLOAT = 2
- PLAYER = 3
- OFFLINE_PLAYER = 4
- MESSAGE = 5
-
- def __init__(self, name, type, definition, required = True):
- self.name = name
- self.type = type
- self.definition = definition
- self.required = required
-
- def syntax(self):
- syntax = self.name
- if self.type == Argument.MESSAGE:
- syntax += "..."
- return (("<%s>" if self.required else "[%s]") % syntax)
-
-#--------------------------------------------------------------------------------------
-
-class Validate():
-
- @staticmethod
- def is_true(expression, fail_message):
- if not expression:
- raise Command_exception(fail_message)
-
- @staticmethod
- def not_none(obj, fail_message):
- if obj == None:
- raise Command_exception(fail_message)