This commit is contained in:
PixelSergey
2015-11-22 19:56:55 +02:00
3 changed files with 245 additions and 167 deletions
+2 -2
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
] ]
) )
+4 -2
View File
@@ -43,7 +43,7 @@ shared["load_modules"] = [
# Adds /calc, toggles automatic solving of Math expressions in chat # Adds /calc, toggles automatic solving of Math expressions in chat
"calc", "calc",
# Adds aliasing of chat words # Adds aliasing of chat words
"chatalias", #"chatalias",
# Plugin to locate laggy chunks. /lc <n> lists chunks with more than n entities # Plugin to locate laggy chunks. /lc <n> lists chunks with more than n entities
"lagchunks", "lagchunks",
# Adds /report and /rp, Stores reports with time and location # Adds /report and /rp, Stores reports with time and location
@@ -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"]:
+239 -163
View File
@@ -3,121 +3,230 @@ 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", "stop", "reload", "op", "deop", "whitelist")
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 signs. \nUse /svs help for more details.",
usage = "[claim|unclaim|add <msg>|remove <line>|clear|info|help]", usage = "<claim|reset|add <msg>[++]|remove <ID>|clear|info|help>",
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", "reverse", "unclaim"),
if arg1 not in ("add", "remove", "clear", "claim", "unclaim", "help"): signsMsg("That argument could not be recognized, use &o/svs help &4for expected arguments"))
return "&4That argument could not be recognized, use &o/svs &4help for more information" Validate.isAuthorized(sender, "utils.serversigns." + arg1)
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): msg = signsMsg("Server signs lets you add messages to a sign.", 'a')
return "&4You have to be looking at a sign to use that!" msg += "\nRight clicking the sign will display all the messages. Commands"
msg += "\ncan also be added, by prefixing the message with a '/'."
msg += "\nHow to use &b/serversigns&a:"
msg += "\n&b/svs claim" + ("" if not sender.hasPermission("utils.serversigns.admin") else " [owner]")
msg += "\n&a- Claims the sign so that you can add messages to it"
msg += "\n&b/svs info"
msg += "\n&a- Displays information about the (claimed) sign"
msg += "\n&b/svs add <message>[++]"
msg += "\n&a- Adds the message to the sign. Use ++ at the end"
msg += "\n&a- to add the message to your buffer. You can then use"
msg += "\n&a- the same command again to create a longer message."
msg += "\n&b/svs remove <message ID>"
msg += "\n&a- Removes the message with the given ID from the sign."
msg += "\n&a- The ID is given before each message by &b/svs info&a."
msg += "\n&b/svs switch|reverse <message ID 1> <message ID 2>"
msg += "\n&a- Reverses the order in which the given messages are shown."
msg += "\n&b/svs clear"
msg += "\n&a- Removes all messages from the sign."
msg += "\n&b/svs reset|unclaim"
msg += "\n&a- Resets the sign, removing all messages and its owner."
return msg
#-------------------------------------------------------------------------------------------
loc = fromLoc(block.getLocation()) block = sender.getTargetBlock(None, 5)
sign = getSign(loc) Validate.isTrue(block.getType() in (Material.SIGN_POST, Material.WALL_SIGN), signsMsg("You have to be looking at a sign to use that!"))
arglen = len(args)
arg2 = args[1].lower() if arglen > 1 else None
loc = fromLoc(block.getLocation())
sign = getSign(loc)
signName = identifySign(loc)
arg2 = args[1].lower() if len(args) > 1 else None
if arg1 == "claim": #------------------------ Sub commands that require the block to be a sign -------------------------------
Validate.isAuthorized(sender, "utils.serversigns.claim") if arg1 == "claim":
target = sender Validate.isTrue(not sign, signsMsg("The %s was already claimed" % signName))
if arg2: Validate.isTrue(can_build2(sender, block), signsMsg("You are not permitted to claim signs here"))
Validate.isAuthorized(sender, "utils.serversigns.admin") target = sender
target = server.getOfflinePlayer(arg2) if arg2:
Validate.notNone(target, signsMsg("That player could not be found", '4')) Validate.isTrue(player.hasPermission("utils.serversigns.admin"), signsMsg("You are not authorized to claim signs for other players"))
target = server.getOfflinePlayer(arg2)
Validate.isPlayer(target) Validate.notNone(target, signsMsg("That player could not be found"))
uuid = uid(sender) Validate.isTrue(target.isOnline(), signsMsg("The target has to be online"))
if sign != None: uuid = uid(target)
if sign[0] == uuid: if sign != None:
return signsMsg(identifySign(loc, True) + " was already owned by that player", '4') if sign[0] == uuid:
else: return signsMsg("The" + signName + " was already owned by that player")
sign[0] = uuid
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] = "" del sign[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 in ("switch", "reverse"):
admin = sender.hasPermission("utils.serversigns.admin") Validate.isTrue(len(args) == 3, signsMsg("You have to enter the 2 IDs of the messages to reverse"))
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]
save_signs()
return signsMsg("Reversed the messages 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:]) save_signs()
Validate.isTrue(line != "" and line != None, signsMsg("You have to enter a message to add or accumulate!", '4')) return signsMsg("Removed all messages from the %s" % signName, 'a')
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 in ("reset", "unclaim"):
Validate.notNone(sign, signsMsg("The %s has not been claimed" % identifySign(loc), '4')) del signs[loc]
lines = "" save_signs()
for id, line in enumerate(sign[1:]): return signsMsg("Removed all messages and the owner from the %s, it can now be claimed" % signName, 'a')
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 +241,57 @@ 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", "monitor")
def on_break(event):
try:
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)
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())
def check_sign(event, block, attached = True):
player = event.getPlayer()
sign = getSign(fromLoc(block.getLocation()))
if not can_build2(player, block):
event.setCancelled(True)
msg(event.getPlayer(), signsMsg("You cannot break %s" % ("the sign attached to that block" if attached else "that sign")))
else:
loc = fromLoc(block.getLocation())
del signs[loc]
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)
checking_block = True
server.getPluginManager().callEvent(event)
checking_block = False
return not event.isCancelled()