def ooc_cmd_unmute(client, arg): """ Unmute a user. Usage: /unmute <ipid> """ if len(arg) == 0: raise ArgumentError("You must specify a target.") args = list(arg.split(" ")) client.send_ooc(f"Attempting to unmute {len(args)} IPIDs.") for raw_ipid in args: if raw_ipid.isdigit(): ipid = int(raw_ipid) clients = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if clients: msg = f"Unmuted the IPID ${str(ipid)}'s following clients:" for c in clients: c.is_muted = False database.log_misc("unmute", client, target=c) msg += " " + c.showname + " [" + str(c.id) + "]," msg = msg[:-1] msg += "." client.send_ooc(msg) else: client.send_ooc( "No targets found. Use /unmute <ipid> <ipid> ... for unmute." ) else: client.send_ooc(f"{raw_ipid} does not look like a valid IPID.")
def ooc_cmd_unmute(client, arg): """ Unmute a user. Usage: /unmute <ipid> """ if len(arg) == 0: raise ArgumentError('You must specify a target.') args = list(arg.split(' ')) client.send_ooc(f'Attempting to unmute {len(args)} IPIDs.') for raw_ipid in args: if raw_ipid.isdigit(): ipid = int(raw_ipid) clients = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if (clients): msg = f'Unmuted the IPID ${str(ipid)}\'s following clients:' for c in clients: c.is_muted = False database.log_misc('unmute', client, target=c) msg += ' ' + c.char_name + ' [' + str(c.id) + '],' msg = msg[:-1] msg += '.' client.send_ooc(msg) else: client.send_ooc( "No targets found. Use /unmute <ipid> <ipid> ... for unmute." ) else: client.send_ooc(f'{raw_ipid} does not look like a valid IPID.')
def refresh(self): """ Refresh as many parts of the server as possible: - MOTD - Mod credentials (unmodding users if necessary) - Censors - Characters - Music - Backgrounds - Commands - Banlists """ with open("config/config.yaml", "r") as cfg: cfg_yaml = yaml.safe_load(cfg) self.config["motd"] = cfg_yaml["motd"].replace("\\n", " \n") # Reload moderator passwords list and unmod any moderator affected by # credential changes or removals if isinstance(self.config["modpass"], str): self.config["modpass"] = { "default": { "password": self.config["modpass"] } } if isinstance(cfg_yaml["modpass"], str): cfg_yaml["modpass"] = { "default": { "password": cfg_yaml["modpass"] } } for profile in self.config["modpass"]: if (profile not in cfg_yaml["modpass"] or self.config["modpass"][profile] != cfg_yaml["modpass"][profile]): for client in filter( lambda c: c.mod_profile_name == profile, self.client_manager.clients, ): client.is_mod = False client.mod_profile_name = None database.log_misc("unmod.modpass", client) client.send_ooc( "Your moderator credentials have been revoked.") self.config["modpass"] = cfg_yaml["modpass"] self.load_config() self.load_command_aliases() self.load_censors() self.load_iniswaps() self.load_characters() self.load_music() self.load_backgrounds() self.load_ipranges() import server.commands importlib.reload(server.commands) server.commands.reload()
def kickban(client, arg, ban_hdid): args = shlex.split(arg) if len(args) < 2: raise ArgumentError('Not enough arguments.') elif len(args) == 2: reason = None ban_id = None try: ban_id = int(args[1]) unban_date = None except ValueError: reason = args[1] unban_date = arrow.get().shift(hours=6).datetime elif len(args) == 3: ban_id = None reason = args[1] if 'perma' in args[2]: unban_date = None else: duration = pytimeparse.parse(args[2], granularity='hours') if duration is None: raise ArgumentError('Invalid ban duration.') unban_date = arrow.get().shift(seconds=duration).datetime else: raise ArgumentError( f'Ambiguous input: {arg}\nPlease wrap your arguments ' 'in quotes.') try: raw_ipid = args[0] ipid = int(raw_ipid) except ValueError: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') ban_id = database.ban(ipid, reason, ban_type='ipid', banned_by=client, ban_id=ban_id, unban_date=unban_date) if ipid != None: targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: for c in targets: if ban_hdid: database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id) c.send_command('KB', reason) c.disconnect() database.log_misc('ban', client, target=c, data={'reason': reason}) client.send_ooc(f'{len(targets)} clients were kicked.') client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')
def start(self): """Start the server.""" loop = asyncio.get_event_loop_policy().get_event_loop() bound_ip = "0.0.0.0" if self.config["local"]: bound_ip = "127.0.0.1" ao_server_crt = loop.create_server(lambda: AOProtocol(self), bound_ip, self.config["port"]) ao_server = loop.run_until_complete(ao_server_crt) if self.config["use_websockets"]: ao_server_ws = websockets.serve(new_websocket_client(self), bound_ip, self.config["websocket_port"]) asyncio.ensure_future(ao_server_ws) if self.config["use_masterserver"]: self.ms_client = MasterServerClient(self) asyncio.ensure_future(self.ms_client.connect(), loop=loop) if self.config["zalgo_tolerance"]: self.zalgo_tolerance = self.config["zalgo_tolerance"] if "bridgebot" in self.config and self.config["bridgebot"]["enabled"]: try: self.bridgebot = Bridgebot( self, self.config["bridgebot"]["channel"], self.config["bridgebot"]["hub_id"], self.config["bridgebot"]["area_id"], ) asyncio.ensure_future(self.bridgebot.init( self.config["bridgebot"]["token"]), loop=loop) except Exception as ex: # Don't end the whole server if bridgebot destroys itself print(ex) asyncio.ensure_future(self.schedule_unbans()) database.log_misc("start") print("Server started and is listening on port {}".format( self.config["port"])) try: loop.run_forever() except KeyboardInterrupt: print("KEYBOARD INTERRUPT") loop.stop() database.log_misc("stop") ao_server.close() loop.run_until_complete(ao_server.wait_closed()) loop.close()
def kickban(client, arg: str, ban_hdid): args = shlex.split(arg) ban_id = None default_ban_duration = client.server.config['default_ban_duration'] if len(args) < 2: raise ArgumentError('Not enough arguments.') elif len(args) == 2: ipid = _convert_ipid_to_int(args[0]) ban_id = args[1] reason = None ban_duration = parse(str(default_ban_duration), granularity='hours') unban_date = arrow.get().shift(hours=ban_duration).datetime elif len(args) == 3: ipid = _convert_ipid_to_int(args[0]) reason = args[1] duration = args[2] ban_duration = parse(str(duration), granularity='hours') if duration is None: raise ArgumentError('Invalid ban duration.') elif 'perma' in duration.lower(): unban_date = None else: if ban_duration is not None: unban_date = arrow.get().shift(hours=ban_duration).datetime else: raise ArgumentError(f'{duration} is an invalid ban duration') else: raise ArgumentError( f'Ambiguous input: {arg}\nPlease wrap your arguments ' 'in quotes.') ban_id = database.ban(ipid, reason, ban_type='ipid', banned_by=client, ban_id=ban_id, unban_date=unban_date) targets = client.server.client_manager.get_targets(client, TargetType.IPID, ipid, False) if targets: for c in targets: if ban_hdid: database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id) c.send_command('KB', reason) c.disconnect() database.log_misc('ban', client, target=c, data={'reason': reason}) client.send_ooc(f'{len(targets)} clients were kicked.') client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')
def ooc_cmd_kms(client, arg): """ Stands for Kick MySelf - Kick other instances of the client opened by you. Useful if you lose connection and the old client is ghosting. Usage: /kms """ if arg != "": raise ArgumentError("This command takes no arguments!") for target in client.server.client_manager.get_multiclients( client.ipid, client.hdid): if target != client: target.disconnect() client.send_ooc("Kicked other instances of client.") database.log_misc("kms", client)
def refresh(self): """ Refresh as many parts of the server as possible: - MOTD - Mod credentials (unmodding users if necessary) - Characters - Music - Backgrounds - Commands """ with open('config/config.yaml', 'r') as cfg: cfg_yaml = yaml.safe_load(cfg) self.config['motd'] = cfg_yaml['motd'].replace('\\n', ' \n') # Reload moderator passwords list and unmod any moderator affected by # credential changes or removals if isinstance(self.config['modpass'], str): self.config['modpass'] = { 'default': { 'password': self.config['modpass'] } } if isinstance(cfg_yaml['modpass'], str): cfg_yaml['modpass'] = { 'default': { 'password': cfg_yaml['modpass'] } } for profile in self.config['modpass']: if profile not in cfg_yaml['modpass'] or \ self.config['modpass'][profile] != cfg_yaml['modpass'][profile]: for client in filter( lambda c: c.mod_profile_name == profile, self.client_manager.clients): client.is_mod = False client.mod_profile_name = None database.log_misc('unmod.modpass', client) client.send_ooc( 'Your moderator credentials have been revoked.') self.config['modpass'] = cfg_yaml['modpass'] self.load_characters() self.load_iniswaps() self.load_music() self.load_backgrounds() import server.commands importlib.reload(server.commands) server.commands.reload()
def ooc_cmd_kick(client, arg: str) -> None: """ Kick a player. Usage: /kick <ipid|*|**> [reason] Special cases: - "*" kicks everyone in the current area. - "**" kicks everyone in the server. """ w = Webhooks(client.server) if len(arg) == 0: raise ArgumentError( 'You must specify a target. Use /kick <ipid> [reason]') elif arg[0] == '*': targets = [c for c in client.area.clients if c != client] elif arg[0] == '**': targets = [ c for c in client.server.client_manager.clients if c != client ] else: targets = None args = list(arg.split(' ')) if targets is None: raw_ipid = args[0] try: ipid = int(raw_ipid) except: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: reason = ' '.join(args[1:]) if reason == '': reason = 'N/A' for c in targets: if c.is_admin: client.send_ooc(f'{c.charname} is an admin, cannot kick them.') continue database.log_misc('kick', client, target=c, data={'reason': reason}) w.kick(char=c.char_name, ipid=c.ipid, reason=reason) client.send_ooc("{} was kicked.".format(c.char_name)) c.send_command('KK', f'Kicked: "{reason}"') c.disconnect() else: client.send_ooc(f'No targets with the IPID {ipid} were found.')
def ooc_cmd_refresh(client, arg): """ Reload all moderator credentials, server options, and commands without restarting the server. Usage: /refresh """ if len(arg) > 0: raise ClientError('This command does not take in any arguments!') else: try: client.server.refresh() database.log_misc('refresh', client) client.send_ooc('You have reloaded the server.') except ServerError: raise
def ooc_cmd_unban(client, arg): """ Unban a list of users. Usage: /unban <ban_id...> """ if len(arg) == 0: raise ArgumentError( 'You must specify a target. Use /unban <ban_id...>') args = list(arg.split(' ')) client.send_ooc(f'Attempting to lift {len(args)} ban(s)...') for ban_id in args: if database.unban(ban_id): client.send_ooc(f'Removed ban ID {ban_id}.') else: client.send_ooc(f'{ban_id} is not on the ban list.') database.log_misc('unban', client, data={'id': ban_id})
def ooc_cmd_kick(client, arg): """ Kick a player. Usage: /kick <ipid|*|@> [reason] Special cases: - "*" kicks everyone in the current area. - "@" kicks everyone in the server. """ if len(arg) == 0: raise ArgumentError( 'You must specify a target. Use /kick <ipid> [reason]') elif arg[0] == '*': targets = [c for c in client.area.clients if c != client] elif arg[0] == '@': targets = [ c for c in client.server.client_manager.clients if c != client ] else: targets = None args = list(arg.split(' ')) if targets is None: raw_ipid = args[0] try: ipid = int(raw_ipid) except: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: reason = ' '.join(args[1:]) if reason == '': reason = 'N/A' for c in targets: database.log_misc('kick', client, target=c, data={'reason': reason}) client.send_ooc("{} was kicked.".format(c.char_name)) c.send_command('KK', reason) c.disconnect() else: try: client.send_ooc(f'No targets with the IPID {ipid} were found.') except: client.send_ooc('No targets to kick!')
def ooc_cmd_login(client, arg): """ Login as a moderator. Usage: /login <password> """ if len(arg) == 0: raise ArgumentError('You must specify the password.') login_name = None try: login_name = client.auth_mod(arg) except ClientError: database.log_misc('login.invalid', client) raise if client.area.evidence_mod == 'HiddenCM': client.area.broadcast_evidence_list() client.send_ooc('Logged in as a moderator.') database.log_misc('login', client, data={'profile': login_name})
def ooc_cmd_unban(client, arg): """ Unban a list of users. Usage: /unban <ban_id...> """ if len(arg) == 0: raise ArgumentError( "You must specify a target. Use /unban <ban_id...>") args = list(arg.split(" ")) client.send_ooc(f"Attempting to lift {len(args)} ban(s)...") for ban_id in args: if database.unban(ban_id): client.send_ooc(f"Removed ban ID {ban_id}.") client.server.webhooks.unban(ban_id, client) else: client.send_ooc(f"{ban_id} is not on the ban list.") database.log_misc("unban", client, data={"id": ban_id})
def ooc_cmd_mute(client, arg): """ Prevent a user from speaking in-character. Usage: /mute <ipid> Special cases: - "*" mutes everyone in the current area. """ if len(arg) == 0: raise ArgumentError('You must specify a target. Use /mute <ipid>.') elif arg[0] == '*': clients = [c for c in client.area.clients if c.is_mod == False] else: clients = None args = list(arg.split(' ')) if clients is None: client.send_ooc(f'Attempting to mute {len(args)} IPIDs.') for raw_ipid in args: if raw_ipid.isdigit(): ipid = int(raw_ipid) clients = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if (clients): msg = 'Muted the IPID ' + str( ipid) + '\'s following clients:' for c in clients: c.is_muted = True database.log_misc('mute', client, target=c) msg += ' ' + c.char_name + ' [' + str(c.id) + '],' msg = msg[:-1] msg += '.' client.send_ooc(msg) else: client.send_ooc( "No targets found. Use /mute <ipid> <ipid> ... for mute." ) else: client.send_ooc(f'{raw_ipid} does not look like a valid IPID.') elif clients: client.send_ooc('Attempting to mute the area.') for c in clients: c.is_muted = True database.log_misc('mute', client, target=c) client.send_ooc(f'Muted {len(args)} IPIDs.') client.area.broadcast_ooc('Area has been muted.')
def ooc_cmd_unwarn(client, arg: str) -> None: """ Remove a list of warn entries from the database. Usage: /unwarn <warn_id ...> """ w = Webhooks(client.server) if len(arg) == 0: raise ArgumentError( 'You must specify a target. Use /unwarn <warn_id...>') args = list(arg.split(' ')) client.send_ooc(f'Attempting to revoke {len(args)} warn(s)...') for warn_id in args: if database.unwarn(warn_id): client.send_ooc(f'Removed warn entry with ID {warn_id}.') w.unwarn(client=client, warn_id=warn_id) else: client.send_ooc(f'No entry exists for warn ID {warn_id}.') database.log_misc('unwarn', client, data={'id': warn_id})
def ooc_cmd_warn(client, arg): """ Warn a player via an OOC message and popup. Usage: /warn <ipid> [reason] Special cases: - "*" warns everyone in the current area. """ if len(arg) == 0: raise ArgumentError( 'You must specify a target. Use /warn <ipid> [reason]') elif arg[0] == '*': targets = [c for c in client.area.clients if c != client] else: targets = None args = list(arg.split(' ')) if targets is None: raw_ipid = args[0] try: ipid = int(raw_ipid) except: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: reason = ' '.join(args[1:]) if reason == '': reason = 'N/A' for c in targets: database.log_misc('warn', client, target=c, data={'reason': reason}) client.send_ooc("{} was warned.".format(c.char_name)) c.send_ooc("You have received a warning from a moderator.") #Pop up message c.send_command('BB', 'You have been warned by a moderator:\n' + reason) else: try: client.send_ooc(f'No targets with the IPID {ipid} were found.') except: client.send_ooc('No targets to warn!')
def ooc_cmd_kick(client, arg): """ Kick a player. Usage: /kick <ipid|*|**> [reason] Special cases: - "*" kicks everyone in the current area. - "**" kicks everyone in the server. """ if len(arg) == 0: raise ArgumentError( "You must specify a target. Use /kick <ipid> [reason]") elif arg[0] == "*": targets = [c for c in client.area.clients if c != client] elif arg[0] == "**": targets = [ c for c in client.server.client_manager.clients if c != client ] else: targets = None args = list(arg.split(" ")) if targets is None: raw_ipid = args[0] try: ipid = int(raw_ipid) except Exception: raise ClientError(f"{raw_ipid} does not look like a valid IPID.") targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: reason = " ".join(args[1:]) for c in targets: database.log_misc("kick", client, target=c, data={"reason": reason}) client.send_ooc(f"{c.showname} was kicked.") c.send_command("KK", reason) c.disconnect() client.server.webhooks.kick(c.ipid, reason, client, c.char_name) else: client.send_ooc(f"No targets with the IPID {ipid} were found.")
def ooc_cmd_login(client, arg): """ Login as a moderator. Usage: /login <password> """ if len(arg) == 0: raise ArgumentError("You must specify the password.") login_name = None try: login_name = client.auth_mod(arg) except ClientError: database.log_misc("login.invalid", client) raise # Make sure the client's available areas are updated client.area.broadcast_area_list(client) client.area.broadcast_evidence_list() client.send_ooc("Logged in as a moderator.") database.log_misc("login", client, data={"profile": login_name})
def start(self): """Start the server.""" loop = asyncio.get_event_loop() bound_ip = '0.0.0.0' if self.config['local']: bound_ip = '127.0.0.1' ao_server_crt = loop.create_server(lambda: AOProtocol(self), bound_ip, self.config['port']) ao_server = loop.run_until_complete(ao_server_crt) if self.config['use_websockets']: ao_server_ws = websockets.serve(new_websocket_client(self), bound_ip, self.config['websocket_port']) asyncio.ensure_future(ao_server_ws) if self.config['use_masterserver']: self.ms_client = MasterServerClient(self) asyncio.ensure_future(self.ms_client.connect(), loop=loop) if self.config['zalgo_tolerance']: self.zalgo_tolerance = self.config['zalgo_tolerance'] asyncio.ensure_future(self.schedule_unbans()) database.log_misc('start') print('Server started and is listening on port {}'.format( self.config['port'])) try: loop.run_forever() except KeyboardInterrupt: pass database.log_misc('stop') ao_server.close() loop.run_until_complete(ao_server.wait_closed()) loop.close()
def send_webhook( self, username=None, avatar_url=None, message=None, embed=False, title=None, description=None, url=None, ): is_enabled = self.server.config["webhooks_enabled"] if url is None: url = self.server.config["webhook_url"] if not is_enabled: return data = {} data["content"] = message data[ "username"] = username if username is not None else "tsuserver webhook" if embed is True: data["embeds"] = [] embed = {} embed["description"] = description embed["title"] = title data["embeds"].append(embed) result = requests.post(url, data=json.dumps(data), headers={"Content-Type": "application/json"}) try: result.raise_for_status() except requests.exceptions.HTTPError as err: database.log_misc("webhook.err", data=err.response.status_code) else: database.log_misc( "webhook.ok", data="successfully delivered payload, code {}".format( result.status_code), )
def ooc_cmd_ungimp(client, arg): """ Allow the user to send their own messages again. Usage: /ungimp <id> """ if len(arg) == 0: raise ArgumentError('You must specify a target ID.') try: targets = client.server.client_manager.get_targets( client, TargetType.ID, int(arg), False) except: raise ArgumentError('You must specify a target. Use /ungimp <id>.') if targets: for c in targets: database.log_misc('ungimp', client, target=c, data=client.area.abbreviation) c.gimp = False client.send_ooc(f'Ungimped {len(targets)} existing client(s).') else: client.send_ooc('No targets found.')
def ooc_cmd_gimp(client, arg): """ Replace a user's message with a random message from a list. Usage: /gimp <id> """ if len(arg) == 0: raise ArgumentError('You must specify a target ID.') try: targets = client.server.client_manager.get_targets( client, TargetType.ID, int(arg), False) except: raise ArgumentError('You must specify a target. Use /gimp <id>.') if targets: for c in targets: database.log_misc('gimp', client, target=c, data=client.area.abbreviation) c.gimp = True client.send_ooc(f'Gimped {len(targets)} existing client(s).') else: client.send_ooc('No targets found.')
def ooc_cmd_login(client, arg: str) -> None: """ Logs the user in as a moderator. Calls auth_mod to check whether or not the user's login attempt is valid. Should return a message in-client confirming login and log profile in the server's internal log. Will throw an error and log it if not and send an OOC message in-client stating that the user's login attempt was invalid. Usage: /login <password> (The user might not require using a mod pass if their profile already exists in the moderation.yaml) Parameters: client = An instance of the class Client. arg = The mod pass used in order to log in. Precondition: arg is a valid mod pass. Otherwise, throws login_invalid error. """ w = Webhooks(client.server) login_name = None try: login_name = client.auth_mod(arg) except ClientError: client.send_command('AUTH', '0') database.log_misc('login.invalid', client) raise client.send_ooc('Logged in as a moderator.') client.send_command('AUTH', '1') w.login(client=client) database.log_misc('login', client, data={'profile': login_name})
def kickban(client, arg, ban_hdid): args = shlex.split(arg) if len(args) < 2: raise ArgumentError("Not enough arguments.") elif len(args) == 2: reason = None ban_id = None try: ban_id = int(args[1]) unban_date = None except ValueError: reason = args[1] unban_date = arrow.get().shift(hours=6).datetime elif len(args) == 3: ban_id = None reason = args[1] if "perma" in args[2]: unban_date = None else: duration = pytimeparse.parse(args[2], granularity="hours") if duration is None: raise ArgumentError("Invalid ban duration.") unban_date = arrow.get().shift(seconds=duration).datetime else: raise ArgumentError( f"Ambiguous input: {arg}\nPlease wrap your arguments " "in quotes.") try: raw_ipid = args[0] ipid = int(raw_ipid) except ValueError: raise ClientError(f"{raw_ipid} does not look like a valid IPID.") ban_id = database.ban( ipid, reason, ban_type="ipid", banned_by=client, ban_id=ban_id, unban_date=unban_date, ) char = None hdid = None if ipid is not None: targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: for c in targets: if ban_hdid: database.ban(c.hdid, reason, ban_type="hdid", ban_id=ban_id) hdid = c.hdid c.send_command("KB", reason) c.disconnect() char = c.char_name database.log_misc("ban", client, target=c, data={"reason": reason}) client.send_ooc(f"{len(targets)} clients were kicked.") client.send_ooc(f"{ipid} was banned. Ban ID: {ban_id}") client.server.webhooks.ban(ipid, ban_id, reason, client, hdid, char, unban_date)
def kickban(client, arg, ban_hdid): args = shlex.split(arg) w = Webhooks(client.server) if len(args) < 2: raise ArgumentError('Not enough arguments.') elif len(args) == 2: reason = None ban_id = None try: ban_id = int(args[1]) unban_date = None except ValueError: reason = args[1] unban_date = arrow.get().shift(hours=6).datetime elif len(args) == 3: ban_id = None reason = args[1] if 'perma' in args[2]: unban_date = None else: duration = pytimeparse.parse(args[2], granularity='hours') if duration is None: raise ArgumentError('Invalid ban duration.') unban_date = arrow.get().shift(seconds=duration).datetime else: raise ArgumentError( f'Ambiguous input: {arg}\nPlease wrap your arguments ' 'in quotes.') try: raw_ipid = args[0] ipid = int(raw_ipid) except ValueError: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') modfile = 'config/moderation.yaml' new = not os.path.exists(modfile) if not new: with open(modfile, 'r') as chars: mods = yaml.safe_load(chars) for item in mods: ipids = [] try: ipids = item['ipid'].split() except: ipids.append(item['ipid']) if ipid in ipids: if item['status'] == 'admin': return client.send_ooc('Can\'t ban an admin.') ban_id = database.ban(ipid, reason, ban_type='ipid', banned_by=client, ban_id=ban_id, unban_date=unban_date) if ipid != None: targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: for c in targets: if ban_hdid: database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id) w.ban(char=c.char_name, ipid=c.ipid, ban_id=ban_id, reason=reason, hdid=c.hdid) else: w.ban(char=c.char_name, ipid=c.ipid, ban_id=ban_id, reason=reason) c.send_command('KB', f'Banned: "{reason}"') c.disconnect() database.log_misc('ban', client, target=c, data={'reason': reason}) client.send_ooc(f'{len(targets)} clients were kicked.') client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')
def kickban(client, arg: str, ban_hdid): args = shlex.split(arg) ban_id = None default_ban_duration = client.server.config['default_ban_duration'] if len(args) < 2: raise ArgumentError('Not enough arguments.') elif len(args) == 2: ipid = _convert_ipid_to_int(args[0]) try: ban_id = int(args[1]) reason = None except ValueError: ban_id = None reason = args[1] ban_duration = parse(str(default_ban_duration)) unban_date = arrow.get().shift(seconds=ban_duration).datetime elif len(args) == 3: ipid = _convert_ipid_to_int(args[0]) reason = args[1] duration = args[2] ban_duration = parse(str(duration)) if duration is None: raise ArgumentError('Invalid ban duration.') elif 'perma' in duration.lower(): unban_date = None else: if ban_duration is not None: unban_date = arrow.get().shift(seconds=ban_duration).datetime else: raise ArgumentError(f'{duration} is an invalid ban duration') else: raise ArgumentError(f'Ambiguous input: {arg}\nPlease wrap your arguments ' 'in quotes.') try: raw_ipid = args[0] ipid = int(raw_ipid) except ValueError: raise ClientError(f'{raw_ipid} does not look like a valid IPID.') if ban_id != None: existing_ban = database.find_ban(None, None, ban_id) if existing_ban: if bool(existing_ban.unbanned) == True: raise ClientError(f'{ban_id} is already unbanned.') ban_id = database.ban(ipid, reason, ban_type='ipid', banned_by=client, ban_id=ban_id, unban_date=unban_date) targets = client.server.client_manager.get_targets( client, TargetType.IPID, ipid, False) if targets: for c in targets: if ban_hdid: database.ban(c.hdid, reason, ban_type='hdid', ban_id=ban_id) c.send_command('KB', reason) c.disconnect() database.log_misc('ban', client, target=c, data={'reason': reason}) client.send_ooc(f'{len(targets)} clients were kicked.') client.send_ooc(f'{ipid} was banned. Ban ID: {ban_id}')