# blockplayer // MuffinTastic // 2016 import json, re, os from pyspades.constants import ERROR_BANNED from commands import admin, add, name, alias def create_path(path): if path: try: os.makedirs(path) except OSError: pass def create_filename_path(path): create_path(os.path.dirname(path)) def open_create(filename, mode): create_filename_path(filename) return open(filename, mode) STORE_BLOCKED = True # will reset each time the server is started if False, and will not STORAGE_LOCATION = "./scripts/blockplayer.txt" def string_segment_in_list(segment, list, numbered, backwards = False): results = [] if backwards: for i, string in enumerate(list): if re.findall(string, segment): if numbered: results.append("[{0}] {1}".format(i, string)) else: results.append("{1}".format(i, string)) else: for i, string in enumerate(list): if re.findall(segment, string): if numbered: results.append("[{0}] {1}".format(i, string)) else: results.append("{1}".format(i, string)) return results def string_segment_in_list_bool(string, list): for segment in list: if re.findall(segment.lower(), string.lower()): return True return False @name("blockplayer") @admin def block_player(connection, action, value = None, extra = None): protocol = connection.protocol irc_relay = protocol.irc_relay def console_or_ingame_print(text): if "console" in connection.user_types: print text elif "irc" in connection.user_types: irc_relay.send(text) else: connection.send_chat(text) if action == "block": results = string_segment_in_list(value, protocol.blocked_players["blocked"], True, True) if len(results) == 0: protocol.blocked_players["blocked"].append(value) else: if extra is None: console_or_ingame_print("{0} blocked: {1}".format(len(results), ", ".join(results))) return "Found {0} blocked names which block '{1}'. Add override to the end of this command to block anyways.".format(len(results), value) elif extra == "override": protocol.blocked_players["blocked"].append(value) protocol.save_blocked() if irc_relay and not "irc" in connection.user_types: irc_relay.send("* {0} blocked name {1}".format(connection.name, value)) return "Blocked name {0}.".format(value) elif action == "except": results = string_segment_in_list(value, protocol.blocked_players["exceptions"], True, True) if len(results) == 0: protocol.blocked_players["exceptions"].append(value) else: if extra is None: console_or_ingame_print("{0} exception[s]: {1}".format(len(results), ", ".join(results))) return "Found {0} excepted players which include '{1}' in their names. Add override to the end of this command to add exception anyways.".format(len(results), value) elif extra == "override": protocol.blocked_players["exceptions"].append(value) protocol.save_blocked() if irc_relay and not "irc" in connection.user_types: irc_relay.send("* {0} excepted name {1}".format(connection.name, value)) return "Excepted name {0}.".format(value) elif action == "unblock": results = string_segment_in_list(value, protocol.blocked_players["blocked"], False) numresults = string_segment_in_list(value, protocol.blocked_players["blocked"], True) removedPlayer = None if len(results) == 0: return 'No excepted players with name including "{0}".'.format(value) elif len(results) == 1: removedPlayer = results[0] protocol.blocked_players["blocked"].remove(results[0]) elif len(results) > 1: if extra is None: console_or_ingame_print("{0} blocked: {1}".format(len(results), ", ".join(numresults))) return "{0} candidates for unblocking. Add the number next to the desired name to the end of this command.".format(len(results)) else: removedPlayer = results[int(extra)] protocol.blocked_players["blocked"].remove(results[int(extra)]) protocol.save_blocked() if irc_relay and not "irc" in connection.user_types: irc_relay.send("* {0} unblocked name {1}".format(connection.name, removedPlayer)) return "Removed name '{0}' from blocked list.".format(removedPlayer) elif action == "unexcept": results = string_segment_in_list(value, protocol.blocked_players["exceptions"], False) numresults = string_segment_in_list(value, protocol.blocked_players["exceptions"], True) removedPlayer = None if len(results) == 0: return 'No excepted players with name including "{0}".'.format(value) elif len(results) == 1: removedPlayer = results[0] protocol.blocked_players["exceptions"].remove(results[0]) elif len(results) > 1: if extra is None: console_or_ingame_print("{0} exception[s]: {1}".format(len(results), ", ".join(numresults))) return "{0} candidates for unexception. Add the number next to the desired name to the end of this command.".format(len(results)) else: removedPlayer = results[int(extra)] protocol.blocked_players["exceptions"].remove(results[int(extra)]) protocol.save_blocked() if irc_relay and not "irc" in connection.user_types: irc_relay.send("* {0} unexcepted name {1}".format(connection.name, removedPlayer)) return "Removed name '{0}' from exception list.".format(removedPlayer) elif action == "search": blockresults = string_segment_in_list(value, protocol.blocked_players["blocked"], True) exceptresults = string_segment_in_list(value, protocol.blocked_players["exceptions"], True) resultnums = [len(blockresults), len(exceptresults)] if resultnums[0] == 0 and resultnums[1] == 0: return "No results for search '{0}'.".format(value) else: if len(blockresults) == 0: blockresults.append("[None]") if len(exceptresults) == 0: exceptresults.append("[None]") console_or_ingame_print("{0} exception[s]: {1}".format(resultnums[1], ", ".join(exceptresults))) console_or_ingame_print("{0} blocked: {1}".format(resultnums[0], ", ".join(blockresults))) return "{0} search result[s]".format(resultnums[0] + resultnums[1]) elif action == "list": blocklisting = protocol.blocked_players["blocked"] exceptlisting = protocol.blocked_players["exceptions"] listingnums = [len(blocklisting), len(exceptlisting)] console_or_ingame_print("{0} exception[s]: {1}".format(listingnums[1], ", ".join(exceptlisting))) console_or_ingame_print("{0} blocked: {1}".format(listingnums[0], ", ".join(blocklisting))) return "{0} listing[s]".format(listingnums[0] + listingnums[1]) elif action == "reload": if STORE_BLOCKED: protocol.blocked_players = json.load(open(STORAGE_LOCATION, 'rb')) return "Reloaded blocked players from file." else: return "Can't reload from file - not storing blocked players!" elif action == "debug": print protocol.blocked_players print action, value, extra print protocol.console, connection add(block_player) def apply_script(protocol, connection, config): class BlockPlayerConnnection(connection): def on_login(self, name): connection.on_login(self, name) if string_segment_in_list_bool(name, self.protocol.blocked_players["blocked"]): if not string_segment_in_list_bool(name, self.protocol.blocked_players["exceptions"]): self.disconnect(ERROR_BANNED) class BlockPlayerProtocol(protocol): blocked_players = None def __init__(self, interface, config): protocol.__init__(self, interface, config) if STORE_BLOCKED: try: self.blocked_players = json.load(open(STORAGE_LOCATION, 'rb')) except IOError: print "Could not load file {0}, creating blank version" self.blocked_players = None if self.blocked_players is None: self.blocked_players = {"exceptions" : [], # [0] name [1] ip "blocked" : []} self.save_blocked() def save_blocked(self): if STORE_BLOCKED: json.dump(self.blocked_players, open_create(STORAGE_LOCATION, 'wb')) return BlockPlayerProtocol, BlockPlayerConnnection