Merge remote-tracking branch 'origin/dev'
This commit is contained in:
118
blockplacemods.py
Normal file
118
blockplacemods.py
Normal file
@@ -0,0 +1,118 @@
|
||||
from helpers import *
|
||||
from basecommands import simplecommand
|
||||
|
||||
denyslabcorrection = open_json_file("denyslabcorrection", []) #Players that don't want slabs corrected
|
||||
denyautofill = open_json_file("denyautocauldronfill", [])
|
||||
denyautolevel = open_json_file("denyautocauldronlevel", [])
|
||||
|
||||
def saveslabs():
|
||||
save_json_file("denyslabcorrection", denyslabcorrection)
|
||||
def savecauldrons():
|
||||
save_json_file("denyautocauldronfill", denyautofill)
|
||||
def savelevels():
|
||||
save_json_file("denyautocauldronlevel", denyautolevel)
|
||||
|
||||
@simplecommand("autofillcauldron",
|
||||
aliases = ["fillcauldronautomatically"],
|
||||
usage = "on/off",
|
||||
helpNoargs = True,
|
||||
description = "Sets whether you want placed cauldrons to fill \nautomatically",
|
||||
amax = 1,
|
||||
senderLimit = 0)
|
||||
def autofillcauldron_command(sender, command, label, args):
|
||||
uuid = uid(server.getPlayer(sender.getName()))
|
||||
if args[0].lower() == "off":
|
||||
if uuid in denyautofill:
|
||||
return "&cAuto fillment of cauldrons is already disabled"
|
||||
denyautofill.append(uuid)
|
||||
savecauldrons()
|
||||
return "&aFilling cauldrons will no longer happen automatically"
|
||||
if args[0].lower() == "on":
|
||||
if uuid not in denyautofill:
|
||||
return "&cAuto fillment of cauldrons is already enabled"
|
||||
denyautofill.remove(uuid)
|
||||
savecauldrons()
|
||||
return "&aFilling cauldrons will happen automatically from now"
|
||||
return "HELP"
|
||||
|
||||
|
||||
@simplecommand("autoflipslab",
|
||||
aliases = ["autoflipstep", "flipslabautomatically", "flipstepautomatically"],
|
||||
usage = "on/off",
|
||||
helpNoargs = True,
|
||||
description = "Sets whether you want placed slabs to be turned \nupside-down",
|
||||
amax = 1,
|
||||
senderLimit = 0)
|
||||
def autoflipslab_command(sender, command, label, args):
|
||||
uuid = uid(server.getPlayer(sender.getName()))
|
||||
if args[0].lower() == "off":
|
||||
if uuid in denyslabcorrection:
|
||||
return "&cAuto flipping of slabs is already disabled"
|
||||
denyslabcorrection.append(uuid)
|
||||
saveslabs()
|
||||
return "&aFlipping slabs will no longer happen automatically"
|
||||
if args[0].lower() == "on":
|
||||
if uuid not in denyslabcorrection:
|
||||
return "&cAuto flipping of slabs is already enabled"
|
||||
denyslabcorrection.remove(uuid)
|
||||
saveslabs()
|
||||
return "&aFlipping slabs will happen automatically from now"
|
||||
return "HELP"
|
||||
|
||||
|
||||
@simplecommand("autotakewater",
|
||||
aliases = ["autocauldronlevel"],
|
||||
usage = "on/off",
|
||||
helpNoargs = True,
|
||||
description = "Sets whether you want right clicking cauldrons \nwith empty hand or redstone dust \nto lower water level",
|
||||
amax = 1,
|
||||
senderLimit = 0)
|
||||
def autoflipslab_command(sender, command, label, args):
|
||||
uuid = uid(server.getPlayer(sender.getName()))
|
||||
if args[0].lower() == "off":
|
||||
if uuid in denyautolevel:
|
||||
return "&cTaking water with hand/redstone is already disabled"
|
||||
denyautolevel.append(uuid)
|
||||
savelevels()
|
||||
return "&aYou can no longer take water with hand/redstone"
|
||||
if args[0].lower() == "on":
|
||||
if uuid not in denyautolevel:
|
||||
return "&cTaking water with hand/redstone is already enabled"
|
||||
denyautolevel.remove(uuid)
|
||||
savelevels()
|
||||
return "&aYou can take water with hand/redstone from now"
|
||||
return "HELP"
|
||||
|
||||
|
||||
@hook.event("block.BlockPlaceEvent", "monitor")
|
||||
def on_block_place(event):
|
||||
if event.isCancelled():
|
||||
return
|
||||
player = event.getPlayer()
|
||||
if player.getWorld().getName() not in ("Creative", "Trusted", "world"):
|
||||
return
|
||||
uuid = uid(player)
|
||||
block = event.getBlockPlaced()
|
||||
if uuid not in denyslabcorrection and str(block.getType()) in ("WOOD_STEP", "STEP") and block.getData() < 8:
|
||||
block.setData(block.getData() + 8) # Flip upside down
|
||||
elif uuid not in denyautofill and str(block.getType()) == "CAULDRON":
|
||||
block.setData(3) #3 layers of water, 3 signal strength
|
||||
|
||||
|
||||
@hook.event("player.PlayerInteractEvent", "monitor")
|
||||
def on_interact(event):
|
||||
player = event.getPlayer()
|
||||
if uid(player) in denyautolevel or player.getWorld().getName() not in ("Creative", "Trusted", "world"):
|
||||
return
|
||||
if str(event.getAction()) != "RIGHT_CLICK_BLOCK":
|
||||
return
|
||||
if event.hasItem() and not str(event.getItem().getType()) == "REDSTONE":
|
||||
return
|
||||
block = event.getClickedBlock()
|
||||
if str(block.getType()) == "CAULDRON" and block.getData() > 0:
|
||||
block.setData(block.getData() - 1) #Lower water level by one
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
10
check.py
10
check.py
@@ -11,7 +11,7 @@ from helpers import *
|
||||
# receive info based on the user's IP. information provided by ipinfo.io
|
||||
def ip_info(player):
|
||||
if player.isOnline():
|
||||
return json.load(urllib2.urlopen("http://ipinfo.io%s/json" % str(player.getAddress().getAddress())))
|
||||
return json.load(urllib2.urlopen("https://ipinfo.io%s/json" % str(player.getAddress().getAddress())))
|
||||
else:
|
||||
return {}
|
||||
|
||||
@@ -42,11 +42,6 @@ def get_website_data(player):
|
||||
return ("http://redstoner.com/users/%s" % results[0][0], results[0][1]) if results else (None, None)
|
||||
|
||||
|
||||
# receive country based on the user's IP
|
||||
def get_country(data):
|
||||
return str(data.get("country"))
|
||||
|
||||
|
||||
def get_all_names(player):
|
||||
uuid = str(uid(player)).replace("-", "")
|
||||
names = json.load(urllib2.urlopen("https://api.mojang.com/user/profiles/%s/names" % uuid))
|
||||
@@ -69,7 +64,8 @@ def get_all_data(sender, player):
|
||||
msg(sender, "&6> Website account: &e%s" % website[0])
|
||||
msg(sender, "&6> email: &e%s" % website[1])
|
||||
msg(sender, "&7 -- Data provided by ipinfo.io")
|
||||
msg(sender, "&6> Country: &e%s" % get_country(data))
|
||||
msg(sender, "&6> Country: &e%s" % str(data.get("country")))
|
||||
msg(sender, "&6> Network: &e%s" % str(data.get("org")))
|
||||
msg(sender, "&7 -- Data provided by Mojang")
|
||||
msg(sender, "&6> All ingame names used so far: &e%s" % get_all_names(player))
|
||||
except:
|
||||
|
||||
121
loginsecurity.py
Normal file
121
loginsecurity.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from helpers import *
|
||||
from basecommands import simplecommand
|
||||
import bcrypt
|
||||
from time import time as now
|
||||
import thread
|
||||
|
||||
|
||||
wait_time = 60 #seconds
|
||||
admin_perm = "utils.loginsecurity.admin"
|
||||
min_pass_length = 6
|
||||
|
||||
run_kick_thread = True
|
||||
blocked_events = ["block.BlockBreakEvent", "block.BlockPlaceEvent", "player.PlayerMoveEvent"]
|
||||
passwords = open_json_file("loginpasswords", {})
|
||||
|
||||
#if passwords == None: (set default value to None ^^)
|
||||
# Keep everyone from playing? (Insecure)
|
||||
|
||||
withholdings = {} #pname : jointime
|
||||
|
||||
|
||||
def save_passwords():
|
||||
save_json_file("loginpasswords", passwords)
|
||||
|
||||
|
||||
def matches(password, user):
|
||||
hashed = passwords.get(uid(user))
|
||||
return bcrypt.hashpw(password, hashed) == hashed
|
||||
|
||||
|
||||
@simplecommand("login",
|
||||
usage = "<password>",
|
||||
description = "Logs you in if <password> matches your password.",
|
||||
senderLimit = 0,
|
||||
helpNoargs = True)
|
||||
def login_command(sender, command, label, args):
|
||||
password = " ".join(args)
|
||||
if matches(password, sender):
|
||||
del withholdings[sender.getName()]
|
||||
return "&aLogged in successfully!"
|
||||
return "&cInvalid password"
|
||||
|
||||
|
||||
@simplecommand("register",
|
||||
usage = "<password>",
|
||||
description = "Registers you with <password>. Next time you join, log in with /login",
|
||||
senderLimit = 0,
|
||||
helpNoArgs = True)
|
||||
def register_command(sender, command, label, args):
|
||||
uuid = uid(sender)
|
||||
if uuid in passwords:
|
||||
return "&cYou are already registered!"
|
||||
password = " ".join(args)
|
||||
if len(password) < min_pass_length:
|
||||
return "&cThe password has to be made up of at least 8 characters!"
|
||||
hashed = bcrypt.hashpw(password, bcrypt.gensalt(16))
|
||||
passwords[uuid] = hashed
|
||||
return "&cPassword set. Use /login <password> upon join."
|
||||
|
||||
|
||||
@simplecommand("rmpass",
|
||||
usage = "<password>",
|
||||
description = "Removes your password if the password matches",
|
||||
senderLimit = 0,
|
||||
helpNoArgs = True)
|
||||
def rmpass_command(sender, command, label, args):
|
||||
password = " ".join(args)
|
||||
if matches(password, sender):
|
||||
del passwords[uuid(sender)]
|
||||
return "&aPassword removed successfully. You will not be prompted anymore."
|
||||
return "&cInvalid password"
|
||||
|
||||
|
||||
@simplecommand("rmotherpass",
|
||||
aliases = ["lacrmpass"],
|
||||
usage = "<user>",
|
||||
description = "Removes password of <user> and sends them a notification",
|
||||
helpNoArgs = True)
|
||||
def rmotherpass_command(sender, command, label, args):
|
||||
user = server.getOfflinePlayer(args[0])
|
||||
if user:
|
||||
del passwords[uid(user)]
|
||||
runas(server.getConsoleSender(), colorify("mail send %s &cYour password was reset by a staff member. Use &o/register&c to set a new one."))
|
||||
return "&sPassword of %s reset successfully" % user.getName()
|
||||
return "&cThat player could not be found"
|
||||
|
||||
|
||||
@hook.event("player.PlayerJoinEvent", "highest")
|
||||
def on_join(event):
|
||||
user = event.getPlayer()
|
||||
if get_id(user) in passwords:
|
||||
withholdings[user.getName()] = now()
|
||||
|
||||
|
||||
@hook.event("player.PlayerQuitEvent", "normal")
|
||||
def on_quit(event):
|
||||
del withholdings[event.getPlayer().getName()]
|
||||
|
||||
|
||||
def kick_thread():
|
||||
wait_time_millis = wait_time * 1000
|
||||
while True:
|
||||
if not run_kick_thread:
|
||||
info("Exiting LoginSecurity kicking thread!")
|
||||
thread.exit()
|
||||
time.sleep(1)
|
||||
moment = now()
|
||||
for name, jointime in withholdings.iteritems():
|
||||
if moment - jointime > wait_time_millis:
|
||||
server.getPlayer(name).kickPlayer(colorify("&cLogin timed out"))
|
||||
|
||||
|
||||
thread.start_new_thread(kick_thread, ())
|
||||
|
||||
for blocked_event in blocked_events:
|
||||
@hook.event(blocked_event, "low")
|
||||
def on_blocked_event(event):
|
||||
user = event.getPlayer()
|
||||
if user.getName() in withholdings:
|
||||
event.setCancelled(True)
|
||||
msg(user, "&cYou have to log in first! Use /login <password>")
|
||||
6
main.py
6
main.py
@@ -38,6 +38,8 @@ shared["load_modules"] = [
|
||||
"adminchat",
|
||||
# Adds /badge, allows to give players achievements
|
||||
"badges",
|
||||
# Adds a few block placement corrections/mods
|
||||
"blockplacemods",
|
||||
# Adds /calc, toggles automatic solving of Math expressions in chat
|
||||
"calc",
|
||||
# Plugin to locate laggy chunks. /lc <n> lists chunks with more than n entities
|
||||
@@ -73,7 +75,9 @@ shared["load_modules"] = [
|
||||
#adds snowbrawl minigame
|
||||
#"snowbrawl",
|
||||
# Adds /tm [player] for a messages to be sent to this player via /msg
|
||||
"pmtoggle"
|
||||
"pmtoggle",
|
||||
# Replacement for LoginSecurity
|
||||
"loginsecurity"
|
||||
# NOTICE: If you add something here, please add a small descriptive comment above!
|
||||
]
|
||||
shared["modules"] = {}
|
||||
|
||||
37
misc.py
37
misc.py
@@ -182,16 +182,44 @@ def eval_argument_thread(event):
|
||||
thread.exit()
|
||||
"""
|
||||
|
||||
|
||||
@simplecommand("pyeval",
|
||||
usage = "[code..]",
|
||||
description = "Runs python [code..] and returns the result",
|
||||
helpNoargs = True)
|
||||
usage = "[code..]",
|
||||
description = "Runs python [code..] and returns the result",
|
||||
helpNoargs = True)
|
||||
def on_pyeval_command(sender, command, label, args):
|
||||
msg(sender, " ".join(args), False, "e")
|
||||
thread.start_new_thread(eval_thread, (sender, " ".join(args)))
|
||||
return None
|
||||
|
||||
|
||||
@simplecommand("tempadd",
|
||||
usage = "<user> <group> [duration]",
|
||||
description = "Temporarily adds <user> to <group> for \n[duration] minutes. Defaults to 1 week.",
|
||||
helpNoargs = True,
|
||||
helpSubcmd = True,
|
||||
amin = 2,
|
||||
amax = 3)
|
||||
def tempadd_command(sender, command, label, args):
|
||||
if not sender.hasPermission("permissions.manage.membership." + args[1]):
|
||||
return "&cYou do not have permission to manage that group!"
|
||||
if len(args) == 3:
|
||||
if not args[2].isdigit():
|
||||
return "&cThats not a number!"
|
||||
duration = int(args[2]) * 60
|
||||
else:
|
||||
duration = 604800
|
||||
if duration <= 0:
|
||||
return "&cThats too short!"
|
||||
cmd = "pex user %s group add %s * %s" % (args[0], args[1], duration)
|
||||
runas(sender, cmd)
|
||||
|
||||
m, s = divmod(duration, 60)
|
||||
h, m = divmod(m, 60)
|
||||
d, h = divmod(h, 24)
|
||||
return "&aAdded to group for %dd%dh%dm" % (d, h, m)
|
||||
|
||||
|
||||
@hook.command("modules")
|
||||
def on_modules_command(sender, command, label, args):
|
||||
"""
|
||||
@@ -228,9 +256,6 @@ def rs_material_broken_by_flow(material):
|
||||
return length > 1 and (parts[0] == "DIODE" or parts[1] in ("TORCH", "WIRE", "BUTTON", "HOOK") or (length == 3 and parts[1] == "COMPARATOR"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
@hook.event("player.AsyncPlayerChatEvent", "lowest")
|
||||
def on_chat(event):
|
||||
|
||||
Reference in New Issue
Block a user