def ooc_cmd_bidisconnect(client, arg: str) -> None: """ Removes two-way connection between areas. """ args = arg.split() if client not in client.area.owners and not client.is_mod: raise ClientError('You must be a CM.') if not client.area.sub: raise ClientError('Must be in a hub subarea.') if len(args) == 0: raise ArgumentError( 'You must specify an area, use /disconnect <abbreviation>') if len(client.area.connections) < 3: for area in client.area.connections: if area != area.hub and area != client.server.area_manager.default_area( ) and area.abbreviation in args: client.area.connections.remove(area) if client.area in area.connections: area.connections.remove(client.area) client.send_ooc('Area disconnected!')
def ooc_cmd_unsneak(client, arg): """ Stop sneaking a.k.a. show your area moving messages in the OOC. Usage: /sneak """ if arg != "": raise ArgumentError("This command takes no arguments!") if not client.sneaking: raise ClientError( "You are not sneaking! Use /sneak to start sneaking.") client.sneak(False)
def ooc_cmd_hubstatus(client, arg: str) -> None: """ Changes a hub and all it's subareas to specified status. Usage: /hubstatus <idle|rp|casing|looking-for-players|lfp|recess|gaming> """ if 'CM' not in client.area.evidence_mod: raise ClientError('You can\'t change the status of this area') if client.area.is_hub and not client in client.area.owners: raise ClientError('Must be CM.') else: try: client.area.hub_status(arg) client.area.broadcast_ooc('{} changed status to {}.'.format( client.char_name, client.area.status)) for sub in client.area.subareas: sub.broadcast_ooc('{} changed status to {}.'.format( client.char_name, client.area.status)) database.log_room('hubstatus', client, client.area, message=arg) except AreaError: raise
def ooc_cmd_g(client, arg): """ Broadcast a server-wide message. Usage: /g <message> """ if client.muted_global: raise ClientError("Global chat toggled off.") if len(arg) == 0: raise ArgumentError("You can't send an empty message.") client.server.broadcast_global(client, arg, client.is_mod) database.log_area("chat.global", client, client.area, message=arg)
def ooc_cmd_need(client, arg): """ Broadcast a server-wide advertisement for your role-play or case. Usage: /need <message> """ if client.muted_adverts: raise ClientError("You have advertisements muted.") if len(arg) == 0: raise ArgumentError("You must specify what you need.") client.server.broadcast_need(client, arg) database.log_area("chat.announce.need", client, client.area, message=arg)
def ooc_cmd_clearconnect(client, arg: str) -> None: """ Removes all connections to other areas. One-way. """ if len(arg) > 0: raise ArgumentError('This command takes no arguments.') if client not in client.area.owners and not client.is_mod: raise ClientError('You must be a CM.') client.area.connections.clear() client.area.is_restricted = False client.area.broadcast_ooc(f'All {client.area.name} connections cleared.')
def change_position(self, pos=''): """ Change the character's current position in the area. :param pos: position in area (Default value = '') """ positions = ('def', 'pro', 'hld', 'hlp', 'jud', 'wit', 'jur', 'sea') if pos not in positions and pos != '': raise ClientError( f'Invalid position. Possible values: {", ".join(positions)}' ) self.pos = pos
def ooc_cmd_narrator(client, arg): if len(arg) > 0: raise ArgumentError('This command takes no arguments.') if client not in client.area.owners and not client.is_mod: raise ClientError('You must be a CM.') if client.narrator: client.narrator = False client.send_ooc('You are no longer speaking as Narrator.') else: client.narrator = True client.send_ooc('You are now speaking as Narrator.')
def ooc_cmd_unlisten_pos(client, arg): """ Undo the effects of /listen_pos command so you stop listening to the position(s). Usage: /unlisten_pos """ if client.listen_pos is None: raise ClientError("You are not listening to any pos at the moment!") client.listen_pos = None client.send_ooc( "You re no longer listening to any pos (All IC messages will appear as normal)." )
def ooc_cmd_invite(client, arg): """ Allow a particular user to join a locked or spectator-only area. Usage: /invite <id> """ if not arg: raise ClientError('You must specify a target. Use /invite <id>') elif client.area.is_locked == client.area.Locked.FREE: raise ClientError('Area isn\'t locked.') try: c = client.server.client_manager.get_targets(client, TargetType.ID, int(arg), False)[0] client.area.invite_list[c.id] = None client.send_ooc('{} is invited to your area.'.format( c.char_name)) c.send_ooc( f'You were invited and given access to {client.area.name}.') database.log_room('invite', client, client.area, target=c) except: raise ClientError('You must specify a target. Use /invite <id>')
def ooc_cmd_gm(client, arg): """ Broadcast a message to all areas, speaking officially. Usage: /gm <message> """ if client.muted_global: raise ClientError('You have the global chat muted.') if len(arg) == 0: raise ArgumentError("Can't send an empty message.") client.server.broadcast_global(client, arg, True) database.log_room('chat.global-mod', client, client.area, message=arg)
def ooc_cmd_g(client, arg): """ Broadcast a message to all areas. Usage: /g <message> """ if client.muted_global: raise ClientError('Global chat toggled off.') if len(arg) == 0: raise ArgumentError("You can't send an empty message.") client.server.broadcast_global(client, arg) database.log_room('chat.global', client, client.area, message=arg)
def ooc_cmd_lm(client, arg): if not client.is_mod: raise ClientError('You must be authorized to do that.') if len(arg) == 0: raise ArgumentError("Can't send an empty message.") client.area.send_command( 'CT', '{}[MOD][{}]'.format(client.server.config['hostname'], client.get_char_name()), arg) logger.log_server( '[{}][{}][LOCAL-MOD]{}.'.format(client.area.id, client.get_char_name(), arg), client)
def ooc_cmd_allowmusic(client, arg): if client not in client.area.owners and not client.is_mod: raise ClientError('You are not a CM!') if client.area.allowmusic: client.area.allowmusic = False client.area.broadcast_ooc( 'Music changes have been disallowed in this area!') else: client.area.allowmusic = True client.area.broadcast_ooc( 'Music changes have been allowed in this area.')
def ooc_cmd_play(client, arg): if not client.is_mod and not client.is_gm and not client.is_cm: raise ClientError('You must be authorized to do that.') if len(arg) == 0: raise ArgumentError('You must specify a song.') client.area.play_music(arg, client.char_id, -1) client.area.add_music_playing(client, arg) logger.log_server( '[{}][{}]Changed music to {}.'.format(client.area.id, client.get_char_name(), arg), client)
def ooc_cmd_need(client, arg): """ Broadcast a need for a specific role in a case. Usage: /need <message> """ if client.muted_adverts: raise ClientError('You have advertisements muted.') if len(arg) == 0: raise ArgumentError("You must specify what you need.") client.server.broadcast_need(client, arg) database.log_room('chat.announce.need', client, client.area, message=arg)
def ooc_cmd_sneak(client, arg): """ Begin sneaking a.k.a. hide your area moving messages from the OOC. Usage: /sneak """ if arg != "": raise ArgumentError("This command takes no arguments!") if client.sneaking: raise ClientError( "You are already sneaking! Use /unsneak to stop sneaking.") client.sneak(True)
def ooc_cmd_area_kick(client, arg): """ Remove a user from the current area and move them to another area. Usage: /area_kick <id> [destination] """ if client.area.is_locked == client.area.Locked.FREE: raise ClientError('Area isn\'t locked.') if not arg: raise ClientError( 'You must specify a target. Use /area_kick <id> [destination #]') arg = arg.split(' ') targets = client.server.client_manager.get_targets(client, TargetType.ID, int(arg[0]), False) if targets: try: for c in targets: if len(arg) == 1: area = client.server.area_manager.get_area_by_id(int(0)) output = 0 else: try: area = client.server.area_manager.get_area_by_id( int(arg[1])) output = arg[1] except AreaError: raise client.send_ooc( "Attempting to kick {} to area {}.".format( c.char_name, output)) c.change_area(area) c.send_ooc( f"You were kicked from the area to area {output}.") database.log_room('area_kick', client, client.area, target=c, message=output) if client.area.is_locked != client.area.Locked.FREE: client.area.invite_list.pop(c.id) except AreaError: raise except ClientError: raise else: client.send_ooc("No targets found.")
def ooc_cmd_area_kick(client, arg): if not client.is_cm and not client.is_mod: raise ClientError('You must be authorized to do that.') if not client.area.is_locked and not client.is_mod: raise ClientError('Area isn\'t locked.') if not arg: raise ClientError('You must specify a target. Use /area_kick <id>') arg = arg.split(' ') if len(arg[0]) == 10: targets = client.server.client_manager.get_targets( client, TargetType.IPID, int(arg[0]), False) elif len(arg[0]) < 10: targets = client.server.client_manager.get_targets( client, TargetType.ID, int(arg[0]), False) if targets: try: for c in targets: if len(arg) == 1: area = client.server.area_manager.get_area_by_id(int(0)) output = 0 else: try: area = client.server.area_manager.get_area_by_id( int(arg[1])) output = arg[1] except AreaError: raise client.send_host_message( "Attempting to kick {} to area {}.".format( c.get_char_name(), output)) c.change_area(area) c.send_host_message( "You were kicked from the area to area {}.".format(output)) if client.area.is_locked or client.area.is_modlocked: client.area.invite_list.pop(c.ipid) except AreaError: raise except ClientError: raise else: client.send_host_message("No targets found.")
def parse_passage_lock(client, areas, bilock=False): now_reachable = [] num_areas = 2 if bilock else 1 # First check if it is the case a non-authorized use is trying to change passages to areas # that do not allow their passages to be modified for i in range(num_areas): if not areas[i].change_reachability_allowed and not client.is_staff(): raise ClientError('You must be authorized to change passages in area {}.' .format(areas[i].name)) # Just in case something goes wrong, have a backup to revert back formerly_reachable = [areas[i].reachable_areas for i in range(num_areas)] for i in range(num_areas): reachable = areas[i].reachable_areas now_reachable.append(False) if reachable == {'<ALL>'}: # Case removing a passage from an area connected to all areas reachable = client.server.area_manager.area_names - {areas[1-i].name} elif areas[1-i].name in reachable: # Case removing a passage reachable = reachable - {areas[1-i].name} else: # Case creating a passage # Make sure that non-authorized users cannot create passages did not exist before if not (client.is_staff() or areas[1-i].name in areas[i].staffset_reachable_areas or areas[i].staffset_reachable_areas == {'<ALL>'}): # And if they try and do, undo changes and restore formerly reachable areas for j in range(num_areas): areas[j].reachable_areas = formerly_reachable[j] raise ClientError('You must be authorized to create a new passage from {} to ' '{}.'.format(areas[i].name, areas[1-i].name)) # Otherise, create new passages reachable.add(areas[1-i].name) now_reachable[i] = True areas[i].reachable_areas = reachable if client.is_staff(): areas[i].staffset_reachable_areas = reachable return now_reachable
def change_area(self, area): if self.area == area: raise ClientError('User already in specified area.') if area.is_locked == area.Locked.LOCKED and not self.is_mod and not self.id in area.invite_list: raise ClientError("That area is locked!") if area.is_locked == area.Locked.SPECTATABLE and not self.is_mod and not self.id in area.invite_list: self.send_host_message( 'This area is spectatable, but not free - you will be unable to send messages ICly unless invited.' ) if self.area.jukebox: self.area.remove_jukebox_vote(self, True) old_area = self.area if not area.is_char_available(self.char_id): try: new_char_id = area.get_rand_avail_char_id() except AreaError: raise ClientError('No available characters in that area.') self.change_character(new_char_id) self.send_host_message( 'Character taken, switched to {}.'.format( self.get_char_name())) self.area.remove_client(self) self.area = area area.new_client(self) self.send_host_message('Changed area to {}.[{}]'.format( area.name, self.area.status)) logger.log_server( '[{}]Changed area from {} ({}) to {} ({}).'.format( self.get_char_name(), old_area.name, old_area.id, self.area.name, self.area.id), self) self.area.send_command('CharsCheck', *self.get_available_char_list()) self.send_command('HP', 1, self.area.hp_def) self.send_command('HP', 2, self.area.hp_pro) self.send_command('BN', self.area.background) self.send_command('LE', *self.area.get_evidence_list(self))
def change_area(self, area): """ Switch the client to another area, unless the area is locked. :param area: area to switch to """ if self.area == area: raise ClientError('User already in specified area.') if area.is_locked == area.Locked.LOCKED and not self.is_mod and not self.id in area.invite_list: raise ClientError('That area is locked!') if area.is_locked == area.Locked.SPECTATABLE and not self.is_mod and not self.id in area.invite_list: self.send_ooc( 'This area is spectatable, but not free - you cannot talk in-character unless invited.' ) if self in self.area.afkers: self.server.client_manager.toggle_afk(self) if self.area.jukebox: self.area.remove_jukebox_vote(self, True) old_area = self.area if not area.is_char_available(self.char_id): try: new_char_id = area.get_rand_avail_char_id() except AreaError: raise ClientError('No available characters in that area.') self.change_character(new_char_id) self.send_ooc( f'Character taken, switched to {self.char_name}.') self.area.remove_client(self) self.area = area area.new_client(self) self.send_ooc(f'Changed area to {area.name} [{self.area.status}].') self.area.send_command('CharsCheck', *self.get_available_char_list()) self.send_command('HP', 1, self.area.hp_def) self.send_command('HP', 2, self.area.hp_pro) self.send_command('BN', self.area.background) self.send_command('LE', *self.area.get_evidence_list(self))
def ooc_cmd_notecard_clear(client, arg): """ Erase a notecard. Usage: /notecard_clear """ try: del client.area.cards[client.char_name] client.area.broadcast_ooc('{} erased their note card.'.format( client.char_name)) database.log_room('notecard_erase', client, client.area) except KeyError: raise ClientError('You do not have a note card.')
def ooc_cmd_announce(client, arg): if not client.is_mod: raise ClientError('You must be authorized to do that.') if len(arg) == 0: raise ArgumentError("Can't send an empty message.") client.server.send_all_cmd_pred( 'CT', '{}'.format(client.server.config['hostname']), '=== Announcement ===\r\n{}\r\n=================='.format(arg)) logger.log_server( '[{}][{}][ANNOUNCEMENT]{}.'.format(client.area.id, client.get_char_name(), arg), client)
def ooc_cmd_pm(client, arg): """ Send a private message to another online user. These messages are not logged by the server owner. Usage: /pm <id|ooc-name|char-name> <message> """ args = arg.split() key = '' msg = None if len(args) < 2: raise ArgumentError( 'Not enough arguments. use /pm <target> <message>. Target should be ID, OOC-name or char-name. Use /getarea for getting info like "[ID] char-name".' ) targets = client.server.client_manager.get_targets(client, TargetType.CHAR_NAME, arg, True) key = TargetType.CHAR_NAME if len(targets) == 0 and args[0].isdigit(): targets = client.server.client_manager.get_targets( client, TargetType.ID, int(args[0]), False) key = TargetType.ID if len(targets) == 0: targets = client.server.client_manager.get_targets( client, TargetType.OOC_NAME, arg, True) key = TargetType.OOC_NAME if len(targets) == 0: raise ArgumentError('No targets found.') try: if key == TargetType.ID: msg = ' '.join(args[1:]) else: if key == TargetType.CHAR_NAME: msg = arg[len(targets[0].char_name) + 1:] if key == TargetType.OOC_NAME: msg = arg[len(targets[0].name) + 1:] except: raise ArgumentError( 'Not enough arguments. Use /pm <target> <message>.') c = targets[0] if c.pm_mute: raise ClientError('This user muted all pm conversation') else: if c.is_mod: c.send_ooc( 'PM from {} (ID: {}, IPID: {}) in {} ({}): {}'.format( client.name, client.id, client.ipid, client.area.name, client.showname, msg)) else: c.send_ooc('PM from {} (ID: {}) in {} ({}): {}'.format( client.name, client.id, client.area.name, client.showname, msg)) client.send_ooc('PM sent to {}. Message: {}'.format( args[0], msg))
def ooc_cmd_vote_reveal(client, arg): """ Reveal the number of votes, the voters and those with the highest amount of votes. Usage: /vote_reveal """ if len(client.area.votes) == 0: raise ClientError("There are no votes to reveal in this area.") msg = "Votes have been revealed:" msg += get_vote_results(client.area.votes) client.area.broadcast_ooc(msg) client.send_ooc("Use /vote_clear for clearing.") database.log_area("vote_reveal", client, client.area)
def ooc_cmd_unban(client, arg): if not client.is_mod: raise ClientError('You must be authorized to do that.') ip = arg.strip() if len(ip) < 7: raise ArgumentError('You must specify an IP.') try: client.server.ban_manager.remove_ban(ip) except ServerError: raise client.send_host_message('Removed {} from the banlist.'.format(ip)) logger.log_server('Unbanned {}.'.format(ip), client)
def ooc_cmd_storemlist(client, arg): if client not in client.area.owners and not client.is_mod: raise ClientError('You must be a CM.') if len(arg) < 1: raise ArgumentError('Your stored list requires a name!') if len(arg) > 12: raise ArgumentError('Keep the name of your list to 12 characters or below.') if len(client.area.cmusic_list) == 0: raise ArgumentError('No list to store!') if '/' in arg or "\\" in arg or '..' in arg: raise ArgumentError('Contains bad characters') client.server.musiclist_manager.storelist(client, arg)
def ooc_cmd_arup_enable(client, arg): """ Enable the ARea UPdate system for this hub. ARUP system is the extra information displayed in the A/M area list, as well as being able to set /status. Usage: /arup_enable """ if client.area.area_manager.arup_enabled: raise ClientError('ARUP system is already enabled! Use /arup_disable to disable it.') client.area.area_manager.arup_enabled = True client.area.area_manager.send_command('FL', client.server.supported_features) client.area.area_manager.broadcast_area_list(refresh=True) client.area.area_manager.broadcast_ooc('ARUP system has been enabled for this hub.')
def ooc_cmd_rolla(client, arg): if not hasattr(client.area, 'ability_dice'): rolla_reload(client.area) if not hasattr(client, 'ability_dice_set'): raise ClientError( 'You must set your ability set using /rolla_set <name>.') ability_dice = client.area.ability_dice[client.ability_dice_set] max_roll = ability_dice['max'] if 'max' in ability_dice else 6 roll = random.randint(1, max_roll) ability = ability_dice[roll] if roll in ability_dice else "Nothing happens" client.area.send_host_message('{} rolled a {} (out of {}): {}.'.format( client.get_char_name(), roll, max_roll, ability))