diff --git a/basecommands.py b/basecommands.py index 7bfb8c2..89e08aa 100644 --- a/basecommands.py +++ b/basecommands.py @@ -1,67 +1,13 @@ from helpers import * -""" -@simplecommand is a decorator which is meant to replace @hook.command in redstoner-utils, where useful. -It takes care of checks such as whether the sender is a player, whether they have permission, -whether there are enough argumens, and also takes care of a help message. -On top of that, it makes the code shorter and easier to write with features like Validate, and returning a message instead of a boolean value. -@simplecommand has an inbuilt tracing feature, so you won't have to put all your code in a try/except statement anymore. -Make sure to `from basecommands import simplecommand` before using this decorator. - -The arguments are as follows: -* cmd: the command, self explanatory (required); - -* aliases: A list containing any aliases for the command, like shortcuts; - -* usage: a String defining the expected arguments for the command. Example: - Let's say I have a command /tp . The usage is: " ". - I suggest we use the same format throughout redstoner-utils: - - Separate arguments by spaces; - - Use <> if the argument is required, and [] if the argument is optional; - - Add .. to the argument's identifier (name) if it is for example a message (containing spaces). - for example in /msg, the usage would be " " - -* description: a description of what the command does. Defaults to "Handles cmd". - This is used for the help message, where the description is (meant to be) indented. To keep this indentation - with longer descriptions, call the help message (with the command, ingame) and add '\n' - when it jumps to a new line in the chat. The decorator will take care of the indentation after that. - -* senderLimit: an integer resembling the accepted sender type. Defaults to -1. Use: - -1 for console as well as players; - 0 for players only; - 1 for console only. - -* amin: an integer resembling the minimum amount of arguments. Defaults to 0 - -* amax: an integer resembling the maximum amount of arguments. Defaults to -1, which means that there is no maximum. - -* helpNoargs: a boolean value resembling whether the help message should be displayed when no arguments are given. - Defaults to False. - -* helpSubcmd: a boolean value resembling whether the help message should be displayed when the first argument.lower() equals "help". - Defaults to False. - -Comments on the function added to the decorator: -It should return a message to send to the player. Color codes are translated automatically. It can return None or an empty string to send nothing. -Returning "HELP" makes it show the help message. - -Inside the function, calls to static methods in the class Validate can be used to make the code shorter and easier to write (maybe not easier to read). -For example, to make sure that a condition is met, use Validate.isTrue(condition, message to send to the player if the condition is not met) -Don't forget to `from basecommands import Validate` if you wish to make use of this. -For all other Validate checks, see the code below. Feel free to add your own. - -Instead of returning a message mid-code to describe an error, you can also use raise CommandException(msg), but it is almost always possible -to replace this return statement with a call to one of the functions in the Validate class. Once again, if you use raise CommandException(msg), -don't forget to `from basecommands import CommandException`. -""" - to_see_permission = "utils.showpermission" # See cmd permission in help + def isSenderValid(senderLimit, isPlayer): return True if senderLimit == -1 else senderLimit != isPlayer def invalidSenderMsg(isPlayer): - return "&cThat command can only be used by " + ("the console" if isPlayer else "players") + return "&cThat command can only be run from the console" if isPlayer else "&cThat command can only be run by players" def helpMsg(sender, cmd, description, usage, aliases, permission): help_msg = "&aInformation about command /%s:\n &9%s" % (cmd, description.replace("\n", "\n ")) @@ -119,7 +65,7 @@ def simplecommand(cmd, except CommandException, e: return e.message except Exception, e: - error(trace()) + error(e.message, trace()) return "&cAn internal error occurred while attempting to perform this command" return call diff --git a/blockplacemods.py b/blockplacemods.py index 37027f4..405ada4 100644 --- a/blockplacemods.py +++ b/blockplacemods.py @@ -1,318 +1,64 @@ from helpers import * -from basecommands import simplecommand, Validate, CommandException -from time import sleep -from collections import deque -import thread -import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent -import org.bukkit.block.Furnace as Furnace -import org.bukkit.inventory.ItemStack as ItemStack import org.bukkit.Material as Material -import org.bukkit.event.block.Action as Action -import org.bukkit.block.BlockFace as BlockFace -import org.bukkit.scheduler.BukkitRunnable as BukkitRunnable -""" - # Permissions: - # - utils.toggle: for use of the command - # - utils.toggle.cauldron - # - utils.toggle.slab - # - utils.toggle.furnace - # - utils.toggle.piston - # - utils.toggle.dropper - # - utils.toggle.hopper -""" +tog_perm = "utils.toggle" -settingInformation = dict( #[setting type, identifying description, detailed description, aliases, (optional) max slot id], setting types: 0 = toggle, default on. 1 = Set your setting to held itemstack, 2 = toggle, default off - cauldron = [0, - "easy cauldron water level control", - "Toggles whether cauldrons auto-fill upon placement and whether right clicking them with redstone dust or empty hand will cycle their water level", - ["caul", "water"] - ], - slab = [0, - "automatically flipping placed slabs upside-down", - "Toggles whether slabs/steps which you place should be automatically flipped upside-down", - ["step"] - ], - furnace = [1, - "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 furnace clear to clear all slots.", - ["cooker", "fillf"], 2 - ], - torch = [0, - "removal of torches you place on redstone blocks", - "Toggles whether redstone torches which you place on redstone blocks will be deleted after a short amount of delay.", - ["redstonetorch", "tor"] - ], - piston = [2, - "rotating pistons, droppers and hoppers to face the block you place them against", - "Toggles whether pistons or sticky pistons which you place will be rotated to face the block which you placed them against.", - ["invert", "rp"] - ], - dropper = [1, - "automatically filling droppers upon placement", - "Sets your preferred default dropper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle dropper clear to clear all slots.", - ["itemshooter", "filld"], 8 - ], - hopper = [1, - "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 hopper clear to clear all slots.", - ["itemtransporter", "fillh"], 4 - ] -) +@hook.event("block.BlockPlaceEvent", "low") +def block_place(event): + block = event.getBlockPlaced() + material = block.getType() + sender = event.getPlayer() + py_player = get_py_player(sender) + if (material in (Material.WOOD_STEP, Material.STEP)) and py_player.slab_toggle and block.getData() < 8: + block.setData(block.getData() + 8) + elif (material == Material.CAULDRON) and py_player.cauldron_toggle: + block.setData(block.getData() + 3) -defaults = { - 0: list, - 1: dict, - 2: list -} - -piston_faces = { - BlockFace.DOWN : 0, - BlockFace.UP : 1, - BlockFace.NORTH : 2, - BlockFace.SOUTH : 3, - BlockFace.WEST : 4, - BlockFace.EAST : 5 -} - -torch_faces = { - 1: BlockFace.WEST, - 2: BlockFace.EAST, - 3: BlockFace.NORTH, - 4: BlockFace.SOUTH, - 5: BlockFace.DOWN -} - -playerSettings = open_json_file("blockplacemods", {}) - -for setting, details in settingInformation.iteritems(): - if playerSettings.get(setting) == None: - playerSettings[setting] = defaults[details[0]]() - -def get(setting): - return playerSettings[setting] - -def saveSettings(): - save_json_file("blockplacemods", playerSettings) - -def getSettingDetails(arg): - try: - arg = arg.lower() - for setting, details in settingInformation.iteritems(): - if setting == arg or arg in details[3]: - return (setting, details) - except: - error(trace()) - raise CommandException(" &cThat setting could not be found.\n For command help, use &o/toggle &cor &o/set") - -@simplecommand("toggle", - aliases = ["setting", "set", "config"], - usage = " [value|info]", - description = "Toggles or sets your preferences for our redstone \nutilities. The following settings are available:\n" + ", ".join([x for x in settingInformation]), - senderLimit = 0, - helpNoargs = True, - helpSubcmd = True, - amax = 2) -def toggle_command(sender, command, label, args): - setting, details = getSettingDetails(args[0]) - Validate.isAuthorized(sender, "utils.toggle." + setting, "that setting") - - values = get(setting) - player = server.getPlayer(sender.getName()) - uuid = uid(player) - arglen = len(args) - - if details[0] in (0,2): # Toggle - default = details[0] == 0 # If True: toggle on if list doesn't contain the uuid - - enabled = (uuid not in values) == default #Invert if details[0] == 2 (toggle disabled by default) - new = None - if arglen == 1: - new = not enabled - else: - arg2 = args[1].lower() - if arg2 == "info": - return " &aSetting %s:\n &9%s\n &6Accepted arguments: [on|enable|off|disable|toggle|switch|info]\n &6Aliases: %s" % (setting, details[2], ", ".join(details[3])) - elif arg2 in ("toggle", "switch"): - new = not enabled - elif arg2 in ("on", "enable"): - new = True - elif arg2 in ("off", "disable"): - new = False - else: - return " &cArgument '%s' was not recognized. \n Use &o/toggle %s info &cfor more information" % (arg2, setting) - if enabled is new: - return " &cAlready %s: &a%s" % ("enabled" if enabled else "disabled", details[1]) - if new is default: - values.remove(uuid) - else: - values.append(uuid) - saveSettings() - return (" &aEnabled " if new else " &aDisabled ") + details[1] - - - elif details[0] == 1: # Save ItemStack in hand - arg2 = args[1].lower() if arglen > 1 else "" - enabled = uuid in values - - if arg2 == "clear": - if enabled: - del values[uuid] - saveSettings() - return " &aDisabled " + details[1] - return " &cAlready disabled: " + details[1] - - if arg2 == "info": - return " &aSetting %s:\n &9%s \n&6Accepted arguments: [|clear|details]" % (setting, details[2]) - - slot = int(arg2) if arg2.isdigit() else 0 - if not (0 <= slot <= details[4]): - return " &cSlot number must be more than or equal to 0 and less than or equal to %s!" % details[4] - - item = fromStack(player.getItemInHand()) - if item[0] == 0 or item[1] <= 0: - if enabled: - items = values[uuid] - if slot in items: - del items[slot] - if len(items) == 0: - del items - saveSettings() - return " &aDisabled " + details[1] - saveSettings() - return " &aCleared slot %s of setting %s" % (slot, setting) - return " &cSlot %s of setting %s was already cleared!" % (slot, setting) - return " &cAlready disabled: " + details[1] - - if arglen == 2 and not arg2.isdigit(): - return " &cArgument '%s' was not recognized. \nUse &o/toggle %s info &cfor more information." % (arg2, setting) - - if not enabled: - values[uuid] = {} - values[uuid][slot] = item - saveSettings() - return ((" &aEnabled setting %s, S" % setting) if len(values[uuid]) == 1 else " &aS") + "et itemstack in slot %s to item in hand" % (slot) - - return None #This shouldn't happen - - -def fromStack(itemStack): - return [itemStack.getTypeId(), itemStack.getAmount(), itemStack.getData().getData()] -def toStack(lst): - return ItemStack(lst[0], lst[1], lst[2]) - -def isEnabled(toggleSetting, uuid): - return (uuid not in get(toggleSetting)) == (settingInformation[toggleSetting][0] == 0) #Invert if off by default - - - -@hook.event("block.BlockPlaceEvent", "monitor") -def on_block_place(event): - try: - - if event.isCancelled(): - return - player = event.getPlayer() - if not is_creative(player): - return - - uuid = uid(player) - block = event.getBlockPlaced() - material = block.getType() - - - if (material in (Material.WOOD_STEP, Material.STEP) - and isEnabled("slab", uuid) - and player.hasPermission("utils.toggle.slab") - and block.getData() < 8 - ): - block.setData(block.getData() + 8) # Flip upside down - - - elif (material == Material.CAULDRON - and isEnabled("cauldron", uuid) - and player.hasPermission("utils.toggle.cauldron") - ): - block.setData(3) #3 layers of water, 3 signal strength - - - elif ((material == Material.FURNACE and player.hasPermission("utils.toggle.furnace")) - or (material == Material.DROPPER and player.hasPermission("utils.toggle.dropper")) - or (material == Material.HOPPER and player.hasPermission("utils.toggle.hopper")) - ): - stacks = get(str(material).lower()).get(uuid) - if stacks != None: # Enabled - state = block.getState() - inv = state.getInventory() - for slot, stack in stacks.iteritems(): - inv.setItem(int(slot), toStack(stack)) - state.update() - - - elif (material == Material.REDSTONE_TORCH_ON - and isEnabled("torch", uuid) - and player.hasPermission("utils.toggle.torch") - and block.getData() in torch_faces - and block.getRelative(torch_faces[block.getData()]).getType() is Material.REDSTONE_BLOCK - ): - torches_to_break.append(block) - - - elif (material in (Material.PISTON_BASE, Material.PISTON_STICKY_BASE) - and isEnabled("piston", uuid) - and player.hasPermission("utils.toggle.piston") - ): - block.setData(piston_faces[block.getFace(event.getBlockAgainst())]) - except: - error(trace()) - - -@hook.event("player.PlayerInteractEvent", "monitor") +@hook.event("player.PlayerInteractEvent", "high") def on_interact(event): - player = event.getPlayer() - if (isEnabled("cauldron", uid(player)) - and player.hasPermission("utils.toggle.cauldron") - and is_creative(player) - and event.getAction() == Action.RIGHT_CLICK_BLOCK - and (not event.hasItem() or event.getItem().getType() == Material.REDSTONE) - and event.getClickedBlock().getType() == Material.CAULDRON - ): - block = event.getClickedBlock() - event2 = BlockBreakEvent(block, player) - server.getPluginManager().callEvent(event2) - if not event2.isCancelled(): - block.setData(block.getData() - 1 if block.getData() > 0 else 3) + block = event.getClickedBlock() + sender = event.getPlayer() + py_player = get_py_player(sender) + if str(event.getAction()) != "RIGHT_CLICK_BLOCK": + return + if block.getType() == Material.CAULDRON and py_player.cauldron_toggle: + block.setData(block.getData() - 1 if block.getData() > 0 else 3) + else: + return + +def help(sender): + msg(sender, "&a-=[&6BPM&a]=-") + msg(sender, "&6Aliases for /toggle: \n &e/set, /setting and /config\n") + msg(sender, "&6Available settings: \n &eSlab and Cauldron\n") + msg(sender, "&6Slab: \n&eThe slab setting flips slabs to the top half \nof the block on placing them.\n") + msg(sender, "&6Cauldron: \n&eThe cauldron setting fills cauldrons on placing them.\n") + +@hook.command("toggle") +def toggle_command(sender, cmd, label, args): + py_player = get_py_player(sender) + if sender.hasPermission(tog_perm) and sender.getWorld().getName() == "creative": + if len(args) > 0: + if str(args[0]) == "slab": + if py_player.slab_toggle == True: + msg(sender, "&a Disabled automatically flipping slabs.") + py_player.slab_toggle = False + else: + msg(sender, "&a Enabled automatically flipping slabs.") + py_player.slab_toggle = True + elif str(args[0]) == "cauldron": + if py_player.cauldron_toggle == True: + msg(sender, "&a Disabled automatically filling cauldrons.") + py_player.cauldron_toggle = False + else: + msg(sender, "&a Enabled automatically filling cauldrons.") + py_player.cauldron_toggle = True + else: + help(sender) + else: + help(sender) + elif sender.getWorld() != "creative": + msg(sender, "&aBPM doesn't work in this world.") + else: + msg(sender, "&aNo permission.") -break_torches = True -torches_to_break = deque() - -def stop_breaking_torches(): - break_torches = False - info("[BlockPlaceMods] Interrupted torch breaking thread") - - -class JBukkitRunnable(BukkitRunnable): - - def __init__(self, func): - self.run = func - - -def torch_breaker(): - - try: - if break_torches: - for i in range(len(torches_to_break)): - block = torches_to_break.popleft() - mat = block.getType() - if mat == Material.REDSTONE_TORCH_OFF: - block.setTypeId(0) - elif mat == Material.REDSTONE_TORCH_ON: - if block.getData() in torch_faces and block.getRelative(torch_faces[block.getData()]).getType() is Material.REDSTONE_BLOCK: - torches_to_break.append(block) - except: - error(trace()) - - -def schedule_torch_breaker(): - JBukkitRunnable(torch_breaker).runTaskTimer(server.getPluginManager().getPlugin("RedstonerUtils"), 0, 1) diff --git a/calc.py b/calc.py index 47326b3..8ac48f0 100644 --- a/calc.py +++ b/calc.py @@ -10,12 +10,6 @@ calc_perm = "utils.calc" calc_perm_power = "utils.calc.power" def calc(sender, text): - try: - return do_calc(sender, text.lower()) - except: - return None - -def do_calc(sender, text): """ extracts a mathematical expression from `text` returns (expression, result) or None diff --git a/chatalias.py b/chatalias.py deleted file mode 100644 index 67de106..0000000 --- a/chatalias.py +++ /dev/null @@ -1,402 +0,0 @@ -# TODO: Add cg/ac/msg support - -import os -import mysqlhack -import org.bukkit as bukkit -from org.bukkit import * -from helpers import * - - -# Version number and requirements - -alias_version = "2.1.0" -helpers_versions = ["1.1.0", "2.0.0"] -enabled = False -error_msg = colorify("&cUnspecified error") -commands_per_page = 5 -global_aliases = {"./":"/"} -data = {} -use_mysql = True - -# Permissions: - -# Grants full access immediately -permission_ALL = "utils.alias.*" -# Access to the command to display the help screen -permission_BASE = "utils.alias" -# Make replacements only when the user has this permission -permission_USE = "utils.alias.use" -# Modify aliases -permission_MODIFY = "utils.alias.modify" -permission_MODIFY_OTHERS = "utils.alias.modify.others" -# List aliases -permission_LIST = "utils.alias.list" -permission_LIST_OTHERS = "utils.alias.list.others" -# Set alias amounts/length limits, e.g. utils.alias.amount.420 -permission_AMOUNT = "utils.alias.amount." -default_alias_limit = 15 -permission_LENGTH = "utils.alias.length." -default_length_limit = 120 -# See when the plugin was disabled due to version errors -permission_INFO = "utils.alias.info" -permission_FINFO = "utils.alias.finfo" - - -def safe_open_json(uuid): - if not os.path.exists("plugins/redstoner-utils.py.dir/files/aliases"): - os.makedirs("plugins/redstoner-utils.py.dir/files/aliases") - value = open_json_file("aliases/" + uuid) - if value is None: - value = dict(global_aliases) - save_json_file("aliases/" + uuid, value) - return value - - -def get_player_alias_limit(player): - value = get_permission_content(player, permission_AMOUNT) - if value is not None and value.isdigit(): - return int(value) - return default_alias_limit - - -def get_player_length_limit(player): - value = get_permission_content(player, permission_LENGTH) - if value is not None and value.isdigit(): - return int(value) - return default_length_limit - - -@hook.event("player.PlayerJoinEvent", "high") -def on_join(event): - if enabled: - t = threading.Thread(target=load_data, args=(uid(event.getPlayer()), )) - t.daemon = True - t.start() - else: - if event.getPlayer().hasPermission(permission_FINFO): - disabled_fallback(event.getPlayer()) - - -@hook.event("player.AsyncPlayerChatEvent", "high") -def on_player_chat(event): - if enabled: - if event.isCancelled(): - return - player = event.getPlayer() - if not hasPerm(player, permission_USE): - return - msg_limit = get_player_length_limit(player) - for alias, value in data[uid(player)].iteritems(): - if player.hasPermission("essentials.chat.color"): - event.setMessage(event.getMessage().replace(colorify(alias), colorify(value))) - else: - event.setMessage(event.getMessage().replace(alias, value)) - if not player.hasPermission(permission_ALL) and len(event.getMessage()) > msg_limit: - event.setCancelled(True) - plugin_header(player, "Chatalias") - msg(player, "The message you wanted to generate would exceed the length limit limit of %d. Please make it shorter!" % msg_limit) - return - - -def hasPerm(player, permission): - return (player.hasPermission(permission)) or (player.hasPermission(permission_ALL)) - - -def disabled_fallback(receiver): - if not hasPerm(receiver, permission_INFO): - msg(receiver, colorify("&cUnknown command. Use &e/help&c, &e/plugins &cor ask a mod.")) - else: - msg(receiver, colorify("&cPlugin alias v" + alias_version + " has experienced an &eEMERGENCY SHUTDOWN:")) - msg(receiver, error_msg) - msg(receiver, colorify("&cPlease contact a dev/admin (especially pep :P) about this to take a look at it.")) - - -def can_remote(player): - return hasPerm(player, permission_LIST_OTHERS) or hasPerm(player, permission_MODIFY_OTHERS) - - -# Command - -@hook.command("alias", - usage="/ [...]", - desc="Allows aliasing of words") -def on_alias_command(sender, cmd, label, args): - plugin_header(sender, "Chatalias") - try: - args = array_to_list(args) - if not enabled: - disabled_fallback(sender) - return - if not hasPerm(sender, permission_BASE): - noperm(sender) - return - if args[0].lower() != "player" and not is_player(sender): - msg(sender, "&cThe console cannot have aliases") - return True - subcommands[args[0].lower()](sender, args[1:]) - except: - subcommands["help"](sender, "1") - return True - - -def help(sender, args): - commands = [colorify("&e/alias help [page]")] - if hasPerm(sender, permission_LIST): - commands += [colorify("&e/alias list &7- Lists all your aliases")] - if hasPerm(sender, permission_MODIFY): - commands += [colorify("&e/alias add &7- Add an alias")] - commands += [colorify("&e/alias remove &7- Remove an alias")] - if can_remote(sender): - while len(commands) < commands_per_page: - commands += [""] - commands += [colorify("&7Following commands will be executed on yet all output will be redirected to you, except when you set silent to false, then will see it too.")] - if hasPerm(sender, permission_LIST_OTHERS): - commands += [colorify("&e/alias player list [silent]")] - if hasPerm(sender, permission_MODIFY_OTHERS): - commands += [colorify("&e/alias player add [silent]")] - commands += [colorify("&e/alias player remove [silent]")] - pages = (len(commands)-1)/commands_per_page + 1 - page = 1 - if len(args) != 0: - page = int(args[0]) - if (page > pages): - page = pages - if page < 1: - page = 1 - msg(sender, colorify("&e---- &6Help &e-- &6Page &c" + str(page) + "&6/&c" + str(pages) + " &e----")) - page -= 1 - to_display = commands[5*page:5*page+5] - for message in to_display: - msg(sender, message) - if page+1 < pages: - msg(sender, colorify("&6To display the next page, type &c/alias help " + str(page+2))) - - -def add(sender, args): - uuid = uid(sender) - args = [args[0]] + [" ".join(args[1:])] - if (args[0] not in data[uuid]) and is_alias_limit_reached(sender, sender): - return - if not add_alias_data(uuid, args[0], args[1]): - msg(sender, colorify("&c") + "Could not add this alias because it would cause some sequences to be replaced multiple times", usecolor = False) - return - msg(sender, colorify("&7Alias: ") + args[0] + colorify("&7 -> ") + args[1] + colorify("&7 was succesfully created!"), usecolor=sender.hasPermission("essentials.chat.color")) - - -def radd(sender, sender_name, target, args, silent): - if len(args) < 2: - msg(sender, "&cYou must pass a sequence and an alias for it") - return - replaced = args[0] - alias = " ".join(args[1:]) - uuid = uid(target) - if not silent: - if sender is not target: - plugin_header(target, "Chatalias") - msg(target, "&cPlayer %s &cis creating an alias for you!" % sender_name) - if (replaced not in data[uuid]) and is_alias_limit_reached(target, sender, silent): - return - if not add_alias_data(uuid, replaced, alias): - message = colorify("&c") + "Could not add this alias because it would cause some sequences to be replaced multiple times" - msg(sender, message, usecolor = False) - if not silent: - msg(target, message, usecolor = False) - return - message = colorify("&7Alias: &7%s&7 -> &7%s&7 was successfully created!") % ((colorify(replaced), colorify(alias)) if target.hasPermission("essentials.chat.color") else (replaced, alias)) - msg(sender, message, usecolor = False) - if not silent: - msg(target, message, usecolor = False) - - -def is_alias_limit_reached(player, recipient, silent = True): - if player.hasPermission(permission_ALL): - return False - alias_limit = get_player_alias_limit(player) - if len(data[uid(player)]) >= alias_limit: - message = ("&cYour limit of %d has been reached" if player is recipient else "&cThe limit of %d has been reached for that player") % alias_limit - msg(recipient, message) - if not silent: - msg(player, message) - return True - return False - - -def add_alias_data(puuid, aliased, new_alias): - prior = dict(data[puuid]) - if aliased in prior: - info("Checking prior, removing previous alias for " + aliased) - del prior[aliased] - - # prevent 2 -> 3 if there is 1 -> 2 - for alias in prior.values(): - if aliased in alias: - info("aliased %s in alias %s" % (aliased, alias)) - return False - - # prevent 1 -> 2 if there is 2 -> 3 - for sequence in prior: - if sequence in new_alias: - info("sequence %s in new_alias %s" % (sequence, new_alias)) - return False - - data[puuid][aliased] = new_alias - save_data(puuid) - return True - - -def remove(sender, args): - try: - msg(sender, colorify("&7Successfully removed alias ") + args[0] + colorify(" &7-> ") + data[uid(sender)].pop(args[0]) + colorify("&7!"), usecolor=sender.hasPermission("essentials.chat.color")) - save_data(uid(sender)) - except: - msg(sender, colorify("&cCould not remove alias ") + args[0] + colorify(", it does not exist."), usecolor=sender.hasPermission("essentials.chat.color")) - - -def rremove(sender, sender_name, target, args, silent): - if len(args) < 1: - msg(sender, "&cYou must specify a sequence whose alias is to be removed") - return - removed = args[0] - uuid = uid(target) - aliases = data[uuid] - if not silent: - msg(target, "&cPlayer %s &cis removing an alias for you!" % sender_name) - if removed in aliases: - alias = aliases.pop(removed) - message = colorify("&7Alias: &7%s&7 -> &7%s&7 successfully removed!") % ((colorify(removed), colorify(alias)) if target.hasPermission("essentials.chat.color") else (removed, alias)) - msg(sender, message, usecolor = False) - if not silent: - msg(target, message, usecolor = False) - save_data(uuid) - else: - message = colorify("&cCould not remove alias &7%s&c, it does not exist") % colorify(removed) if target.hasPermission("essentials.chat.color") else removed - msg(sender, message, usecolor = False) - if not silent: - msg(target, message, usecolor = False) - - -def list_alias(sender, args): - msg(sender, "&7You have a total of " + str(len(data[uid(sender)])) + " aliases:") - for word, alias in data[str(uid(sender))].items(): - msg(sender, colorify("&7") + word + colorify("&7 -> ") + alias, usecolor=sender.hasPermission("essentials.chat.color")) - - -def rlist_alias(sender, sender_name, target, args, silent): - aliases = data[uid(target)] - msg(sender, "&7Player %s has a total of %d aliases:" % (target.getName(), len(aliases))) - if not silent: - if sender is not target: - plugin_header(target, "Chatalias") - msg(target, "&cPlayer %s &cis listing your aliases" % sender_name) - if target.hasPermission("essentials.chat.color"): - for pair in aliases.iteritems(): - msg(sender, colorify("&7%s&7 -> %s" % pair), usecolor = False) - else: - for pair in aliases.iteritems(): - msg(sender, colorify("&7%s&7 -> %s") % pair, usecolor = False) - - -def remote(sender, args): - if len(args) < 2: - msg(sender, "&cAlias remotes take at least 3 arguments") - return - target_remote = remotes.get(args[1].lower()) - if target_remote is None: - msg(sender, "&cThat remote command does not exist") - return - target = server.getOfflinePlayer(args[0]) - if target is None or not (target.hasPlayedBefore() or target.isOnline()): - msg(sender, "&cThat player could not be found") - return - silent = True - if len(args) > (2 if target_remote is rlist_alias else 3 if target_remote is rremove else 4): - if args[-1].lower() == "false": - silent = sender is target or not target.isOnline() - args = args[:-1] - elif args[-1].lower() == "true": - args = args[:-1] - target_remote(sender, sender.getDisplayName() if is_player(sender) else colorify("&6Console"), target, args[2:], silent) - - -subcommands = { - "help": help, - "?": help, - "add": add, - "remove": remove, - "del": remove, - "delete": remove, - "player": remote, - "remote": remote, - "list": list_alias -} - -remotes = { - "add": radd, - "remove": rremove, - "del": rremove, - "delete": rremove, - "list": rlist_alias, -} - - -# Storage -# MySQL Table: -# CREATE TABLE `chatalias` (`uuid` VARCHAR(36) PRIMARY KEY, `alias` TEXT); - -def load_data(uuid): - if use_mysql: - try: - t = threading.Thread(target=load_data_thread, args=(uuid,)) - t.daemon = True - t.start() - except: - error(trace()) - else: - data[uuid] = safe_open_json(uuid) - -def load_data_thread(uuid): - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.cursor() - curs.execute("SELECT `alias` FROM `chatalias` WHERE `uuid` = ?;", (uuid, )) - results = curs.fetchall() - curs.close() - conn.close() - if len(results) == 0: - value = dict(global_aliases) - else: - value = json_loads(results[0][0]) - data[uuid] = value - - -def save_data(uuid): - if use_mysql: - try: - t = threading.Thread(target=save_data_thread, args=(uuid,)) - t.daemon = True - t.start() - except: - error(trace()) - else: - save_json_file("aliases/" + uuid, data[uuid]) - -def save_data_thread(uuid): - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.cursor() - curs.execute("INSERT INTO `chatalias` (`uuid`, `alias`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `alias` = VALUES(`alias`);", - (uuid, json_dumps(data[uuid]))) - conn.commit() - curs.close() - conn.close() - - -# OnModuleLoad - -enabled = helpers_version in helpers_versions -if not enabled: - error_msg = colorify("&6Incompatible versions detected (&chelpers.py&6)") -for player in server.getOnlinePlayers(): - if enabled: - load_data(uid(player)) - else: - if player.hasPermission(permission_FINFO): - disabled_fallback(player) diff --git a/chatgroups.py b/chatgroups.py index b3838a0..326b8d3 100644 --- a/chatgroups.py +++ b/chatgroups.py @@ -21,8 +21,6 @@ def on_chatgroup_command(sender, command, label, args): if len(args) == 1 and args[0] == "leave": if sender_id in groups.keys(): groupchat(sender, "left the group", True) - if sender in cg_toggle_list: - cg_toggle_list.remove(p) group = groups[sender_id] del(groups[sender_id]) save_groups() @@ -45,18 +43,11 @@ def on_chatgroup_command(sender, command, label, args): msg(sender, "&aUse chat like '&e%s' to send messages to this group." % get_key(sender_id)) elif len(args) == 1 and args[0] == "key": msg(sender, "&aYour chatgroup key is currently: '&c%s&a'" % get_key(sender_id)) - elif len(args) == 1 and args[0] == "tpahere": - if sender_id in groups.keys(): - do_for_chatgroup(groups[sender_id], send_tpa_request, sender) - msg(sender, "&aSent a tpahere request to all users in your chatgroup") - else: - msg(sender, "&cYou have to be in a chatgroup to do that") else: msg(sender, "&e/chatgroup join ") msg(sender, "&e/chatgroup leave") msg(sender, "&e/chatgroup info") msg(sender, "&e/chatgroup key") - msg(sender, "&e/chatgroup tpahere") @hook.command("cgt") @@ -81,19 +72,11 @@ def groupchat(sender, message, ann = False): mesg = "&8[&bCG&8] &e&o%s&e&o %s" % (name, message) else: mesg = "&8[&bCG&8] &f%s&f: &6%s" % (name, message) - mesg = colorify(mesg) - info("[ChatGroups] %s (%s): %s" % (sender.getDisplayName(), group, message)) - do_for_chatgroup(group, msg, mesg, usecolor = False) - -def do_for_chatgroup(group, func, *args, **kwargs): for receiver in server.getOnlinePlayers(): - if groups.get(uid(receiver)) == group: - func(receiver, *args, **kwargs) + groups.get(uid(receiver)) == group and msg(receiver, mesg) + -def send_tpa_request(receiver, sender): - if not receiver == sender: - runas(sender, "/tpahere " + receiver.getName()) def save_groups(): save_json_file("chatgroups", groups) @@ -102,9 +85,8 @@ def save_groups(): @hook.event("player.AsyncPlayerChatEvent", "normal") def on_chat(event): sender = event.getPlayer() - user = get_py_player(sender) msge = event.getMessage() - if (not user.logging_in) and (not event.isCancelled()): + if not event.isCancelled(): sender_id = uid(sender) key = get_key(sender_id) keylen = len(key) @@ -133,6 +115,5 @@ def chatgroupkey_command(sender, command, label, args): save_keys() return "&aYour chatgroup key was set to: '&c%s&a'" % key - def save_keys(): save_json_file("chatgroup_keys", cg_keys) diff --git a/check.py b/check.py index 3eb4026..8bbfdeb 100644 --- a/check.py +++ b/check.py @@ -35,11 +35,11 @@ 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`, `confirmed` FROM users WHERE `uuid` = ? LIMIT 1", (uuid,)) + 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], False if results[0][2] == 0 else True) if results else (None, None, True) + 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 @@ -68,8 +68,6 @@ def get_all_data(sender, player): website = get_website_data(player) msg(sender, "&6> Website account: &e%s" % website[0]) msg(sender, "&6> email: &e%s" % website[1]) - if not website[2]: - msg(sender, "&6> &cEmail NOT Confirmed!") msg(sender, "&7 -- Data provided by ipinfo.io") msg(sender, "&6> Country: &e%s" % get_country(data)) msg(sender, "&7 -- Data provided by Mojang") @@ -88,10 +86,7 @@ def on_hook_command(sender, command, label, args): plugin_header(sender, "Check") msg(sender, "&7Please notice that the data may not be fully accurate!") player = server.getOfflinePlayer(args[0]) if len(args) > 0 else None - - t = threading.Thread(target=get_all_data, args=(sender, player)) - t.daemon = True - t.start() + get_all_data(sender, player) else: msg(sender, "&4You don't have the required permissions to execute this command!") return True \ No newline at end of file diff --git a/cycle.py b/cycle.py index 17889c9..2caeac2 100644 --- a/cycle.py +++ b/cycle.py @@ -56,7 +56,7 @@ def on_slot_change(event): def do_cycle(player, down): inv = player.getInventory() - items = inv.getStorageContents() + items = inv.getContents() shift = -9 if down else 9 shift = shift % len(items) for _ in range(4): @@ -64,7 +64,7 @@ def do_cycle(player, down): uniq_items = sorted(set(list(items)[:9])) # get unique inventory if uniq_items != [None]: # row not empty break - inv.setStorageContents(items) + inv.setContents(items) def save_cyclers(): save_json_file("cycle", no_cyclers) \ No newline at end of file diff --git a/damnspam.py b/damnspam.py index a81d3cf..6a4c2b3 100644 --- a/damnspam.py +++ b/damnspam.py @@ -1,15 +1,12 @@ #pylint: disable = F0401 from helpers import * from time import time as now -import org.bukkit.Material as Material -import org.bukkit.block.BlockFace as BlockFace +import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent inputs = open_json_file("damnspam", {}) # format "x;y;z;World" accepted_inputs = ["WOOD_BUTTON", "STONE_BUTTON", "LEVER"] changing_input = False removing_input = False -max_timeout = 240 -timeout_error_str = "&cThe timeout must be -1 or within 0 and %d" % max_timeout def save_inputs(): @@ -29,35 +26,31 @@ def add_input(creator, block, timeout_off, timeout_on): } -def is_acceptable_timeout(timeout): - return (0 < timeout <= max_timeout) or timeout == -1 - - @hook.command("damnspam") def on_dammnspam_command(sender, command, label, args): - plugin_header(sender, "DamnSpam") + global changing_input + plugin_header(sender, "DamnSpam") if not checkargs(sender, args, 1, 2): msg(sender, "&c/damnspam &e(Buttons/Levers)") msg(sender, "&c/damnspam &e(Levers only)") return True #Gittestlol - if not is_creative(sender): - msg(sender, "&cYou can only do this in Creative mode") - return True + if not is_creative(sender): + msg(sender, "&cYou can only do this in Creative mode.") + return True # /damnspam - destroying_input = False # if both timeouts are 0, the plugin will attempt to remove the protection if len(args) == 1: timeout_on = args[0] try: timeout_on = round(float(timeout_on), 2) - if timeout_on == 0: - destroying_input = True - elif not is_acceptable_timeout(timeout_on): - msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout) - return True timeout_off = timeout_on + if 60 >= timeout_on <= -2 or timeout_on == 0: + timeout_on = False + if timeout_on == False: + msg(sender, "&cThe timeout must be within 0-60 or -1.") + return True except ValueError: msg(sender, "&cThe timeout must be a number") return True @@ -69,10 +62,12 @@ def on_dammnspam_command(sender, command, label, args): try: timeout_on = round(float(timeout_on), 2) timeout_off = round(float(timeout_off), 2) - if timeout_on == 0 and timeout_off == 0: - destroying_input = True - elif not (is_acceptable_timeout(timeout_on) and is_acceptable_timeout(timeout_off)): - msg(sender, "&cThe timeout must be -1 or within 0 and %d" % max_timeout) + if 60 >= timeout_on <= -2 or timeout_on == 0: + timeout_on = False + if 60 >= timeout_off <= -2 or timeout_off == 0: + timeout_off = False + if timeout_on == False or timeout_off == False: + msg(sender, "&cThe timeout must be within 0-60 or -1.") return True except ValueError: msg(sender, "&cThe timeout must be a number") @@ -85,111 +80,72 @@ def on_dammnspam_command(sender, command, label, args): msg(sender, "&cPlease look at a button or lever while executing this command!") return True - global changing_input - target_loc_str = location_str(target) - if target_loc_str in inputs: + if location_str(target) in inputs: changing_input = True # this input already has a timeout - - type_str = ttype.lower().replace("_", " ") - # test if player is allowed to build here - build_check = can_build(sender, target) + test_event = BlockBreakEvent(target, sender) + server.getPluginManager().callEvent(test_event) changing_input = False - if not build_check: - msg(sender, "&cYou are not allowed to modify this %s" % type_str) + if test_event.isCancelled(): + msg(sender, "&cYou are not allowed to modify this %s" % str(target.getType()).lower()) return True # add block to inputs - if destroying_input: - if target_loc_str not in inputs: - msg(sender, "&cThere is no timeout to remove on this %s (by setting the timeout to 0)" % type_str) - return True - del inputs[target_loc_str] - msg(sender, "&aSuccessfully removed the timeout for this %s" % type_str) - else: - add_input(sender, target, timeout_off, timeout_on) - msg(sender, "&aSuccessfully set a timeout for this %s" % type_str) + add_input(sender, target, timeout_off, timeout_on) save_inputs() + msg(sender, "&aSuccessfully set a timeout for this %s." % ttype.lower().replace("_", " ")) return True -def check_block_break(break_event, block): - if str(block.getType()) not in accepted_inputs: - return - pos_str = location_str(block) - if pos_str not in inputs: - return - sender = break_event.getPlayer() - input_str = ("this %s" if block is break_event.getBlock() else "the %s attached to that block") % str(block.getType()).lower().replace("_", " ") - if not sender.isSneaking(): - msg(sender, "&cYou cannot destroy " + input_str) - msg(sender, "&c&nSneak&c and break or set the timeout to 0 if you want to remove it.") - break_event.setCancelled(True) - return - global removing_input - removing_input = True - success = can_build(sender, block) - removing_input = False - if success: - del inputs[pos_str] - save_inputs() - msg(sender, "&aSuccessfully removed %s!" % input_str) - else: - msg(sender, "&cYou are not allowed to remove " + input_str) - break_event.setCancelled(True) - - -# a dict for levers and buttons, with a tuple of tuples as value. The tuples in the tuple represent -# the data values which the block must have if the block were placed towards the linked blockface to be affected. -# The order is DOWN, UP, NORTH, SOUTH, WEST, EAST -attached_blocks = { - - Material.LEVER: ((0, 7, 8, 15), (5, 6, 13, 14), (4, 12), (3, 11), (2, 10), (1, 9)), - Material.STONE_BUTTON: ((0, 8), (5, 6, 7, 13, 14, 15), (4, 12), (3, 11), (2, 10), (1, 9)), - Material.WOOD_BUTTON: ((0, 8), (5, 6, 7, 13, 14, 15), (4, 12), (3, 11), (2, 10), (1, 9)), - -} - -# returns a generator containing the levers or buttons that would be broken if this block were broken -def get_attached_blocks(block): - for i, face in ((0, BlockFace.DOWN), (1, BlockFace.UP), (2, BlockFace.NORTH), (3, BlockFace.SOUTH), (4, BlockFace.WEST), (5, BlockFace.EAST)): - side = block.getRelative(face) - dvalues = attached_blocks.get(side.getType()) - if dvalues is not None and side.getData() in dvalues[i]: - yield side - - -@hook.event("block.BlockBreakEvent", "highest") +@hook.event("block.BlockBreakEvent", "normal") def on_block_break(event): - if removing_input or changing_input or event.isCancelled(): + global removing_input + + if removing_input: return - block = event.getBlock() - check_block_break(event, event.getBlock()) - for affected_block in get_attached_blocks(block): - check_block_break(event, affected_block) + sender = event.getPlayer() + block = event.getBlock() + btype = str(block.getType()).lower() + if str(block.getType()) in accepted_inputs and not event.isCancelled(): + pos_str = location_str(block) + if inputs.get(pos_str): + if sender.isSneaking(): + # test if player is allowed to build here + removing_input = True + test_event = BlockBreakEvent(block, sender) + server.getPluginManager().callEvent(test_event) + removing_input = False + if test_event.isCancelled(): + event.setCancelled(True) + msg(sender, "&cYou are not allowed to remove this %s" % btype) + return True + inputs.pop(pos_str) # remove + save_inputs() + msg(sender, "&eSuccessfully removed this %s!" % btype) + return True + elif not changing_input: + event.setCancelled(True) + msg(sender, "&cYou cannot destroy this %s!" % btype) + msg(sender, "&c&nSneak&c and break if you want to remove it.") + return True @hook.event("player.PlayerInteractEvent", "normal") def on_interact(event): if (str(event.getAction()) == "RIGHT_CLICK_BLOCK") and not event.isCancelled(): - sender = event.getPlayer() + sender = event.getPlayer() 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: - sender = event.getPlayer() - btype = str(block.getType()).lower().replace("_", " ") - if btype == "lever" and block.getData() < 8: - checktime = data["timeout_off"] - else: - checktime = data["timeout_on"] - time_left = data["last_time"] + checktime - now() - + checktime = data["timeout_on"] if powered else data["timeout_off"] if checktime == -1: event.setCancelled(True) msg(sender, "&cThis %s is locked permanently by /damnspam." % (btype)) - elif time_left > 0: + elif data["last_time"] + checktime > now(): event.setCancelled(True) - msg(sender, "&cThis %s has a damnspam timeout of %.2fs, with %.2fs left." % (btype, checktime, time_left)) + msg(sender, "&cThis %s has a damnspam timeout of %ss." % (btype, checktime)) else: - data["last_time"] = round(now(), 2) + inputs[pos_str]["last_time"] = round(now(), 2) diff --git a/dicode bpm.py b/dicode bpm.py new file mode 100644 index 0000000..246f9eb --- /dev/null +++ b/dicode bpm.py @@ -0,0 +1,285 @@ +from helpers import * +from basecommands import simplecommand, Validate, CommandException +from time import sleep +from collections import deque +import thread +import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent +import org.bukkit.block.Furnace as Furnace +import org.bukkit.inventory.ItemStack as ItemStack +import org.bukkit.Material as Material +import org.bukkit.event.block.Action as Action +import org.bukkit.block.BlockFace as BlockFace +import org.bukkit.scheduler.BukkitRunnable as Runnable + +settingInformation = dict( #[setting type, identifying description, detailed description, aliases, (optional) max slot id], setting types: 0 = toggle, default on. 1 = Set your setting to held itemstack, 2 = toggle, default off + cauldron = [0, + "easy cauldron water level control", + "Toggles whether cauldrons auto-fill upon placement and whether right clicking them with redstone dust or empty hand will cycle their water level", + ["caul", "water"] + ], + slab = [0, + "automatically flipping placed slabs upside-down", + "Toggles whether slabs/steps which you place should be automatically flipped upside-down", + ["step"] + ], + furnace = [1, + "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.", + ["cooker", "fillf"], 2 + ], + #torch = [0, + # "removal of torches you place on redstone blocks", + # "Toggles whether redstone torches which you place on redstone blocks will be deleted after a short amount of delay.", + # ["redstonetorch", "tor"] + #], + piston = [2, + "rotating pistons, droppers and hoppers to face the block you place them against", + "Toggles whether pistons or sticky pistons which you place will be rotated to face the block which you placed them against.", + ["invert", "rp"] + ], + dropper = [1, + "automatically filling droppers upon placement", + "Sets your preferred default dropper contents to your currently held itemstack. Use an empty hand to empty a slot, or /toggle dropper clear to clear all slots.", + ["itemshooter", "filld"], 8 + ], + hopper = [1, + "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.", + ["itemtransporter", "fillh"], 4 + ] +) + +defaults = { + 0: list, + 1: dict, + 2: list +} + +faces = { + BlockFace.DOWN : 0, + BlockFace.UP : 1, + BlockFace.NORTH : 2, + BlockFace.SOUTH : 3, + BlockFace.WEST : 4, + BlockFace.EAST : 5 +} + +playerSettings = open_json_file("blockplacemods", {}) + +for setting, details in settingInformation.iteritems(): + if playerSettings.get(setting) == None: + playerSettings[setting] = defaults[details[0]]() + +def get(setting): + return playerSettings[setting] + +def saveSettings(): + save_json_file("blockplacemods", playerSettings) + +def getSettingDetails(arg): + try: + arg = arg.lower() + for setting, details in settingInformation.iteritems(): + if setting == arg or arg in details[3]: + return (setting, details) + except: + error(trace()) + raise CommandException(" &cThat setting could not be found.\n For command help, use &o/toggle &cor &o/set") + +@simplecommand("toggle", + aliases = ["setting", "set", "config"], + usage = " [value|info]", + description = "Toggles or sets your preferences for our redstone \nutilities. The following settings are available:\n" + ", ".join([x for x in settingInformation]), + senderLimit = 0, + helpNoargs = True, + helpSubcmd = True, + amax = 2) +def toggle_command(sender, command, label, args): + setting, details = getSettingDetails(args[0]) + Validate.isAuthorized(sender, "utils.toggle." + setting, "that setting") + + values = get(setting) + player = server.getPlayer(sender.getName()) + uuid = uid(player) + arglen = len(args) + + if details[0] in (0,2): # Toggle + default = details[0] == 0 # If True: toggle on if list doesn't contain the uuid + + enabled = (uuid not in values) == default #Invert if details[0] == 2 (toggle disabled by default) + new = None + if arglen == 1: + new = not enabled + else: + arg2 = args[1].lower() + if arg2 == "info": + return " &aSetting %s:\n &9%s\n &6Accepted arguments: [on|enable|off|disable|toggle|switch|info]\n &6Aliases: %s" % (setting, details[2], ", ".join(details[3])) + elif arg2 in ("toggle", "switch"): + new = not enabled + elif arg2 in ("on", "enable"): + new = not default + elif arg2 in ("off", "disable"): + new = default + else: + return " &cArgument '%s' was not recognized. \n Use &o/toggle %s info &cfor more information" % (arg2, setting) + if enabled == new: + return " &cAlready %s: &a%s" % ("enabled" if enabled else "disabled", details[1]) + if new == default: + values.remove(uuid) + else: + values.append(uuid) + saveSettings() + return (" &aEnabled " if new else " &aDisabled ") + details[1] + + + elif details[0] == 1: # Save ItemStack in hand + arg2 = args[1].lower() if arglen > 1 else "" + enabled = uuid in values + + if arg2 == "clear": + if enabled: + del values[uuid] + return " &aDisabled " + details[1] + + if arg2 == "details": + return " &aSetting %s:\n &9%s \n&6Accepted arguments: [|clear|details]" % (setting, details[2]) + + slot = int(arg2) if arg2.isdigit() else 0 + if not (0 <= slot <= details[4]): + return " &cSlot number must be more than or equal to 0 and less than or equal to %s!" % details[4] + + item = fromStack(player.getItemInHand()) + if item[0] == 0 or item[1] <= 0: + if enabled: + items = values[uuid] + if slot in items: + del items[slot] + saveSettings() + if len(items) == 0: + del items + return " &aDisabled " + details[1] + return " &aCleared slot %s of setting %s" % (slot, setting) + return " &cSlot %s of setting %s was already cleared!" % (slot, setting) + return " &cAlready disabled: " + details[1] + + if arglen == 2 and not arg2.isdigit(): + return " &cArgument '%s' was not recognized. \nUse &o/toggle %s details &cfor more detailsrmation." % (arg2, setting) + + if not enabled: + values[uuid] = {} + values[uuid][slot] = item + saveSettings() + return ((" &aEnabled setting %s, S" % setting) if len(values[uuid]) == 1 else " &aS") + "et itemstack in slot %s to item in hand" % (slot) + + return None #This shouldn't happen + + +def fromStack(itemStack): + return [itemStack.getTypeId(), itemStack.getAmount(), itemStack.getData().getData()] +def toStack(lst): + return ItemStack(lst[0], lst[1], lst[2]) + +def isEnabled(toggleSetting, uuid): + return (uuid not in get(toggleSetting)) == (settingInformation[toggleSetting][0] == 0) #Invert if off by default + + + +@hook.event("block.BlockPlaceEvent", "monitor") +def on_block_place(event): + if event.isCancelled(): + return + player = event.getPlayer() + if not is_creative(player): + return + + uuid = uid(player) + block = event.getBlockPlaced() + material = block.getType() + + + if (material in (Material.WOOD_STEP, Material.STEP) + and isEnabled("slab", uuid) + and player.hasPermission("utils.toggle.slab") + and block.getData() < 8 + ): + block.setData(block.getData() + 8) # Flip upside down + + + elif (material == Material.CAULDRON + and isEnabled("cauldron", uuid) + and player.hasPermission("utils.toggle.cauldron") + ): + block.setData(3) #3 layers of water, 3 signal strength + + + elif ((material == Material.FURNACE and player.hasPermission("utils.toggle.furnace")) + or (material == Material.DROPPER and player.hasPermission("utils.toggle.dropper")) + or (material == Material.HOPPER and player.hasPermission("utils.toggle.hopper")) + ): + stacks = get(str(material).lower()).get(uuid) + if stacks != None: # Enabled + state = block.getState() + inv = state.getInventory() + for slot, stack in stacks.iteritems(): + inv.setItem(int(slot), toStack(stack)) + state.update() + + """ + elif (material == Material.REDSTONE_TORCH_ON + and event.getBlockAgainst().getType() == Material.REDSTONE_BLOCK + and isEnabled("torch", uuid) + and player.hasPermission("utils.toggle.torch") + ): + torches_to_break.append(block) + """ + + + if (material in (Material.PISTON_BASE, Material.PISTON_STICKY_BASE) + and isEnabled("piston", uuid) + and player.hasPermission("utils.toggle.piston") + ): + block.setData(faces[block.getFace(event.getBlockAgainst())]) + + +@hook.event("player.PlayerInteractEvent", "monitor") +def on_interact(event): + player = event.getPlayer() + if (isEnabled("cauldron", uid(player)) + and player.hasPermission("utils.toggle.cauldron") + and is_creative(player) + and event.getAction() == Action.RIGHT_CLICK_BLOCK + and (not event.hasItem() or event.getItem().getType() == Material.REDSTONE) + and event.getClickedBlock().getType() == Material.CAULDRON + ): + block = event.getClickedBlock() + event2 = BlockBreakEvent(block, player) + server.getPluginManager().callEvent(event2) + if not event2.isCancelled(): + block.setData(block.getData() - 1 if block.getData() > 0 else 3) + +""" +break_torches = True +torches_to_break = deque() + +def stop_breaking_torches(): + break_torches = False + info("Interrupted torch breaking thread") + + +class torch_breaker(Runnable): + + def run(): + + try: + if break_torches: + for i in range(len(torches_to_break)): + block = torches_to_break.popleft() + mat = block.getType() + if mat == Material.REDSTONE_TORCH_OFF: + block.setTypeId(0) + elif mat == Material.REDSTONE_TORCH_ON: + torches_to_break.append(block) + except: + error(trace()) +""" + diff --git a/forcefield.py b/forcefield.py index 74c728f..e17ad5d 100644 --- a/forcefield.py +++ b/forcefield.py @@ -4,6 +4,7 @@ from helpers import * from org.bukkit.util import Vector from math import sin +ff_help = "utils.forcefeild.help" ff_perm = "utils.forcefield" pass_perm = "utils.forcefield.ignore" ff_prefix = "&8[&bFF&8] " @@ -42,7 +43,7 @@ def on_forcefield_command(sender, command, label, args): else: forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.") - elif args[0] in ["HELP", "?"]: # /forcefield help + elif args[0] in ["HELP", "?"] and sender.hasPermission(ff_help): # /forcefield help forcefield_help(sender) else: forcefield_header(sender, "&cInvalid syntax. Use &e/ff ? &cfor info.") @@ -194,4 +195,4 @@ def on_quit(event): player = event.getPlayer() player_id = uid(player) if player_id in ff_users: - ff_users.remove(player_id) \ No newline at end of file + ff_users.remove(player_id) diff --git a/friends.py b/friends.py index 51243ac..870560e 100644 --- a/friends.py +++ b/friends.py @@ -5,10 +5,6 @@ friends = open_json_file("friends", {}) # {Player_UUID:[List_of_friend friend_join_sound = "random.orb" -def is_friend_of(player, other): - lst = friends.get(uid(player)) - return lst is not None and uid(other) in lst - @hook.event("player.PlayerJoinEvent", "high") # creates sound and sends a bold message on friend join def fjm(event): # friend join message @@ -29,13 +25,6 @@ def friendmessage(player, message): # sends a message with a prefix msg(player, "&7[&aFriends&7] " + message) -def get_player(name): - result = server.getOfflinePlayer(name) - if result is not None and (result.hasPlayedBefore() or result.isOnline()): - return result - return None - - def ls(sender): try: sender_friends = friends.get(uid(sender), False) @@ -66,25 +55,21 @@ def add(sender, names): added = [] notfound = [] friendalready = [] - added_self = False if not sender_id in friends: friends[sender_id] = [] for name in names: - player = get_player(name) + player = server.getPlayer(name) if player: player_id = uid(player) - not_yourself = sender != player + not_yourself = player != sender if not player_id in friends[sender_id]: if not_yourself: friends[sender_id].append(player_id) added.append(player.getName()) - if player.isOnline(): - friendmessage(player.getPlayer(), "&a&o%s &aadded you to their friends list" % stripcolors(sender.getDisplayName())) - else: - added_self = True + friendmessage(player.getPlayer(), "&a&o%s &aadded you to their friends list" % stripcolors(sender.getDisplayName())) else: friendalready.append(player.getName()) @@ -95,10 +80,10 @@ def add(sender, names): if added: friendmessage(sender, "&a&o%s&a added." % ", ".join(added)) if notfound: - friendmessage(sender, "&c&o%s&c not found." % ", ".join(notfound)) + friendmessage(sender, "&c&o%s&c not found. (must be online)" % ", ".join(notfound)) if friendalready: friendmessage(sender, "&c&o%s&c is/are already your friend." % ", ".join(friendalready)) - if added_self: + if not not_yourself: friendmessage(sender, "&cYou can't add yourself to your friends list.") @@ -109,21 +94,18 @@ def rem(sender, names): notafriend = [] for name in names: - player = get_player(name) + player = server.Player(name) if player: player_id = uid(player) if player_id in friends.get(sender_id, []): friends[sender_id].remove(player_id) removed.append(player.getName()) - if player.isOnline(): - friendmessage(player.getPlayer(), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName())) + friendmessage(player.getPlayer(), "&c&o%s &cremoved you from their friends list" % stripcolors(sender.getDisplayName())) else: notafriend.append(player.getName()) else: notfound.append(name) - if not friends.get(sender_id, False): - del friends[sender_id] save_friends() if removed: friendmessage(sender, "&a&o%s&a removed." % ", ".join(removed)) @@ -144,38 +126,35 @@ def fhelp(sender): @hook.command("friends") def on_friend_command(sender, command, label, args): - try: - if not is_player(sender): - friendmessage(sender, "&c&lYou can't have friends!") - return True + if not is_player(sender): + friendmessage(sender, "&c&lYou can't have friends!") + return True - cmd = args[0] if args else None - fargs = args[1:] + cmd = args[0] if args else None + fargs = args[1:] - # /friends list - if cmd in ["list", "lst", "*"]: - thread.start_new_thread(ls, (sender,)) + # /friends list + if cmd in ["list", "lst", "*"]: + thread.start_new_thread(ls, (sender,)) - # /friends clear - elif cmd in ["clear", "/"]: - clear(sender) - - # /friends add - elif cmd in ["add", "+"]: - if fargs: - add(sender, fargs) - else: - fhelp(sender) - - # /friends remove - elif cmd in ["remove", "rem", "delete", "del", "-"]: - if fargs: - rem(sender, fargs) - else: - fhelp(sender) + # /friends clear + elif cmd in ["clear", "/"]: + clear(sender) + # /friends add + elif cmd in ["add", "+"]: + if fargs: + add(sender, fargs) else: fhelp(sender) - return True - except: - error(trace()) + + # /friends remove + elif cmd in ["remove", "rem", "delete", "del", "-"]: + if fargs: + rem(sender, fargs) + else: + fhelp(sender) + + else: + fhelp(sender) + return True \ No newline at end of file diff --git a/helpers.py b/helpers.py old mode 100755 new mode 100644 index 285a0f5..70479be --- a/helpers.py +++ b/helpers.py @@ -6,21 +6,16 @@ import org.bukkit as bukkit import org.bukkit.Location as Location import org.bukkit.entity.Player as Player import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause -import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent import org.bukkit.block as bblock import org.bukkit.event.entity as entity import org.bukkit.command.ConsoleCommandSender from org.bukkit.entity import * - -#Imports for async query -from secrets import * -import mysqlhack -from com.ziclix.python.sql import zxJDBC -import threading +from player import get_py_player +from player import py_players from traceback import format_exc as trace -helpers_version = "2.0.0" + shared = {} # this dict can be used to share stuff across modules server = bukkit.Bukkit.getServer() @@ -142,15 +137,6 @@ def is_player(obj): return (isinstance(obj, Player)) -def can_build(player, block): - """ - return True if the player can change/build at the location of given block - """ - event = BlockBreakEvent(block, player) - server.getPluginManager().callEvent(event) - return not event.isCancelled() - - def checkargs(sender, args, amin, amax): """ check if a command has a valid amount of args, otherwise notify the sender @@ -202,30 +188,6 @@ def known_player(player): """ return player.hasPlayedBefore() -""" -Runs a async query, calls target function with fetchall as an argument, it will be an empty list if there is nothing to fetch. -(So make sure your function takes that argument.) - -If you want your function to run sync in the case you are doing something spigot wouldn't like to be async use the bukkit scheduler. -Example can be found in loginsecurity.py - -""" -def async_query(mysql_database,query,query_args,target,*target_args,**target_kwargs): - - def async_query_t(mysql_database,query,query_args,target,target_args,target_kwargs): - db_conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - db_curs = db_conn.cursor() - db_curs.execute(query,query_args) - db_conn.commit() - fetchall = db_curs.fetchall() - db_curs.close() - db_conn.close() - target(fetchall,target_args,target_kwargs) - - t = threading.Thread(target=async_query_t,args=(mysql_database,query,query_args,target,target_args,target_kwargs)) - t.daemon = True - t.start() - def open_json_file(filename, default = None): """ @@ -258,66 +220,9 @@ def toggle(player, ls, name = "Toggle", add = None): If add is given, True explicitely adds it whereas False removes it """ pid = uid(player) - if pid in ls or add is False: + if pid in ls or add == False: ls.remove(pid) msg(player, "&a%s turned off!" % name) - elif add is not False: + elif add != False: ls.append(pid) - msg(player, "&a%s turned on!" % name) - - - -def send_JSON_message(playername, message): - bukkit.Bukkit.getServer().dispatchCommand(bukkit.Bukkit.getServer().getConsoleSender(), "tellraw " + playername + " " + message) - - -# Allows to check if a String is a valid IPv4 or not. Accepts any string, returns true if the String is a valid IPv4 -def is_ip(tocheck): - subsets = ["","","",""] - i = 0 - for j in range(0,len(tocheck)): - if not (tocheck[j] in "0123456789."): - return False - elif tocheck[j] == ".": - i += 1 - if (i >= 4): - return False - else: - subsets[i] += tocheck[j] - if not (i == 3): - return False - for j in range(0,3): - if not ((int(subsets[j]) >= 0) & (int(subsets[j]) <= 255)): - return False - return True - - -# Allows the use of e.g. numeric permission nodes like "permission.amount.5" and similar. -# To get the data fetch the player and the start of the permission node, looking like "permission.amount." -def get_permission_content(player, permnode, default_value = None): - try: - perms = player.getEffectivePermissions() - for perm in perms: - if str(perm.getPermission()).startswith(permnode): - return str(perm.getPermission())[len(permnode):] - return default_value - except: - error(trace()) - - -def array_to_list(array): - return_list = [] - for a in array: - return_list.append(a) - return return_list - - -#debug wrapper -def debug(func): - def wrap(*args, **kwargs): - try: - return func(*args, **kwargs) - except: - error(trace()) - return None - return wrap + msg(player, "&a%s turned on!" % name) \ No newline at end of file diff --git a/imbusy.py b/imbusy.py deleted file mode 100644 index a8c5280..0000000 --- a/imbusy.py +++ /dev/null @@ -1,318 +0,0 @@ -""" -This plugin permits users to -send a command that renders -them "busy", not letting them -to get tpa requests or direct -messages, except from console. -On restart, all busy data will -be cleared. -""" - -from helpers import * -from friends import is_friend_of -import org.bukkit.command.Command as Command -from time import time as now - -imbusy_version = "v1.1.0" - -base_permission = "utils.imbusy" # for /busy status -use_permission = "utils.imbusy.use" # for being busy -override_permission = "utils.imbusy.override" # for being able to bother busy people - -busy_status_change_timeout = 15 # seconds - -busy_players = {} # name : (status, timeout_expire) -# possible statuses: True if SUPER busy, False if normal busy, None if not busy - - -@hook.command("imbusy", - aliases = ["busy"], - usage = "/ [on, off, status/check]", - description = "Offers control over your busy status" - ) -@debug -def on_busy_command(sender, cmd, label, args): - if not is_player(sender): - msg(sender, "&7Sorry, Console cannot be busy") - return True - - plugin_header(recipient = sender, name = "I'M BUSY!") - - if not sender.hasPermission(base_permission): - noperm(sender) - return True - - if len(args) == 0: - return toggle(sender) - - arg0 = args[0].lower() - if arg0 == "on": - return on(sender) - if arg0 == "off": - return off(sender) - if arg0 in ("status", "check"): - return status(sender, args[1:]) - if arg0 == "super": - return super_cmd(sender) - return help(sender) - - -def change_status(target, status): - target_name = target.getName() - old_status = None - if target_name in busy_players: - value = busy_players[target_name] - time_left = value[1] - now() - if time_left > 0: - msg(target, "&cYou must wait %.2fs untill you can change your status" % time_left) - return - old_status = value[0] - - if old_status is status: - if status is True: - msg(target, "&cYou are already SUPER busy") - elif status is False: - msg(target, "&cYou are already busy") - else: - msg(target, "&cYou weren't busy yet") - return - - busy_players[target_name] = (status, now() + busy_status_change_timeout) - if status is True: - broadcast(None, target.getDisplayName() + " &7is now SUPER busy") - elif status is False: - broadcast(None, target.getDisplayName() + " &7is now busy") - else: - broadcast(None, target.getDisplayName() + " &7is not busy anymore") - - -def get_status(target): - return busy_players.get(target.getName(), (None,))[0] - - -def toggle(sender): - if not sender.hasPermission(use_permission): - noperm(sender) - return True - if get_status(sender) is None: - change_status(sender, False) - else: - change_status(sender, None) - return True - - -def help(sender): - msg(sender, "Let's you put yourself in busy status, preventing pms and tpa requests from other players") - msg(sender, "\n&eCommands:") - msg(sender, "&e/busy &7- Toggles busy status") - msg(sender, "&e/busy on &7- Turns on busy status") - msg(sender, "&e/busy off &7- Turns off busy status") - msg(sender, "&e/busy status [player] &7- shows your or [player]'s current busy status") - msg(sender, "&e/busy super &7- sets your status to SUPER busy such that even friends can not bother you") - return True - - -def on(sender): - if not sender.hasPermission(use_permission): - noperm(sender) - return True - change_status(sender, False) - return True - - -def off(sender): - if not sender.hasPermission(use_permission): - noperm(sender) - return True - change_status(sender, None) - return True - - -def status(sender, args): - if not sender.hasPermission(base_permission): - noperm(sender) - return True - if len(args) == 0: - target = sender - else: - target = server.getPlayer(args[0]) - if target is None: - msg(sender, "&cThat player is not online") - return True - status = get_status(target) - if status is True: - status_str = "SUPER busy" - elif status is False: - status_str = "busy" - else: - status_str = "not busy" - msg(sender, "&7%s currently %s" % ("You are" if target is sender else "Player %s&7 is" % target.getDisplayName()), status_str) - return True - - -def super_cmd(sender): - if not sender.hasPermission(use_permission): - noperm(sender) - return True - change_status(sender, True) - return True - - -@hook.event("player.PlayerQuitEvent", "lowest") -def on_player_leave(event): - player_name = event.getPlayer().getName() - if player_name in busy_players: - del busy_players[player_name] - - -# Block any bothering if should be. If a busy player msgs someone else, they can be replied to and /msg'd as well. -# It's not entirely perfect in that regard as the ability to reply is lost when you are /msg'd by someone else. - -reply_targets = {} # name : (reply_target_name, true if initiated by target) - - -def can_send(sender, target): - if target is sender or sender.hasPermission(override_permission): - return True - status = get_status(target) - if status is None: - return True - return status is False and is_friend_of(target, sender) - - -def whisper(sender, target_name): - target = server.getPlayer(target_name) - - if target is not None: - sender_name = sender.getName() - if not can_send(sender, target): - value = reply_targets[sender_name] - if value[0] != target_name or value[1] is False: - msg(sender, "&c[&fBUSY&c] %s&r is busy!" % target.getDisplayName()) - return False - - reply_targets[sender_name] = (target_name, False) - reply_targets[target_name] = (sender_name, True) - return True - - -def reply(sender): - sender_name = sender.getName() - if sender_name in reply_targets: - value = reply_targets[sender_name] - target = server.getPlayer(value[0]) - if target is not None: - if not value[1] and not can_send(sender, target): - msg(sender, "&c[&fBUSY&c] %s&r is busy!" % target.getDisplayName()) - return False - - reply_targets[target.getName()] = (sender_name, True) - return True - - -class CommandWrapper(Command): - - def __init__(self, wrapped, checker): - Command.__init__(self, wrapped.getName()) - self.setDescription(wrapped.getDescription()) - self.setPermission(wrapped.getPermission()) - self.setUsage(wrapped.getUsage()) - self.setAliases(wrapped.getAliases()) - self.wrapped = wrapped - self.checker = checker - - def execute(self, sender, label, args): - try: - if not is_player(sender) or self.checker(sender, args): - return self.wrapped.execute(sender, label, args) - except: - error(trace()) - return True - - def tabComplete(self, sender, alias, args): - return self.wrapped.tabComplete(sender, alias, args) - - -def msg_command_checker(sender, args): - return len(args) <= 1 or whisper(sender, args[0]) - -def reply_command_checker(sender, args): - return len(args) == 0 or reply(sender) - -def tpa_command_checker(sender, args): - if len(args) == 0: - return True - target = server.getPlayer(args[0]) - if target is not None and not can_send(sender, target): - msg(sender, "&c[&fBUSY&c] %s&r is busy!" % target.getDisplayName()) - return False - return True - -def tpahere_command_checker(sender, args): - return tpa_command_checker(sender, args) - -def mail_command_checker(sender, args): - if len(args) < 3 or args[0].lower() != "send": - return True - target = server.getPlayer(args[1]) - if target is not None and not can_send(sender, target): - msg(sender, "&c[&fBUSY&c] %s&r is busy!" % target.getDisplayName()) - return False - return True - - -@hook.event("player.PlayerCommandPreprocessEvent", "monitor") -def on_player_command_preprocess(event): - message = event.getMessage().split(" ") - if len(message) > 1 and message[0].lower() in ("/tell", "/minecraft:tell") and not whisper(event.getPlayer(), message[1]): - event.setCancelled(True) - - -def replace_ess_commands(): - - try: - map_field = server.getPluginManager().getClass().getDeclaredField("commandMap") - map_field.setAccessible(True) - command_map = map_field.get(server.getPluginManager()) - - commands_field = command_map.getClass().getDeclaredField("knownCommands") - commands_field.setAccessible(True) - map = commands_field.get(command_map) - - ess_msg_cmd = map.get("essentials:msg") - ess_reply_cmd = map.get("essentials:reply") - ess_tpa_cmd = map.get("essentials:tpa") - ess_tpahere_cmd = map.get("essentials:tpahere") - ess_mail_cmd = map.get("essentials:mail") - - msg_cmd_wrapper = CommandWrapper(ess_msg_cmd, msg_command_checker) - reply_cmd_wrapper = CommandWrapper(ess_reply_cmd, reply_command_checker) - tpa_cmd_wrapper = CommandWrapper(ess_tpa_cmd, tpa_command_checker) - tpahere_cmd_wrapper = CommandWrapper(ess_tpahere_cmd, tpahere_command_checker) - mail_cmd_wrapper = CommandWrapper(ess_mail_cmd, mail_command_checker) - - iterator = map.entrySet().iterator() - wrapped_commands = [] - while iterator.hasNext(): - entry = iterator.next() - value = entry.getValue() - changed = True - if value is ess_msg_cmd: - entry.setValue(msg_cmd_wrapper) - elif value is ess_reply_cmd: - entry.setValue(reply_cmd_wrapper) - elif value is ess_tpa_cmd: - entry.setValue(tpa_cmd_wrapper) - elif value is ess_tpahere_cmd: - entry.setValue(tpahere_cmd_wrapper) - elif value is ess_mail_cmd: - entry.setValue(mail_cmd_wrapper) - else: - changed = False - if changed: - wrapped_commands.append(entry.getKey()) - info("[imbusy] wrapped commands: /" + ", /".join(wrapped_commands)) - - except: - error("[Imbusy] Failed to wrap essentials commands") - error(trace()) diff --git a/iptracker.py b/iptracker.py deleted file mode 100755 index 969a822..0000000 --- a/iptracker.py +++ /dev/null @@ -1,108 +0,0 @@ -import mysqlhack -import org.bukkit as bukkit -import json -from java.util import UUID as UUID -from helpers import * -from org.bukkit import * -from traceback import format_exc as trace -from iptracker_secrets import * - - -iptrack_permission = "utils.iptrack" -iptrack_version = "1.1.0" - - -@hook.event("player.PlayerJoinEvent", "low") -def on_player_join(event): - t = threading.Thread(target=on_player_join_thread, args=(event, )) - t.daemon = True - t.start() - -def on_player_join_thread(event): - player = event.getPlayer() - ip = player.getAddress().getHostString() - uuid = uid(player) - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.cursor() - curs.execute("SELECT ips FROM uuid2ips WHERE uuid = ?", (uuid, )) - results = curs.fetchall() - if len(results) == 0: - ips = [] - else: - ips = json.loads(results[0][0]) - curs.execute("SELECT uuids FROM ip2uuids WHERE ip = ?", (ip, )) - results = curs.fetchall() - if len(results) == 0: - uuids = [] - else: - uuids = json.loads(results[0][0]) - new_ip_entry = (len(ips) == 0) - new_uuid_entry = (len(uuids) == 0) - if ip not in ips: - ips.append(ip) - if new_ip_entry: - curs.execute("INSERT INTO uuid2ips VALUES (?,?)", (uuid, json.dumps(ips), )) - else: - curs.execute("UPDATE uuid2ips SET ips = ? WHERE uuid = ?", (json.dumps(ips), uuid, )) - if uuid not in uuids: - uuids.append(uuid) - if new_uuid_entry: - curs.execute("INSERT INTO ip2uuids VALUES (?,?)", (ip, json.dumps(uuids), )) - else: - curs.execute("UPDATE ip2uuids SET uuids = ? WHERE ip = ?", (json.dumps(uuids), ip, )) - conn.commit() - curs.close() - conn.close() - - -@hook.command("getinfo") -def on_getinfo_command(sender, args): - t = threading.Thread(target=on_getinfo_command_thread, args=(sender, args)) - t.daemon = True - t.start() - -def on_getinfo_command_thread(sender, args): - if(sender.hasPermission(iptrack_permission)): - if not checkargs(sender, args, 1, 1): - return False - else: - if is_ip(args[0]): - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.cursor() - curs.execute("SELECT uuids FROM ip2uuids WHERE ip = ?", (args[0], )) - results = curs.fetchall() - curs.close() - conn.close() - if len(results) == 0: - msg(sender, "IP " + args[0] + " is not registered in the database, maybe you got a number wrong?") - else: - uuids = json.loads(results[0][0]) - msg(sender, "IP " + args[0] + " was seen with " + str(len(uuids)) + " different Accounts:") - for i in range(0, len(uuids)): - p=Bukkit.getOfflinePlayer(UUID.fromString(uuids[i])) - if is_player(sender): - send_JSON_message(sender.getName(), '["",{"text":"' + p.getName() + ' - (uuid: ' + uuids[i] + '","color":"gold","clickEvent":{"action":"run_command","value":"/getinfo ' + p.getName() + '"},"hoverEvent":{"action":"show_text","value":{"text":"","extra":[{"text":"To search for ' + p.getName() + ' in the database, simply click the name!","color":"gold"}]}}}]') - else: - msg(sender,p.getName() + " - (uuid: " + uuids[i] + ")") - else: - target = Bukkit.getOfflinePlayer(args[0]) - uuid = target.getUniqueId() - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.cursor() - curs.execute("SELECT ips FROM uuid2ips WHERE uuid = ?", (uuid.toString(), )) - results = curs.fetchall() - curs.close() - conn.close() - if len(results) == 0: - msg(sender, "Player " + args[0] + " is not registered in the database, maybe you misspelled the name?") - else: - ips = json.loads(results[0][0]) - msg(sender, "Player " + args[0] + " was seen with " + str(len(ips)) + " different IPs:") - for i in range(0, len(ips)): - if is_player(sender): - send_JSON_message(sender.getName(), '["",{"text":"' + ips[i] + '","color":"gold","clickEvent":{"action":"run_command","value":"/getinfo ' + ips[i] + '"},"hoverEvent":{"action":"show_text","value":{"text":"","extra":[{"text":"To search for the IP ' + ips[i] + ' in the database, simply click the IP!","color":"gold"}]}}}]') - else: - msg(sender,ips[i]) - else: - noperm(sender) - return True diff --git a/loginsecurity.py b/loginsecurity.py index d1607ef..bf56a40 100644 --- a/loginsecurity.py +++ b/loginsecurity.py @@ -7,12 +7,11 @@ from login_secrets import * #Don't forget to make login_secrets aswell import mysqlhack from com.ziclix.python.sql import zxJDBC from java.lang import Runnable -from player import get_py_player, py_players wait_time = 30 #seconds admin_perm = "utils.loginsecurity.admin" min_pass_length = 8 -blocked_events = ["block.BlockBreakEvent", "block.BlockPlaceEvent", "player.AsyncPlayerChatEvent"] +blocked_events = ["block.BlockBreakEvent", "block.BlockPlaceEvent", "player.PlayerMoveEvent","player.AsyncPlayerChatEvent"] @@ -204,12 +203,12 @@ def delete_pass(uuid): curs.close() conn.close() -@hook.event("player.PlayerJoinEvent", "highest") +@hook.event("player.PlayerJoinEvent", "low") def on_join(event): user = event.getPlayer() py_player = get_py_player(event.getPlayer()) if is_registered(uid(user)): - msg(event.getPlayer(), "&4You will be disconnected after 60 seconds if you don't &alogin") + msg(event.getPlayer(), "&6You will be disconnected after 60 seconds if you don't &alogin") msg(user, "&cUse /login ") py_player.logging_in = True py_player.login_time = time.time() @@ -265,18 +264,3 @@ for blocked_event in blocked_events: user = get_py_player(event.getPlayer()) if user.logging_in: event.setCancelled(True) - -@hook.event("player.PlayerCommandPreprocessEvent","normal") -def pre_command_proccess(event): - player = get_py_player(event.getPlayer()) - if player.logging_in: - args = event.getMessage().split(" ") - if not args[0].lower() == "/login": - msg(player.player, "&4You need to login before you do that!") - event.setCancelled(True) - -@hook.event("player.PlayerMoveEvent","normal") -def player_move(event): - user = get_py_player(event.getPlayer()) - if user.logging_in: - event.setTo(event.getFrom()) diff --git a/main.py b/main.py index 1b9e3f4..2038e43 100644 --- a/main.py +++ b/main.py @@ -19,19 +19,12 @@ except: @hook.enable def on_enable(): - if "blockplacemods" in shared["modules"]: - shared["modules"]["blockplacemods"].schedule_torch_breaker() - if "imbusy" in shared["modules"]: - shared["modules"]["imbusy"].replace_ess_commands() - if "serversigns" in shared["modules"]: - shared["modules"]["serversigns"].check_all_signs_and_force_commands() info("RedstonerUtils enabled!") @hook.disable def on_disable(): - if "reports" in shared["modules"]: - shared["modules"]["reports"].stop_reporting() + shared["modules"]["reports"].stop_reporting() info("RedstonerUtils disabled!") @@ -49,10 +42,6 @@ shared["load_modules"] = [ "blockplacemods", # Adds /calc, toggles automatic solving of Math expressions in chat "calc", - # Adds aliasing of chat words - "chatalias", - # For players to point friends - "friends", # Plugin to locate laggy chunks. /lc lists chunks with more than n entities "lagchunks", # Adds /report and /rp, Stores reports with time and location @@ -63,8 +52,6 @@ shared["load_modules"] = [ "webtoken", # Adds /lol, broadcasts random funyy messages. A bit like the splash text in the menu "saylol", - # Adds /signalstrength, lets you request a signal strength and an amount of items will be inserted into target container to meet that strength. - "signalstrength", # Shows the owner of a skull when right-clicked "skullclick", # Adds /listen, highlights chat and plays a sound when your name was mentioned @@ -83,8 +70,6 @@ shared["load_modules"] = [ "check", # Adds /an, a command you can use to share thoughts/plans/news "adminnotes", - # Adds busy status to players - "imbusy", # Adds /imout, displays fake leave/join messages "imout", #adds snowbrawl minigame @@ -94,25 +79,7 @@ shared["load_modules"] = [ # Replacement for LoginSecurity "loginsecurity", # Centralized Player class - "player", - # Servercontrol extension for telnet access to logs/AC - #"servercontrol", - # Script helper plugin - "scriptutils", - # Per-player notes - "tag", - # vanish toggle module - temporary fix - #"vanishfix", - # obisidian mining punishment plugin - "punishments", - # a simple replacement for the buggy essentials /vanish - "vanish", - # ip-tracking utility - disabled as of instability - #"iptracker", - #server signs for everyone - "serversigns", - # Makes player's names colored, sorts tab list by rank - "nametags" + "player" ] shared["modules"] = {} for module in shared["load_modules"]: diff --git a/mentio.py b/mentio.py index fa46d71..528d7ad 100644 --- a/mentio.py +++ b/mentio.py @@ -4,21 +4,24 @@ from traceback import format_exc as print_traceback mentions = open_json_file("mentio", {}) # contains a list of keywords for each player (uuid) -max_amount = 1000 +max_amount = 3 arrow = colorify(u"&r&7\u2192&r") colors_reg = reg_compile(u"\u00A7[\\da-fk-or]") # finds color codes +mentio_toggle = [] def saveMentions(): save_json_file("mentio", mentions) -@hook.event("player.AsyncPlayerChatEvent", "monitor") +@hook.event("player.AsyncPlayerChatEvent", "high") def onChat(event): if not event.isCancelled(): sender = event.getPlayer() words = event.getMessage().split(" ") recipients = event.getRecipients() # set of , may be a lazy or unmodifiable collection + n = sender.getName() + for recipient in list(recipients): recuid = uid(recipient) @@ -46,7 +49,7 @@ def onChat(event): break # player was mentioned - if rec_words != words: + if rec_words != words and n not in mentio_toggle: try: recipients.remove(recipient) # don't send original message except: @@ -70,7 +73,7 @@ def add_keyword(sender, args): keywords = get_keywords(sender) new_word = stripcolors(args[1].lower()) - if (len(keywords) >= max_amount) and (max_amount >= 0): + if len(keywords) >= max_amount: msg(sender, "&cYou are already listening for %s words! Try &6/mentio del " % max_amount) return True @@ -116,6 +119,7 @@ def show_help(player): msg(player, "&a/mentio add ") msg(player, "&a/mentio del ") msg(player, "&a/mentio list") + msg(player, "&a/mentio toggle") @hook.command("mentio") @@ -142,8 +146,18 @@ def onListenCommand(sender, command, label, args): msg(sender, "&c- &3%s" % word) if not keywords: msg(sender, "&cYou are currently listening for no words! Try &6/mentio add ") + + # /mentio toggle + elif argnum == 1 and cmd == "toggle": + n = sender.getName() + if n in mentio_toggle: + msg(sender,"&aNow listening.") + mentio_toggle.remove(n) + else: + msg(sender,"&aNo longer listening.") + mentio_toggle.append(n) else: show_help(sender) else: show_help(sender) - return True + return True \ No newline at end of file diff --git a/misc.py b/misc.py index e495317..c346be9 100644 --- a/misc.py +++ b/misc.py @@ -6,8 +6,7 @@ from sys import exc_info import thread import org.bukkit.inventory.ItemStack as ItemStack import org.bukkit.Bukkit as Bukkit -from basecommands import simplecommand, Validate -import java.util.Arrays as Arrays +from basecommands import simplecommand @@ -71,6 +70,7 @@ def cmd_event2(event): + """ Disabled while builder can't access Trusted @hook.event("player.PlayerGameModeChangeEvent", "low") def on_gamemode(event): @@ -115,19 +115,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.PlayerInteractEvent") -def on_interact(event): - if (not event.isCancelled() - and str(event.getAction()) == "RIGHT_CLICK_BLOCK" - and str(event.getMaterial()) in ("REDSTONE_COMPARATOR_OFF", "REDSTONE_COMPARATOR_ON") - and not can_build(player, event.getClickedBlock()) - ): - event.setCancelled(True) - - -sudo_blacklist = ["pyeval", "script_backup_begin", "script_backup_end", "script_backup_error", "script_backup_database_begin", "script_backup_database_dumps", "script_backup_database_end", -"script_backup_database_error", "script_backup_database_abort", "script_trim", "script_trim_result", "script_spigot_update", "script_disk_filled", "script_restart", "script_restart_abort", -"script_stop", "script_stop_abort", "script_shutdown", "stop", "esudo", "essentials:sudo", "sudo", "essentials:esudo"] @simplecommand("sudo", usage = " [cmd..]", @@ -140,14 +127,11 @@ def on_sudo_command(sender, command, label, args): msg(sender, "&2[SUDO] &rRunning '&e%s&r' as &3%s" % (cmd, target)) is_cmd = cmd[0] == "/" is_console = target.lower() in ["server", "console"] - first_cmd = (args[1])[1:] if is_cmd else None - if first_cmd in sudo_blacklist and (is_player(sender) and uid(sender) not in pythoners): - return "&cYou can't sudo this command" if is_console: server.dispatchCommand(server.getConsoleSender(), cmd[1:] if is_cmd else cmd) return None target_player = server.getPlayer(target) - if target_player: + if target_player and uid(target_player) not in pythoners: target_player.chat(cmd) return None return "&cPlayer %s not found!" % target @@ -173,8 +157,7 @@ def on_pluginversions_command(sender, command, label, args): """ try: plugin_header(sender, "Plugin versions") - raw_plugins = server.getPluginManager().getPlugins() # Plugin[] - plugins = [raw_plugins[i].getDescription() for i in range(len(raw_plugins))] + plugins = [pl.getDescription() for pl in list(ArrayList(java_array_to_list(server.getPluginManager().getPlugins())))] info(type(plugins[0]).__name__) plugins.sort(key = lambda pl: pl.getDescription().getName()) msg(sender, "&3Listing all " + str(len(plugins)) + " plugins and their version:") @@ -212,13 +195,11 @@ def eval_thread(sender, code): msg(sender, ">>> %s: %s" % (eclass.__name__, e) + "\n ", False, "c") thread.exit() -pythoners = ( - "e452e012-2c82-456d-853b-3ac8e6b581f5", # Nemes - "ae795aa8-6327-408e-92ab-25c8a59f3ba1", # jomo - "d2693e91-93e1-4e3f-929f-f38e1ce8df03", # Pepich1851 - "51f2ad3c-6cc8-40ea-aa2b-f25970316921", # Dico200 - "15ad0e60-8691-4e29-9de9-2d6b538bf56d" # psrcek -) +pythoners = [ +"e452e012-2c82-456d-853b-3ac8e6b581f5", # Nemes +"ae795aa8-6327-408e-92ab-25c8a59f3ba1", # jomo +"305ccbd7-0589-403e-a45b-d791dcfdee7d" # PanFritz +] @simplecommand("pyeval", usage = "[code..]", @@ -271,31 +252,6 @@ def on_modules_command(sender, command, label, args): msg(sender, ", ".join([(("&a" if mod in shared["modules"] else "&c") + mod) for mod in shared["load_modules"]])) -@simplecommand("warn", - usage = "", - description = "Warns everybody on the server that you will cause lag shortly", - amax = 0, - helpSubcmd = True) -def warn_command(sender, command, label, args): - if sender.hasPermission("utils.warn"): - broadcast(None, " &b= &2&lLag incoming! &r-%s" % sender.getDisplayName()) - else: - noperm(sender) - - -@simplecommand("warnp", - usage = "", - description = "Warns everybody on the server that you might cause lag shortly", - amax = 0, - helpSubcmd = True) -def warnp_command(sender, command, label, args): - if sender.hasPermission("utils.warnp"): - broadcast(None, " &b= &2&lPossible lag incoming! &r-%s" % sender.getDisplayName()) - else: - noperm(sender) - - - """ Something I'm planning for schematics @hook.event("player.PlayerCommandPreprocessEvent", "low") def on_command(event): diff --git a/nametags.py b/nametags.py deleted file mode 100755 index 4d86bbe..0000000 --- a/nametags.py +++ /dev/null @@ -1,37 +0,0 @@ -from helpers import * - -############################################################## -# # -# This module automatically puts people in the corresponding # -# scoreboard team so that their name is colored properly and # -# tab will be nicely sorted. # -# # -############################################################## - -ranks = ["visitor", "member", "builder", "trusted", "trainingmod", "mod", "admin"] -# prefixes are used for sorting in the tab list -prefixes = {"admin":"a", "mod":"b", "trainingmod":"c", "trusted":"d", "builder":"e", "member":"f","visitor":"g"} - -@hook.event("player.PlayerJoinEvent", "low") -def on_player_join(event): - player = event.getPlayer() - team = get_team(player) - if team: - cmd = "scoreboard teams join %s %s" % (team, player.getName()) - server.dispatchCommand(server.getConsoleSender(), cmd) - -def get_rank(player): - player_rank = None - for rank in ranks: - if not player.hasPermission("group.%s" % rank): - break - player_rank = rank - if not player_rank: - warn("Couldn't find rank for player %s" % player.getName()) - return player_rank - -def get_team(player): - rank = get_rank(player) - if rank: - prefix = prefixes.get(rank) - return "_".join([prefix, rank]) \ No newline at end of file diff --git a/player.py b/player.py index b1a2ddd..289b247 100644 --- a/player.py +++ b/player.py @@ -4,10 +4,12 @@ py_players = [] class py_player: def __init__(self,player): - self.player = player - self.logging_in = False - self.login_time = 0 - + self.player = player + self.logging_in = False + self.login_time = 0 + self.slab_toggle = False + self.cauldron_toggle = False + def get_py_player(player): #py_player = py_players[py_players.index(player)] @@ -25,6 +27,4 @@ def on_join(event): @hook.event("player.PlayerQuitEvent","highest") def on_leave(event): - player = get_py_player(event.getPlayer()) - if player in py_players: - py_players.remove(player) + py_players.remove(get_py_player(event.getPlayer())) diff --git a/plotter.py b/plotter.py new file mode 100644 index 0000000..d598554 --- /dev/null +++ b/plotter.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +""" +*Very basic* start of a custom plot-plugin like PlotMe +on hold because the PlotMe developer continued to develop PlotMe +""" + +import sys + +x_plot_size = 3 +z_plot_size = 3 +padding = 1 + +def base_coords(x, z): + pid = plot_id(x, z) + return [pid[0] * (x_plot_size + padding), pid[1] * (z_plot_size + padding)] + +def bounds(x, z): + base = base_coords(x, z) + return [base, [base[0] + x_plot_size, base[1] + z_plot_size]] + +def plot_id(x, z): + return [x // (x_plot_size + padding), z // (z_plot_size + padding)] + + +x = int(sys.argv[1]) +z = int(sys.argv[2]) +print "id: %s" % plot_id(x, z) +print "base: %s" % base_coords(x, z) +print "bounds: %s" % bounds(x, z) diff --git a/plugin.yml b/plugin.yml index bdd5acb..4991e40 100644 --- a/plugin.yml +++ b/plugin.yml @@ -2,3 +2,4 @@ name: RedstonerUtils main: main.py version: 3.1.0 author: redstone_sheep + diff --git a/pmtoggle.py b/pmtoggle.py index 19caf9e..e1bac06 100644 --- a/pmtoggle.py +++ b/pmtoggle.py @@ -5,11 +5,7 @@ from java.util.UUID import fromString as juuid toggle_dict = {} permission = "utils.pmtoggle" -@hook.command("pmtoggle", - aliases = ["tm", "mt", "tmsg", "msgt", "pmt", "tpm"], - usage = "/ [player]", - description = "Toggle automatic sending of messages" - ) +@hook.command("tm") def on_toggle_message_command(sender, command, label, args): if not sender.hasPermission(permission) or not is_player(sender): noperm(sender) diff --git a/punishments.py b/punishments.py deleted file mode 100644 index 886d026..0000000 --- a/punishments.py +++ /dev/null @@ -1,130 +0,0 @@ -from helpers import * -from java.util.UUID import fromString as juuid -import org.bukkit.Material as Material - -spawn_world = "Spawn" -punish_world = "Punishments" - -slave_perm = "utils.minerslaves" - -slaves = [] - -def save_slaves(): - buf = [] - for slave in slaves: - buf.append(slave.get_data()) - save_json_file("miner_slaves", buf) - -def load_slaves(): - buf = open_json_file("miner_slaves", []) - for data in buf: - slave = Slave(True, None, None) - slave.load_data(data) - slaves.append(slave) - -def get_slave(player): - for slave in slaves: - if slave.get_uuid() == player: - return slave - return None - -class Slave(object): - - def __init__(self, from_file, player, amount): - if from_file: - self.players = None - self.blocks = None - return - slave = get_slave(uid(player)) - if slave != None: - slave.set_blocks(slave.get_blocks() + amount) - else: - self.player = uid(player) - self.blocks = amount - slaves.append(self) - - def get_uuid(self): - return self.player - - def get_blocks(self): - return self.blocks - - def set_blocks(self, amount): - self.blocks = amount - - def update(self): - self.blocks -= 1 - if self.blocks <= 0: - server.getPlayer(juuid(self.get_uuid())).teleport(server.getWorld(spawn_world).getSpawnLocation()) - server.getPlayer(juuid(self.get_uuid())).teleport(server.getWorld(spawn_world).getSpawnLocation()) - slaves.remove(self) - save_slaves() - - def get_data(self): - return { - "player": self.player, - "amount": self.blocks - } - - def load_data(self, data): - self.player = str(data["player"]) - self.blocks = int(data["amount"]) - -load_slaves() - -@hook.event("block.BlockBreakEvent", "low") -def event(event): - if event.getPlayer().getWorld().getName() != punish_world: - return - slave = get_slave(uid(event.getPlayer())) - if slave != None and event.getBlock().getType() == Material.OBSIDIAN: - slave.update() - -@hook.command("miner") -def command(sender, cmd, label, args): - if not sender.hasPermission(slave_perm): - noperm(sender) - return True - if len(args) == 0 or (len(args) != 1 and args[0] == "list") or (len(args) != 2 and args[0] == "rem") or (len(args) != 3 and args[0] == "add"): - msg(sender, "&e-&a /miner add/rem/list ") - return True - if args[0] == "add": - try: - int(args[2]) - except: - msg(sender, "&cArgument is not a number") - return True - if args[0] == "list": - if len(slaves) == 0: - msg(sender, "&e-&a There are no people mining obsidian") - return True - for slave in slaves: - msg(sender, "&e-&a %s: %s blocks" % (server.getOfflinePlayer(juuid(slave.get_uuid())).getName(), slave.get_blocks())) - return True - elif args[0] == "add": - player = server.getOfflinePlayer(str(args[1])) - if player.isOnline(): - player.teleport(server.getWorld(punish_world).getSpawnLocation()) - Slave(False, player, int(args[2])) - save_slaves() - msg(player, "&e-&a You have been punished, mine %s blocks of obsidian to get out!" % args[2]) - msg(sender, "&e-&a Player %s has been added into punishments for %s blocks of obsidian" % (player.getName(), args[2])) - else: - msg(sender, "&cYou can only punish online players") - return True - elif args[0] == "rem": - player = server.getOfflinePlayer(str(args[1])) - if player.isOnline(): - slave = get_slave(uid(player)) - if slave != None: - server.getPlayer(juuid(slave.get_uuid())).teleport(server.getWorld(spawn_world).getSpawnLocation()) - slaves.remove(slave) - save_slaves() - else: - msg(sender, "&e-&a Player not in punishments") - else: - msg(sender, "&cYou can only remove online players") - return True - else: - msg(sender, "&e-&a /miner add/rem/list ") - return True diff --git a/saylol.py b/saylol.py index 84172af..f1854df 100644 --- a/saylol.py +++ b/saylol.py @@ -1,12 +1,11 @@ from time import time from helpers import * from random import randrange -import math lols = open_json_file("lol", []) timeout = 15 last_msg = 0 -list_limit = 20 + def save_lols(): @@ -70,26 +69,8 @@ def on_lol_command(sender, command, label, args): noperm(sender) elif cmd == "list": - arg1 = args[1] if len(args) > 1 else None - if not arg1: - arg1 = "1" - if not arg1.isdigit(): - msg(sender, "&cInvalid argument \"%s\"" % arg1) - return True - if int(arg1) == 0: - msg(sender, "&cPage 0 does not exist") - return True - arg1 = int(arg1) - 1 - offset = list_limit * arg1 - if offset > len(lols): - msg(sender, "&cNot a valid page (too high).") - return True - msg(sender, " &9&nLol list page %s/%s" % (arg1 + 1, int(math.ceil(len(lols) / float(list_limit))))) #"\t" symbol displays weirdly, hence the 4 spaces - for i in range(offset, min(offset + list_limit, len(lols))): + for i in range(len(lols)): msg(sender, "&a%s: &e%s" % (str(i).rjust(3), lols[i])) - msg(sender, "") - msg(sender, "&eFor a specific page, type &a/lol list &e.") - msg(sender, "") #emptyline elif cmd == "search": if sender.hasPermission("utils.lol.search"): @@ -114,9 +95,9 @@ def on_lol_command(sender, command, label, args): msg(sender, "&cInvalid number '&e%s&c'" % args[1]) else: - msg(sender, "&a/lol &eSay random message") - msg(sender, "&a/lol list [page] &eList messages") - msg(sender, "&a/lol id &eSay specific message") - msg(sender, "&a/lol add &eAdd message") - msg(sender, "&a/lol del &eDelete message") + msg(sender, "&a/lol &eSay random message") + msg(sender, "&a/lol list &eList all messages") + msg(sender, "&a/lol id &eSay specific message") + msg(sender, "&a/lol add &eAdd message") + msg(sender, "&a/lol del &eDelete message") return True diff --git a/scriptutils.py b/scriptutils.py index 312f6c4..2e0dd2d 100644 --- a/scriptutils.py +++ b/scriptutils.py @@ -149,7 +149,7 @@ 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 Database backup completed.") + broadcast(None, "&6 =&2 Databse backup completed.") server.dispatchCommand(server.getConsoleSender(), "ac &abackup size: &2%sMB&a." % args[0]) else: noperm(sender) diff --git a/servercontrol.py b/servercontrol.py deleted file mode 100644 index 91055d7..0000000 --- a/servercontrol.py +++ /dev/null @@ -1,115 +0,0 @@ -from helpers import * -import socket -import threading -import time -from java.lang import Runnable -from adminchat import adminchat - -""" -Module to allow our servercontrol telnet server forward chat and speak in AC - - -""" -host = "" -port = 1122 - -sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) - -try: - sock.bind((host,port)) - sock.setblocking(True) - sock.listen(5) -except socket.error as e: - print(str(e)) - -def command_process(text): - text = list(text) - args = [] - arg = "" - - for char in text: - if char != " " and char != "\n" and char != "\r" and char != "\t": - arg += char - elif arg != "": - args.append(arg) - arg = "" - if arg != "": - args.append(arg) - return args - -clients = [] -clients_l = threading.Lock() - -class client(): - def __init__(self,conn,address,name): - self.conn = conn - self.address = address - self.name = name - - with clients_l: - clients.append(self) - - self.conn.setblocking(False) - - self.client_thread = threading.Thread(target=self.client_t) - self.client_thread.daemon = True - self.client_thread.start() - - def getName(self): - return self.name - - - def close_connection(self): - try: - self.conn.close() - with clients_l: - clients.remove(self) - except: - pass - - - def client_t(self): - - while True: - time.sleep(0.1) - try: - data = self.conn.recv(1024) - except: - if self not in clients: - self.close_connection() - continue - - if self not in clients: #If the connection was closed, kill the thread - break - - adminchat(self,data) - - -def handle_conn(): - while True: - try: - conn, address = sock.accept() - except: - time.sleep(0.1) - continue - - #Send name - data = conn.recv(1024) - data = command_process(data) - print "servercontrol connected! %s " %data[0] - client_c = client(conn, address,data[0]) - - -handle_conn_t = threading.Thread(target=handle_conn) -handle_conn_t.daemon = True -handle_conn_t.start() - - -@hook.event("player.AsyncPlayerChatEvent","low") -def on_chat(event): - sender = event.getPlayer().getName() - msg = event.getMessage() - - for entry in clients: - entry.conn.sendall(sender + " " + msg) \ No newline at end of file diff --git a/serversigns.py b/serversigns.py deleted file mode 100644 index 4fe952e..0000000 --- a/serversigns.py +++ /dev/null @@ -1,416 +0,0 @@ -from helpers import * -from basecommands import simplecommand, Validate -import org.bukkit.Material as Material -import java.util.UUID as UUID -import org.bukkit.Material as Material -import org.bukkit.block.BlockFace as BlockFace -from math import ceil - -commands_whitelist = ( - "mail", "email", "memo", - "echo", "ping", - "cg join", - "cg info", - "chatgroup join", - "chatgroup info", - "i", - "item", - "p h", "plot home", "plot h", "p home", "plotme home", "plotme h", - "up", - "tppos", - "seen", -) - -max_line_length = 256 -max_lines = 20 -help_page_size = 12 - -def load_signs(): - signs_obj = open_json_file("serversigns", []) - loaded = {} - for entry in signs_obj: - loaded[tuple(entry[:4])] = list(entry[4:]) - return loaded - -def save_signs(): - signs_obj = [] - for key, value in signs.iteritems(): - signs_obj.append(key + tuple(value)) - save_json_file("serversigns", signs_obj) - -# {("world", x, y, z): ["owner_id", "msg1", "msg2"]} -signs = load_signs() - -# Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""} -lines = {} - -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 - - -# /svs command - - -subcommand_info = ( - - (("claim",), ( - "Claims the sign so that you can add messages to it", - ), (("[owner]", "claims.other"),)), - (("info", "lines"), ( - "Displays information about the (claimed) sign", - )), - (("add",), ( - "Adds the message to the sign. Use ++ at the end", - "to add the message to your buffer. You can then use", - "the same command again to create a longer message", - ), (("[++]", None),)), - (("remove", "rem", "del", "delete"), ( - "Removes the message with the given ID from the sign.", - "The ID is given before each message by &b/svs info&a.", - ), (("", None),)), - (("switch", "reverse"), ( - "Reverses the order in which the given messages are shown.", - ), ((" ", None),)), - (("clear",), ( - "Removes all messages from the sign.", - )), - (("reset", "unclaim"), ( - "Resets the sign, removing all messages and its owner.", - )), - (("whitelist", "commands", "wl"), ( - "Displays a list of whitelisted commands", - )), - (("help",), ( - "Displays this help page", - ), (("[page]", None),)), - -) - - - -@simplecommand(cmd = "serversigns", aliases = ["svs", "signmsg"], - description = "Makes something happen when you right click signs. \nUse /svs help for more details.", - usage = "[++]|remove |clear|info|help>", - helpNoargs = True, - senderLimit = 0) -def svs_command(sender, command, label, args): - arg1 = args[0].lower() - - cmd_info = None - for cmd in subcommand_info: - if arg1 in cmd[0]: - cmd_info = cmd - break - - Validate.notNone(cmd_info, signsMsg("That command could not be recognized, use &o/svs help &4for expected arguments")) - cmd = cmd_info[0][0] - Validate.isAuthorized(sender, "utils.serversigns." + cmd) - - #-------------------- Sub commands that don't require any conditions ----------------------- - if cmd == "help": - all_lines = [ - "&aServer signs let's you add messages to a sign.", - "Right clicking the sign will display all the messages. Commands", - "can also be added, by prefixing the message with a '/'.", - "How to use &b/serversigns&a:", - ] - - for cmd in subcommand_info: - if sender.hasPermission("utils.serversigns." + cmd[0][0]): - params = "" - if len(cmd) == 3: - for param, perm in cmd[2]: - if perm is None or sender.hasPermission("utils.serversigns." + perm): - params += param + " " - all_lines.append("&b/svs %s %s" % ("|".join(cmd[0]), params)) - for info_line in cmd[1]: - all_lines.append("&a- " + info_line) - - last_page = int(ceil(len(all_lines) / help_page_size)) - info("last page: %d" % last_page) - page = 1 - if len(args) > 1 and args[1].isdigit(): - page = int(args[1]) - if page <= 0: - page = 1 - elif page > last_page: - page = last_page - - first_line = signsMsg("Serversigns help page %d" % page, '6') - if page < last_page: - first_line += ", &e/svs help %d&6 for the next" % (page + 1) - page_lines = [first_line] + all_lines[(page - 1) * help_page_size : min(page * help_page_size, len(all_lines))] - return "\n".join(page_lines) - - - if cmd == "whitelist": - return signsMsg("Whitelisted commands: &3" + ", ".join(commands_whitelist), 'a') - #------------------------------------------------------------------------------------------- - - block = sender.getTargetBlock(None, 5) - Validate.isTrue(block.getType() in (Material.SIGN_POST, Material.WALL_SIGN), signsMsg("You have to be looking at a sign to use that!")) - - loc = fromLoc(block.getLocation()) - sign = getSign(loc) - signName = identifySign(loc) - arg2 = args[1].lower() if len(args) > 1 else None - - #------------------------ Sub commands that require the block to be a sign ------------------------------- - if cmd == "claim": - Validate.isTrue(not sign, signsMsg("The %s was already claimed" % signName)) - Validate.isTrue(can_build2(sender, block), signsMsg("You are not permitted to claim signs here")) - target = sender - if arg2: - Validate.isTrue(player.hasPermission("utils.serversigns.admin"), signsMsg("You are not authorized to claim signs for other players")) - target = server.getOfflinePlayer(arg2) - Validate.notNone(target, signsMsg("That player could not be found")) - Validate.isTrue(target.isOnline(), signsMsg("The target has to be online")) - uuid = uid(target) - if sign != None: - if sign[0] == uuid: - return signsMsg("The " + signName + " was already owned by that player") - else: - sign[0] = uuid - else: - signs[loc] = [uuid] - save_signs() - return signsMsg("Claimed the " + signName + ((" for %s" % target.getName()) if (target != sender) else ""), 'a') - #---------------------------------------------------------------------------------------------------------- - - Validate.notNone(sign, signsMsg("The %s has not been claimed" % signName)) - - #----------------------Sub commands that require the sign to be claimed as well------------------------------------ - if cmd == "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 cmd == "add": - Validate.isTrue(len(sign) - 1 <= max_lines, signsMsg("This sign already has the maximum amount of lines, you cannot add more")) - - 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] = "" - Validate.isTrue(len(lines[key]) + len(line[:-2]) + 1 <= max_line_length, signsMsg("This line would be too long, so the given message was not added to the accumulated message")) - 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(len(line) <= max_line_length, signsMsg("This line would be too long, so it was not added to the sign. It is however still accumulated.")) - - if line[0] == "/": - cmd = line[1:].lower() - whitelisted = False - for wl_cmd in commands_whitelist: - if cmd[:len(wl_cmd)] == wl_cmd: - whitelisted = True - break - Validate.isTrue(whitelisted, signsMsg("That command is not whitelisted for use with serversigns")) - - if key in lines: - del lines[key] - - sign.append(colorify(line) if line[0] != "/" else line) - save_signs() - return signsMsg("Added line \"&f%s&a\" to the %s" % (line, signName), 'a') - - - if cmd == "remove": - Validate.notNone(arg2, signsMsg("You have to enter the ID of the message to remove!")) - 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") - 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))) - del sign[id] - return signsMsg("Removed message with id %s from the %s" % (id, signName), 'a') - - - if cmd == "switch": - Validate.isTrue(len(args) == 3, signsMsg("You have to enter the 2 IDs of the messages to reverse")) - try: - 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') - - - if cmd == "clear": - signs[loc] = [sign[0]] - save_signs() - return signsMsg("Removed all messages from the %s" % signName, 'a') - - - if cmd == "reset": - del signs[loc] - save_signs() - return signsMsg("Removed all messages and the owner from the %s, it can now be claimed" % signName, 'a') - - #------------------------------------------------------------------------------------------------------- - - -@hook.event("player.PlayerInteractEvent") -def on_click(event): - if str(event.getAction()) != "RIGHT_CLICK_BLOCK": - return - block = event.getClickedBlock() - if block.getType() not in (Material.WALL_SIGN, Material.SIGN_POST): - return - sign = getSign(fromLoc(block.getLocation())) - if sign != None: - player = event.getPlayer() - for message in sign[1:]: - if message[:1] == "/": - server.dispatchCommand(player, message[1:]) - else: - msg(player, message, usecolor = False) - -# ---------------------------Sign breaking-------------------------------- - -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): - 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) - - -def check_sign(event, block, attached = True): - player = event.getPlayer() - loc = fromLoc(block.getLocation()) - if block.getType() not in (Material.WALL_SIGN, Material.SIGN_POST) or getSign(loc) is None: - return - 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: - 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() - - -def check_all_signs_and_force_commands(): - for loc in signs: - if server.getWorld(loc[0]).getBlockAt(loc[1], loc[2], loc[3]).getType() not in (Material.WALL_SIGN, Material.SIGN_POST): - del signs[loc] - - try: - map_field = server.getPluginManager().getClass().getDeclaredField("commandMap") - map_field.setAccessible(True) - command_map = map_field.get(server.getPluginManager()) - - commands_field = command_map.getClass().getDeclaredField("knownCommands") - commands_field.setAccessible(True) - map = commands_field.get(command_map) - - rsutils_cmd = map.get("redstonerutils:serversigns") - map.put("svs", rsutils_cmd) - map.put("serversigns", rsutils_cmd) - map.put("signsmsg", rsutils_cmd) - - except: - error("[Serversigns] failed to force commands") - error(trace()) diff --git a/setup.sh b/setup.sh index e542e09..3748cca 100755 --- a/setup.sh +++ b/setup.sh @@ -4,7 +4,7 @@ set -e for cmd in curl java unzip git pip; do - if ! which "$cmd" >/dev/null; then + if ! which -s "$cmd"; then tput setf 4 >&2 echo "Error: please install '$cmd' to proceed" >&2 tput sgr0 >&2 @@ -25,7 +25,7 @@ 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" +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 @@ -91,7 +91,7 @@ echo -e "\n> All plugins downloaded" cd "redstoner-utils.py.dir" echo -e "\n> Duplicating sample files" -for file in ./*.example; do +for file in ls ./*.example; do cp -v "$file" "$(echo "$file" | rev | cut -d "." -f 2- | rev)" done @@ -172,4 +172,4 @@ 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" +echo "> Our plugins are in redstoner/server/plugins/redstoner-utils.py.dir" \ No newline at end of file diff --git a/signalstrength.py b/signalstrength.py deleted file mode 100644 index d51f35a..0000000 --- a/signalstrength.py +++ /dev/null @@ -1,159 +0,0 @@ -from helpers import * -import org.bukkit.inventory.ItemStack as ItemStack -import org.bukkit.Material as Material -from math import ceil -from basecommands import simplecommand, Validate, CommandException - -""" Suggestion by Armadillo28, see thread: http://redstoner.com/forums/threads/2213?page=1#reply-14507 """ - -disallowed_item_types = ( - Material.getMaterial(0), - Material.getMaterial(175), - Material.getMaterial(383), -) - -default_args = open_json_file("signalstrengthdefaults", {}) - -def save_defaults(): - save_json_file("signalstrengthdefaults", default_args) - - -def item_name(item_type, remove_underscores = True): - typ = str(item_type).lower() - return typ.replace("_", "") if remove_underscores else typ - - -def item_type_allowed(item_type): - return not item_type in disallowed_item_types - - -def required_item_count(strength, stack_size, slot_count): - if strength == 0: - item_count = 0 - elif strength == 1: - item_count = 1 - else: - item_count = int(ceil(slot_count * stack_size / 14.0 * (strength - 1))) - - resulting_strength = 0 if item_count == 0 else int(1 + 14.0 * item_count / stack_size / slot_count) - #Clarification on these formulas at http://minecraft.gamepedia.com/Redstone_Comparator#Containers - - return item_count if resulting_strength == strength else None - - -def get_data(player, args): - uuid = uid(player) - if uuid in default_args: - strength, item_type, item_data = default_args[uuid] - item_type = Material.getMaterial(item_type) - else: - strength = 1 - item_type = Material.REDSTONE - item_data = 0 - - if len(args) > 0: - Validate.isTrue(args[0].isdigit() and 0 <= int(args[0]) <= 15, "&cThe signal strength has to be a value from 0 to 15") - strength = int(args[0]) - - if len(args) > 1: - if args[1].isdigit(): - item_type = Material.getMaterial(int(args[1])) - else: - item_type = Material.matchMaterial(args[1]) - Validate.notNone(item_type, "&cThat item type could not be found") - Validate.isTrue(item_type not in disallowed_item_types, "&cThat item type may not be used") - - if len(args) > 2: - Validate.isTrue(args[2].isdigit() and 0 <= int(args[2]) <= 15, "&cThe data has to be a value from 0 to 15") - item_data = int(args[2]) - - return (strength, item_type, item_data) - - -def get_inventory(block): - try: - return block.getState().getInventory() - except AttributeError: - return None - - -def get_entire_container(container): - container_blocks = [container] - container_type = container.getType() - if container_type in (Material.CHEST, Material.TRAPPED_CHEST): - loc = container.getLocation() - x = loc.getBlockX() - y = loc.getBlockY() - z = loc.getBlockZ() - world = loc.getWorld() - - container_blocks += [ - block for block in ( - world.getBlockAt(x + 1, y, z), - world.getBlockAt(x - 1, y, z), - world.getBlockAt(x, y, z + 1), - world.getBlockAt(x, y, z - 1), - ) if block.getType() == container_type - ] - - return container_blocks - - - -@simplecommand("signalstrength", - usage = "(default) [signalstrength] [item] [data]", - aliases = ["ss", "level"], - description = "Fills the targeted container with the correct amount of items to achieve the desired signal strength.", - amin = 0, - amax = 4, - helpSubcmd = True, - senderLimit = 0) -def on_signalstrength_command(sender, command, label, args): - - if len(args) > 0 and args[0].lower() in ("default", "defaults", "setdefaults"): - strength, item_type, item_data = get_data(sender, args[1:]) - - uuid = uid(sender) - if strength == 1 and item_type == Material.REDSTONE and item_data == 0: - if uuid in default_args: - del default_args[uuid] - save_defaults() - else: - default_args[uuid] = (strength, str(item_type), item_data) - save_defaults() - - return "&aSet your signal strength defaults to (%s, %s, %s)" % (strength, item_name(item_type, False), item_data) - - Validate.isTrue(len(args) <= 3, "&cExpected at most 3 arguments") - - target_block = sender.getTargetBlock(None, 5) - Validate.notNone(target_block, "&cThat command can only be used when a container is targeted") - - inventory = get_inventory(target_block) - Validate.notNone(inventory, "&cThat command can only be used if a container is targeted") - - strength, item_type, item_data = get_data(sender, args) - - #--------Get the stack size and required amount of items to achieve the desired signal strength--------- - stack_size = item_type.getMaxStackSize() - slot_count = inventory.getSize() - - item_count = required_item_count(strength, stack_size, slot_count) - Validate.notNone(item_count, "&cThe desired signal strength could not be achieved with the requested item type") - - #--------Add the other side of the chest if target is a double chest and check if player can build--------- - container_blocks = get_entire_container(target_block) - for block in container_blocks: - Validate.isTrue(can_build(sender, block), "&cYou do not have permission to do that here") - - #----------------Insert items------------- - full_stack_count, remaining = divmod(item_count, stack_size) - for block in container_blocks: - inv = block.getState().getInventory() - inv.clear() - for i in range(full_stack_count): - inv.setItem(i, ItemStack(item_type, stack_size, item_data)) - if remaining > 0: - inv.setItem(full_stack_count, ItemStack(item_type, remaining, item_data)) - - return "&aComparators attached to that %s will now put out a signal strength of %s" % (item_name(target_block.getType()), strength) diff --git a/synchronizeranks.py b/synchronizeranks.py index 4509185..97439e0 100644 --- a/synchronizeranks.py +++ b/synchronizeranks.py @@ -3,14 +3,6 @@ from secrets import * import mysqlhack from com.ziclix.python.sql import zxJDBC -""" -WORK IN PROGRESS -""" - -#-----------------------Config-------------------------- - -config_file = "website-roles" - ranks = { "member" : 3, "builder" : 7, @@ -21,42 +13,33 @@ ranks = { "admin" : 5 } -ranks = open_json_file(config_file, ranks) - -def save_ranks(): - save_json_file(config_file, ranks) - -#-----------------------Event--------------------------- @hook.event("player.PlayerJoinEvent", "normal") def on_player_join(event): user = event.getPlayer() uuid = uid(player).replace("-", "") + role = get_role(uuid) + if role in [1, 2, 6]: #Disabled/Banned/Superadmin + return + if role: + for rank in ranks: + if user.hasPermission("group." + rank): + if role != ranks[rank]: + set_role(uuid, ranks[rank]) + return + if not user.hasPlayedBefore(): + return + if role == None: + msg(user, "&cYou haven't registed yet! Make sure to do so on redstoner.com") - sql_instruction - - def callback_thing(role, args): - - if role in [1, 2, 6]: #Disabled/Banned/Superadmin - return - if role != None: - for rank in ranks: - if user.hasPermission("group." + rank): - if role != ranks[rank]: - set_role(uuid, ranks[rank]) - elif user.hasPlayedBefore(): - msg(user, "&cYou haven't registed yet! Make sure to do so on redstoner.com") def get_role(uuid): - results = execute_query("SELECT `role_id` FROM users WHERE `uuid` = ? LIMIT 1;", uuid) - return results[0][0] - # Returns a table with 1 row (LIMIT 1) and 1 column (SELECT `role_id`), so we're looking for the first row of the first column. + return execute_query("SELECT `role_id` FROM users WHERE `uuid` = ? LIMIT 1", uuid)[0][17] def set_role(uuid, role_id): - execute_update("UPDATE users SET `role_id` = ? WHERE `uuid` = ?;", (role_id, uuid,)) - # %d is like %s for integers (unlogically, you'd expect something like %i), though %s also works here. + execute_update("UPDATE users SET `role_id` = %d WHERE `uuid` = ?" % role_id, uuid) def execute_query(query, uuid): @@ -73,40 +56,5 @@ def execute_update(update, uuid): conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") curs = conn.cursor() curs.execute(update, (uuid,)) - conn.commit() curs.close() - conn.close() - -def get_role(uuid): - sql_instruction() - -#--------------------------------Queries / Updates---------------------------- - -def sql_instruction(instruction, args, fetch = True, callback_func = ignored_func, callback_args = tuple()): - thread = threading.Thread(target = curs_instruction, args = (instruction_executor, instruction, fetch, callback_func, callback_args)) - thread.start() - - -def curs_instruction(func, instruction, fetch, callback_func, callback_args): - conn = zxJDBC.connect(mysql_database, mysql_user, mysql_pass, "com.mysql.jdbc.Driver") - curs = conn.getCursor() - - if fetch: - returned = func(curs, instruction, fetch) - curs.close() - conn.close() - callback_func(returned, callback_args) - - else: - func(curs, instruction, fetch) - conn.commit() - curs.close() - conn.close() - - -def instruction_executor(curs, instruction, fetch): - curs.execute(instruction) - return curs.fetchall() if fetch else None - -def ignored_func(*args): - pass \ No newline at end of file + conn.close() \ No newline at end of file diff --git a/tag.py b/tag.py deleted file mode 100644 index b2aa98d..0000000 --- a/tag.py +++ /dev/null @@ -1,78 +0,0 @@ -from helpers import * - -add_perm = "utils.tag.add" -del_perm = "utils.tag.del" -check_perm = "utils.tag.check" - -data = open_json_file("tag", {}) - -@hook.command("tag") -def command(sender, command, label, args): - if len(args) > 0: - if str(args[0]) == "add": - if sender.hasPermission(add_perm): - if len(args) > 2: - add(sender, args[1:]) - else: - msg(sender, "&a-&c Usage: /tag add ") - else: - noperm(sender) - elif str(args[0]) == "check": - if sender.hasPermission(check_perm): - if len(args) == 2: - check(sender, args[1:]) - else: - msg(sender, "&a-&c Usage: /tag check ") - else: - noperm(sender) - elif str(args[0]) == "del": - if sender.hasPermission(del_perm): - if len(args) == 3: - delete(sender, args[1:]) - else: - msg(sender, "&a-&c Usage: /tag del ") - else: - msg(sender, "&a-&c Unknown subcommand! (add, check, del)") - else: - msg(sender, "&a&c Usage: /tag add/check/del") - return True - -def delete(sender, args): - player = server.getOfflinePlayer(args[0]) - uuid = uid(player) - try: - if data[uuid] == None: - pass - except: - msg(sender, "&a-&e There are no notes about this player") - return - if int(args[1]) - 1 >= len(data[uuid]): - msg(sender, "&a-&c Id of note is out of range") - return - del (data[uuid])[int(args[1]) - 1] - save_json_file("tag", data) - msg(sender, "&a-&e Deleted note at %s" % args[1]) - -def add(sender, args): - player = server.getOfflinePlayer(args[0]) - uuid = uid(player) - try: - if data[uuid] == None: - pass - except: - data[uuid] = [] - data[uuid].append(" ".join(args[1:])) - msg(sender, "&a-&e Note added") - save_json_file("tag", data) - -def check(sender, args): - player = server.getOfflinePlayer(args[0]) - uuid = uid(player) - try: - num = 0 - for tag in data[uuid]: - num += 1 - msg(sender, "&a-&e %s: %s" % (str(num), str(tag))) - except: - msg(sender, "&a-&e There are no notes about this player") - diff --git a/vanish.py b/vanish.py deleted file mode 100644 index a572ebc..0000000 --- a/vanish.py +++ /dev/null @@ -1,121 +0,0 @@ -from helpers import * -from basecommands import simplecommand -from basecommands import Validate - -vanished = [] - - -def is_authorized(player): - return player.hasPermission("utils.vanish") - - -def is_vanished(player): - return uid(player) in vanished - - -#this can be used to silently set the vanished state of a player -def set_state(player, state): - if state == is_vanished(player): - return - - if state: - enable_vanish(player) - else: - disable_vanish(player) - - -def enable_vanish(target): - vanished.append(uid(target)) - for player in list(server.getOnlinePlayers()): - if not is_authorized(player): - player.hidePlayer(target) - - -def disable_vanish(target): - vanished.remove(uid(target)) - for player in list(server.getOnlinePlayers()): - player.showPlayer(target) - - -@simplecommand("vanish", - aliases = ["v"], - usage = "[on/off]", - description = "Toggles vanish mode, hiding you and your online status \nfrom other players.", - senderLimit = 0, - amin = 0, - amax = 1, - helpNoargs = False, - helpSubcmd = True -) -def vanish_command(sender, command, label, args): - try: - current_state = is_vanished(sender) - new_state = not current_state - - if len(args) == 1: - arg = args[0].lower() - if arg == "on": - new_state = True - elif arg == "off": - new_state = False - - if current_state == new_state: - return "&cYou were %s vanished!" % ("already" if current_state else "not yet") - - set_state(sender, new_state) - return "&a%s vanish mode!" % ("Enabled" if new_state else "Disabled") - except: - error(trace()) - - -@hook.event("player.PlayerJoinEvent") -def on_player_join(event): - player = event.getPlayer() - - if not is_authorized(player): - for uuid in vanished: - player.hidePlayer(retrieve_player(uuid)) - - elif is_vanished(player): - msg(player, "&cKeep in mind that you are still vanished! Use /vanish to disable.") - - -@hook.event("player.PlayerQuitEvent") -def on_player_quit(event): - player = event.getPlayer() - - if not is_authorized(player): - for uuid in vanished: - player.showPlayer(retrieve_player(uuid)) - - -@simplecommand("vanishother", - usage = "{player} [on/off]", - description = "Toggles vanish mode for someone, hiding them and their online status from other players.", - amin = 1, - amax = 2, - helpNoargs = True, - helpSubcmd = True) -def vanishother_command(sender, command, label, args): - target = server.getPlayer(args[0]) - Validate.notNone(target, "&cThe specified player is not online") - - current_state = is_vanished(target) - new_state = not current_state - - if len(args) == 2: - arg = args[1].lower() - if arg == "on": - new_state = True - elif arg == "off": - new_state = False - - if current_state == new_state: - return "&cThat player was already vanished!" if current_state else "&cThat player was not yet vanished!" - - set_state(target, new_state) - - enabled_str = "enabled" if new_state else "disabled" - if target != sender: - msg(target, "&aVanish mode %s by %s" % (enabled_str, sender.getDisplayName() if is_player(sender) else "&9CONSOLE")) - return "&aVanish mode %s%s" % (enabled_str, " for " + target.getDisplayName() if target != sender else "") diff --git a/vanishfix.py b/vanishfix.py deleted file mode 100644 index b13b059..0000000 --- a/vanishfix.py +++ /dev/null @@ -1,14 +0,0 @@ -from helpers import * -from java.lang import Runnable - -class run(Runnable): - - def run(self): - players = server.getOnlinePlayers() - for player in players: - if player.hasPermission("essentials.vanish"): - player.performCommand("vanish") - player.performCommand("vanish") - -def enabled(): - server.getScheduler().runTaskTimer(server.getPluginManager().getPlugin("RedstonerUtils"), run(), 20, 1200)