This commit is contained in:
Gap
2015-01-14 18:30:31 +01:00
25 changed files with 1608 additions and 1544 deletions

View File

@@ -59,7 +59,4 @@ def on_calc_command(sender, args):
toggle(sender, calc_users, name = "Calc")
save_json_file("calc", calc_users)
status = "enabled" if uid(sender) in calc_users else "disabled"
msg(sender, "&6We just &e%s&6 Chat Calculator for you!" % status)
return True

View File

@@ -1,20 +1,45 @@
import json
import urllib2
import datetime
import mysqlhack #pylint: disable = unused-import
from traceback import format_exc as print_traceback
from com.ziclix.python.sql import zxJDBC
from secrets import *
from helpers import *
# receive info based on the user's IP. information provided by ipinfo.io
def ip_info(player):
data = json.load(urllib2.urlopen("http://ipinfo.io%s/json" % str(player.getAddress().getAddress())))
return data
if player.isOnline():
return json.load(urllib2.urlopen("http://ipinfo.io%s/json" % str(player.getAddress().getAddress())))
else:
return {}
# receive first join date based on the player data (may not be accurate)
def get_first_join(player):
first_join = int(player.getFirstPlayed())
dt = datetime.datetime.fromtimestamp(first_join/1000.0)
return "%s-%s-%s %s:%s:%s" % (str(dt.year), str(dt.month), str(dt.day), str(dt.hour), str(dt.minute), str(dt.second))
return dt.strftime("%Y-%m-%d %H:%M")
# receive last seen date based on the player data
def get_last_seen(player):
last_seen = int(player.getLastPlayed())
dt = datetime.datetime.fromtimestamp(last_seen/1000.0)
return dt.strftime("%Y-%m-%d %H:%M")
# receive link and email from website
def get_website_data(player):
conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver")
curs = conn.cursor()
uuid = str(uid(player)).replace("-", "")
curs.execute("SELECT DISTINCT `id`, `email` FROM users WHERE `uuid` = ? LIMIT 1", (uuid,))
results = curs.fetchall()
curs.close()
conn.close()
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
@@ -23,9 +48,10 @@ def get_country(data):
def get_all_names(player):
uuid = str(player.getUniqueId()).replace("-", "")
uuid = str(uid(player)).replace("-", "")
names = json.load(urllib2.urlopen("https://api.mojang.com/user/profiles/%s/names" % uuid))
return ", ".join(names)
# [ {"name": "some_name"}, {"name": "other_name"} ]
return ", ".join([name["name"] for name in names])
# combines data
@@ -36,29 +62,31 @@ def get_all_data(sender, player):
try:
msg(sender, "&7 -- Data provided by Redstoner")
msg(sender, "&6> UUID: &e%s" % str(player.getUniqueId()))
msg(sender, "&6> UUID: &e%s" % str(uid(player)))
msg(sender, "&6> First joined: &7(y-m-d h:m:s) &e%s" % get_first_join(player))
msg(sender, "")
msg(sender, "&6> Last seen: &7(y-m-d h:m:s) &e%s" % get_last_seen(player))
website = get_website_data(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, "&7 -- Data provided by Mojang")
msg(sender, "&6> All ingame names used so far: &e%s" % get_all_names(player))
except Exception as e:
except:
# can throw exceptions such as timeouts when Mojang API is down
warn(e)
warn(print_traceback())
msg(sender, "&cSorry, something went wrong while fetching data")
@hook.command("check", description="Displays useful stuff about a user", usage="/check <player>")
def on_hook_command(sender, args):
if sender.hasPermission("utils.check"):
if not checkargs(sender, args, 1, 1):
return True
plugin_header(sender, "Check")
msg(sender, "&7Please notice that the data may not be fully accurate!")
player = server.getPlayer(args[0]) if len(args) > 0 else None
if player is not None and is_player(player):
player = server.getOfflinePlayer(args[0]) if len(args) > 0 else None
get_all_data(sender, player)
else:
msg(sender, "&cLooks like this player is not online.")
else:
msg(sender, "&4You don't have the required permissions to execute this command!")
return True

View File

@@ -35,7 +35,7 @@ def on_dammnspam_command(sender, args):
msg(sender, "&c/damnspam <seconds> &e(Buttons/Levers)")
msg(sender, "&c/damnspam <seconds after off> <seconds after on> &e(Levers only)")
return True
#Gittestlol
if not is_creative(sender):
msg(sender, "&cYou can only do this in Creative mode.")
return True

View File

