コード例 #1
0
 def add_poll(self, value):
     test = time.strftime('%y-%m-%d %H%M-%S')
     if not ([item for item in self.poll_list if item[0] == value]):
         if len(self.poll_list) < self.server.config['poll_slots']:
             self.poll_list.append([value, test])
             tmp = time.strftime('%y-%m-%d %H:%M:%S')
             newfile = {
                 'name': value,
                 'polldetail': None,
                 'multivote': False,
                 'choices': ["Yes", "No"],
                 'votes': {"yes": 0, "no": 0},
                 'created': tmp,
                 'log': [],
             }
             with open('storage/poll/{} \'{}\'.yaml'.format(test, value), 'w') as file:
                 yaml.dump(newfile, file, default_flow_style=False)
                 logger.log_serverpoll('Poll \'{}\' added successfully.'.format(value))
         else:
             logger.log_serverpoll('Failed to add poll. Reason: The poll queue is full.')
             raise ServerError('The Poll Queue is full!')
     else:
         logger.log_serverpoll('Failed to add poll. Reason: This poll already exists.')
         raise ServerError('This poll already exists.')
     self.write_poll_list()
コード例 #2
0
    def load_config(self):
        with Constants.fopen('config/config.yaml', 'r',
                             encoding='utf-8') as cfg:
            self.config = Constants.yaml_load(cfg)
            self.config['motd'] = self.config['motd'].replace('\\n', ' \n')

        for i in range(1, 8):
            daily_gmpass = '******'.format(i)
            if daily_gmpass not in self.config or not self.config[daily_gmpass]:
                self.config[daily_gmpass] = None

        # Default values to fill in config.yaml if not present
        defaults_for_tags = {
            'discord_link': None,
            'max_numdice': 20,
            'max_numfaces': 11037,
            'max_modifier_length': 12,
            'max_acceptable_term': 22074,
            'def_numdice': 1,
            'def_numfaces': 6,
            'def_modifier': '',
            'blackout_background': 'Blackout_HD',
            'default_area_description': 'No description.',
            'party_lights_timeout': 10,
            'showname_max_length': 30,
            'sneak_handicap': 5,
            'spectator_name': 'SPECTATOR',
            'music_change_floodguard': {
                'times_per_interval': 1,
                'interval_length': 0,
                'mute_length': 0
            }
        }

        for (tag, value) in defaults_for_tags.items():
            if tag not in self.config:
                self.config[tag] = value

        # Check that all passwords were generated and that they are unique
        passwords = [
            'guardpass', 'modpass', 'cmpass', 'gmpass', 'gmpass1', 'gmpass2',
            'gmpass3', 'gmpass4', 'gmpass5', 'gmpass6', 'gmpass7'
        ]
        for password_type in passwords:
            if password_type not in self.config:
                info = (
                    'Password "{}" not defined in server/config.yaml. Please make sure it is '
                    'set and try again.'.format(password_type))
                raise ServerError(info)

        for (i, password1) in enumerate(passwords):
            for (j, password2) in enumerate(passwords):
                if i != j and self.config[password1] == self.config[
                        password2] != None:
                    info = (
                        'Passwords "{}" and "{}" in server/config.yaml match. '
                        'Please change them so they are different and try again.'
                        .format(password1, password2))
                    raise ServerError(info)
コード例 #3
0
 def fopen(file, *args, **kwargs):
     try:
         f = open(file, *args, **kwargs)
         return f
     except FileNotFoundError:
         info = 'File not found: {}'.format(file)
         raise ServerError(info, code="FileNotFound")
     except OSError as ex:
         raise ServerError(str(ex))
