summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2015-11-25 01:15:44 +0100
committerDico200 <dico.karssiens@gmail.com>2015-11-25 01:15:44 +0100
commit522a7a99a115b2c32e8edd00fe47d1b288d6b006 (patch)
tree96e7ecce13318d035e95fb776e01393317713858
parent4d5861fd3648e969b6a5dc6b210a81eccda2636c (diff)
wrapper_command WIP
-rw-r--r--serversigns.py53
-rw-r--r--vanish.py53
-rw-r--r--wrapper_command.py237
-rw-r--r--wrapper_player.py3
4 files changed, 290 insertions, 56 deletions
diff --git a/serversigns.py b/serversigns.py
index 297b727..f8f9db5 100644
--- a/serversigns.py
+++ b/serversigns.py
@@ -5,6 +5,14 @@ import java.util.UUID as UUID
import org.bukkit.Material as Material
import org.bukkit.block.BlockFace as BlockFace
+"""
+ # About permissions:
+ # To use the command, the user needs to have utils.serversigns.
+ # To use ANY subcommand, the user needs to have utils.serversigns.<subcommand> IN ADDITION to the previously mentioned node.
+ # To be able to add commands as messages to a sign, a user will need the node utils.serversigns.command.
+ # To be able to claim a sign for another player or to edit signs that the user doesn't own, they will need utils.serversigns.admin.
+"""
+
blocked_cmds = ("pex", "kick", "ban", "tempban", "pyeval", "sudo", "stop", "reload", "op", "deop", "whitelist")
def load_signs():
@@ -24,6 +32,18 @@ signs = load_signs() # {("world", x, y, z): ["owner_id", "msg1", "msg2"]}
lines = {} # Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""}
+@hook.enable
+def check_all_signs():
+ # Check if all saved signs actually represent a sign block. There are ways to break the signs without the plugin knowing.
+ for loc in dict(signs): # Can't change dict size during iteration, using a copy
+ world = server.getWorld(loc[0])
+ if world and world.getBlockAt(loc[1], loc[2], loc[3]).getType() in (Material.SIGN_POST, Material.WALL_SIGN):
+ continue
+ del signs[loc]
+ info("[Server Signs] Couldn't find a %s, removed the data for the sign that was once there." % identifySign(loc))
+ save_signs()
+
+
def fromLoc(bLoc):
"""
# Returns a tuple containing the (bukkit)location's world's name and its x, y and z coordinates
@@ -222,9 +242,6 @@ def svs_command(sender, command, label, args):
return signsMsg("Removed all messages and the owner from the %s, it can now be claimed" % signName, 'a')
#-------------------------------------------------------------------------------------------------------
-
-
-
@hook.event("player.PlayerInteractEvent")
def on_click(event):
if str(event.getAction()) != "RIGHT_CLICK_BLOCK":
@@ -254,25 +271,22 @@ faces = {
@hook.event("block.BlockBreakEvent", "monitor")
def on_break(event):
- try:
- global checking_block
- if checking_block or event.isCancelled():
- return
+ global checking_block
+ if checking_block or event.isCancelled():
+ return
- block = event.getBlock()
- if block.getType() in (Material.SIGN_POST, Material.WALL_SIGN):
- check_sign(event, block, attached = False)
+ block = event.getBlock()
+ if block.getType() in (Material.SIGN_POST, Material.WALL_SIGN):
+ check_sign(event, block, attached = False)
- for block_face, data_values in faces.iteritems():
- block2 = block.getRelative(block_face)
- if block2.getType() == Material.WALL_SIGN and block2.getData() in data_values:
- check_sign(event, block2)
+ for block_face, data_values in faces.iteritems():
+ block2 = block.getRelative(block_face)
+ if block2.getType() == Material.WALL_SIGN and block2.getData() in data_values:
+ check_sign(event, block2)
- block3 = block.getRelative(BlockFace.UP)
- if block3.getType() == Material.SIGN_POST:
- check_sign(event, block3)
- except:
- error(trace())
+ block3 = block.getRelative(BlockFace.UP)
+ if block3.getType() == Material.SIGN_POST:
+ check_sign(event, block3)
def check_sign(event, block, attached = True):
@@ -287,6 +301,7 @@ def check_sign(event, block, attached = True):
save_signs()
msg(player, signsMsg("Reset the %s which you just broke" % identifySign(loc)))
+
def can_build2(player, block):
global checking_block
event = BlockBreakEvent(block, player)
diff --git a/vanish.py b/vanish.py
index a572ebc..87a667b 100644
--- a/vanish.py
+++ b/vanish.py
@@ -13,7 +13,7 @@ def is_vanished(player):
return uid(player) in vanished
-#this can be used to silently set the vanished state of a player
+#this can be used to silently set the vanished state of a player I guess.
def set_state(player, state):
if state == is_vanished(player):
return
@@ -37,6 +37,10 @@ def disable_vanish(target):
player.showPlayer(target)
+def get_online_vanished_players():
+ return (player.getPlayer() for player in (retrieve_player(uuid) for uuid in vanished) if player.isOnline())
+
+
@simplecommand("vanish",
aliases = ["v"],
usage = "[on/off]",
@@ -48,45 +52,38 @@ def disable_vanish(target):
helpSubcmd = True
)
def vanish_command(sender, command, label, args):
- try:
- current_state = is_vanished(sender)
- new_state = not current_state
+ current_state = is_vanished(sender)
+ new_state = not current_state
- if len(args) == 1:
- arg = args[0].lower()
- if arg == "on":
- new_state = True
- elif arg == "off":
- new_state = False
-
- if current_state == new_state:
- return "&cYou were %s vanished!" % ("already" if current_state else "not yet")
+ if len(args) == 1:
+ arg = args[0].lower()
+ if arg == "on":
+ new_state = True
+ elif arg == "off":
+ new_state = False
- set_state(sender, new_state)
- return "&a%s vanish mode!" % ("Enabled" if new_state else "Disabled")
- except:
- error(trace())
+ Validate.isTrue(current_state != new_state, "&cYou were %s vanished!" % ("already" if current_state else "not yet"))
+ set_state(sender, new_state)
+ return "&a%s vanish mode!" % ("Enabled" if new_state else "Disabled")
@hook.event("player.PlayerJoinEvent")
def on_player_join(event):
player = event.getPlayer()
-
if not is_authorized(player):
- for uuid in vanished:
- player.hidePlayer(retrieve_player(uuid))
-
- elif is_vanished(player):
- msg(player, "&cKeep in mind that you are still vanished! Use /vanish to disable.")
+ for vanished in get_online_vanished_players():
+ player.hidePlayer(vanished)
@hook.event("player.PlayerQuitEvent")
def on_player_quit(event):
player = event.getPlayer()
-
if not is_authorized(player):
- for uuid in vanished:
- player.showPlayer(retrieve_player(uuid))
+ for vanished in get_online_vanished_players():
+ player.showPlayer(vanished)
+
+ elif is_vanished(player):
+ disable_vanish(player)
@simplecommand("vanishother",
@@ -110,9 +107,7 @@ def vanishother_command(sender, command, label, args):
elif arg == "off":
new_state = False
- if current_state == new_state:
- return "&cThat player was already vanished!" if current_state else "&cThat player was not yet vanished!"
-
+ Validate.isTrue(current_state != new_state, "&cThat player was %s vanished!" % ("already" if current_state else "not yet"))
set_state(target, new_state)
enabled_str = "enabled" if new_state else "disabled"
diff --git a/wrapper_command.py b/wrapper_command.py
index dd51534..90eaf01 100644
--- a/wrapper_command.py
+++ b/wrapper_command.py
@@ -1,11 +1,232 @@
from wrapper_player import *
+from helpers import *
-def command(command = "help"):
- def decorator(wrapped):
- @hook.command(command)
- def wrapper(sender, command, label, args):
+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):
+
+ 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):
+
+ self.command = command.lower()
+ self.arguments = arguments
+
+ check_arguments(self.command, self.arguments)
+
+ 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)
+
+ self.aliases = tuple(alias.lower() for alias in aliases)
+ self.parent = parent
+ self.sub_commands = Command_dict()
+
+ if self.parent == None:
+ root_commands[self.command] = self
+ else:
try:
- return wrapped(sender = py_players[sender], command = command, label = label, args = args)
- except:
- print(print_traceback())
- return decorator \ No newline at end of file
+ parent_route = self.parent.split(" ")
+ 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_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())
+
+ def __call__(self, handler):
+ self.handler = handler
+
+ if parent == None:
+ @hook.command(self.command, self.aliases)
+ def run(sender, command, label, args):
+ try:
+ message = self.execute(sender, command, label, args)
+ except Command_exception as e:
+ message = e.message
+ except Exception:
+ error(trace())
+ return True
+ if message:
+ sender.sendMessage(message)
+ return True
+
+ return handler
+
+ def execute(self, sender, command, label, args):
+ try:
+ return self.sub_commands.get_command_object(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)
+ if is_player(sender):
+ sender = py_players[sender]
+
+ return self.handler(sender, self, scape)
+
+ def syntax(self):
+ return " ".join(tuple(arg_info.syntax() for arg_info in self.arguments))
+
+#--------------------------------------------------------------------------------------
+
+class Command_scape(list):
+
+ def __init__(self, args, arg_layout):
+ super(list, self).__init__()
+ self.raw = args
+ self.arg_layout = arg_layout
+
+ has_message = False
+ for i in range(len(arg_layout)):
+ arg_info = arg_layout[i]
+
+ given = (len(args) >= i + 1)
+ if arg_info.required and not given:
+ raise Argument_exception("You must specify the " + arg_info.name)
+
+ if not given:
+ self.append(None)
+ continue
+
+ given_arg = args[i]
+ arg_type = arg_info.type
+
+ if arg_type == Argument.STRING:
+ self.append(given_arg)
+
+ elif arg_type == Argument.INTEGER:
+ try:
+ value = int(given_arg)
+ except ValueError:
+ raise Argument_exception("The %s has to be a round number" % arg_info.name)
+ self.append(value)
+
+ elif arg_type == Argument.FLOAT:
+ try:
+ value = float(given_arg)
+ except ValueError:
+ raise Argument_exception("The %s has to be a number" % arg_info.name)
+ self.append(value)
+
+ elif arg_type == Argument.PLAYER:
+ target = server.getPlayer(given_arg)
+ if target == None:
+ raise Argument_exception("The %s has to be an online player" % arg_info.name)
+ self.append(py_players[target])
+
+ elif arg_type == Argument.OFFLINE_PLAYER:
+ try:
+ # Code to get the PY PLAYER by name. Possibly, uid(server.getOfflinePlayer(given_arg)) can be used?
+ pass
+ except KeyError:
+ raise Argument_exception("The %s has to be an existing player" % arg_info.name)
+ self.append(None)
+
+ elif arg_type == Argument.MESSAGE:
+ self.append(" ".join(args[i:]))
+ has_message = True
+ else:
+ error("Argument type not found: %d" % arg_type)
+ raise Argument_exception("A weird thing has happened, please contact an administrator")
+
+ if not has_message:
+ self.remainder = args[len(arg_layout):]
+ else:
+ self.remainder = None
+
+ def has_flag(self, flag, check_all = False):
+ return (("-" + flag) in self.raw) if check_all else (("-" + flag) in self.remainder)
+
+ def get_raw(self):
+ return self.raw
+
+ 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)
diff --git a/wrapper_player.py b/wrapper_player.py
index a889ede..db7f6cc 100644
--- a/wrapper_player.py
+++ b/wrapper_player.py
@@ -6,6 +6,9 @@ from players_secret import *
from datetime import datetime
from com.ziclix.python.sql import zxJDBC
+def get_py_player(player):
+
+
class py_player:
def __init__(self,player):
self.player = player