@@ -198,28 +198,15 @@ def save_json_file(filename, obj):
error("Failed to write to %s: %s" % (filename, e))
def toggle(player, ls, add = None, name = "Toggle", on = "&a%s now on!", off = "&c%s now off!", already = "&c%s was already %s"):
def toggle(player, ls, name = "Toggle", add = None):
"""
Toggle presence of a player's UUID in a list (ls)
'add' controls if a player should be added(True) or removed(False)
if 'add' is None, ls will simply be toggled for that player.
%s in on, off, and already is replaced with the name
when 'add' is given, but won't change anything, %s in 'already' is replaced with "ON" or "OFF"
Toggles presence of a player's UUID in a list
If add is given, True explicitely adds it whereas False removes it
"""
pid = uid(player)
enabled = pid in ls
# Do some checks and remove pid.
if enabled and add == False:
if pid in ls or add == False:
ls.remove(pid)
msg(player, on % name)
# Do some checks and append pid.
elif not enabled and add == True:
msg(player, "&a%s turned off!" % name)
elif add != False:
ls.append(pid)
msg(player, off % name)
# Already on/off (optional)
else:
msg(player, already % (name, " ON" if add else " OFF"))
msg(player, "&a%s turned on!" % name)

23
main.py
View File

@@ -9,6 +9,7 @@ from traceback import format_exc as print_traceback
sys.path += ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/pymodules/python2.7', '/usr/lib/pyshared/python2.7']
try:
# Library that adds a bunch of re-usable methods which are used in nearly all other modules
from helpers import *
except:
print("[RedstonerUtils] ERROR: Failed to import helpers:")
@@ -31,23 +32,43 @@ info("Loading RedstonerUtils...")
# Import all modules, in this order
shared["load_modules"] = [
# Collection of tiny utilities
"misc",
# Adds chat for staff using /ac <text or ,<text>
"adminchat",
# Adds /badge, allows to give players achievements
"badges",
# 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
"lagchunks",
# Adds /report and /rp, Stores reports with time and location
"reports",
# Adds group-chat with /chatgroup and /cgt to toggle normal chat into group mode
"chatgroups",
# Adds /token, reads and writes from the database to generate pronouncable (and thus memorable) registration-tokens for the website
"webtoken",
# Adds /lol, broadcasts random funyy messages. A bit like the splash text in the menu
"saylol",
# Shows the owner of a skull when right-clicked
"skullclick",
# Adds /listen, highlights chat and plays a sound when your name was mentioned
"mentio",
# Adds /cycler, swaps the hotbar with inventory when player changes slot from right->left or left->right
"cycle",
# Adds /getmotd & /setmotd to update the motd on the fly (no reboot)
"motd",
# AnswerBot. Hides stupid questions from chat and tells the sender about /faq or the like
"abot",
# Adds '/forcefield', creates forcefield for players who want it.
"forcefield",
# Adds /damnspam, creates timeout for buttons/levers to mitigate button spam.
"damnspam",
"check"
# Adds /check, useful to lookup details about a player
"check",
# Adds /imout, displays fake leave/join messages
"imout"
# NOTICE: If you add something here, please add a small descriptive comment above!
]
shared["modules"] = {}
for module in shared["load_modules"]:

77
misc.py
View File