コード例 #4
0
    async def as_afk_kick(self, client, args):
        afk_delay, afk_sendto = args
        try:
            delay = int(afk_delay)*60 # afk_delay is in minutes, so convert to seconds
        except (TypeError, ValueError):
            info = ('The area file contains an invalid AFK kick delay for area {}: {}'.
                    format(client.area.id, afk_delay))
            raise ServerError(info)

        if delay <= 0: # Assumes 0-minute delay means that AFK kicking is disabled
            return

        try:
            await asyncio.sleep(delay)
        except asyncio.CancelledError:
            raise
        else:
            try:
                area = client.server.area_manager.get_area_by_id(int(afk_sendto))
            except Exception:
                info = ('The area file contains an invalid AFK kick destination area for area {}: '
                        '{}'.format(client.area.id, afk_sendto))
                raise ServerError(info)
            if client.area.id == afk_sendto: # Don't try and kick back to same area
                return
            if client.char_id < 0: # Assumes spectators are exempted from AFK kicks
                return
            if client.is_staff(): # Assumes staff are exempted from AFK kicks
                return

            try:
                original_area = client.area
                original_name = client.displayname
                client.change_area(area, override_passages=True, override_effects=True,
                                   ignore_bleeding=True)
            except Exception:
                pass # Server raised an error trying to perform the AFK kick, ignore AFK kick
            else:
                client.send_ooc('You were kicked from area {} to area {} for being inactive for '
                                '{} minutes.'.format(original_area.id, afk_sendto, afk_delay))

                if client.area.is_locked or client.area.is_modlocked:
                    try: # Try and remove the IPID from the area's invite list
                        client.area.invite_list.pop(client.ipid)
                    except KeyError:
                        pass # Would only happen if they joined the locked area through mod powers

                if client.party:
                    p = client.party
                    client.party.remove_member(client)
                    client.send_ooc('You were also kicked off from your party.')
                    for c in p.get_members():
                        c.send_ooc('{} was AFK kicked from your party.'.format(original_name))
コード例 #5
0
ファイル: ban_manager.py プロジェクト: Link990/TsuserverDR
 def remove_ban(self, ip):
     try:
         try:
             int(ip)
         except ValueError:
             ipaddress.ip_address(ip)
             ip = self.server.get_ipid(ip)
     except ValueError:
         raise ServerError('Argument must be an IP address or IPID.')
     if ip in self.bans:
         self.bans.remove(ip)
     else:
         raise ServerError('User is already not banned.')
     self.write_banlist()
コード例 #6
0
    async def as_afk_kick(self, client, args):
        afk_delay, afk_sendto = args
        try:
            delay = int(
                afk_delay
            ) * 60  # afk_delay is in minutes, so convert to seconds
        except (TypeError, ValueError):
            raise ServerError(
                'The area file contains an invalid AFK kick delay for area {}: {}'
                .format(client.area.id, afk_delay))

        if delay <= 0:  # Assumes 0-minute delay means that AFK kicking is disabled
            return

        try:
            await asyncio.sleep(delay)
        except asyncio.CancelledError:
            raise
        else:
            try:
                area = client.server.area_manager.get_area_by_id(
                    int(afk_sendto))
            except:
                raise ServerError(
                    'The area file contains an invalid AFK kick destination area for area {}: {}'
                    .format(client.area.id, afk_sendto))

            if client.area.id == afk_sendto:  # Don't try and kick back to same area
                return
            if client.char_id < 0:  # Assumes spectators are exempted from AFK kicks
                return
            if client.is_staff():  # Assumes staff are exempted from AFK kicks
                return

            try:
                original_area = client.area
                client.change_area(area,
                                   override_passages=True,
                                   override_effects=True,
                                   ignore_bleeding=True)
            except:
                pass  # Server raised an error trying to perform the AFK kick, ignore AFK kick
            else:
                client.send_host_message(
                    "You were kicked from area {} to area {} for being inactive for {} minutes."
                    .format(original_area.id, afk_sendto, afk_delay))

                if client.area.is_locked or client.area.is_modlocked:
                    client.area.invite_list.pop(client.ipid)
コード例 #7
0
 def remove_ban(self, ip):
     try:
         try:
             int(ip)
         except ValueError:
             ipaddress.ip_address(ip)
             ip = self.server.get_ipid(ip)
     except ValueError:
         raise ServerError(
             'Argument must be an IP address or 10-digit number.')
     if ip in self.bans:
         self.bans.remove(ip)
     else:
         raise ServerError('This IPID is not banned.')
     self.write_banlist()
