#pylint: disable = F0401 from re import sub from java.util.UUID import fromString as juuid from json import dumps as json_dumps, loads as json_loads 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.block as bblock shared = {} # this dict can be used to share stuff across modules server = bukkit.Bukkit.getServer() def info(text): server.getLogger().info("[RedstonerUtils] %s" % text) def warn(text): server.getLogger().warning("[RedstonerUtils] %s" % text) def error(text): server.getLogger().severe("[RedstonerUtils] %s" % text) def msg(player, text, usecolor = True, basecolor = None): """ send a message to player the player may be None or offline, which this method just ignores unless usecolor is False, &-codes are translated to real color codes for that case, basecolor can be useful. basecolor accepts a single character as color code """ if player and (player == server.getConsoleSender() or player.getPlayer()): # getPlayer() returns None when offline if basecolor: if usecolor: text = colorify(text) player.sendMessage(colorify("&%s" % basecolor) + text) else: player.sendMessage(colorify(text) if usecolor else text) def broadcast(perm, text): """ better than bukkit's broadcast. bukkit only works with permissibles that are subscribed to perm """ text = colorify(text) for recipient in list(server.getOnlinePlayers()) + [server.getConsoleSender()]: if not perm or recipient.hasPermission(perm): msg(recipient, text) def colorify(text): """ replace &-codes with real color codes """ return sub("&(?=[?\\da-fk-or])", u"\u00A7", "%s" % text) def stripcolors(text): """ strips all (real) color codes from text """ return sub(u"\u00A7[\\da-fk-or]", "", "%s" % text) def safetp(player, world, x, y, z, yaw = 0, pitch = 0): """ teleports the player to the given Location if the player would spawn inside blocks, the location is escalated until the location is safe """ tpblock = Location(world, x, y, z).getBlock() if (tpblock.isEmpty() and tpblock.getRelative(bblock.BlockFace.UP).isEmpty()) or y > 255: player.teleport(Location(world, x+0.5, y, z+0.5, yaw, pitch), TeleportCause.COMMAND) else: safetp(player, world, x, y+1, z, yaw, pitch) def plugin_header(recipient = None, name="Redstoner Utils"): """ sends the recipient a "Plugin Header", in the format of: --=[ PluginName ]=-- """ head = "\n&2--=[ %s ]=--" % name msg(recipient, head) return head def noperm(player): msg(player, "&cno permission") def runas(player, cmd): """ run a command as player the cmd should no be prefixed with a / """ server.dispatchCommand(player, cmd) def is_player(obj): """ return True when ob is a bukkit Player """ return (isinstance(obj, Player)) def checkargs(sender, args, amin, amax): """ check if a command has a valid amount of args, otherwise notify the sender amin is the minimum amount of args amax is the maximum amount of args if amax is < 0, infinite args will be accepted return True if args has a valid length, False otherwise """ if not (len(args) >= amin and (amax < 0 or len(args) <= amax)): if amin == amax: msg(sender, "&cNeeds " + str(amin) + " arguments!") return False elif amax < 0: msg(sender, "&cNeeds at least " + str(amin) + " arguments!") return False else: msg(sender, "&cNeeds " + str(amin) + " to " + str(amax) + " arguments!") return False return True def warp(player, args, warpname): if not checkargs(player, args, 0, 1): return False # You can check if it worked runas(player, "warp %s" % warpname) return True def is_creative(player): """ returns True if the player is in Creative mode """ return str(player.getGameMode()) == "CREATIVE" def uid(player): """ returns the player's UUID """ return str(player.getUniqueId()) def retrieve_player(uuid_str): """ gets an offline player by UUID string the uuid MUST contain dashes """ return server.getOfflinePlayer(juuid(uuid_str)) def known_player(player): """ to be used on OfflinePlayer returns True if the player has been on the server this is different to HasPlayedBefore(), which will return False on first join """ return player.getFirstPlayed() != 0 def open_json_file(filename, default): """ opens the given json file and returns an object or returns None on error filename is the path + name of the file. """ data = None try: with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename) as obj: data = json_loads(obj.read()) except Exception, e: error("Failed to read from %s: %s" % (filename, e)) return (default if data is None else data) def save_json_file(filename, obj): """ saves the given object as json into filename filename is the path + name of the file. """ try: with open("plugins/redstoner-utils.py.dir/files/%s.json" % filename, "w") as f: f.write(json_dumps(obj)) except Exception, e: error("Failed to write to %s: %s" % (filename, e)) def toggle(player, ls, add = None, on = "&aToggle now on!", off = "&cToggle now off!", already = "&cToggle was already %s"): """ Toggle presence of a player's UUID in a list (ls) 'add' controls if a player should be added(True) or removed(False) if 'add' is None, ls will simply be toggled for that player. when 'add' is given, but won't change anything, %s in 'already' is replaced with "ON" or "OFF" """ pid = uid(player) enabled = pid in ls # Do some checks and remove pid. if enabled and add == False: ls.remove(pid) msg(player, on) # Do some checks and append pid. elif not enabled and add == True: ls.append(pid) msg(player, off) # Already on/off (optional) else: msg(player, already % (" ON" if add else " OFF"))