@@ -5,12 +5,12 @@ from sys import exc_info
import thread
import org.bukkit.inventory.ItemStack as ItemStack
#
# Welcome new players
#
@hook.event("player.PlayerJoinEvent", "monitor")
def on_join(event):
"""
Welcome new players
"""
player = event.getPlayer()
# send welcome broadcast
@@ -23,7 +23,7 @@ def on_join(event):
msg(player, " \n \n \n \n \n \n \n \n \n \n \n \n ")
msg(player, " &4Welcome to the Redstoner Server!")
msg(player, " &6Before you ask us things, take a quick")
msg(player, " &6look at the &a&l/FAQ &6command.")
msg(player, " &6look at &a&nredstoner.com/info")
msg(player, " \n&6thank you and happy playing ;)")
msg(player, " \n \n")
@@ -36,13 +36,12 @@ def on_join(event):
player.teleport(player.getWorld().getSpawnLocation())
#
# /sudo - execute command/chat *as* a player/console
#
@hook.command("sudo")
def on_sudo_command(sender, args):
"""
/sudo
execute command/chat *as* a player/console
"""
if sender.hasPermission("utils.sudo"):
plugin_header(sender, "Sudo")
if not checkargs(sender, args, 2, -1):
@@ -71,13 +70,11 @@ def on_sudo_command(sender, args):
return True
#
# /gm - custom gamemode command with extra perms for greater control
#
#@hook.command("gm")
#def on_gm_command(sender, args):
# """
# /gm - custom gamemode command with extra perms for greater control
# """
# if not is_player(sender):
# msg(sender, "&cDerp! Can't run that from console!")
# return True
@@ -98,14 +95,14 @@ def on_sudo_command(sender, args):
# return True
#
# Clicking redstone_sheep with shears will drop redstone + wool and makes a moo sound
#
last_shear = 0.0
@hook.event("player.PlayerInteractEntityEvent")
def on_player_entity_interact(event):
"""
Clicking redstone_sheep with shears will drop redstone + wool
also makes a moo sound for the shearer
"""
global last_shear
if not event.isCancelled():
shear_time = now()
@@ -120,12 +117,12 @@ def on_player_entity_interact(event):
sender.playSound(entity.getLocation(), "mob.cow.say", 1, 1)
#
# /pluginversions - print all plugins + versions; useful when updating plugins
#
@hook.command("pluginversions")
def on_pluginversions_command(sender, args):
"""
/pluginversions
print all plugins + versions; useful when updating plugins
"""
plugin_header(sender, "Plugin versions")
plugins = list(server.getPluginManager().getPlugins())
plugins.sort(key = lambda pl: pl.getDescription().getName())
@@ -135,21 +132,20 @@ def on_pluginversions_command(sender, args):
return True
#
# /echo - essentials echo sucks and prints mail alerts sometimes
#
@hook.command("echo")
def on_echo_command(sender, args):
"""
/echo
essentials echo sucks and prints mail alerts sometimes
"""
msg(sender, " ".join(args).replace("\\n", "\n"))
#
# /pyeval - run python ingame
#
# has to be in main.py so we can access the modules
def eval_thread(sender, code):
"""
/pyeval
run python ingame
"""
try:
result = eval(code)
msg(sender, ">>> %s: %s" % (colorify("&3") + type(result).__name__, colorify("&a") + unicode(result) + "\n "), usecolor = False)
@@ -165,6 +161,10 @@ def eval_thread(sender, code):
@hook.command("pyeval")
def on_pyeval_command(sender, args):
"""
/pyeval
run python code ingame
"""
if sender.hasPermission("utils.pyeval"):
if not checkargs(sender, args, 1, -1):
return True
@@ -177,7 +177,22 @@ def on_pyeval_command(sender, args):
@hook.command("modules")
def on_modules_command(sender, args):
"""
/modules
list all modules, unloaded modules in red
"""
plugin_header(sender, "Modules")
for mod in shared["load_modules"]:
color = "a" if mod in shared["modules"] else "c"
msg(sender, "&" + color + mod)
@hook.event("player.PlayerTeleportEvent")
def on_player_teleport(event):
"""
Disable spectator teleportation
"""
player = event.getPlayer()
if not event.isCancelled() and str(event.getCause()) == "SPECTATE" and not player.hasPermission("utils.tp.spectate"):
event.setCancelled(True)
msg(event.getPlayer(), "&cSpectator teleportation is disabled")

View File

@@ -1,4 +1,9 @@
#pylint: disable = F0401
"""
A library that makes use of the so called ClassPathHack for jython
to allow proper loading of mysql-connector.jar at runtime.
Import only, no methods.
"""
import java.lang.reflect.Method
import java.io.File
import java.net.URL

View File

@@ -1,7 +1,9 @@
#!/usr/bin/python
# this was going to be a PlotMe-like plugin "plotter"
# but it seems like PlotMe is still beeing developed, so we don't need our own.
"""
*Very basic* start of a custom plot-plugin like PlotMe
on hold because the PlotMe developer continued to develop PlotMe
"""
import sys

View File

@@ -1,3 +1,9 @@
"""
Code that was used once to create this awesome screenshot
- https://i.imgur.com/v4wg5kl.png
- https://i.imgur.com/tIZ3jmC.png
- https://www.reddit.com/r/Minecraft/comments/28le52/screenshot_of_all_players_that_joined_my_server/
"""
import net.minecraft.server.v1_7_R1.EntityPlayer as EntityPlayer
import net.minecraft.server.v1_7_R1.PacketPlayOutNamedEntitySpawn as PacketPlayOutNamedEntitySpawn
import net.minecraft.server.v1_7_R1.PlayerInteractManager as PlayerInteractManager

View File

@@ -1,4 +1,7 @@
#pylint: disable = F0401
"""
A plugin that automatically tiles (stacks) blocks inside a selected region in configurable directions.
"""
import org.bukkit.event.block.BlockPlaceEvent as BlockPlaceEvent
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
import org.bukkit.event.player.PlayerInteractEvent as PlayerInteractEvent