Major serversigns overhaul, it mostly works now. A little bit of testing and command help is left

This commit is contained in:
Dico200
2015-11-22 14:51:47 +01:00
parent 1b59c79fd7
commit 23b3bffcf6
3 changed files with 208 additions and 162 deletions

View File

@@ -24,7 +24,7 @@ settingInformation = dict( #[setting type, identifying description, detailed des
], ],
furnace = [1, furnace = [1,
"automatically filling furnaces upon placement", "automatically filling furnaces upon placement",
"Sets your preferred default furnace contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle dropper clear to clear all slots.", "Sets your preferred default furnace contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle furnace clear to clear all slots.",
["cooker", "fillf"], 2 ["cooker", "fillf"], 2
], ],
#torch = [0, #torch = [0,
@@ -44,7 +44,7 @@ settingInformation = dict( #[setting type, identifying description, detailed des
], ],
hopper = [1, hopper = [1,
"automatically filling hoppers upon placement", "automatically filling hoppers upon placement",
"Sets your preferred default hopper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle dropper clear to clear all slots.", "Sets your preferred default hopper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle hopper clear to clear all slots.",
["itemtransporter", "fillh"], 4 ["itemtransporter", "fillh"], 4
] ]
) )

View File

@@ -99,7 +99,9 @@ shared["load_modules"] = [
# a simple replacement for the buggy essentials /vanish # a simple replacement for the buggy essentials /vanish
"vanish", "vanish",
# ip-tracking utility # ip-tracking utility
"iptracker" "iptracker",
#server signs for everyone
"serversigns"
] ]
shared["modules"] = {} shared["modules"] = {}
for module in shared["load_modules"]: for module in shared["load_modules"]:

View File

