diff --git a/blockplacemods.py b/blockplacemods.py index 37027f4..fd7071e 100644 --- a/blockplacemods.py +++ b/blockplacemods.py @@ -9,7 +9,7 @@ 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 +import org.bukkit.scheduler.BukkitRunnable as Runnable """ # Permissions: @@ -38,11 +38,11 @@ settingInformation = dict( #[setting type, identifying description, detailed des "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"] - ], + #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.", @@ -66,7 +66,7 @@ defaults = { 2: list } -piston_faces = { +faces = { BlockFace.DOWN : 0, BlockFace.UP : 1, BlockFace.NORTH : 2, @@ -75,14 +75,6 @@ piston_faces = { 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(): @@ -136,14 +128,14 @@ def toggle_command(sender, command, label, args): elif arg2 in ("toggle", "switch"): new = not enabled elif arg2 in ("on", "enable"): - new = True + new = not default elif arg2 in ("off", "disable"): - new = False + new = default else: return " &cArgument '%s' was not recognized. \n Use &o/toggle %s info &cfor more information" % (arg2, setting) - if enabled is new: + if enabled == new: return " &cAlready %s: &a%s" % ("enabled" if enabled else "disabled", details[1]) - if new is default: + if new == default: values.remove(uuid) else: values.append(uuid) @@ -158,11 +150,9 @@ def toggle_command(sender, command, label, args): if arg2 == "clear": if enabled: del values[uuid] - saveSettings() - return " &aDisabled " + details[1] - return " &cAlready disabled: " + details[1] + return " &aDisabled " + details[1] - if arg2 == "info": + 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 @@ -175,17 +165,16 @@ def toggle_command(sender, command, label, args): items = values[uuid] if slot in items: del items[slot] + saveSettings() 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) + return " &cArgument '%s' was not recognized. \nUse &o/toggle %s details &cfor more detailsrmation." % (arg2, setting) if not enabled: values[uuid] = {} @@ -208,63 +197,59 @@ def isEnabled(toggleSetting, uuid): @hook.event("block.BlockPlaceEvent", "monitor") def on_block_place(event): - try: + if event.isCancelled(): + return + player = event.getPlayer() + if not is_creative(player): + return - if event.isCancelled(): - return - player = event.getPlayer() - if not is_creative(player): - return - - uuid = uid(player) - block = event.getBlockPlaced() - material = block.getType() + 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 + 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.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.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) + """ - 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()) + 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") @@ -283,36 +268,29 @@ def on_interact(event): 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("[BlockPlaceMods] Interrupted torch breaking thread") + info("Interrupted torch breaking thread") -class JBukkitRunnable(BukkitRunnable): +class torch_breaker(Runnable): - def __init__(self, func): - self.run = func + def run(): - -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: + 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()) + except: + error(trace()) +""" - -def schedule_torch_breaker(): - JBukkitRunnable(torch_breaker).runTaskTimer(server.getPluginManager().getPlugin("RedstonerUtils"), 0, 1) diff --git a/chatalias.py b/chatalias.py index 67de106..25e3336 100644 --- a/chatalias.py +++ b/chatalias.py @@ -1,402 +1,138 @@ -# TODO: Add cg/ac/msg support +# Chat Aliasing plugin by Curs3d # +################################## +# Allows users to alias words, +# so that when they send a +# message in chat, it gets +# replaced by their specified +# word. The JSON file for this +# plugin is generated if not +# present. Set values to -1 +# for "unlimited" setting. -import os -import mysqlhack -import org.bukkit as bukkit -from org.bukkit import * from helpers import * +import re +from traceback import format_exc as trace + +data = None + +max_entries = 10 +max_alias_length = 35 +# Minecraft message limit is 100 so I decided to give a little tolerance (and I added a bit more) +max_overall_length = 100 + max_alias_length + +alias_perm = "utils.alias.allowed" +exceed_length = "utils.alias.exceedlimit" +exceed_entries = "utils.alias.exceedlimit" +exceed_overall_length = "utils.alias.exceedlimit" -# Version number and requirements +def safe_open_json(): + global data + if data is not None: + return data + data = open_json_file("aliases") + if data is None: + data = {} + save_json_file("aliases", data) + return data -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 multiple_replace(aliases, text): + regex = re.compile("|".join(map(re.escape, aliases.keys()))) + return regex.sub(lambda mo: aliases[mo.group(0)], text) -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 +@hook.command("alias", + usage="/ [to_alias] [alias...]", + desc="Aliases words in chat") +def on_alias_command(sender, cmd, label, args): - -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() + if not is_player(sender): + msg(sender, "Sorry, non-players cannot alias words") + return True + if not sender.hasPermission(alias_perm): + plugin_header(recipient=sender, name="Chat Alias") + noperm(sender) + return True + if len(args) == 0: + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7This is a plugin that allows you to get words" + + "replaced by other ones automatically!") + msg(sender, "&7\nCommands:") + msg(sender, "&e/alias &7removes from your aliases. " + + "Use &e/alias * &7to remove all aliases.") + msg(sender, "&e/alias &7will change &e " + + "&7to &e &7in chat") + msg(sender, "&7\nYour Aliases:") + data = safe_open_json() + try: + for alias, value in data[str(sender.getUniqueId())].items(): + msg(sender, "&7%s &7==> %s" % (alias, value)) + except KeyError: + pass + return True + elif len(args) == 1: + data = safe_open_json() + if args[0] == "*": + try: + del data[str(sender.getUniqueId())] + except KeyError: + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7No alias data to remove!") + return True + save_json_file("aliases", data) + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&cALL &7alias data successfuly removed!") + return True + try: + if data[str(sender.getUniqueId())].pop(args[0], None) is None: + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7Could not remove: alias not present!") + return True + except KeyError: + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7Could not remove: you do not have any aliases!") + return True + save_json_file("aliases", data) + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7Alias for %s &7successfuly removed" % args[0]) + return True + elif len(args) >= 2: + data = safe_open_json() + alias = " ".join(args[1:]) + try: + if (len(alias) > max_alias_length) and (max_alias_length >= 0) and (not sender.hasPermission(exceed_length)): + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7Please do not alias long words/sentences.") + return True + if (len(data[str(sender.getUniqueId())]) >= max_entries) and (max_entries >= 0) and (not sender.hasPermission(exceed_entries)): + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7You have reached your alias limit!") + return True + except KeyError: + data[str(sender.getUniqueId())] = {} + data[str(sender.getUniqueId())][args[0]] = alias + save_json_file("aliases", data) + plugin_header(recipient=sender, name="Chat Alias") + msg(sender, "&7Chat Alias %s &7==> %s &7successfully created!" % (args[0], alias)) + return True else: - if event.getPlayer().hasPermission(permission_FINFO): - disabled_fallback(event.getPlayer()) + return False @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): + playerid = str(event.getPlayer().getUniqueId()) + data = safe_open_json() + if event.isCancelled(): 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) + if not playerid in data: return - msg(sender, colorify("&7Alias: ") + args[0] + colorify("&7 -> ") + args[1] + colorify("&7 was succesfully created!"), usecolor=sender.hasPermission("essentials.chat.color")) + event.setMessage(multiple_replace(data[playerid], event.getMessage())) -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) + if (event.getPlayer().hasPermission("essentials.chat.color")): + event.setMessage(colorify(event.getMessage())) + if (max_overall_length >= 0) and (len(event.getMessage()) > max_overall_length) and (not event.getPlayer().hasPermission(exceed_overall_length)): + event.setCancelled(True) + plugin_header(recipient=event.getPlayer(), name="Chat Alias") + msg(event.getPlayer(), "&7The message generated was too long and was not sent. :/") diff --git a/chatgroups.py b/chatgroups.py index b3838a0..9965b96 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() @@ -89,7 +87,7 @@ def groupchat(sender, message, ann = False): def do_for_chatgroup(group, func, *args, **kwargs): for receiver in server.getOnlinePlayers(): if groups.get(uid(receiver)) == group: - func(receiver, *args, **kwargs) + func(receiver, args, kwargs) def send_tpa_request(receiver, sender): if not receiver == sender: @@ -102,9 +100,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) diff --git a/check.py b/check.py index 3eb4026..33ffb57 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") 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/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..79af3a0 --- a/helpers.py +++ b/helpers.py @@ -11,6 +11,8 @@ import org.bukkit.block as bblock import org.bukkit.event.entity as entity import org.bukkit.command.ConsoleCommandSender from org.bukkit.entity import * +from player import get_py_player +from player import py_players #Imports for async query from secrets import * @@ -20,7 +22,7 @@ import threading 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() @@ -85,7 +87,7 @@ def colorify(text): """ replace &-codes with real color codes """ - return sub("&(?=[?\\da-fk-or])", u"\u00A7", "%s" % text) + return sub("&" + u"\u00A7", "&", "%s" % sub("&(?=[?\\da-fk-or])", u"\u00A7", "%s" % text)) def stripcolors(text): @@ -179,6 +181,16 @@ def is_creative(player): return str(player.getGameMode()) == "CREATIVE" +def is_rank(player, rank): + """ + rank: a string equal to the PEX group name found in /pex groups + returns True if one of the following conditions are met: + - the player is of the given rank, + - their rank inherits the given rank. + """ + return player.hasPermission("groups." + rank) + + def uid(player): """ returns the player's UUID @@ -258,21 +270,18 @@ 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): +def isIP(tocheck): subsets = ["","","",""] i = 0 for j in range(0,len(tocheck)): @@ -290,34 +299,3 @@ def is_ip(tocheck): 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 diff --git a/imbusy.py b/imbusy.py index a8c5280..64fa30b 100644 --- a/imbusy.py +++ b/imbusy.py @@ -1,318 +1,107 @@ -""" -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. -""" +# I'M BUSY! Plugin by Curs3d # +############################## +# Concept by CookieManors :D # +# http://bit.ly/1GnNPW8 # +############################## +# 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 +from basecommands import simplecommand +from traceback import format_exc as trace +busy_players = [] -@hook.command("imbusy", - aliases = ["busy"], - usage = "/ [on, off, status/check]", - description = "Offers control over your busy status" +def unclear(): + msg(sender, "Umm, what? Sorry, directions unlclear, got head stuck in washing machine") + + +@hook.command("busy", + aliases = ["focus"], + usage = "/ ", + description = "Sets busy mode on, you cannot recieve tpas and MSGs" ) -@debug def on_busy_command(sender, cmd, label, args): + if not is_player(sender): - msg(sender, "&7Sorry, Console cannot be busy") - return True + msg(sender, "Sorry, Console cannot be busy") + return True - plugin_header(recipient = sender, name = "I'M BUSY!") - - if not sender.hasPermission(base_permission): + if not sender.hasPermission("utils.busy.allowed"): + plugin_header(recipient = sender, name = "I'M BUSY!") 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) + plugin_header(recipient = sender, name = "I'M BUSY!") + msg(sender, "This plugin allows being busy, and when turned on you will not recieve any direct messages or tpa requests.") + msg(sender, "\nCommands:") + msg(sender, "/busy on: turns on busy mode") + msg(sender, "/busy off: turns off busy mode") + msg(sender, "/busy status [player]: shows your or [player]'s current busy status.") 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") + elif len(args) == 1: + if args[0] == "on": + if sender.getName() in busy_players: + plugin_header(recipient = sender, name = "I'M BUSY!") + msg(sender, "You cannot be even more focused than this without being a jedi!") + return True + busy_players.append(sender.getName()) + plugin_header(recipient = sender, name = "I'M BUSY!") + broadcast(None, "%s is now SUPER busy! Don't even TRY bothering them, it will not work!" % sender.getName()) return True - status = get_status(target) - if status is True: - status_str = "SUPER busy" - elif status is False: - status_str = "busy" + + elif args[0] == "off": + plugin_header(recipient = sender, name = "I'M BUSY!") + try: + busy_players.remove(sender.getName()) + msg(sender, "Master has sent /busy command, %s is freeee!" % sender.getName()) + return True + except ValueError: + msg(sender, "You are not busy! You cannot be even less busy! Are you perhaps bored?") + return True + + elif args[0] == "status": + plugin_header(recipient = sender, name = "I'M BUSY!") + if sender.getName() in busy_players: + msg(sender, "You are super-duper busy and concentrated right now. Think, think, think!") + return True + else: + msg(sender, "You are completely unable to focus right now.") + return True + + else: + plugin_header(recipient = sender, name = "I'M BUSY!") + unclear() + return False + + elif len(args) == 2 and args[0] == "status": + plugin_header(recipient = sender, name = "I'M BUSY!") + if args[1] in busy_players: + msg(sender, "Yes, %s is busy. Shhh..." % args[1]) + return True + else: + msg(sender, "No, you're good. Feel free to chat with %s!" % args[1]) + return True + 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()) + plugin_header(recipient = sender, name = "I'M BUSY!") + unclear() 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): +def on_cmd_preprocess_event(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()) + if message[0] == "/msg" or message[0] == "/w" or message[0] == "/m" or \ + message[0] == "/tell" or message[0] == "/tpa" or message[0] == "/tpahere": + if message[1] in busy_players: + plugin_header(recipient = event.getPlayer(), name = "I'M BUSY!") + msg(event.getPlayer(), "We are sorry, but %s is currently busy. Please try again later." % message[1]) + event.setCancelled(True) diff --git a/iptracker.py b/iptracker.py old mode 100755 new mode 100644 index 969a822..8bbd053 --- a/iptracker.py +++ b/iptracker.py @@ -1,108 +1,107 @@ -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 +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" + + +@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 = ?", (uuid, json.dumps(ips), )) + 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 uuid = ?", (ip, json.dumps(uuids), )) + conn.commit() + curs.close() + conn.close() + + +@hook.command("getinfo") +def on_getinfo_command(sender, args): + t = threading.Thread(target=on_player_join_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 isIP(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/killpotdisable.py b/killpotdisable.py new file mode 100644 index 0000000..6a4ed23 --- /dev/null +++ b/killpotdisable.py @@ -0,0 +1,20 @@ +import org.bukkit.potion.PotionEffect as PotionEffect +import org.bukkit.potion.PotionEffectType as PotionEffectType + + +@hook.event("entity.PotionSplashEvent", "high") +def on_splash(event): + potion_effects = event.getPotion().getEffects() + + for eff in potion_effects: + if eff.getType() == PotionEffectType.HEAL: + if eff.getAmplifier() > 250: + + event.setCancelled(True) + break + + elif eff.getType() == PotionEffectType.HARM: + if eff.getAmplifier() > 250: + + event.setCancelled(True) + break diff --git a/loginsecurity.py b/loginsecurity.py index d1607ef..edf51e9 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"] @@ -273,10 +272,4 @@ def pre_command_proccess(event): 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()) + event.setCancelled(True) \ No newline at end of file diff --git a/main.py b/main.py index 1b9e3f4..7411d17 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!") @@ -50,9 +43,7 @@ shared["load_modules"] = [ # Adds /calc, toggles automatic solving of Math expressions in chat "calc", # Adds aliasing of chat words - "chatalias", - # For players to point friends - "friends", + #"chatalias", # Plugin to locate laggy chunks. /lc lists chunks with more than n entities "lagchunks", # Adds /report and /rp, Stores reports with time and location @@ -98,7 +89,7 @@ shared["load_modules"] = [ # Servercontrol extension for telnet access to logs/AC #"servercontrol", # Script helper plugin - "scriptutils", + "scriptutils", # Per-player notes "tag", # vanish toggle module - temporary fix @@ -107,12 +98,10 @@ shared["load_modules"] = [ "punishments", # a simple replacement for the buggy essentials /vanish "vanish", - # ip-tracking utility - disabled as of instability - #"iptracker", + # ip-tracking utility + "iptracker", #server signs for everyone - "serversigns", - # Makes player's names colored, sorts tab list by rank - "nametags" + "serversigns" ] shared["modules"] = {} for module in shared["load_modules"]: diff --git a/misc.py b/misc.py index e495317..0fd4a6a 100644 --- a/misc.py +++ b/misc.py @@ -127,7 +127,7 @@ def on_interact(event): 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"] +"script_stop", "script_stop_abort", "script_shutdown", "stop", "esudo", "essentials:sudo", "sudo"] @simplecommand("sudo", usage = " [cmd..]", @@ -212,13 +212,12 @@ 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 +"51f2ad3c-6cc8-40ea-aa2b-f25970316921" # Dico +] @simplecommand("pyeval", usage = "[code..]", 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..0f4a47f 100644 --- a/player.py +++ b/player.py @@ -25,6 +25,5 @@ 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 index 886d026..4b57be1 100644 --- a/punishments.py +++ b/punishments.py @@ -55,7 +55,6 @@ class Slave(object): 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() 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/serversigns.py b/serversigns.py index 4fe952e..d9f2a44 100644 --- a/serversigns.py +++ b/serversigns.py @@ -4,26 +4,8 @@ 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 +blocked_cmds = tuple(shared["modules"]["misc"].sudo_blacklist) + ("pex", "kick", "ban", "tempban", "reload", "op", "deop", "whitelist") def load_signs(): signs_obj = open_json_file("serversigns", []) @@ -38,11 +20,9 @@ def save_signs(): signs_obj.append(key + tuple(value)) save_json_file("serversigns", signs_obj) -# {("world", x, y, z): ["owner_id", "msg1", "msg2"]} -signs = load_signs() +signs = load_signs() # {("world", x, y, z): ["owner_id", "msg1", "msg2"]} -# Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""} -lines = {} +lines = {} # Accumulated messages so players can have longer messages: {"Dico200": "Message...........", ""} def fromLoc(bLoc): """ @@ -105,46 +85,6 @@ def signsMsg(msg, colour = '4'): 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>", @@ -152,56 +92,35 @@ subcommand_info = ( 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) + Validate.isTrue(arg1 in ("claim", "reset", "add", "remove", "info", "clear", "help", "switch", "reverse", "unclaim"), + signsMsg("That argument could not be recognized, use &o/svs help &4for expected arguments")) + Validate.isAuthorized(sender, "utils.serversigns." + arg1) #-------------------- 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') + if arg1 == "help": + admin = sender.hasPermission("utils.serversigns.admin") + msg = signsMsg("Server signs lets you add messages to a sign.", 'a') + msg += "\nRight clicking the sign will display all the messages. Commands" + msg += "\ncan also be added, by prefixing the message with a '/'." + msg += "\nHow to use &b/serversigns&a:" + msg += "\n&b/svs claim" + ("" if not sender.hasPermission("utils.serversigns.admin") else " [owner]") + msg += "\n&a- Claims the sign so that you can add messages to it" + msg += "\n&b/svs info" + msg += "\n&a- Displays information about the (claimed) sign" + msg += "\n&b/svs add [++]" + msg += "\n&a- Adds the message to the sign. Use ++ at the end" + msg += "\n&a- to add the message to your buffer. You can then use" + msg += "\n&a- the same command again to create a longer message." + msg += "\n&b/svs remove " + msg += "\n&a- Removes the message with the given ID from the sign." + msg += "\n&a- The ID is given before each message by &b/svs info&a." + msg += "\n&b/svs switch|reverse " + msg += "\n&a- Reverses the order in which the given messages are shown." + msg += "\n&b/svs clear" + msg += "\n&a- Removes all messages from the sign." + msg += "\n&b/svs reset|unclaim" + msg += "\n&a- Resets the sign, removing all messages and its owner." + return msg #------------------------------------------------------------------------------------------- block = sender.getTargetBlock(None, 5) @@ -213,7 +132,7 @@ def svs_command(sender, command, label, args): arg2 = args[1].lower() if len(args) > 1 else None #------------------------ Sub commands that require the block to be a sign ------------------------------- - if cmd == "claim": + if arg1 == "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 @@ -225,7 +144,7 @@ def svs_command(sender, command, label, args): uuid = uid(target) if sign != None: if sign[0] == uuid: - return signsMsg("The " + signName + " was already owned by that player") + return signsMsg("The" + signName + " was already owned by that player") else: sign[0] = uuid else: @@ -237,7 +156,7 @@ def svs_command(sender, command, label, args): 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": + if arg1 == "info": sign_lines = "" for id, line in enumerate(sign[1:]): sign_lines += ("\n &a%s: \"&f%s&a\"" % (id + 1, line)) @@ -247,44 +166,26 @@ def svs_command(sender, command, label, args): 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")) - + if arg1 == "add": 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] - + Validate.isTrue(line[0] != "/" or line.split(" ")[0][1:] not in blocked_cmds, signsMsg("Usage of that command with server signs is prohibited")) 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": + if arg1 == "remove": Validate.notNone(arg2, signsMsg("You have to enter the ID of the message to remove!")) try: id = int(arg2) @@ -295,7 +196,7 @@ def svs_command(sender, command, label, args): return signsMsg("Removed message with id %s from the %s" % (id, signName), 'a') - if cmd == "switch": + if arg1 in ("switch", "reverse"): Validate.isTrue(len(args) == 3, signsMsg("You have to enter the 2 IDs of the messages to reverse")) try: id1 = int(args[1]) @@ -309,20 +210,21 @@ def svs_command(sender, command, label, args): return signsMsg("Reversed the messages with IDs %s and %s of the %s" % (id1, id2, signName), 'a') - if cmd == "clear": + if arg1 == "clear": signs[loc] = [sign[0]] save_signs() return signsMsg("Removed all messages from the %s" % signName, 'a') - if cmd == "reset": + if arg1 in ("reset", "unclaim"): 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": @@ -352,37 +254,39 @@ faces = { @hook.event("block.BlockBreakEvent", "monitor") def on_break(event): - if checking_block or event.isCancelled(): - return + try: + global checking_block + 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) + 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) + 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) + block3 = block.getRelative(BlockFace.UP) + if block3.getType() == Material.SIGN_POST: + check_sign(event, block3) + except: + error(trace()) 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 + sign = getSign(fromLoc(block.getLocation())) 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: + loc = fromLoc(block.getLocation()) 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) @@ -391,26 +295,3 @@ def can_build2(player, block): 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())