Major serversigns overhaul, it mostly works now. A little bit of testing and command help is left
This commit is contained in:
@@ -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
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
4
main.py
4
main.py
@@ -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"]:
|
||||||
|
|||||||
362
serversigns.py
362
serversigns.py
@@ -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()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user