Exemple #1
0
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.")
Exemple #2
0
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()
Exemple #4
0
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()
Exemple #6
0
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()
Exemple #9
0
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.')
Exemple #10
0
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
Exemple #11
0
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})
Exemple #12
0
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!')
Exemple #13
0
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})
Exemple #14
0
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})
Exemple #15
0
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.')
Exemple #16
0
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})
Exemple #17
0
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!')
Exemple #18
0
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.")
Exemple #19
0
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()
Exemple #21
0
    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),
            )
Exemple #22
0
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.')
Exemple #23
0
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.')
Exemple #24
0
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})
Exemple #25
0
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)
Exemple #26
0
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}')
Exemple #27
0
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}')