Merge branch 'dev' of github.com:RedstonerServer/redstoner-utils into dev

Conflicts:
	loginsecurity.py
	player.py
This commit is contained in:
PanFritz
2015-08-18 00:24:26 +02:00
14 changed files with 521 additions and 85 deletions

64
calc.py
View File

@@ -1,29 +1,67 @@
from helpers import * from helpers import *
import threading
import time
calc_users = open_json_file("calc", []) calc_users = open_json_file("calc", [])
math_operators = ["+", "-", "*", "/", "&", "|"] math_operators = ["+", "-", "*", "/", "%", ">", "<", "^", "&", "|"]
ignore_operators = ["**", "&&", "||"] # ** may be too intensive, the others cause syntax errors allowed_strings = ["0b", "0x", "(", ")", "hex(", "bin(", "abs(", "int(", "min(", "max(", "round(", "float("]
allowed_alpha = ["a", "b", "c", "d", "e", "f"]
calc_perm = "utils.calc" calc_perm = "utils.calc"
calc_perm_power = "utils.calc.power"
def calc(sender, text):
def calc(text):
""" """
extracts a mathematical expression from `text` extracts a mathematical expression from `text`
returns (expression, result) or None returns (expression, result) or None
""" """
expression = "" expression = ""
should_calc = False should_calc = False
for char in text: i = 0
if char.isdigit() or (expression and char == ".") or (should_calc and char == " "): while True:
if i >= len(text):
break
char = text[i]
if i < len(text) - 5 and str(char + text[i+1] + text[i+2] + text[i+3] + text[i+4] + text[i+5]) in allowed_strings:
expression += char expression += char
elif char in math_operators: expression += text[i + 1]
expression += text[i + 2]
expression += text[i + 3]
expression += text[i + 4]
expression += text[i + 5]
i += 5
should_calc = True
elif i < len(text) - 3 and str(char + text[i+1] + text[i+2] + text[i+3]) in allowed_strings:
expression += char
expression += text[i + 1]
expression += text[i + 2]
expression += text[i + 3]
i += 3
should_calc = True
elif i < len(text) - 1 and str(char + text[i + 1]) in allowed_strings:
expression += char
expression += text[i + 1]
i += 1
should_calc = True
elif char.isdigit() or char in allowed_alpha or (expression and char == ".") or (should_calc and char == " ") or (should_calc and char == ","):
expression += char
should_calc = True
elif char in math_operators or char in ["(", ")"]:
# calculation must include at least 1 operator # calculation must include at least 1 operator
should_calc = True should_calc = True
expression += char expression += char
elif should_calc and char.isalpha(): elif should_calc and char.isalpha():
# don't include any more text in the calculation # don't include any more text in the calculation
break break
if should_calc and not any(op in expression for op in ignore_operators): i += 1
last_char = ' '
for char in expression:
if last_char == '*' and char == '*':
if sender.hasPermission(calc_perm_power):
break
else:
return None
last_char = char
if should_calc:
try: try:
result = str(eval(expression)) # pylint: disable = W0123 result = str(eval(expression)) # pylint: disable = W0123
except: # pylint: disable = W0702 except: # pylint: disable = W0702
@@ -33,15 +71,19 @@ def calc(text):
return (expression, result) return (expression, result)
return None return None
def thread_calc(message, sender):
output = calc(sender, message)
if output and sender.isOnline():
msg(sender, "&2=== Calc: &e" + output[0] + " &2= &c" + output[1])
@hook.event("player.AsyncPlayerChatEvent", "monitor") @hook.event("player.AsyncPlayerChatEvent", "monitor")
def on_calc_chat(event): def on_calc_chat(event):
sender = event.getPlayer() sender = event.getPlayer()
message = event.getMessage() message = event.getMessage()
if not event.isCancelled() and uid(sender) in calc_users and sender.hasPermission(calc_perm): if not event.isCancelled() and uid(sender) in calc_users and sender.hasPermission(calc_perm):
output = calc(message) thread = threading.Thread(target=thread_calc, args=(message, sender))
if output: thread.daemon = True
msg(sender, "&2=== Calc: &e" + output[0] + " &2= &c" + output[1]) thread.start()
@hook.command("calc", description="Toggles chat calculations") @hook.command("calc", description="Toggles chat calculations")

View File

