Merge branch 'dev' of bitbucket.org:redstonesheep/redstoner-utils into dev

This commit is contained in:
Louis Vogt
2014-07-14 16:23:33 +02:00
12 changed files with 338 additions and 139 deletions

View File

@@ -14,7 +14,7 @@ Detailed description:
0. Download [the latest spigot](http://ci.md-5.net/job/Spigot/lastStableBuild/artifact/Spigot-Server/target/spigot.jar) 0. Download [the latest spigot](http://ci.md-5.net/job/Spigot/lastStableBuild/artifact/Spigot-Server/target/spigot.jar)
0. Run it once inside redstoner, then shut it down again 0. Run it once inside redstoner, then shut it down again
0. Create a new directory (inside redstoner) called 'lib' 0. Create a new directory (inside redstoner) called 'lib'
0. Download [jython](http://search.maven.org/remotecontent?filepath=org/python/jython-standalone/2.5.3/jython-standalone-2.5.3.jar) and save it as 'jython.jar' inside lib 0. Download [jython](http://search.maven.org/remotecontent?filepath=org/python/jython-standalone/2.7-b2/jython-standalone-2.7-b2.jar) and save it as 'jython.jar' inside lib
0. Download [mysql-connector](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.30.zip), extract 'mysql-connector-java-X.X.XX-bin.jar 0. Download [mysql-connector](https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.30.zip), extract 'mysql-connector-java-X.X.XX-bin.jar
' and save it as 'mysql-connector.jar' inside lib ' and save it as 'mysql-connector.jar' inside lib
0. Download [PyPluginLoader](http://gserv.me/static/PyPluginLoader-0.3.5.jar) (we're using [this fork](https://github.com/gdude2002/Python-Plugin-Loader)) into the plugins directory 0. Download [PyPluginLoader](http://gserv.me/static/PyPluginLoader-0.3.5.jar) (we're using [this fork](https://github.com/gdude2002/Python-Plugin-Loader)) into the plugins directory
@@ -135,7 +135,11 @@ If you want the server to load a file (*module*) on startup, add it to the `modu
* `damnspam.py` * `damnspam.py`
> Prevents spamming of contraptions by setting a custom timeout > Adds `/damnspam`, creates timeout for buttons/levers to mitigate button spam.
* `forcefield.py`
> Adds '/forcefield', creates forcefield for players who want it.
# Code styleguide & tips # Code styleguide & tips

79
abot.py
View File

@@ -1,31 +1,68 @@
import json
from helpers import * from helpers import *
from re import compile as reg_compile from re import compile as reg_compile
rank_regex = "visitor|member|builder|trusted|helper|mod\\b|moderator|admin|owner|rank" answers_filename = "plugins/redstoner-utils.py.dir/files/abot.json"
answers = []
faq_regex = [
# ranks
"\\b(how.*? (get\\b|be\\b|become)|who is|are you).*? (%s)|\\bwho owns.* server" % rank_regex,
# WE
"\\b(can|how|why).*? (have|haz|use|get|doesn|can'?t).*? (WorldEdit|WE\\b|W\\.E\\.\\b)",
# clearing plot
"\\b((why|how|who).*? (do|can)|how to).*?( /?p clear| clear.*? plot)",
# add someone to a plot, claim plot
"\\bhow.*? (get|claim|own|add).*? plot"
]
faq_regex = [reg_compile(reg.lower()) for reg in faq_regex] def load_answers():
global answers
try:
answers = json.loads(open(answers_filename).read())
except Exception, e:
error("Failed to load answers: %s" % e)
# compile answers
for answer in answers:
answer["regex"] = [reg_compile(reg.lower()) for reg in answer["regex"]]
def list_answers(sender):
for answer in answers:
msg(sender, "&e{")
msg(sender, " &eregex:")
for regex in answer["regex"]:
msg(sender, " " + regex.pattern, basecolor="a", usecolor=False)
msg(sender, " &epermission:")
msg(sender, " " + str(answer["hide-perm"]), basecolor="a", usecolor=False)
msg(sender, " &emessage:")
msg(sender, " " + "\n ".join(answer["message"].split("\n")))
msg(sender, "&e}")
@hook.command("abot")
def onAbotCommand(sender, args):
plugHeader(sender, "AnswerBot")
if sender.hasPermission("utils.abot.admin"):
if not args:
msg(sender, "&2/abot list &eList all answers and their regex")
msg(sender, "&2/abot reload &eReload the config file")
elif args[0] == "list":
list_answers(sender)
elif args[0] == "reload":
load_answers()
msg(sender, "&2Reloaded!")
else:
msg(sender)
else:
noperm(sender)
return True
@hook.event("player.AsyncPlayerChatEvent", "low") @hook.event("player.AsyncPlayerChatEvent", "low")
def onChat(event): def onChat(event):
sender = event.getPlayer() sender = event.getPlayer()
if not sender.hasPermission("utils.ignore_abot"): message = event.getMessage().lower()
message = event.getMessage().lower() for answer in answers:
for regex in faq_regex: for regex in answer["regex"]:
if regex.search(message): if regex.search(message):
plugHeader(sender, "AnswerBot") if answer["hide-perm"] and not sender.hasPermission(answer["hide-perm"]):
msg(sender, "&aLooks like you're asking something that's likely in our FAQ.") plugHeader(sender, "AnswerBot")
msg(sender, "&aTake a look at &4&l/faq&a and read through the pages.\n ") # trailing space required msg(sender, answer["message"] + "\n ")
event.setCancelled(True) event.setCancelled(True)
log("(hidden) %s: '%s'" % (sender.getName(), message)) log("(hidden) %s: '%s'" % (sender.getName(), message))
break break
load_answers()

View File

@@ -1,7 +1,7 @@
#pylint: disable=F0401 #pylint: disable=F0401
from helpers import * from helpers import *
from java.utils.UUID import fromString as juuid from java.util.UUID import fromString as juuid
import simplejson as json import json
chatgroups_filename = "plugins/redstoner-utils.py.dir/files/chatgroups.json" chatgroups_filename = "plugins/redstoner-utils.py.dir/files/chatgroups.json"
groups = {} groups = {}
@@ -18,17 +18,18 @@ except Exception, e:
def onChatgroupCommand(sender, args): def onChatgroupCommand(sender, args):
try: try:
plugHeader(sender, "ChatGroups") plugHeader(sender, "ChatGroups")
sender_id = str(sender.getUniqueId())
if len(args) == 1 and args[0] == "leave": if len(args) == 1 and args[0] == "leave":
if str(sender.getUniqueId()) in groups.keys(): if sender_id in groups.keys():
groupchat(sender, "left the group", True) groupchat(sender, "left the group", True)
group = groups[sender.getName()] group = groups[sender_id]
del(groups[sender.getName()]) del(groups[sender_id])
saveGroups() saveGroups()
else: else:
msg(sender, "&aYou can't leave no group, derp!") msg(sender, "&aYou can't leave no group, derp!")
elif len(args) == 1 and args[0] == "info": elif len(args) == 1 and args[0] == "info":
if str(sender.getUniqueId()) in groups.keys(): if sender_id in groups.keys():
group = groups[str(sender.getUniqueId())] group = groups[sender_id]
msg(sender, "&aCurrent chatgroup: %s" % group) msg(sender, "&aCurrent chatgroup: %s" % group)
users = [] users = []
for uid, ugroup in groups.iteritems(): for uid, ugroup in groups.iteritems():
@@ -41,11 +42,11 @@ def onChatgroupCommand(sender, args):
else: else:
msg(sender, "&aYou're in no chatgroup.") msg(sender, "&aYou're in no chatgroup.")
elif len(args) == 2 and args[0] == "join": elif len(args) == 2 and args[0] == "join":
groups[str(sender.getUniqueId())] = args[1] groups[sender_id] = args[1]
groupchat(sender, "joined the group", True) groupchat(sender, "joined the group", True)
saveGroups() saveGroups()
msg(sender, "&aYour chatgroup is set to '%s'" % args[1]) msg(sender, "&aYour chatgroup is set to '%s'" % args[1])
msg(sender, "&aAnyone in the group sees chat that begins with &e%s" % cg_key) msg(sender, "&aUse chat like '&e%s<message>' to send messages to this group." % cg_key)
else: else:
msg(sender, "&e/chatgroup join <name>") msg(sender, "&e/chatgroup join <name>")
msg(sender, "&e/chatgroup leave") msg(sender, "&e/chatgroup leave")
@@ -65,6 +66,7 @@ def onCgtCommand(sender, args):
msg(sender, "&8[&bCG&8] &e&oCG toggle: on") msg(sender, "&8[&bCG&8] &e&oCG toggle: on")
return True return True
def groupchat(sender, message, ann=False): def groupchat(sender, message, ann=False):
#try: #try:
group = groups.get(str(sender.getUniqueId())) group = groups.get(str(sender.getUniqueId()))
@@ -76,6 +78,7 @@ def groupchat(sender, message, ann=False):
mesg = "&8[&bCG&8] &e&o%s&e&o %s" % (name, message) mesg = "&8[&bCG&8] &e&o%s&e&o %s" % (name, message)
else: else:
mesg = "&8[&bCG&8] &f%s&f: &6%s" % (name, message) mesg = "&8[&bCG&8] &f%s&f: &6%s" % (name, message)
log("[ChatGroups] %s (%s): %s" % (sender, group, message))
for receiver in server.getOnlinePlayers(): for receiver in server.getOnlinePlayers():
groups.get(str(receiver.getUniqueId())) == group and msg(receiver, mesg) groups.get(str(receiver.getUniqueId())) == group and msg(receiver, mesg)
#except Exception, e: #except Exception, e:
@@ -96,9 +99,10 @@ def onChat(event):
sender = event.getPlayer() sender = event.getPlayer()
msge = event.getMessage() msge = event.getMessage()
if not event.isCancelled(): if not event.isCancelled():
if msge[:len(cg_key)] == cg_key and str(sender.getUniqueId()) in groups.keys(): sender_id = str(sender.getUniqueId())
if msge[:len(cg_key)] == cg_key and sender_id in groups.keys():
groupchat(sender, msge[1:]) groupchat(sender, msge[1:])
event.setCancelled(True) event.setCancelled(True)
elif str(sender.getUniqueId()) in cg_toggle_list: elif sender_id in cg_toggle_list:
groupchat(sender, msge) groupchat(sender, msge)
event.setCancelled(True) event.setCancelled(True)

View File

@@ -1,4 +1,4 @@
import simplejson as json import json
from helpers import * from helpers import *
cyclers_file = "plugins/redstoner-utils.py.dir/files/cycle.json" cyclers_file = "plugins/redstoner-utils.py.dir/files/cycle.json"

View File

@@ -1,10 +1,12 @@
#pylint: disable=F0401 #pylint: disable=F0401
from helpers import * from helpers import *
import simplejson as json from time import time as now
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import json
spam_filename = "plugins/redstoner-utils.py.dir/files/damnspam.json" spam_filename = "plugins/redstoner-utils.py.dir/files/damnspam.json"
inputs = [] inputs = {} # format "x;y;z;World"
accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON"] accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"]
try: try:
inputs = json.loads(open(spam_filename).read()) inputs = json.loads(open(spam_filename).read())
@@ -12,71 +14,127 @@ except Exception, e:
error("Failed to load buttons and levers: %s" % e) error("Failed to load buttons and levers: %s" % e)
@hook.command("damnspam")
def onTimeoutCommand(sender, args):
global inputs
try:
plugHeader(sender, "DamnSpam")
if len(args) == 1:
timeout = args[0]
if not timeout.isdigit():
msg(sender, "&cThe timeout has to be a digit.")
return True
tB = sender.getTargetBlock(None, 10)
if str(tB.getType()) not in accepted_inputs:
msg(sender, "&cPlease look at a button/lever while executing this command!")
return True
data = {
"type": str(tB.getType()),
"creator": str(sender.getUniqueId()),
"timeout": int(args[0]),
"x": int(tB.getX()),
"y": int(tB.getY()),
"z": int(tB.getZ()),
"next": 'NULL',
"last": 'NULL'
}
inputs.append(data)
saveInputs()
msg(sender, "&eSuccessfully set a timeout for this button")
return True
else:
msg(sender, "&c/timeout <seconds>")
except Exception, e:
error(e)
def saveInputs(): def saveInputs():
try: try:
spam_file = open(spam_filename, "w") spam_file = open(spam_filename, "w")
spam_file.write(json.dumps(inputs)) spam_file.write(json.dumps(inputs))
spam_file.close() spam_file.close()
except Exception, e: except Exception, e:
error("Failed to save buttons and levers: " + str(e)) error("Failed to save damnspam: " + str(e))
def location_str(block):
return ";".join([block.getWorld().getName(), str(block.getX()), str(block.getY()), str(block.getZ())])
def add_input(creator, block, timeout_off, timeout_on):
global inputs
inputs[location_str(block)] = {
"creator" : str(creator.getUniqueId()),
"timeout_off" : timeout_off,
"timeout_on" : timeout_on,
"last_time" : 0
}
@hook.command("damnspam")
def onDammnspamCommand(sender, args):
global inputs
plugHeader(sender, "DamnSpam")
if len(args) in [1,2]:
if not str(sender.getGameMode()) == "CREATIVE":
msg(sender, "&cYou can only do this in Creative mode.")
return True
# /damnspam <secs>
if len(args) == 1:
timeout_on = args[0]
try:
timeout_on = round(float(timeout_on), 2)
timeout_off = timeout_on
if not 0 <= timeout_on <= 60:
msg(sender, "&cThe timeout must be within 0-60.")
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
return True
# /damnspam <off> <on>
elif len(args) == 2:
timeout_on = args[0]
timeout_off = args[1]
try:
timeout_on = round(float(timeout_on), 2)
timeout_off = round(float(timeout_off), 2)
if not 0 <= timeout_on <= 60 or not 0 <= timeout_off <= 60:
msg(sender, "&cThe timeout must be within 0-60.")
return True
except ValueError:
msg(sender, "&cThe timeout must be a number")
return True
# get the block we're looking at
target = sender.getTargetBlock(None, 10)
ttype = str(target.getType())
if ttype not in accepted_inputs:
msg(sender, "&cPlease look at a button or lever while executing this command!")
return True
test_event = BlockBreakEvent(target, sender)
server.getPluginManager().callEvent(test_event)
if test_event.isCancelled():
msg(sender, "&cYou are not allowed to modify this button")
return True
# add block to inputs
add_input(sender, target, timeout_off, timeout_on)
saveInputs()
msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower())
return True
else:
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
@hook.event("block.BlockBreakEvent", "normal") @hook.event("block.BlockBreakEvent", "normal")
def onBreak(event): def onBreak(event):
try: global inputs
sender = event.getPlayer()
block = event.getBlock() sender = event.getPlayer()
if str(block.getType()) in accepted_inputs: block = event.getBlock()
for entry in inputs: if str(block.getType()) in accepted_inputs and not event.isCancelled():
posX = int(entry["x"]) pos_str = location_str(block)
posY = int(entry["y"]) if inputs.get(pos_str):
posZ = int(entry["z"]) plugHeader(sender, "DamnSpam")
posX2 = block.getX() if sender.isSneaking():
posY2 = block.getY() inputs.pop(pos_str) # remove
posZ2 = block.getZ() saveInputs()
if posX == posX2 and posY == posY2 and posZ == posZ2: msg(sender, "&eSuccessfully removed the input!")
if sender.isSneaking(): return True
inputs.remove(entry) else:
saveInputs() event.setCancelled(True)
msg(sender, "&eSuccessfully removed the input!") msg(sender, "&cYou cannot destroy this input!")
return True msg(sender, "&c&nSneak&c and break if you want to remove it.")
else: return True
event.setCancelled(True)
msg(sender, "&cYou cannot destroy this input!")
msg(sender, "&7&lSneak&7 and break if you want to remove it.") @hook.event("player.PlayerInteractEvent", "normal")
return True def onInteract(event):
break if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled():
except Exception, e: sender = event.getPlayer()
error("BlockBreakEvent failed: " + str(e)) block = event.getClickedBlock()
btype = str(block.getType()).lower()
powered = (block.getData() & 0x8) == 0x8 if btype == "lever" else False # data > 7, but this is how bukkit does it
pos_str = location_str(block)
data = inputs.get(pos_str)
if data:
checktime = data["timeout_on"] if powered else data["timeout_off"]
if data["last_time"] + checktime > now():
event.setCancelled(True)
plugHeader(sender, "DamnSpam")
msg(sender, "&cThis %s has a timeout of %ss." % (btype, checktime))
else:
inputs[pos_str]["last_time"] = round(now(), 2)

91
forcefield.py Normal file
View File

@@ -0,0 +1,91 @@
from helpers import *
from java.util.UUID import fromString as juuid
forcefield_permissions = ["utils.forcefield", "utils.forcefield.ignore"]
forcefield_prefix = "&8[&aFF&8]"
fd = 4 # forcefield distance
forcefield_toggle = []
forcefield_whitelist = {}
def forcefield_help(sender):
msg(sender, "%s &a&l/ForceField Help: \n&aYou can use the forcefield to keep players on distance." % forcefield_prefix)
msg(sender, "&2Commands:")
msg(sender, "&a1. &6/ff &ohelp &a: aliases: ?")
msg(sender, "&a2. &6/ff &o(toggle)")
msg(sender, "&a3. &6/ff &owhitelist (list) &a: aliases: wlist, wl")
msg(sender, "&a4. &6/ff wl &oclear")
msg(sender, "&a5. &6/ff wl &oadd <players> &a: aliases: &o+")
msg(sender, "&a6. &6/ff wl &oremove <players> &a: aliases: &odelete, rem, del, -")
#forcefield toggle
@hook.command("forcefield")
def onForceFieldCommand(sender, args):
if not sender.hasPermission(forcefield_permissions[0]):
noperm(sender)
return True
sender_id = str(sender.getUniqueId())
args = args.lower()
if not args or args[0] == "toggle": #Toggle
if sender_id in forcefield_toggle:
forcefield_toggle.remove(sender_id)
msg(sender, "%s &aForceField toggle: &cOFF" % forcefield_prefix)
else:
forcefield_toggle.append(sender_id)
msg(sender, "%s &aForceField toggle: &2ON" % forcefield_prefix)
elif args[0] in ["whitelist", "wl", "wlist"]: #Whitelist commands
if not args[1] or args[1] == "list":
msg(sender, "%s &aForceField Whitelist:") % forcefield_prefix
c=0
for uid in forcefield_whitelist[sender_id]:
c+=1
msg(sender, "&a%s. &f%s") % (c, juuid(uid))
elif args[1] == "clear":
forcefield_whitelist[sender_id] = []
msg(sender, "%s &aForceField Whitelist cleared.")
elif args[1] in ["add", "+"]:
if not args[2:]:
msg(sender, "%s &cGive playernames to add to your whitelist." % forcefield_prefix)
else:
for name in args[2:]:
uid = str(server.getPlayer(name).getUniqueId())
forcefield_whitelist[sender_id].append(uid)
elif args[1] in ["remove", "delete", "rem", "del", "-"]:
if not args[2:]:
msg(sender, "%s &cGive playernames to remove from your whitelist." % forcefield_prefix)
else:
for name in args[2:]:
uid = str(server.getPlayer(name).getUniqueId())
forcefield_whitelist[sender_id].remove(uid)
elif args[0] in ["help", "?"]: #/forcefield help
forcefield_help(sender)
else:
msg(sender, "%s &cInvalid syntax. Use &o/ff ? &cfor more info.")
return True
def setVelocityAway(player, entity):
player_loc = player.getLocation()
entity_loc = entity.getLocation()
dx = entity_loc.getX() - player_loc.getX()
dy = entity_loc.getY() - player_loc.getY()
dz = entity_loc.getZ() - player_loc.getZ()
negator = fd/2
entity.setVelocity(negator/dx, negator/dy, negator/dz)
@hook.event("player.PlayerMoveEvent")
def onMove(event):
player = event.getPlayer()
player_id = str(player.getUniqueId())
if player_id in forcefield_toggle: #player has forcefield, entity should be launched
for entity in player.getNearbyEntities(fd, fd, fd):
if isPlayer(entity) and not entity.hasPermission(forcefield_permissions[1]) and not str(entity.getUniqueId()) in forcefield_whitelist[player_id]:
setVelocityAway(player, entity)
elif not player.hasPermission(forcefield_permissions[1]): #player should be launched, entity has forcefield
for entity in player.getNearbyEntities(fd, fd, fd):
entity_id = str(entity.getUniqueId())
if isPlayer(entity) and entity_id in forcefield_toggle and not player_id in forcefield_whitelist[entity_id]:
if event.getFrom().distance(entity.getLocation()) > 4:
event.setCancelled(True)
msg(player, "&cYou may not get closer than %sm to %s due to their forcefield." % (fd, entity.getDisplayName()))
else:
setVelocityAway(entity, player)

View File

@@ -6,6 +6,9 @@ import org.bukkit.entity.Player as Player
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause
import org.bukkit.block as bblock import org.bukkit.block as bblock
shared = {}
server = bukkit.Bukkit.getServer() server = bukkit.Bukkit.getServer()
def log(text): def log(text):

43
main.py
View File

@@ -3,7 +3,6 @@ __plugin_version__ = "3.0"
__plugin_mainclass__ = "foobar" __plugin_mainclass__ = "foobar"
import sys import sys
import thread
from traceback import format_exc as print_traceback from traceback import format_exc as print_traceback
# damn pythonloader changed the PATH # damn pythonloader changed the PATH
@@ -24,14 +23,14 @@ def onEnable():
@hook.disable @hook.disable
def onDisable(): def onDisable():
mod["reports"].stopChecking() shared["modules"]["reports"].stopChecking()
log("RedstonerUtils disabled!") log("RedstonerUtils disabled!")
log("Loading RedstonerUtils...") log("Loading RedstonerUtils...")
# Import all modules, in this order # Import all modules, in this order
modules = [ load_modules = [
"misc", "misc",
"adminchat", "adminchat",
"lagchunks", "lagchunks",
@@ -43,41 +42,15 @@ modules = [
"mentio", "mentio",
"cycle", "cycle",
"motd", "motd",
"abot" "abot",
"forcefield",
"damnspam"
] ]
mod = {} shared["modules"] = {}
for module in modules: for module in load_modules:
try: try:
mod[module] = __import__(module) shared["modules"][module] = __import__(module)
log("Module %s loaded." % module) log("Module %s loaded." % module)
except: except:
error("Failed to import module %s:" % module) error("Failed to import module %s:" % module)
error(print_traceback()) error(print_traceback())
#
# /pyeval - run python ingame
#
# has to be in main.py so we can access the modules
def evalThread(sender, code):
try:
msg(sender, "%s" % unicode(eval(code)), False, "a")
except Exception, e:
msg(sender, "%s: %s" % (e.__class__.__name__, e), False, "c")
thread.exit()
@hook.command("pyeval")
def onPyevalCommand(sender, args):
if sender.hasPermission("utils.pyeval"):
if not checkargs(sender, args, 1, -1):
return True
msg(sender, "%s" % " ".join(args), False, "e")
try:
thread.start_new_thread(evalThread, (sender, " ".join(args)))
except Exception, e:
msg(sender, "&cInternal error: %s" % e)
else:
noperm(sender)
return True

33
misc.py
View File

@@ -1,6 +1,7 @@
#pylint: disable=F0401 #pylint: disable=F0401
from helpers import * from helpers import *
from time import time as now from time import time as now
import thread
import org.bukkit.inventory.ItemStack as ItemStack import org.bukkit.inventory.ItemStack as ItemStack
# #
@@ -99,12 +100,13 @@ def onPlayerInteractEntity(event):
def onPluginversionsCommand(sender, args): def onPluginversionsCommand(sender, args):
plugHeader(sender, "Plugin versions") plugHeader(sender, "Plugin versions")
plugins = list(server.getPluginManager().getPlugins()) plugins = list(server.getPluginManager().getPlugins())
plugins.sort(key=lambda pl: pl.getName()) plugins.sort(key=lambda pl: pl.getDescription().getName())
msg(sender, "&3Listing all " + str(len(plugins)) + " plugins and their version:") msg(sender, "&3Listing all " + str(len(plugins)) + " plugins and their version:")
for plugin in plugins: for plugin in plugins:
msg(sender, "&6" + plugin.getName() + "&r: &e" + plugin.getDescription().getVersion()) msg(sender, "&6" + plugin.getDescription().getName() + "&r: &e" + plugin.getDescription().getVersion())
return True return True
# #
# /echo - essentials echo sucks and prints mail alerts sometimes # /echo - essentials echo sucks and prints mail alerts sometimes
# #
@@ -112,3 +114,30 @@ def onPluginversionsCommand(sender, args):
@hook.command("echo") @hook.command("echo")
def onEchoCommand(sender, args): def onEchoCommand(sender, args):
msg(sender, " ".join(args).replace("\\n", "\n")) msg(sender, " ".join(args).replace("\\n", "\n"))
#
# /pyeval - run python ingame
#
# has to be in main.py so we can access the modules
def evalThread(sender, code):
try:
msg(sender, "%s" % unicode(eval(code)), False, "a")
except Exception, e:
msg(sender, "%s: %s" % (e.__class__.__name__, e), False, "c")
thread.exit()
@hook.command("pyeval")
def onPyevalCommand(sender, args):
if sender.hasPermission("utils.pyeval"):
if not checkargs(sender, args, 1, -1):
return True
msg(sender, "%s" % " ".join(args), False, "e")
try:
thread.start_new_thread(evalThread, (sender, " ".join(args)))
except Exception, e:
msg(sender, "&cInternal error: %s" % e)
else:
noperm(sender)
return True

View File

@@ -1,5 +1,5 @@
from helpers import * from helpers import *
import simplejson as json import json
import time import time
import thread import thread
@@ -42,7 +42,7 @@ def deleteReport(sender, rep_id):
msg(sender, "&aReport #%s deleted." % rep_id) msg(sender, "&aReport #%s deleted." % rep_id)
reporter = server.getOfflinePlayer(report["player"]) reporter = server.getOfflinePlayer(report["player"])
plugHeader(reporter, "Report") plugHeader(reporter, "Report")
msg(reporter, "&aReport '&e%s&a" was resolved by %s." % (report["msg"], sender.getName())) msg(reporter, "&aReport '&e%s&a' was resolved by %s." % (report["msg"], sender.getName()))
else: else:
msg(sender, "&cThat report does not exist!") msg(sender, "&cThat report does not exist!")

View File

@@ -1,4 +1,4 @@
import simplejson as json import json
from time import time from time import time
from helpers import * from helpers import *
from random import randrange from random import randrange

View File

@@ -3,7 +3,7 @@ import org.bukkit.event.block.BlockPlaceEvent as BlockPlaceEvent
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent
import thread import thread
import simplejson as json import json
from time import sleep from time import sleep
from helpers import * from helpers import *