コード例 #8
0
 def get_votelist(self, value):
     try:
         if [i for i in self.poll_list if i[0] == "{}".format(value)]:
             poll_selected = [i[1] for i in self.poll_list if i[0] == "{}".format(value)]
             output = ('{} \'{}\''.format("".join(poll_selected), value))
             stream = open('storage/poll/{}.yaml'.format(output), 'r')
             stream2 = yaml.load(stream)
             log = stream2['log']
             return log
         else:
             return None
     except FileNotFoundError:
         raise ServerError('The specified poll has no file associated with it.')
     except IndexError:
         raise ServerError('The poll list is currently empty.')
コード例 #9
0
 def add_ban(self, ip):
     try:
         try:
             int(ip)
         except ValueError:
             ipaddress.ip_address(ip)
             ip = self.server.get_ipid(ip)
     except ValueError:
         raise ServerError(
             'Argument must be an IP address or 10-digit number.')
     if ip not in self.bans:
         self.bans.append(ip)
     else:
         raise ServerError('User is already banned.')
     self.write_banlist()
コード例 #10
0
def ooc_cmd_playrandom(client, arg):
	"""
	Plays a random track.
	Usage: /playrandom
	"""
	if len(arg) > 0:
		raise ArgumentError('This command takes no arguments.')
	index = 0
	for item in client.server.music_list:
		for song in item['songs']:
			index += 1
	if index == 0:
		raise ServerError(
				'No music found.')
	else:
		music_set = set(range(index))
		trackid = random.choice(tuple(music_set))
		index = 1
		for item in client.server.music_list:
			for song in item['songs']:
				if index == trackid:
					client.area.play_music(song['name'], client.char_id, song['length'])
					client.area.add_music_playing(client, song['name'])
					database.log_room('play', client, client.area, message=song['name'])
					return
				else:
					index += 1
コード例 #11
0
 def add_poll_choice(self, client, value, add):
     try:
         if [i for i in self.poll_list if i[0] == "{}".format(value)]:
             poll_selected = [
                 i[1] for i in self.poll_list if i[0] == "{}".format(value)
             ]
             output = ('{} \'{}\''.format("".join(poll_selected), value))
             stream = open('storage/poll/{}.yaml'.format(output), 'r')
             stream2 = yaml.load(stream)
             if add.lower() in [x.lower() for x in stream2['choices']]:
                 client.send_host_message('Item already a choice.')
                 return
             stream2['choices'].append(str(add))
             stream2['votes'][add.lower()] = 0
             with open('storage/poll/{}.yaml'.format(output),
                       'w') as votelist_file:
                 yaml.dump(stream2, votelist_file, default_flow_style=False)
             return stream2['choices']
         else:
             return None
     except FileNotFoundError:
         raise ServerError(
             'The specified poll has no file associated with it.')
     except IndexError:
         return
コード例 #12
0
 def remove_poll_choice(self, client, value, remove):
     try:
         if [i for i in self.poll_list if i[0] == "{}".format(value)]:
             poll_selected = [
                 i[1] for i in self.poll_list if i[0] == "{}".format(value)
             ]
             output = ('{} \'{}\''.format("".join(poll_selected), value))
             stream = open('storage/poll/{}.yaml'.format(output), 'r')
             stream2 = yaml.load(stream)
             choices = stream2['choices']
             if not remove in choices:
                 client.send_host_message('Item is not a choice.')
                 return
             stream2['choices'] = [x for x in choices if not x == remove]
             stream2['votes'].pop(remove.lower())
             with open('storage/poll/{}.yaml'.format(output),
                       'w') as votelist_file:
                 yaml.dump(stream2, votelist_file, default_flow_style=False)
             return stream2['choices']
         else:
             return None
     except FileNotFoundError:
         raise ServerError(
             'The specified poll has no file associated with it.')
     except IndexError:
         return
コード例 #13
0
 def get_char_id_by_name(self, name):
     if name == self.config['spectator_name']:
         return -1
     for i, ch in enumerate(self.char_list):
         if ch.lower() == name.lower():
             return i
     raise ServerError('Character not found.')