@@ -37,10 +37,10 @@ def matches_thread(password, user):
@simplecommand("cgpass", @simplecommand("cgpass",
usage = "<password> <new password>", usage = "<password> <new password>",
description = "Changes your password", description = "Changes your password",
senderLimit = 0, senderLimit = 0,
helpNoargs = True) helpNoargs = True)
def change_pass_command(sender, command, label, args): def change_pass_command(sender, command, label, args):
py_player = get_py_player(sender) py_player = get_py_player(sender)

View File

@@ -38,8 +38,8 @@ shared["load_modules"] = [
"adminchat", "adminchat",
# Adds /badge, allows to give players achievements # Adds /badge, allows to give players achievements
"badges", "badges",
# Adds a few block placement corrections/mods # Adds a few block placement corrections/mods
"blockplacemods", "blockplacemods",
# Adds /calc, toggles automatic solving of Math expressions in chat # Adds /calc, toggles automatic solving of Math expressions in chat
"calc", "calc",
# 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

11
misc.py
View File

@@ -116,7 +116,6 @@ def rs_material_broken_by_flow(material):
@simplecommand("sudo", @simplecommand("sudo",
usage = "<player> [cmd..]", usage = "<player> [cmd..]",
description = "Makes <player> write [cmd..] in chat", description = "Makes <player> write [cmd..] in chat",
@@ -132,7 +131,7 @@ def on_sudo_command(sender, command, label, args):
server.dispatchCommand(server.getConsoleSender(), cmd[1:] if is_cmd else cmd) server.dispatchCommand(server.getConsoleSender(), cmd[1:] if is_cmd else cmd)
return None return None
target_player = server.getPlayer(target) target_player = server.getPlayer(target)
if target_player: if target_player and uid(target_player) not in pythoners:
target_player.chat(cmd) target_player.chat(cmd)
return None return None
return "&cPlayer %s not found!" % target return "&cPlayer %s not found!" % target
@@ -196,11 +195,19 @@ def eval_thread(sender, code):
msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c") msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c")
thread.exit() thread.exit()
pythoners = [
"e452e012-2c82-456d-853b-3ac8e6b581f5", # Nemes
"ae795aa8-6327-408e-92ab-25c8a59f3ba1", # jomo
"305ccbd7-0589-403e-a45b-d791dcfdee7d" # PanFritz
]
@simplecommand("pyeval", @simplecommand("pyeval",
usage = "[code..]", usage = "[code..]",
description = "Runs python [code..] and returns the result", description = "Runs python [code..] and returns the result",
helpNoargs = True) helpNoargs = True)
def on_pyeval_command(sender, command, label, args): def on_pyeval_command(sender, command, label, args):
if is_player(sender) and uid(sender) not in pythoners:
return noperm(sender)
msg(sender, " ".join(args), False, "e") msg(sender, " ".join(args), False, "e")
thread.start_new_thread(eval_thread, (sender, " ".join(args))) thread.start_new_thread(eval_thread, (sender, " ".join(args)))
return None return None

212
scriptutils.py Normal file
View File

@@ -0,0 +1,212 @@
from helpers import *
"""
Prints server restart message
arg 0 timeout
arg 1 $(whoami)
arg 2: reason
"""
@hook.command("script_restart")
def print_restart(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&2&l=============================================")
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&9%s is restarting the server." % args[1])
broadcast(None, "&a&lServer is going to restart in %s seconds." % args[0])
broadcast(None, "&6&l%s" % " ".join(args[2:]))
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&2&l=============================================")
else:
noperm(sender)
"""
Prints the server shut down message
arg 0 timeout
arg 1 $(whoami)
arg 2: reason
"""
@hook.command("script_stop")
def print_stop(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&2&l=============================================")
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&9%s is shutting down the server." % args[1])
broadcast(None, "&a&lServer is going to shut down in %s seconds." % args[0])
broadcast(None, "&6&l%s" % " ".join(args[2:]))
broadcast(None, "&r")
broadcast(None, "&r")
broadcast(None, "&2&l=============================================")
else:
noperm(sender)
"""
Prints the shut down abort message
"""
@hook.command("script_stop_abort")
def abort_stop(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4&oShut down has been aborted.")
else:
noperm(sender)
"""
Prints the restart abort message
"""
@hook.command("script_restart_abort")
def abort_restart(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4&oRestart has been aborted.")
else:
noperm(sender)
"""
Prints the backup started message, saves all worlds and turns off world saving
"""
@hook.command("script_backup_begin")
def print_backup_begin(sender, command, lable, args):
if not is_player(sender):
broadcast(None, "&4 =&2 Starting backup now.")
server.dispatchCommand(server.getConsoleSender(), "save-all")
server.dispatchCommand(server.getConsoleSender(), "save-off")
else:
noperm(sender)
"""
Prints the backup finished message and turns on world saving
"""
@hook.command("script_backup_end")
def print_backup_end(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&2 Backup completed.")
server.dispatchCommand(server.getConsoleSender(), "save-on")
else:
noperm(sender)
"""
Prints the backup error message and turns on world saving
"""
@hook.command("script_backup_error")
def print_backup_error(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&c&l Error while backing up!")
server.dispatchCommand(server.getConsoleSender(), "save-on")
else:
noperm(sender)
"""
Prints the world trimming started message and starts trimming
"""
@hook.command("script_trim")
def print_backup_trim(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&3 Deleting all chunks beyond border now.")
server.dispatchCommand(server.getConsoleSender(), "wb Creative trim 1000000 15")
server.dispatchCommand(server.getConsoleSender(), "wb trim confirm")
else:
noperm(sender)
"""
Prints the thimming finished message
arg 0 size difference of world
arg 1: world border trim data
"""
@hook.command("script_trim_result")
def print_backup_trim_res(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&4 =&3 Chunk deletion saved %s (&a%sMB&3)" % (" ".join(args[1:]), args[0]))
else:
noperm(sender)
"""
Prints the database backup started message and admin-chat warning
"""
@hook.command("script_backup_database_begin")
def print_backup_db_begin(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Starting database backup now.")
server.dispatchCommand(server.getConsoleSender(), "ac &aLogblock may be unavailable!")
else:
noperm(sender)
"""
Prints the database dumps compression started message
"""
@hook.command("script_backup_database_dumps")
def print_backup_db_dumps(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "ac &aDumps completed, logblock available again.")
server.dispatchCommand(server.getConsoleSender(), "ac &aNow compressing dumps, will take a while...")
else:
noperm(sender)
"""
Prints the database finished message and backup size in admin-chat
arg 0 size of backup
"""
@hook.command("script_backup_database_end")
def print_backup_db_end(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Databse backup completed.")
server.dispatchCommand(server.getConsoleSender(), "ac &abackup size: &2%sMB&a." % args[0])
else:
noperm(sender)
"""
Prints the database backup error message
"""
@hook.command("script_backup_database_error")
def print_backup_db_error(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&c&l Error while backing up database!")
else:
noperm(sender)
"""
Prints the database backup abort message
"""
@hook.command("script_backup_database_abort")
def print_backup_db_abort(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&6 =&2 Database backup aborted.")
else:
noperm(sender)
"""
Prints the spigot update message
"""
@hook.command("script_spigot_update")
def print_update(sender, command, label, args):
if not is_player(sender):
broadcast(None, "&9 =&2 A new Spigot version has been downloaded!")
broadcast(None, "&9 =&2 Update will be applied after the next reboot.")
else:
noperm(sender)
"""
Prints the admin-chat warning for disk is filled
arg 0 fill percentage
"""
@hook.command("script_disk_filled")
def print_disk_filled(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "ac &4&lWARNING:&6 Disk is filled > 96% (" + args[0] + "%)")
server.dispatchCommand(server.getConsoleSender(), "ac &4 Server will shut down at 98%!")
server.dispatchCommand(server.getConsoleSender(), "ac &4 Contact an admin &nimmediately&4!")
else:
noperm(sender)
"""
Saves all worlds, kicks players and shuts down the server
arg 0: reason
"""
@hook.command("script_shutdown")
def shutdown(sender, command, label, args):
if not is_player(sender):
server.dispatchCommand(server.getConsoleSender(), "save-all")
server.dispatchCommand(server.getConsoleSender(), "kickall %s" % " ".join(args))
server.dispatchCommand(server.getConsoleSender(), "stop")
else:
noperm(sender)

175
setup.sh Executable file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env bash
# exit on failure
set -e
for cmd in curl java unzip git pip; do
if ! which -s "$cmd"; then
tput setf 4 >&2
echo "Error: please install '$cmd' to proceed" >&2
tput sgr0 >&2
exit 1
fi
done
echo -e "> This will only set up Spigot and all the plugins, configuration files are still up to you to manage"
echo -e "> Press enter to coninue"
read
mkdir -v "redstoner"
cd "redstoner"
mkdir -v "server"
mkdir -v "build"
cd "build"
echo -e "\n> Downloading Spigot build tools"
curl --progress-bar -Lo "buildtools.jar" "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
echo -e "\n> Building Spigot, this will take a while ..."
java -jar BuildTools.jar > /dev/null
cp -v spigot-*.jar "../server/spigot.jar"
rm spigot-*.jar
cd "../server/"
mkdir -v "plugins"
cd "plugins"
echo ">> Downloading essentials.jar ..."
curl --progress-bar -Lo "essentials.jar" "https://github.com/RedstonerServer/Essentials/releases/download/stable-2.9.6-REDSTONER/Essentials-2.x-REDSTONER.jar"
echo ">> Downloading essentialschat.jar ..."
curl --progress-bar -Lo "essentialschat.jar" "https://hub.spigotmc.org/jenkins/job/Spigot-Essentials/lastSuccessfulBuild/artifact/EssentialsChat/target/EssentialsChat-2.x-SNAPSHOT.jar"
echo ">> Downloading imageonmap.jar ..."
curl --progress-bar -Lo "imageonmap.jar." "https://dev.bukkit.org/media/files/772/680/imageonmap.jar"
echo ">> Downloading logblock.jar ..."
curl --progress-bar -Lo "logblock.jar." "https://dev.bukkit.org/media/files/757/963/LogBlock.jar"
echo ">> Downloading logblockquestioner.zip ..."
curl --progress-bar -Lo "logblockquestioner.zip" "https://cloud.github.com/downloads/DiddiZ/LogBlockQuestioner/LogBlockQuestioner%20v0.03.zip"
echo ">> Downloading multiverse-core.jar ..."
curl --progress-bar -Lo "multiverse-core.jar" "https://dev.bukkit.org/media/files/588/781/Multiverse-Core-2.4.jar"
echo ">> Downloading multiverse-portals.jar ..."
curl --progress-bar -Lo "multiverse-portals.jar." "https://dev.bukkit.org/media/files/588/790/Multiverse-Portals-2.4.jar"
echo ">> Downloading multiverse-netherportals.jar ..."
curl --progress-bar -Lo "multiverse-netherportals.jar." "https://dev.bukkit.org/media/files/589/64/Multiverse-NetherPortals-2.4.jar"
echo ">> Downloading multiverse-inventories.jar ..."
curl --progress-bar -Lo "multiverse-inventories.jar." "https://dev.bukkit.org/media/files/663/303/Multiverse-Inventories-2.5.jar"
echo ">> Downloading permissionsex.jar ..."
curl --progress-bar -Lo "permissionsex.jar" "https://dev.bukkit.org/media/files/882/992/PermissionsEx-1.23.3.jar"
echo ">> Downloading plotme.jar ..."
curl --progress-bar -Lo "plotme.jar" "http://ci.worldcretornica.com/job/PlotMe-Core/244/artifact/target/PlotMe-Core.jar"
echo ">> Downloading plotme-defaultgenerator.jar ..."
curl --progress-bar -Lo "plotme-defaultgenerator.jar" "http://ci.worldcretornica.com/job/PlotMe-DefaultGenerator/83/artifact/target/PlotMe-DefaultGenerator.jar"
echo ">> Downloading serversigns.jar ..."
curl --progress-bar -Lo "serversigns.jar." "https://dev.bukkit.org/media/files/876/381/ServerSigns.jar"
echo ">> Downloading redstoneclockdetector.jar ..."
curl --progress-bar -Lo "redstoneclockdetector.jar." "https://dev.bukkit.org/media/files/577/253/RedstoneClockDetector.jar"
echo ">> Downloading vault.jar ..."
curl --progress-bar -Lo "vault.jar" "https://dev.bukkit.org/media/files/837/976/Vault.jar"
echo ">> Downloading worldborder.jar ..."
curl --progress-bar -Lo "worldborder.jar." "https://dev.bukkit.org/media/files/883/629/WorldBorder.jar"
echo ">> Downloading worldguard.jar ..."
curl --progress-bar -Lo "worldguard.jar." "https://github.com/RedstonerServer/WorldGuard/releases/download/6.0.0-redstoner/worldguard-6.0.0-REDSTONER.jar"
echo ">> Downloading worldedit.jar ..."
curl --progress-bar -Lo "worldedit.jar" "https://dev.bukkit.org/media/files/880/435/worldedit-bukkit-6.1.jar"
echo ">> Downloading pythonpluginloader.jar ..."
curl --progress-bar -Lo "pythonpluginloader.jar" "https://bamboo.gserv.me/browse/PLUG-PYPL/latestSuccessful/artifact/JOB1/Version-agnostic-jar/PyPluginLoader.jar"
echo -e "\n> Unpacking LogBlockQuestioner"
unzip -q "logblockquestioner.zip" "LogBlockQuestioner.jar"
rm "logblockquestioner.zip"
mv -v "LogBlockQuestioner.jar" "logblockquestioner.jar."
echo -e "\n> Pulling redstoner-utils ..."
git clone -q "git@github.com:RedstonerServer/redstoner-utils.git" "redstoner-utils.py.dir" > /dev/null
echo -e "\n> Installing dependencies"
pip install passlib
echo -e "\n> All plugins downloaded"
cd "redstoner-utils.py.dir"
echo -e "\n> Duplicating sample files"
for file in ls ./*.example; do
cp -v "$file" "$(echo "$file" | rev | cut -d "." -f 2- | rev)"
done
cd "../.."
mkdir -v "lib"
cd "lib"
echo -e "\n> Downloading MySQL Connector ..."
curl --progress-bar -Lo "mysql-connector.zip" "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.36.zip"
echo "> Extracting MySQL Connector"
unzip -p mysql-connector.zip "mysql-connector-java-5.1.36/mysql-connector-java-5.1.36-bin.jar" > mysql-connector.jar
rm "mysql-connector.zip"
cd ".."
echo -e "\n> Creating startup script"
cat > start.sh <<EOF
#!/usr/bin/env bash
java -Xms512m -Xmx1g -jar spigot.jar
EOF
chmod +x start.sh
port="25565"
re='^[0-9]+$'
if [[ "$1" =~ $re ]]; then
port="$1"
fi
echo "> Setting port to $port"
echo "> Generating server.properties"
cat > server.properties <<EOF
#Minecraft server properties
#Sat Jul 25 15:42:21 CEST 2015
spawn-protection=16
generator-settings=
force-gamemode=false
allow-nether=true
gamemode=1
broadcast-console-to-ops=true
enable-query=false
player-idle-timeout=0
difficulty=1
spawn-monsters=true
op-permission-level=4
resource-pack-hash=
announce-player-achievements=true
pvp=true
snooper-enabled=true
level-type=FLAT
hardcore=false
enable-command-block=false
max-players=20
network-compression-threshold=256
max-world-size=29999984
server-port=$port
server-ip=
spawn-npcs=true
allow-flight=false
level-name=world
view-distance=10
resource-pack=
spawn-animals=true
white-list=false
generate-structures=true
online-mode=true
max-build-height=256
level-seed=
use-native-transport=true
motd=Redstoner dev server
enable-rcon=false
EOF
echo -e "> Generating eula.txt"
echo "eula=true" > eula.txt
echo -e "\n> $(tput setf 2)All Done! $(tput sgr0)Don't forget to configure plugins for your needs."
echo "> Run redstoner/server/start.sh to start the server"
echo "> Our plugins are in redstoner/server/plugins/redstoner-utils.py.dir"

View File

@@ -359,11 +359,11 @@ class Arena(object):
return data return data
def load(self, data): def load(self, data):
self.explosion_damage = float(data["explosion"]) self.explosion_damage = None if str(data["explosion"]) == "None" else float(data["explosion"])
self.player_limit = int(data["players"]) self.player_limit = None if str(data["players"]) == "None" else int(data["players"])
self.refill = int(data["refill"]) self.refill = None if str(data["refill"]) == "None" else int(data["refill"])
self.arena_type = str(data["type"]) self.arena_type = str(data["type"])
self.match_goal = int(data["goal"]) self.match_goal = None if str(data["goal"]) == "None" else int(data["goal"])
self.corner1 = Coords(None).load(data["corners"][0]) if not data["corners"][0] == None else None self.corner1 = Coords(None).load(data["corners"][0]) if not data["corners"][0] == None else None
self.corner2 = Coords(None).load(data["corners"][1]) if not data["corners"][1] == None else None self.corner2 = Coords(None).load(data["corners"][1]) if not data["corners"][1] == None else None
self.tpp = Coords(None).load(data["corners"][2]) if not data["corners"][2] == None else None self.tpp = Coords(None).load(data["corners"][2]) if not data["corners"][2] == None else None
@@ -561,7 +561,7 @@ timingsThread.start()
# Events # Events
############################################################################################## ##############################################################################################
@hook.event("player.PlayerMoveEvent", "high") @hook.event("player.PlayerMoveEvent", "low")
def onMove(event): def onMove(event):
if event.getPlayer().getWorld().getName() != "minigames": if event.getPlayer().getWorld().getName() != "minigames":
return return