@@ -3,17 +3,87 @@ from basecommands import simplecommand, Validate
import org.bukkit.Material as Material import org.bukkit.Material as Material
import java.util.UUID as UUID import java.util.UUID as UUID
import org.bukkit.Material as Material import org.bukkit.Material as Material
import java.util.HashSet as JSet import org.bukkit.block.BlockFace as BlockFace
blocked_cmds = ("pex", "kick", "ban", "tempban", "pyeval", "sudo")
cmd_use_perm = "utils.svs.cmd" def load_signs():
msg_use_perm = "utils.svs.msg" signs_obj = open_json_file("serversigns", [])
loaded = {}
for entry in signs_obj:
loaded[tuple(entry[:4])] = list(entry[4:])
return loaded
signs = open_json_file("serversigns", {}) # {("world", x, y, z): ["owner_id", "msg1", "msg2"]} def save_signs():
signs_obj = []
for key, value in signs.iteritems():
signs_obj.append(key + tuple(value))
save_json_file("serversigns", signs_obj)
lines = {} #Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""} signs = load_signs() # {("world", x, y, z): ["owner_id", "msg1", "msg2"]}
lines = {} # Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""}
def fromLoc(bLoc):
"""
# Returns a tuple containing the (bukkit)location's world's name and its x, y and z coordinates
# The format for the tuple is ("world_name", x, y, z)
"""
return (bLoc.getWorld().getName(), bLoc.getBlockX(), bLoc.getBlockY(), bLoc.getBlockZ())
def equals(loc1, loc2):
"""
# Returns whether loc1 and loc2 represent the same block
"""
for i in range(4):
if loc1[i] != loc2[i]:
return False
return True
def getOwner(sign):
"""
# Returns the name of the sign its owner
"""
return retrieve_player(sign[0]).getName()
def isOwner(sign, player):
"""
# Returns whether the given player owns the sign
"""
return sign and sign[0] == uid(player)
def canEdit(sign, player):
"""
# Returns whether the given player can edit the sign.
# Returns False if the sign wasn't claimed.
"""
return (sign and player.hasPermission("utils.serversigns.admin")) or isOwner(sign, player)
def getSign(locAt):
"""
# If data was found for a sign at the given location, returns the data.
# This data follows the format of ["owner_id", "msg1", "msg2"...].
"""
for loc, sign in signs.iteritems():
if equals(locAt, loc):
return sign
return None
def identifySign(loc):
"""
# Returns a string from which the user can tell what sign you're talking about.
# The string follows the format of "sign at (x,y,z) in world_name".
"""
return "sign at (%s) in %s" % (",".join((str(i) for i in loc[1:])), loc[0])
def signsMsg(msg, colour = '4'):
"""
# Returns the given msg, prefixed with '[Signs] '.
# The given colour is after applied to the msg.
# The colour defaults to 4 (dark red).
"""
return "&c[Signs] &" + colour + msg
transparent_blocks_set = JSet([Material.AIR, Material.GLASS, Material.STAINED_GLASS]) #used in sender.getTargetBlock()
@simplecommand(cmd = "serversigns", aliases = ["svs", "signmsg"], @simplecommand(cmd = "serversigns", aliases = ["svs", "signmsg"],
description = "Makes something happen when you right click certain signs", description = "Makes something happen when you right click certain signs",
@@ -21,103 +91,117 @@ transparent_blocks_set = JSet([Material.AIR, Material.GLASS, Material.STAINED_GL
helpNoargs = True, helpNoargs = True,
senderLimit = 0) senderLimit = 0)
def svs_command(sender, command, label, args): def svs_command(sender, command, label, args):
try: arg1 = args[0].lower()
arg1 = args[0].lower() Validate.isTrue(arg1 in ("claim", "reset", "add", "remove", "info", "clear", "help", "switch"), signsMsg("That argument could not be recognized, use &o/svs help &4for expected arguments"))
if arg1 not in ("add", "remove", "clear", "claim", "unclaim", "help"): Validate.isAuthorized(sender, "utils.serversigns." + arg1)
return "&4That argument could not be recognized, use &o/svs &4help for more information"
sender = server.getPlayer(sender.getName()) #-------------------- Sub commands that don't require any conditions -----------------------
block = sender.getTargetBlock(transparent_blocks_set, 8) if arg1 == "help":
info("Block type: " + str(block.getType())) admin = sender.hasPermission("utils.serversigns.admin")
if block.getType() not in (Material.SIGN_POST, Material.WALL_SIGN):
return "&4You have to be looking at a sign to use that!"
loc = fromLoc(block.getLocation()) return "&2COMMAND HELP HERE"
sign = getSign(loc) #-------------------------------------------------------------------------------------------
arglen = len(args)
arg2 = args[1].lower() if arglen > 1 else None
block = sender.getTargetBlock(None, 5)
Validate.isTrue(block.getType() in (Material.SIGN_POST, Material.WALL_SIGN), signsMsg("You have to be looking at a sign to use that!"))
if arg1 == "claim": loc = fromLoc(block.getLocation())
Validate.isAuthorized(sender, "utils.serversigns.claim") sign = getSign(loc)
target = sender signName = identifySign(loc)
if arg2: arg2 = args[1].lower() if len(args) > 1 else None
Validate.isAuthorized(sender, "utils.serversigns.admin") is_admin = sender.hasPermission("utils.serversigns.admin")
target = server.getOfflinePlayer(arg2)
Validate.notNone(target, signsMsg("That player could not be found", '4'))
Validate.isPlayer(target) #------------------------ Sub commands that require the block to be a sign -------------------------------
uuid = uid(sender) if arg1 == "claim":
if sign != None: target = sender
if sign[0] == uuid: if arg2:
return signsMsg(identifySign(loc, True) + " was already owned by that player", '4') Validate.isTrue(is_admin, signsMsg("You are not authorized to claim signs for other players"))
else: target = server.getOfflinePlayer(arg2)
sign[0] = uuid Validate.notNone(target, signsMsg("That player could not be found"))
Validate.isTrue(target.isOnline(), signsMsg("The target has to be online"))
uuid = uid(target)
if sign != None:
if sign[0] == uuid:
return signsMsg("The" + signName + " was already owned by that player")
else: else:
signs[loc] = [uuid] sign[0] = uuid
else:
signs[loc] = [uuid]
save_signs()
return signsMsg("Claimed the " + signName + ((" for %s" % target.getName()) if (target != sender) else ""), 'a')
#----------------------------------------------------------------------------------------------------------
return signsMsg("Claimed " + identifySign(loc)) Validate.notNone(sign, signsMsg("The %s has not been claimed" % signName))
#----------------------Sub commands that require the sign to be claimed as well------------------------------------
if arg1 == "info":
sign_lines = ""
for id, line in enumerate(sign[1:]):
sign_lines += ("\n &a%s: \"&f%s&a\"" % (id + 1, line))
return signsMsg("Properties of the %s:\n Owner: %s\n Lines: %s" % (signName, getOwner(sign), sign_lines), 'a')
#---------------------------------------------------------------------------------------------------------------
Validate.isTrue(canEdit(sign, sender), signsMsg("You do not own the %s!" % signName))
#---------------------- Sub commands that require you to own targeted sign as well -------------------------
if arg1 == "add":
line = " ".join(args[1:])
Validate.isTrue(line != "" and line != None, signsMsg("You have to enter a message to add or accumulate"))
key = sender.getName()
global lines
Validate.isTrue(key in lines or line[:1] != "/" or sender.hasPermission("utils.serversigns.command"), signsMsg("You cannot add commands to a sign!"))
if line[-2:] == "++":
if key not in lines:
lines[key] = ""
lines[key] += " " + line[:-2]
return signsMsg("Added given message to the message you're accumulating. \nYour accumulated message is now as follows: \n&f%s" % lines[key], 'a')
if key in lines:
line = (lines[key] + " " + line)[1:]
Validate.isTrue(line[0] != "/" or line.split(" ")[0][1:] not in blocked_cmds, signsMsg("Usage of that command with server signs is prohibited"))
sign.append(colorify(line) if line[0] != "/" else line)
save_signs()
return signsMsg("Added line \"&f%s&a\" to the %s" % (line, signName), 'a')
elif arg1 == "unclaim": if arg1 == "remove":
Validate.isAuthorized(sender, "utils.serversigns.unclaim") Validate.notNone(arg2, signsMsg("You have to enter the ID of the message to remove!"))
Validate.isTrue(canEdit(sign, sender), signsMsg("You cannot unclaim the %s!" % identifySign(loc)), '4') try:
id = int(arg2)
if not (("-c" in args) and sender.hasPermission("utils.serversigns.admin")): except:
del signs[locAt] return signsMsg("The ID of the message has to be a number and can be found by using &o/svs info")
return signsMsg("The %s was reset successfully" % identifySign(loc)) Validate.isTrue(id != 0 and id < len(sign), signsMsg("The %s has no message with an ID of %s, use &o/svs info &4for all messages." % (signName, id)))
sign[0] = "" sign.remove(id)
return signsMsg("The %s had its owner removed successfully" % identifySign(loc)) return signsMsg("Removed message with id %s from the %s" % (id, signName), 'a')
elif arg1 == "help": if arg1 == "switch":
admin = sender.hasPermission("utils.serversigns.admin") Validate.isTrue(len(args) == 3, signsMsg("You have to enter the 2 IDs of the lines to switch"))
try:
return id1 = int(args[1])
id2 = int(args[2])
except:
return signsMsg("The ID of the message has to be a number and can be found by using &o/svs info")
for id in (id1, id2):
Validate.isTrue(id != 0 and id < len(sign), signsMsg("The %s has no message with an ID of %s, use &o/svs info &4for all messages." % (signName, id)))
sign[id1], sign[id2] = sign[id2], sign[id1]
return signsMsg("Switched the lines with IDs %s and %s of the %s" % (id1, id2, signName), 'a')
elif arg1 == "add": if arg1 == "clear":
Validate.isTrue(canEdit(sign, sender), signsMsg("You cannot edit the %s!" % identifySign(loc)), '4') signs[loc] = [sign[0]]
line = " ".join(args[1:]) return signsMsg("Removed all messages from the %s" % signName, 'a')
Validate.isTrue(line != "" and line != None, signsMsg("You have to enter a message to add or accumulate!", '4'))
key = sender.getName()
Validate.isTrue(key in lines or line[:1] != "/" or sender.hasPermission("utils.serversigns.command"), signsMsg("You cannot add commands to a sign!", '4'))
if line[-2:] == "++":
if key not in lines:
lines[key] = ""
lines[key] += " " + line[:-2]
elif key in lines:
line = lines[key] + " " + line
sign.append(colorify(line) if line[0] != "/" else line)
return signsMsg("Added line \"%s&a\" to the %s" % (line, identifySign(loc)))
elif arg1 == "info": if arg1 == "reset":
Validate.notNone(sign, signsMsg("The %s has not been claimed" % identifySign(loc), '4')) del signs[loc]
lines = "" return signsMsg("Removed all messages and the owner from the %s, it can now be claimed" % signName, 'a')
for id, line in enumerate(sign[1:]): #-------------------------------------------------------------------------------------------------------
lines += ("\n &a%s: \"%s&a\"" % (id + 1, line))
msg = signsMsg("Some information about the %s:\n Owner: %s\n Lines: %s" % identifySign(loc), getOwner(sign), lines)
elif arg1 == "remove":
Validate.notNone(arg2, signsMsg("You have to enter the ID of the message to remove!", '4'))
try:
id = int(arg2)
except:
return signsMsg("The ID of the message has to be a number and can be found by using &o/svs info", '4')
Validate.isTrue(id != 0 and id < len(sign), signsMsg("The %s has no message with an ID of %s, use &o/svs info &4for all messages." % (identifySign(loc), id), '4'))
sign.remove(id)
return signsMsg("Removed message with id %s from the %s" % (id, identifySign(loc)))
except:
error(trace())
@hook.event("player.PlayerInteractEvent") @hook.event("player.PlayerInteractEvent")
def onClick(event): def on_click(event):
if str(event.getAction()) != "RIGHT_CLICK_BLOCK": if str(event.getAction()) != "RIGHT_CLICK_BLOCK":
return return
block = event.getClickedBlock() block = event.getClickedBlock()
@@ -132,90 +216,50 @@ def onClick(event):
else: else:
msg(player, message, usecolor = False) msg(player, message, usecolor = False)
def fromLoc(bLoc): #Bukkit Location to ("world", x, y, z) # ---------------------------Sign breaking--------------------------------
return (bLoc.getWorld().getName(), bLoc.getBlockX(), bLoc.getBlockY(), bLoc.getBlockZ())
def equals(loc1, loc2):
for i in range(4):
if loc1[i] != loc2[i]:
return False
return True
def getOwner(sign):
return retrieve_player(sign[0]).getName()
def isOwner(sign, player):
return sign and sign[0] == uid(player)
def canEdit(sign, player):
return player.hasPermission("utils.serversigns.admin") or isOwner(sign, player)
def getSign(locAt):
for loc, sign in signs.iteritems():
if equals(locAt, loc):
return sign
return None
def identifySign(loc, capital = False):
return "%sign at (%s) in %s" % ("S" if capital else "s", ",".join(loc[1:]), loc[0])
def signsMsg(msg, colour = 'a'):
return "&c[Signs] &" + colour + msg
"""
def eventhook(event, priority = "normal"):
if "." not in event:
word = ""
for s in event:
if word != "" and s in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
break;
word += s.lower()
event = "%s.%s" % (word, event)
def decorator(function):
@hook.event(event, priority)
def hook(event):
try:
function(event)
except EventException, e:
pass
return hook
return decorator
class EventException(Exception):
def __init__(self, msg):
self.msg = msg
""
@eventhook("PlayerInteractEvent")
def x(event):
p = event.getPlayer()
if p == None:
raise EventException(Stuff)
""
"""
checking_block = False
faces = {
BlockFace.NORTH : (0,1,2),
BlockFace.SOUTH : 3,
BlockFace.WEST : 4,
BlockFace.EAST : 5
}
@hook.event("block.BlockBreakEvent", "highest")
def on_break(event):
global checking_block
if checking_block or event.isCancelled():
return
block = event.getBlock()
if block.getMaterial() 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.getData() in data_values:
check_sign(event, block2)
block3 = block.getRelative(BlockFace.UP)
if block3.getMaterial == Material.SIGN_POST:
check_sign(event, block3)
def check_sign(event, block, attached = True):
player = event.getPlayer()
sign = getSign(fromLoc(block.getLocation()))
if not canEdit(sign, player) and not can_build(player, block.getLocation()):
event.setCancelled(True)
msg(event.getPlayer(), signsMsg("You cannot break %s" % ("the sign attached to that block" if attached else "that sign")))
def can_build(player, block):
global checking_block
event = BlockBreakEvent(block, player)
checking_block = True
server.getPluginManager().callEvent(event)
checking_block = False
return not event.isCancelled()