コード例 #14
0
    def get_song_data(self, music, area):
        """
		Get information about a track, if exists.
		:param music: track name
		:returns: tuple (name, length or -1)
		:raises: ServerError if track not found
		"""
        for item in self.music_list:
            if item['category'] == music:
                return '~stop.mp3', 0, -1, False
            for song in item['songs']:
                if song['name'] == music:
                    try:
                        return song['name'], song['length'], song['mod']
                    except KeyError:
                        try:
                            return song['name'], song['length'], -1, False
                        except KeyError:
                            return song['name'], 0, -1, False
        if len(area.cmusic_list) != 0:
            for item in area.cmusic_list:
                if item['category'] == music:
                    return '~stop.mp3', 0, -1, True
                if len(item['songs']) != 0:
                    for song in item['songs']:
                        if song['name'] == music:
                            try:
                                return song['name'], song['length'], song[
                                    'mod'], True
                            except KeyError:
                                return song['name'], song['length'], -1, True
        raise ServerError('Music not found.')
コード例 #15
0
 def add_ban(self, ipid, reason):
     ipid = str(ipid)
     if not self.is_banned(ipid):
         self.bans[ipid] = {'Reason': reason}
     else:
         raise ServerError('This IPID is already banned.')
     self.write_banlist()
コード例 #16
0
 def remove_ban(self, ipid):
     ipid = str(ipid)
     if self.is_banned(ipid):
         del self.bans[ipid]
     else:
         raise ServerError('This IPID is not banned.')
     self.write_banlist()
コード例 #17
0
ファイル: ban_manager.py プロジェクト: Iamgoofball/tsuserver3
 def add_ban(self, ip):
     try:
         x = len(ip)
     except AttributeError:
         raise ServerError('Argument must be an 12-digit number.')
     if x == 12:
         self.bans[ip] = True
         self.write_banlist()
コード例 #18
0
def rolla_reload(area):
    try:
        import yaml
        with open('config/dice.yaml', 'r') as dice:
            area.ability_dice = yaml.safe_load(dice)
    except:
        raise ServerError(
            'There was an error parsing the ability dice configuration. Check your syntax.'
        )
コード例 #19
0
ファイル: tsuserver.py プロジェクト: Qubrick/tsuserver3
 def get_song_data(self, music):
     for item in self.music_list:
         if item['category'] == music:
             return item['category'], -1
         for song in item['songs']:
             if song['name'] == music:
                 try:
                     return song['name'], song['length']
                 except KeyError:
                     return song['name'], -1
     raise ServerError('Music not found.')
コード例 #20
0
 def remove_poll(self, value):
     if ([i for i in self.poll_list if i[0] == "{}".format(value)]):
         self.poll_list = [i for i in self.poll_list if i[0] != "{}".format(value)]
         logger.log_serverpoll('Poll \'{}\' removed.'.format(value))
     elif value == "all":
         self.poll_list = []
         logger.log_serverpoll('All polls removed.')
     else:
         logger.log_serverpoll('Poll removal failed. Reason: The specified poll does not exist.')
         raise ServerError('The specified poll does not exist.')
     self.write_poll_list()
コード例 #21
0
    def get_char_id_by_name(self, name):
        """
        Get a character ID by the name of the character.
        :param name: name of character
        :returns: Character ID

        """
        for i, ch in enumerate(self.char_list):
            if ch.lower() == name.lower():
                return i
        raise ServerError('Character not found.')
コード例 #22
0
ファイル: ban_manager.py プロジェクト: Iamgoofball/tsuserver3
 def remove_ban(self, client, ip):
     try:
         try:
             int(ip)
         except ValueError:
             ipaddress.ip_address(ip)
             ip = client.server.get_ipid(ip)
     except ValueError:
         if not len(ip) == 12:
             raise ServerError(
                 'Argument must be an IP address or 10-digit number.')
     del self.bans[ip]
     self.write_banlist()
コード例 #23
0
def ooc_cmd_judgelog(client, arg):
    if not client.is_mod:
        raise ClientError('You must be authorized to do that.')
    if len(arg) != 0:
        raise ArgumentError('This command does not take any arguments.')
    jlog = client.area.judgelog
    if len(jlog) > 0:
        jlog_msg = '== Judge Log =='
        for x in jlog:
            jlog_msg += '\r\n{}'.format(x)
        client.send_host_message(jlog_msg)
    else:
        raise ServerError(
            'There have been no judge actions in this area since start of session.'
        )
コード例 #24
0
    def load_music(self,
                   music_list_file='config/music.yaml',
                   server_music_list=True):
        try:
            with open(music_list_file, 'r', encoding='utf-8') as music:
                music_list = yaml.safe_load(music)
        except FileNotFoundError:
            raise ServerError(
                'Could not find music list file {}'.format(music_list_file))

        if server_music_list:
            self.music_list = music_list
            self.build_music_pages_ao1()
            self.build_music_list_ao2(music_list=music_list)

        return music_list
コード例 #25
0
def ooc_cmd_cleartesti(client, arg):
    """
    Clears the testimony list, deleting all statements.
    Very handy, since otherwise you'd have to rewrite the testimony with
    a 1-statement new one and remove that statement manually.
    For mods and CM use only to prevent abuse.
    Usage: /cleartesti
    """
    if len(arg) != 0:
        raise ArgumentError('This command does not take any arguments.')
    testi = list(client.area.testimony.statements)
    if len(testi) <= 1:
        raise ServerError('There is no testimony in this area.')
    else:
        client.area.testimony.statements = []
        client.area.testimony.title = ''
        client.send_ooc('You have cleared the testimony.')
コード例 #26
0
def ooc_cmd_judgelog(client, arg):
    """
    List the last 10 uses of judge controls in the current area.
    Usage: /judgelog
    """
    if len(arg) != 0:
        raise ArgumentError('This command does not take any arguments.')
    jlog = client.area.judgelog
    if len(jlog) > 0:
        jlog_msg = '== Judge Log =='
        for x in jlog:
            jlog_msg += f'\r\n{x}'
        client.send_ooc(jlog_msg)
    else:
        raise ServerError(
            'There have been no judge actions in this area since start of session.'
        )
コード例 #27
0
 def get_song_data(self, music):
     """
     Get information about a track, if exists.
     :param music: track name
     :returns: tuple (name, length or -1)
     :raises: ServerError if track not found
     """
     for item in self.music_list:
         if item['category'] == music:
             return item['category'], -1
         for song in item['songs']:
             if song['name'] == music:
                 try:
                     return song['name'], song['length']
                 except KeyError:
                     return song['name'], -1
     raise ServerError('Music not found.')
コード例 #28
0
 def make_multipoll(self, value):
     try:
         if [i for i in self.poll_list if i[0] == "{}".format(value)]:
             poll_selected = [i[1] for i in self.poll_list if i[0] == "{}".format(value)]
             output = ('{} \'{}\''.format("".join(poll_selected), value))
             stream = open('storage/poll/{}.yaml'.format(output), 'r')
             stream2 = yaml.load(stream)
             stream2['multivote'] = not stream2['multivote']
             with open('storage/poll/{}.yaml'.format(output), 'w') as votelist_file:
                 yaml.dump(stream2, votelist_file, default_flow_style=False)
             return stream2['choices']
         else:
             return None
     except FileNotFoundError:
         raise ServerError('The specified poll has no file associated with it.')
     except IndexError:
         return
コード例 #29
0
    def get_song_data(self, music, c=None):
        # The client's personal music list should also be a valid place to search
        # so search in there too if possible
        if c and c.music_list:
            valid_music = self.music_list + c.music_list
        else:
            valid_music = self.music_list

        for item in valid_music:
            if item['category'] == music:
                return item['category'], -1
            for song in item['songs']:
                if song['name'] == music:
                    try:
                        return song['name'], song['length']
                    except KeyError:
                        return song['name'], -1
        raise ServerError('Music not found.')
コード例 #30
0
def ooc_cmd_testimony(client, arg):
    """
    List the current testimony in this area.
    Usage: /testimony
    """
    if len(arg) != 0:
        raise ArgumentError('This command does not take any arguments.')
    testi = list(client.area.testimony.statements)
    if len(testi) <= 1:
        raise ServerError('There is no testimony in this area.')
    else:
        testi.pop(0)
        testi_msg = 'Testimony: ' + client.area.testimony.title
        i = 1
        for x in testi:
            testi_msg += f'\r\n{i}: '
            testi_msg += x[4]
            i = i + 1
        client.send_ooc(testi_msg)