Exemple #1
0
 def activate(self):
     super(PlayerManagerPlugin, self).activate()
     self.player_manager = PlayerManager(self.config)
     self.l_call = LoopingCall(self.check_logged_in)
     self.l_call.start(1, now=False)
     self.regexes = self.config.plugin_config['name_removal_regexes']
     self.adminss = self.config.plugin_config['admin_ss']
Exemple #2
0
 def activate(self):
     super(PlayerManagerPlugin, self).activate()
     self.player_manager = PlayerManager(self.config)
     self.l_call = LoopingCall(self.check_logged_in)
     self.l_call.start(1, now=False)
     self.regexes = self.config.plugin_config['name_removal_regexes']
     self.adminss = self.config.plugin_config['admin_ss']
Exemple #3
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = 'player_manager_plugin'
    commands = ['player_list', 'player_delete', 'nick', 'nick_set']

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']
        self.adminss = self.config.plugin_config['admin_ss']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.who():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False
                player.admin_logged_in = False
                player.party_id = ''

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            changed_name = client_data.name

            # Replace problematic chars in client name
            for regex in self.regexes:
                changed_name = re.sub(regex, '', changed_name)

            # If the username is nothing but spaces.
            if not client_data.name.strip():
                raise NameError('Your name must not be empty!')

            # Logging changed username
            if client_data.name != changed_name:
                self.logger.info(
                    'Player tried to log in with name %s, replaced with %s.',
                    client_data.name, changed_name)

            changed_player = self.player_manager.get_by_uuid(client_data.uuid)
            if (changed_player is not None
                    and changed_player.name != changed_name):
                self.logger.info(
                    'Got player with changed nickname. Fetching nickname!')
                changed_name = changed_player.name

            duplicate_player = self.player_manager.get_by_org_name(
                client_data.name)
            if (duplicate_player is not None
                    and duplicate_player.uuid != client_data.uuid):
                self.logger.info('CLONE WARNING: {} '
                                 'MAY BE TRYING TO IMPERSONATE {}!'.format(
                                     self.protocol.transport.getPeer().host,
                                     client_data.name))

            if client_data.account == self.adminss:
                admin_login = True
            else:
                admin_login = False

            original_name = client_data.name
            client_data.name = changed_name
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                org_name=original_name,
                admin_logged_in=admin_login,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id,
            )
            return True

        except AlreadyLoggedIn:
            self.reject_with_reason(
                'You\'re already logged in! If this is not the case, '
                'please wait 10 seconds and try again.')
            self.logger.info('Already logged in user tried to log in.')

        except Banned:
            self.reject_with_reason('You have been banned!')
            self.logger.info('Banned user tried to log in.')
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        # here there be magic... ask Carrots or Teihoo about this...
        magic_sector = (
            'AQAAAAwAAAAy+gofAAX14QD/Z2mAAJiWgAUFYWxwaGEMQWxwaGEgU2VjdG9yAAAAE'
            'LIfhbMFQWxwaGEHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQ'
            'RhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9'
            'pZGZpZWxkBwcCaWQFBWFscGhhBG5hbWUFDEFscGhhIFNlY3RvcgpzZWN0b3JTZWVk'
            'BISWofyWZgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzEucG5nCGh1Z'
            'VNoaWZ0BDsGcHJlZml4BQVBbHBoYQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZX'
            'ZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAU'
            'Ec25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBGJldGELQmV0YSBTZWN0'
            'b3IAAADUWh1fvwRCZXRhBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZ'
            'XMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQ'
            'ZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcHAmlkBQRiZXRhBG5hbWUFC0J'
            'ldGEgU2VjdG9yCnNlY3RvclNlZWQEtYuh6v5+DHNlY3RvclN5bWJvbAUXL2NlbGVz'
            'dGlhbC9zZWN0b3IvMi5wbmcIaHVlU2hpZnQEAAZwcmVmaXgFBEJldGEPd29ybGRQY'
            'XJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYX'
            'JpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGU'
            'FBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAVnYW1tYQxHYW1tYSBTZWN0b3IAAADMTMw7'
            '9wVHYW1tYQcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFya'
            'WQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQ'
            'pncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQHBwJpZAUFZ2FtbWEEbmF'
            'tZQUMR2FtbWEgU2VjdG9yCnNlY3RvclNlZWQEs4nM4e9uDHNlY3RvclN5bWJvbAUX'
            'L2NlbGVzdGlhbC9zZWN0b3IvMy5wbmcIaHVlU2hpZnQEPAZwcmVmaXgFBUdhbW1hD'
            '3dvcmxkUGFyYW1ldGVycwcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbW'
            'VzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgU'
            'GanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQFZGVsdGEM'
            'RGVsdGEgU2VjdG9yAAAA1Ooj2GcFRGVsdGEHAgt0aHJlYXRMZXZlbAYCBAgECA51b'
            'mxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBH'
            'Nub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwU'
            'GdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWRl'
            'bHRhBG5hbWUFDERlbHRhIFNlY3RvcgpzZWN0b3JTZWVkBLWdop7hTgxzZWN0b3JTe'
            'W1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzQucG5nCGh1ZVNoaWZ0BHgGcHJlZml4BQ'
            'VEZWx0YQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2t'
            '==')
        unlocked_sector_magic = base64.decodestring(
            magic_sector.encode('ascii'))
        rejection = build_packet(
            packets.Packets.CONNECT_FAILURE,
            packets.connect_failure().build(Container(reject_reason=reason)) +
            unlocked_sector_magic)
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def on_connect_failure(self, data):
        self.protocol.transport.loseConnection()

    def on_connect_success(self, data):
        try:
            connection_parameters = connect_success().parse(data.data)

            self.protocol.player.client_id = connection_parameters.client_id
            self.protocol.player.logged_in = True
            self.protocol.player.party_id = ''
            self.logger.info('Player %s (UUID: %s, IP: %s) logged in',
                             self.protocol.player.name,
                             self.protocol.player.uuid,
                             self.protocol.transport.getPeer().host)
        except:
            self.logger.exception('Exception in on_connect_success, '
                                  'player info may not have been logged.')
        finally:
            return True

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        if 'ship.maxFuel' in world_start['world_properties']:
            self.logger.info('Player %s is now on a ship.',
                             self.protocol.player.name)
            self.protocol.player.on_ship = True
            self.protocol.player.planet = 'On ship'
        elif world_start.planet['celestialParameters'] is None:
            self.protocol.player.on_ship = False
            self.protocol.player.planet = 'On Outpost'
        else:
            coords = world_start.planet['celestialParameters']['coordinate']
            parent_system = coords
            l = parent_system['location']
            self.protocol.player.on_ship = False
            planet = Planet(l[0], l[1], l[2], coords['planet'],
                            coords['satellite'])
            self.protocol.player.planet = str(planet)

    def on_client_disconnect_request(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info('Player disconnected: %s',
                             self.protocol.player.name)
            self.protocol.player.logged_in = False
            self.protocol.player.admin_logged_in = False
        return True

    @permissions(UserLevels.REGISTERED)
    def nick(self, data):
        """
        Changes your nickname.
        Syntax: /nick (new name)
        """
        if not data:
            self.protocol.send_chat_message(self.nick.__doc__)
            return
        name = ' '.join(data)
        org_name = self.protocol.player.org_name

        # Replace problematic chars in client name
        for regex in self.regexes:
            name = re.sub(regex, '', name)
        if (self.player_manager.get_by_name(name) or
            (self.player_manager.get_by_org_name(name) and org_name != name)):
            self.protocol.send_chat_message(
                'There\'s already a player by that name.')
        else:
            old_name = self.protocol.player.colored_name(self.config.colors)
            self.protocol.player.name = name
            self.factory.broadcast(
                '{}^green;\'s name has been changed to {}'.format(
                    old_name,
                    self.protocol.player.colored_name(self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def nick_set(self, data):
        """
        Changes player nickname.
        Syntax: /nick_set (name) (new name)
        """
        if data:
            self.protocol.send_chat_message(self.nick_set.__doc__)
            return
        try:
            first_name, rest = extract_name(data)

            # Replace problematic chars in client name
            for regex in self.regexes:
                first_name = re.sub(regex, '', first_name)
        except ValueError:
            self.protocol.send_chat_message(
                'Name not recognized. If it has spaces, '
                'please surround it by quotes!')
            return
        if not rest:
            self.protocol.send_chat_message(self.nick_set.__doc__)
        else:
            try:
                second_name = extract_name(rest)[0]

                # Replace problematic chars in client name
                for regex in self.regexes:
                    second_name = re.sub(regex, '', second_name)
            except ValueError:
                self.protocol.send_chat_message(
                    'New name not recognized. If it has spaces, '
                    'please surround it by quotes!')
                return
        player = self.player_manager.get_by_name(str(first_name))
        player2 = self.player_manager.get_by_name(str(second_name))
        org_player = self.player_manager.get_by_org_name(str(first_name))
        org_player2 = self.player_manager.get_by_org_name(str(second_name))
        if player:
            first_uuid = player.uuid
        elif org_player:
            first_uuid = org_player.uuid
        if player2:
            second_uuid = player2.uuid
        elif org_player2:
            second_uuid = org_player2.uuid
        if player or org_player:
            if (player2 or org_player2) and first_uuid != second_uuid:
                self.protocol.send_chat_message(
                    'There\'s already a player by that name.')
            else:
                old_name = player.colored_name(self.config.colors)
                player.name = second_name
                self.factory.broadcast(
                    '{}^green;\'s name has been changed to {}'.format(
                        old_name, player.colored_name(self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def player_delete(self, data):
        """
        Delete a player from database.
        Syntax: /player_del (player)
        """
        if not data:
            self.protocol.send_chat_message(self.player_del.__doc__)
            return
        name = ' '.join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                'That player is currently logged in. '
                'Refusing to delete logged in character.')
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    'Couldn\'t find a player named {}. '
                    'Please check the spelling and try again.'.format(name))
                return False
            self.player_manager.delete(player)
            self.protocol.send_chat_message(
                'Deleted player with name {}.'.format(name))

    @permissions(UserLevels.ADMIN)
    def player_list(self, data):
        """
        List registered players on the server.
        Syntax: /player_list [search term]
        """
        if not data:
            self.format_player_response(self.player_manager.all())
        else:
            rx = re.sub(r'[\*]', '%', ' '.join(data))
            self.format_player_response(self.player_manager.all_like(rx))

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message('Results:\n%s'.format('\n'.join([
                PLAYER_PATTER.format(player.uuid,
                                     player.colored_name(self.config.colors),
                                     player.org_name) for player in players
            ])))
        else:
            self.protocol.send_chat_message('Results:\n{}'.format('\n'.join([
                PLAYER_PATTER.format(player.uuid,
                                     player.colored_name(self.config.colors),
                                     player.org_name)
                for player in players[:25]
            ])))
            self.protocol.send_chat_message(
                'And {} more. Narrow it down with SQL like syntax. Feel free '
                'to use a *, it will be replaced appropriately.'.format(
                    len(players) - 25))
Exemple #4
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = "player_manager_plugin"
    commands = ["player_list", "player_delete", "nick", "nick_set"]

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']
        self.blocked_regexes = self.config.plugin_config['name_blocked_regexes']
        self.adminss = self.config.plugin_config['admin_ss']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.who():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False
                player.admin_logged_in = False
                player.party_id = ""

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            clone_append = ""
            changed_name = client_data.name.encode("utf-8")

            for regex in self.blocked_regexes:  # Replace blocked chars in client name
                changed_name = re.sub(regex, "", changed_name)

            if client_data.name != changed_name:  # Logging changed username
                raise NameError("Your name must not be colored or encoded!")

            changed_name = client_data.name.encode("utf-8")

            for regex in self.regexes:  # Replace problematic chars in client name
                changed_name = re.sub(regex, "", changed_name)

            if len(client_data.name.strip()) == 0:  # If the username is nothing but spaces.
                raise NameError("Your name must not be empty!")

            if client_data.name != changed_name:  # Logging changed username
                self.logger.info("Player tried to log in with name %s, replaced with %s.", client_data.name, changed_name)

            changed_player = self.player_manager.get_by_uuid(client_data.uuid)
            if changed_player is not None and changed_player.name != changed_name:
                self.logger.info("Got player with changed nickname. Fetching nickname!")
                changed_name = changed_player.name

            duplicate_player = self.player_manager.get_by_org_name(client_data.name)
            if duplicate_player is not None and duplicate_player.uuid != client_data.uuid:
                #raise NameError(
                #    "The name of this character is already taken on the server!\nPlease, create a new character with a different name or talk to an administrator.")
                self.logger.info("CLONE WARNING: {} MAY BE TRYING TO IMPERSONATE {}!".format(self.protocol.transport.getPeer().host, client_data.name))
                #clone_append = " [CLONE]"
                #changed_name += clone_append
                #client_data.name += clone_append

            if client_data.account == self.adminss:
                admin_login = True
            else:
                admin_login = False

            original_name = client_data.name
            client_data.name = changed_name
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                org_name=original_name,
                admin_logged_in = admin_login,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id,
            )

            #self.protocol.player.name += clone_append

            return True
        except AlreadyLoggedIn:
            self.reject_with_reason(
                "You're already logged in! If this is not the case, please wait 10 seconds and try again.")
            self.logger.info("Already logged in user tried to log in.")
        except Banned:
            self.reject_with_reason("You have been banned!")
            self.logger.info("Banned user tried to log in.")
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        # here there be magic... ask Carrots or Teihoo about this...
        magic_sector = "AQAAAAwAAAAy+gofAAX14QD/Z2mAAJiWgAUFYWxwaGEMQWxwaGEgU2VjdG9yAAAAELIfhbMFQWxwaGEHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWFscGhhBG5hbWUFDEFscGhhIFNlY3RvcgpzZWN0b3JTZWVkBISWofyWZgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzEucG5nCGh1ZVNoaWZ0BDsGcHJlZml4BQVBbHBoYQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBGJldGELQmV0YSBTZWN0b3IAAADUWh1fvwRCZXRhBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcHAmlkBQRiZXRhBG5hbWUFC0JldGEgU2VjdG9yCnNlY3RvclNlZWQEtYuh6v5+DHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMi5wbmcIaHVlU2hpZnQEAAZwcmVmaXgFBEJldGEPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAVnYW1tYQxHYW1tYSBTZWN0b3IAAADMTMw79wVHYW1tYQcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQHBwJpZAUFZ2FtbWEEbmFtZQUMR2FtbWEgU2VjdG9yCnNlY3RvclNlZWQEs4nM4e9uDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMy5wbmcIaHVlU2hpZnQEPAZwcmVmaXgFBUdhbW1hD3dvcmxkUGFyYW1ldGVycwcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQFZGVsdGEMRGVsdGEgU2VjdG9yAAAA1Ooj2GcFRGVsdGEHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWRlbHRhBG5hbWUFDERlbHRhIFNlY3RvcgpzZWN0b3JTZWVkBLWdop7hTgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzQucG5nCGh1ZVNoaWZ0BHgGcHJlZml4BQVEZWx0YQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkB3NlY3RvcngIWCBTZWN0b3IAAABjhzJHNwFYBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcIAmlkBQdzZWN0b3J4BG5hbWUFCFggU2VjdG9yCnNlY3RvclNlZWQEmPDzkpxuDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IveC5wbmcIaHVlU2hpZnQEgTQIcHZwRm9yY2UDAQZwcmVmaXgFAVgPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZA=="
        unlocked_sector_magic = base64.decodestring(magic_sector.encode("ascii"))
        rejection = build_packet(
            packets.Packets.CONNECT_FAILURE,
            packets.connect_failure().build(
                Container(
                    reject_reason=reason
                )
            ) + unlocked_sector_magic
        )
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def on_connect_failure(self,data):
        self.protocol.transport.loseConnection()

    def on_connect_success(self, data):
        try:
            connection_parameters = connect_success().parse(data.data)
            #if not connection_parameters.success:
            #    self.protocol.transport.loseConnection()
            #else:
            self.protocol.player.client_id = connection_parameters.client_id
            self.protocol.player.logged_in = True
            self.protocol.player.party_id = ""
            self.logger.info("Player %s (UUID: %s, IP: %s) logged in" % (
                self.protocol.player.name, self.protocol.player.uuid,
                self.protocol.transport.getPeer().host))
        except:
            self.logger.exception("Exception in on_connect_success, player info may not have been logged.")
        finally:
            return True

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        if 'ship.maxFuel' in world_start['world_properties']:
            self.logger.info("Player %s is now on a ship.", self.protocol.player.name)
            self.protocol.player.on_ship = True
            self.protocol.player.planet = "On ship"
        elif world_start.planet['celestialParameters'] is None:
            self.protocol.player.on_ship = False
            self.protocol.player.planet = "On Outpost"
        else:
            coords = world_start.planet['celestialParameters']['coordinate']
            parent_system = coords
            l = parent_system['location']
            self.protocol.player.on_ship = False
            planet = Planet(l[0], l[1], l[2],
                            coords['planet'], coords['satellite'])
            self.protocol.player.planet = str(planet)

    def on_client_disconnect_request(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info("Player disconnected: %s", self.protocol.player.name)
            self.protocol.player.logged_in = False
            self.protocol.player.admin_logged_in = False
        return True

    @permissions(UserLevels.REGISTERED)
    def nick(self, data):
        """Changes your nickname.\nSyntax: /nick (new name)"""
        if len(data) == 0:
            self.protocol.send_chat_message(self.nick.__doc__)
            return
        name = " ".join(data)
        org_name = self.protocol.player.org_name
        for regex in self.regexes:  # Replace problematic chars in client name
            name = re.sub(regex, "", name)
        if self.player_manager.get_by_name(name) or (self.player_manager.get_by_org_name(name) and org_name != name):
            self.protocol.send_chat_message("There's already a player by that name.")
        else:
            old_name = self.protocol.player.colored_name(self.config.colors)
            self.protocol.player.name = name
            self.factory.broadcast("%s^green;'s name has been changed to %s" % (
                old_name, self.protocol.player.colored_name(self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def nick_set(self, data):
        """Changes player nickname.\nSyntax: /nick_set (name) (new name)"""
        if len(data) <= 1:
            self.protocol.send_chat_message(self.nick_set.__doc__)
            return
        try:
            first_name, rest = extract_name(data)
            for regex in self.regexes:  # Replace problematic chars in client name
                first_name = re.sub(regex, "", first_name)
        except ValueError:
            self.protocol.send_chat_message("Name not recognized. If it has spaces, please surround it by quotes!")
            return
        if rest is None or len(rest) == 0:
            self.protocol.send_chat_message(self.nick_set.__doc__)
        else:
            try:
                second_name = extract_name(rest)[0]
                for regex in self.regexes:  # Replace problematic chars in client name
                    second_name = re.sub(regex, "", second_name)
            except ValueError:
                self.protocol.send_chat_message(
                    "New name not recognized. If it has spaces, please surround it by quotes!")
                return
        player = self.player_manager.get_by_name(str(first_name))
        player2 = self.player_manager.get_by_name(str(second_name))
        org_player = self.player_manager.get_by_org_name(str(first_name))
        org_player2 = self.player_manager.get_by_org_name(str(second_name))
        if player:
            first_uuid = player.uuid
        elif org_player:
            first_uuid = org_player.uuid
        if player2:
            second_uuid = player2.uuid
        elif org_player2:
            second_uuid = org_player2.uuid
        if player or org_player:
            if (player2 or org_player2) and first_uuid != second_uuid:
                self.protocol.send_chat_message("There's already a player by that name.")
            else:
                old_name = player.colored_name(self.config.colors)
                player.name = second_name
                self.factory.broadcast("%s^green;'s name has been changed to %s" % (
                    old_name, player.colored_name(self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def player_delete(self, data):
        """Delete a player from database.\nSyntax: /player_del (player)"""
        if len(data) == 0:
            self.protocol.send_chat_message(self.player_del.__doc__)
            return
        name = " ".join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                "That player is currently logged in. Refusing to delete logged in character.")
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    "Couldn't find a player named %s. Please check the spelling and try again." % name)
                return False
            self.player_manager.delete(player)
            self.protocol.send_chat_message("Deleted player with name %s." % name)

    @permissions(UserLevels.ADMIN)
    def player_list(self, data):
        """List registered players on the server.\nSyntax: /player_list [search term]"""
        if len(data) == 0:
            self.format_player_response(self.player_manager.all())
        else:
            rx = re.sub(r"[\*]", "%", " ".join(data))
            self.format_player_response(self.player_manager.all_like(rx))

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message(
                #_("Results: %s") % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players]))
                "Results:\n%s" % "\n".join(
                    ["^cyan;%s: ^yellow;%s ^green;: ^gray;%s" % (
                        player.uuid, player.colored_name(self.config.colors), player.org_name) for player in
                     players]))
        else:
            self.protocol.send_chat_message(
                #_("Results: %s)" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players[:25]])))
                "Results:\n%s" % "\n".join(
                    ["^cyan;%s: ^yellow;%s ^green;: ^gray;%s" % (
                        player.uuid, player.colored_name(self.config.colors), player.org_name) for player in
                     players[:25]]))
            self.protocol.send_chat_message(
                "And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately." % (
                    len(players) - 25))
Exemple #5
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = "player_manager"
    commands = ["list_players", "delete_player"]

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.session.query(Player).filter_by(
                logged_in=True).all():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            original_name = client_data.name
            for regex in self.regexes:
                client_data.name = re.sub(regex, "", client_data.name)
            if len(client_data.name.strip()
                   ) == 0:  # If the username is nothing but spaces.
                raise NameError("Your name must not be empty!")
            if client_data.name != original_name:
                self.logger.info(
                    "Player tried to log in with name %s, replaced with %s.",
                    original_name, client_data.name)
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id)
            return True
        except AlreadyLoggedIn:
            self.reject_with_reason(
                "You're already logged in! If this is not the case, please wait 10 seconds and try again."
            )
            self.logger.info("Already logged in user tried to log in.")
        except Banned:
            self.reject_with_reason("You have been banned!")
            self.logger.info("Banned user tried to log in.")
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        rejection = build_packet(
            packets.Packets.CONNECT_RESPONSE,
            packets.connect_response().build(
                Container(success=False, client_id=0, reject_reason=reason)))
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def after_connect_response(self, data):
        connection_parameters = connect_response().parse(data.data)
        if not connection_parameters.success:
            self.protocol.transport.loseConnection()
        else:
            self.protocol.player.client_id = connection_parameters.client_id
            self.protocol.player.logged_in = True
            self.logger.info(
                "Player %s (UUID: %s, IP: %s) logged in" %
                (self.protocol.player.name, self.protocol.player.uuid,
                 self.protocol.transport.getPeer().host))

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        coords = world_start.planet['config']['coordinate']
        if coords is not None:
            parent_system = coords['parentSystem']
            location = parent_system['location']
            l = location
            self.protocol.player.on_ship = False
            planet = Planet(parent_system['sector'], l[0], l[1], l[2],
                            coords['planetaryOrbitNumber'],
                            coords['satelliteOrbitNumber'])
            self.protocol.player.planet = str(planet)
            self.logger.debug("Player %s is now at planet: %s",
                              self.protocol.player.name, str(planet))
        else:
            self.logger.info("Player %s is now on a ship.",
                             self.protocol.player.name)
            self.protocol.player.on_ship = True

    def on_client_disconnect(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info("Player disconnected: %s",
                             self.protocol.player.name)
            self.protocol.player.logged_in = False

    @permissions(UserLevels.ADMIN)
    def delete_player(self, data):
        name = " ".join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                "That player is currently logged in. Refusing to delete logged in character."
            )
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    "Couldn't find a player named %s. Please check the spelling and try again."
                    % name)
                return False
            self.player_manager.session.delete(player)
            self.protocol.send_chat_message("Deleted player with name %s." %
                                            name)

    @permissions(UserLevels.ADMIN)
    def list_players(self, data):
        if len(data) == 0:
            self.format_player_response(
                self.player_manager.session.query(Player).all())
        else:
            rx = re.sub(r"[\*]", "%", " ".join(data))
            self.format_player_response(
                self.player_manager.session.query(Player).filter(
                    Player.name.like(rx)).all())

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message("Results: %s" % "\n".join(
                ["%s: %s" % (player.uuid, player.name) for player in players]))
        else:
            self.protocol.send_chat_message("Results: %s" % "\n".join([
                "%s: %s" % (player.uuid, player.name)
                for player in players[:25]
            ]))
            self.protocol.send_chat_message(
                "And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately."
                % (len(players) - 25))
Exemple #6
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = "player_manager"
    commands = ["player_list", "player_delete", "nick", "nick_set"]

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']
        self.adminss = self.config.plugin_config['admin_ss']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.who():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False
                player.admin_logged_in = False

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            changed_name = client_data.name
            for regex in self.regexes:  # Replace problematic chars in client name
                changed_name = re.sub(regex, "", changed_name)

            if len(client_data.name.strip()
                   ) == 0:  # If the username is nothing but spaces.
                raise NameError("Your name must not be empty!")

            if client_data.name != changed_name:  # Logging changed username
                self.logger.info(
                    "Player tried to log in with name %s, replaced with %s.",
                    client_data.name, changed_name)

            changed_player = self.player_manager.get_by_uuid(client_data.uuid)
            if changed_player is not None and changed_player.name != changed_name:
                self.logger.info(
                    "Got player with changed nickname. Fetching nickname!")
                changed_name = changed_player.name

            duplicate_player = self.player_manager.get_by_org_name(
                client_data.name)
            if duplicate_player is not None and duplicate_player.uuid != client_data.uuid:
                raise NameError(
                    "The name of this character is already taken on the server!\nPlease, create a new character with a different name or talk to an administrator."
                )
                self.logger.info(
                    "Got a duplicate original player name, asking player to change character name!"
                )
                #rnd_append = str(randrange(10, 99))
                #original_name += rnd_append
                #client_data.name += rnd_append

            if client_data.account == self.adminss:
                admin_login = True
            else:
                admin_login = False

            original_name = client_data.name
            client_data.name = changed_name
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                org_name=original_name,
                admin_logged_in=admin_login,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id,
            )

            return True
        except AlreadyLoggedIn:
            self.reject_with_reason(
                "You're already logged in! If this is not the case, please wait 10 seconds and try again."
            )
            self.logger.info("Already logged in user tried to log in.")
        except Banned:
            self.reject_with_reason("You have been banned!")
            self.logger.info("Banned user tried to log in.")
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        # here there be magic... ask Carrots or Teihoo about this...
        magic_sector = "AQAAAAwAAAAy+gofAAX14QD/Z2mAAJiWgAUFYWxwaGEMQWxwaGEgU2VjdG9yAAAAELIfhbMFQWxwaGEHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWFscGhhBG5hbWUFDEFscGhhIFNlY3RvcgpzZWN0b3JTZWVkBISWofyWZgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzEucG5nCGh1ZVNoaWZ0BDsGcHJlZml4BQVBbHBoYQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBGJldGELQmV0YSBTZWN0b3IAAADUWh1fvwRCZXRhBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcHAmlkBQRiZXRhBG5hbWUFC0JldGEgU2VjdG9yCnNlY3RvclNlZWQEtYuh6v5+DHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMi5wbmcIaHVlU2hpZnQEAAZwcmVmaXgFBEJldGEPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAVnYW1tYQxHYW1tYSBTZWN0b3IAAADMTMw79wVHYW1tYQcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQHBwJpZAUFZ2FtbWEEbmFtZQUMR2FtbWEgU2VjdG9yCnNlY3RvclNlZWQEs4nM4e9uDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMy5wbmcIaHVlU2hpZnQEPAZwcmVmaXgFBUdhbW1hD3dvcmxkUGFyYW1ldGVycwcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQFZGVsdGEMRGVsdGEgU2VjdG9yAAAA1Ooj2GcFRGVsdGEHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWRlbHRhBG5hbWUFDERlbHRhIFNlY3RvcgpzZWN0b3JTZWVkBLWdop7hTgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzQucG5nCGh1ZVNoaWZ0BHgGcHJlZml4BQVEZWx0YQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkB3NlY3RvcngIWCBTZWN0b3IAAABjhzJHNwFYBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcIAmlkBQdzZWN0b3J4BG5hbWUFCFggU2VjdG9yCnNlY3RvclNlZWQEmPDzkpxuDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IveC5wbmcIaHVlU2hpZnQEgTQIcHZwRm9yY2UDAQZwcmVmaXgFAVgPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZA=="
        unlocked_sector_magic = base64.decodestring(
            magic_sector.encode("ascii"))
        rejection = build_packet(
            packets.Packets.CONNECT_RESPONSE,
            packets.connect_response().build(
                Container(success=False, client_id=0, reject_reason=reason)) +
            unlocked_sector_magic)
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def on_connect_response(self, data):
        try:
            connection_parameters = connect_response().parse(data.data)
            if not connection_parameters.success:
                self.protocol.transport.loseConnection()
            else:
                self.protocol.player.client_id = connection_parameters.client_id
                self.protocol.player.logged_in = True
                self.logger.info(
                    "Player %s (UUID: %s, IP: %s) logged in" %
                    (self.protocol.player.name, self.protocol.player.uuid,
                     self.protocol.transport.getPeer().host))
        except:
            self.logger.exception(
                "Exception in on_connect_response, player info may not have been logged."
            )
        finally:
            return True

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        if 'ship.maxFuel' in world_start['world_properties']:
            self.logger.info("Player %s is now on a ship.",
                             self.protocol.player.name)
            self.protocol.player.on_ship = True
            self.protocol.player.planet = "On ship"
        elif world_start.planet['celestialParameters'] is None:
            self.protocol.player.on_ship = False
            self.protocol.player.planet = "On Outpost"
        else:
            coords = world_start.planet['celestialParameters']['coordinate']
            parent_system = coords
            l = parent_system['location']
            self.protocol.player.on_ship = False
            planet = Planet(l[0], l[1], l[2], coords['planet'],
                            coords['satellite'])
            self.protocol.player.planet = str(planet)

    def on_client_disconnect_request(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info("Player disconnected: %s",
                             self.protocol.player.name)
            self.protocol.player.logged_in = False
            self.protocol.player.admin_logged_in = False
        return True

    @permissions(UserLevels.REGISTERED)
    def nick(self, data):
        """Changes your nickname.\nSyntax: /nick (new name)"""
        if len(data) == 0:
            self.protocol.send_chat_message(self.nick.__doc__)
            return
        name = " ".join(data)
        org_name = self.protocol.player.org_name
        for regex in self.regexes:  # Replace problematic chars in client name
            name = re.sub(regex, "", name)
        if self.player_manager.get_by_name(name) or (
                self.player_manager.get_by_org_name(name)
                and org_name != name):
            self.protocol.send_chat_message(
                "There's already a player by that name.")
        else:
            old_name = self.protocol.player.colored_name(self.config.colors)
            self.protocol.player.name = name
            self.factory.broadcast(
                "%s^green;'s name has been changed to %s" %
                (old_name, self.protocol.player.colored_name(
                    self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def nick_set(self, data):
        """Changes player nickname.\nSyntax: /nick_set (name) (new name)"""
        if len(data) <= 1:
            self.protocol.send_chat_message(self.nick_set.__doc__)
            return
        try:
            first_name, rest = extract_name(data)
            for regex in self.regexes:  # Replace problematic chars in client name
                first_name = re.sub(regex, "", first_name)
        except ValueError:
            self.protocol.send_chat_message(
                "Name not recognized. If it has spaces, please surround it by quotes!"
            )
            return
        if rest is None or len(rest) == 0:
            self.protocol.send_chat_message(self.nick_set.__doc__)
        else:
            try:
                second_name = extract_name(rest)[0]
                for regex in self.regexes:  # Replace problematic chars in client name
                    second_name = re.sub(regex, "", second_name)
            except ValueError:
                self.protocol.send_chat_message(
                    "New name not recognized. If it has spaces, please surround it by quotes!"
                )
                return
        player = self.player_manager.get_by_name(str(first_name))
        player2 = self.player_manager.get_by_name(str(second_name))
        org_player = self.player_manager.get_by_org_name(str(first_name))
        org_player2 = self.player_manager.get_by_org_name(str(second_name))
        if player:
            first_uuid = player.uuid
        elif org_player:
            first_uuid = org_player.uuid
        if player2:
            second_uuid = player2.uuid
        elif org_player2:
            second_uuid = org_player2.uuid
        if player or org_player:
            if (player2 or org_player2) and first_uuid != second_uuid:
                self.protocol.send_chat_message(
                    "There's already a player by that name.")
            else:
                old_name = player.colored_name(self.config.colors)
                player.name = second_name
                self.factory.broadcast(
                    "%s^green;'s name has been changed to %s" %
                    (old_name, player.colored_name(self.config.colors)))

    @permissions(UserLevels.ADMIN)
    def player_delete(self, data):
        """Delete a player from database.\nSyntax: /player_del (player)"""
        if len(data) == 0:
            self.protocol.send_chat_message(self.player_del.__doc__)
            return
        name = " ".join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                "That player is currently logged in. Refusing to delete logged in character."
            )
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    "Couldn't find a player named %s. Please check the spelling and try again."
                    % name)
                return False
            self.player_manager.delete(player)
            self.protocol.send_chat_message("Deleted player with name %s." %
                                            name)

    @permissions(UserLevels.ADMIN)
    def player_list(self, data):
        """List registered players on the server.\nSyntax: /player_list [search term]"""
        if len(data) == 0:
            self.format_player_response(self.player_manager.all())
        else:
            rx = re.sub(r"[\*]", "%", " ".join(data))
            self.format_player_response(self.player_manager.all_like(rx))

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message(
                #_("Results: %s") % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players]))
                "Results:\n%s" % "\n".join([
                    "^cyan;%s: ^yellow;%s ^green;: ^gray;%s" %
                    (player.uuid, player.colored_name(
                        self.config.colors), player.org_name)
                    for player in players
                ]))
        else:
            self.protocol.send_chat_message(
                #_("Results: %s)" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players[:25]])))
                "Results:\n%s" % "\n".join([
                    "^cyan;%s: ^yellow;%s ^green;: ^gray;%s" %
                    (player.uuid, player.colored_name(
                        self.config.colors), player.org_name)
                    for player in players[:25]
                ]))
            self.protocol.send_chat_message(
                "And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately."
                % (len(players) - 25))
Exemple #7
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = "player_manager"
    commands = ["list_players", "delete_player"]

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.session.query(Player).filter_by(logged_in=True).all():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            original_name = client_data.name
            for regex in self.regexes:
                client_data.name = re.sub(regex, "", client_data.name)
            if len(client_data.name.strip()) == 0:  # If the username is nothing but spaces.
                raise NameError("Your name must not be empty!")
            if client_data.name != original_name:
                self.logger.info("Player tried to log in with name %s, replaced with %s.",
                                 original_name, client_data.name)
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id)
            return True
        except AlreadyLoggedIn:
            self.reject_with_reason(
                "You're already logged in! If this is not the case, please wait 10 seconds and try again.")
            self.logger.info("Already logged in user tried to log in.")
        except Banned:
            self.reject_with_reason("You have been banned!")
            self.logger.info("Banned user tried to log in.")
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        rejection = build_packet(
            packets.Packets.CONNECT_RESPONSE,
            packets.connect_response().build(
                Container(
                    success=False,
                    client_id=0,
                    reject_reason=reason
                )
            )
        )
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def after_connect_response(self, data):
        connection_parameters = connect_response().parse(data.data)
        if not connection_parameters.success:
            self.protocol.transport.loseConnection()
        else:
            self.protocol.player.client_id = connection_parameters.client_id
            self.protocol.player.logged_in = True
            self.logger.info("Player %s (UUID: %s, IP: %s) logged in" % (
                self.protocol.player.name, self.protocol.player.uuid,
                self.protocol.transport.getPeer().host))

    def after_world_start(self, data):
        world_start = packets.Variant("").parse(data.data)
        coords = world_start['config']['coordinate']
        if coords is not None:
            parent_system = coords['parentSystem']
            location = parent_system['location']
            l = location['data']
            self.protocol.player.on_ship = False
            planet = Planet(parent_system['sector'], l[0], l[1], l[2],
                            coords['planetaryOrbitNumber'], coords['satelliteOrbitNumber'])
            self.protocol.player.planet = str(planet)
            self.logger.debug("Player %s is now at planet: %s", self.protocol.player.name, str(planet))
        else:
            self.logger.info("Player %s is now on a ship.", self.protocol.player.name)
            self.protocol.player.on_ship = True

    def on_client_disconnect(self, player):
        if self.protocol.player.logged_in:
            self.logger.info("Player disconnected: %s", self.protocol.player.name)
            self.protocol.player.logged_in = False

    @permissions(UserLevels.ADMIN)
    def delete_player(self, data):
        name = " ".join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                "That player is currently logged in. Refusing to delete logged in character.")
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    "Couldn't find a player named %s. Please check the spelling and try again." % name)
                return False
            self.player_manager.session.delete(player)
            self.protocol.send_chat_message("Deleted player with name %s." % name)

    @permissions(UserLevels.ADMIN)
    def list_players(self, data):
        if len(data) == 0:
            self.format_player_response(self.player_manager.session.query(Player).all())
        else:
            rx = re.sub(r"[\*]", "%", " ".join(data))
            self.format_player_response(
                self.player_manager.session.query(Player).filter(Player.name.like(rx)).all())

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message(
                "Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players]))
        else:
            self.protocol.send_chat_message(
                "Results: %s" % "\n".join(["%s: %s" % (player.uuid, player.name) for player in players[:25]]))
            self.protocol.send_chat_message(
                "And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately." % (
                len(players) - 25))
Exemple #8
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = "player_manager"
    commands = ["list_players", "delete_player"]

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.who():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            original_name = client_data.name
            for regex in self.regexes:
                client_data.name = re.sub(regex, "", client_data.name)
            if len(client_data.name.strip()) == 0:  # If the username is nothing but spaces.
                raise NameError("Your name must not be empty!")
            if client_data.name != original_name:
                self.logger.info("Player tried to log in with name %s, replaced with %s.",
                                 original_name, client_data.name)

            for duplicate_player in self.player_manager.all():
                if duplicate_player.name == client_data.name and duplicate_player.uuid != client_data.uuid:
                    self.logger.info("Got a duplicate player, asking player to change name")
                    raise NameError(
                        "The name of this character is already taken on the server! Please, create a new character with a different name or use Starcheat and change the name.")

            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id,
            )

            return True
        except AlreadyLoggedIn:
            self.reject_with_reason(
                "You're already logged in! If this is not the case, please wait 10 seconds and try again.")
            self.logger.info("Already logged in user tried to log in.")
        except Banned:
            self.reject_with_reason("You have been banned!")
            self.logger.info("Banned user tried to log in.")
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        magic_sector = "AQAAAAwAAAAy+gofAAX14QD/Z2mAAJiWgAUFYWxwaGEMQWxwaGEgU2VjdG9yAAAAELIfhbMFQWxwaGEHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWFscGhhBG5hbWUFDEFscGhhIFNlY3RvcgpzZWN0b3JTZWVkBISWofyWZgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzEucG5nCGh1ZVNoaWZ0BDsGcHJlZml4BQVBbHBoYQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBGJldGELQmV0YSBTZWN0b3IAAADUWh1fvwRCZXRhBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcHAmlkBQRiZXRhBG5hbWUFC0JldGEgU2VjdG9yCnNlY3RvclNlZWQEtYuh6v5+DHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMi5wbmcIaHVlU2hpZnQEAAZwcmVmaXgFBEJldGEPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAVnYW1tYQxHYW1tYSBTZWN0b3IAAADMTMw79wVHYW1tYQcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQHBwJpZAUFZ2FtbWEEbmFtZQUMR2FtbWEgU2VjdG9yCnNlY3RvclNlZWQEs4nM4e9uDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IvMy5wbmcIaHVlU2hpZnQEPAZwcmVmaXgFBUdhbW1hD3dvcmxkUGFyYW1ldGVycwcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQFZGVsdGEMRGVsdGEgU2VjdG9yAAAA1Ooj2GcFRGVsdGEHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWRlbHRhBG5hbWUFDERlbHRhIFNlY3RvcgpzZWN0b3JTZWVkBLWdop7hTgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzQucG5nCGh1ZVNoaWZ0BHgGcHJlZml4BQVEZWx0YQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBHNub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwUGdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkB3NlY3RvcngIWCBTZWN0b3IAAABjhzJHNwFYBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcIAmlkBQdzZWN0b3J4BG5hbWUFCFggU2VjdG9yCnNlY3RvclNlZWQEmPDzkpxuDHNlY3RvclN5bWJvbAUXL2NlbGVzdGlhbC9zZWN0b3IveC5wbmcIaHVlU2hpZnQEgTQIcHZwRm9yY2UDAQZwcmVmaXgFAVgPd29ybGRQYXJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQKBBQOdW5sb2NrZWRCaW9tZXMGDgUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGUFCmdyYXNzbGFuZHMFBW1hZ21hBQl0ZW50YWNsZXMFBnR1bmRyYQUIdm9sY2FuaWMFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZA=="
        unlocked_sector_magic = base64.decodestring(magic_sector.encode("ascii"))
        rejection = build_packet(
            packets.Packets.CONNECT_RESPONSE,
            packets.connect_response().build(
                Container(
                    success=False,
                    client_id=0,
                    reject_reason=reason
                )
            ) + unlocked_sector_magic
        )
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def on_connect_response(self, data):
        try:
            connection_parameters = connect_response().parse(data.data)
            if not connection_parameters.success:
                self.protocol.transport.loseConnection()
            else:
                self.protocol.player.client_id = connection_parameters.client_id
                self.protocol.player.logged_in = True
                self.logger.info("Player %s (UUID: %s, IP: %s) logged in" % (
                    self.protocol.player.name, self.protocol.player.uuid,
                    self.protocol.transport.getPeer().host))
        except:
            self.logger.exception("Exception in on_connect_response, player info may not have been logged.")
        finally:
            return True

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        if 'fuel.max' in world_start['world_properties']:
            self.logger.info("Player %s is now on a ship.", self.protocol.player.name)
            self.protocol.player.on_ship = True
        else:
            coords = world_start.planet['celestialParameters']['coordinate']
            parent_system = coords
            location = parent_system['location']
            l = location
            self.protocol.player.on_ship = False
            planet = Planet(parent_system['sector'], l[0], l[1], l[2],
                            coords['planet'], coords['satellite'])
            self.protocol.player.planet = str(planet)

    def on_client_disconnect(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info("Player disconnected: %s", self.protocol.player.name)
            self.protocol.player.logged_in = False
        return True

    @permissions(UserLevels.ADMIN)
    def delete_player(self, data):
        name = " ".join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                "That player is currently logged in. Refusing to delete logged in character.")
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    "Couldn't find a player named %s. Please check the spelling and try again." % name)
                return False
            self.player_manager.delete(player)
            self.protocol.send_chat_message("Deleted player with name %s." % name)

    @permissions(UserLevels.ADMIN)
    def list_players(self, data):
        if len(data) == 0:
            self.format_player_response(self.player_manager.all())
        else:
            rx = re.sub(r"[\*]", "%", " ".join(data))
            self.format_player_response(self.player_manager.all_like(rx))

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message(
                "Results:\n%s" % "\n".join(
                    ["^cyan;%s: ^yellow;%s" % (player.uuid, player.colored_name(self.config.colors)) for player in
                     players]))
        else:
            self.protocol.send_chat_message(
                "Results:\n%s" % "\n".join(
                    ["^cyan;%s: ^yellow;%s" % (player.uuid, player.colored_name(self.config.colors)) for player in
                     players[:25]]))
            self.protocol.send_chat_message(
                "And %d more. Narrow it down with SQL like syntax. Feel free to use a *, it will be replaced appropriately." % (
                    len(players) - 25))
Exemple #9
0
class PlayerManagerPlugin(SimpleCommandPlugin):
    name = 'player_manager_plugin'
    commands = ['player_list', 'player_delete', 'nick', 'nick_set']

    def activate(self):
        super(PlayerManagerPlugin, self).activate()
        self.player_manager = PlayerManager(self.config)
        self.l_call = LoopingCall(self.check_logged_in)
        self.l_call.start(1, now=False)
        self.regexes = self.config.plugin_config['name_removal_regexes']
        self.adminss = self.config.plugin_config['admin_ss']

    def deactivate(self):
        del self.player_manager

    def check_logged_in(self):
        for player in self.player_manager.who():
            if player.protocol not in self.factory.protocols.keys():
                player.logged_in = False
                player.admin_logged_in = False
                player.party_id = ''

    def on_client_connect(self, data):
        client_data = client_connect().parse(data.data)
        try:
            changed_name = client_data.name

            # Replace problematic chars in client name
            for regex in self.regexes:
                changed_name = re.sub(regex, '', changed_name)

            # If the username is nothing but spaces.
            if not client_data.name.strip():
                raise NameError('Your name must not be empty!')

            # Logging changed username
            if client_data.name != changed_name:
                self.logger.info(
                    'Player tried to log in with name %s, replaced with %s.',
                    client_data.name, changed_name
                )

            changed_player = self.player_manager.get_by_uuid(client_data.uuid)
            if (
                    changed_player is not None and
                    changed_player.name != changed_name
            ):
                self.logger.info(
                    'Got player with changed nickname. Fetching nickname!'
                )
                changed_name = changed_player.name

            duplicate_player = self.player_manager.get_by_org_name(
                client_data.name
            )
            if (
                    duplicate_player is not None and
                    duplicate_player.uuid != client_data.uuid
            ):
                self.logger.info(
                    'CLONE WARNING: {} '
                    'MAY BE TRYING TO IMPERSONATE {}!'.format(
                        self.protocol.transport.getPeer().host,
                        client_data.name
                    )
                )

            if client_data.account == self.adminss:
                admin_login = True
            else:
                admin_login = False

            original_name = client_data.name
            client_data.name = changed_name
            self.protocol.player = self.player_manager.fetch_or_create(
                name=client_data.name,
                org_name=original_name,
                admin_logged_in=admin_login,
                uuid=str(client_data.uuid),
                ip=self.protocol.transport.getPeer().host,
                protocol=self.protocol.id,
            )
            return True

        except AlreadyLoggedIn:
            self.reject_with_reason(
                'You\'re already logged in! If this is not the case, '
                'please wait 10 seconds and try again.'
            )
            self.logger.info('Already logged in user tried to log in.')

        except Banned:
            self.reject_with_reason('You have been banned!')
            self.logger.info('Banned user tried to log in.')
            return False
        except NameError as e:
            self.reject_with_reason(str(e))

    def reject_with_reason(self, reason):
        # here there be magic... ask Carrots or Teihoo about this...
        magic_sector = (
            'AQAAAAwAAAAy+gofAAX14QD/Z2mAAJiWgAUFYWxwaGEMQWxwaGEgU2VjdG9yAAAAE'
            'LIfhbMFQWxwaGEHAgt0aHJlYXRMZXZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQ'
            'RhcmlkBQZkZXNlcnQFBmZvcmVzdAUEc25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9'
            'pZGZpZWxkBwcCaWQFBWFscGhhBG5hbWUFDEFscGhhIFNlY3RvcgpzZWN0b3JTZWVk'
            'BISWofyWZgxzZWN0b3JTeW1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzEucG5nCGh1Z'
            'VNoaWZ0BDsGcHJlZml4BQVBbHBoYQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZX'
            'ZlbAYCBAIEAg51bmxvY2tlZEJpb21lcwYHBQRhcmlkBQZkZXNlcnQFBmZvcmVzdAU'
            'Ec25vdwUEbW9vbgUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBGJldGELQmV0YSBTZWN0'
            'b3IAAADUWh1fvwRCZXRhBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZ'
            'XMGCQUEYXJpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQ'
            'ZqdW5nbGUFBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAcHAmlkBQRiZXRhBG5hbWUFC0J'
            'ldGEgU2VjdG9yCnNlY3RvclNlZWQEtYuh6v5+DHNlY3RvclN5bWJvbAUXL2NlbGVz'
            'dGlhbC9zZWN0b3IvMi5wbmcIaHVlU2hpZnQEAAZwcmVmaXgFBEJldGEPd29ybGRQY'
            'XJhbWV0ZXJzBwILdGhyZWF0TGV2ZWwGAgQEBAQOdW5sb2NrZWRCaW9tZXMGCQUEYX'
            'JpZAUGZGVzZXJ0BQhzYXZhbm5haAUGZm9yZXN0BQRzbm93BQRtb29uBQZqdW5nbGU'
            'FBmJhcnJlbgUNYXN0ZXJvaWRmaWVsZAVnYW1tYQxHYW1tYSBTZWN0b3IAAADMTMw7'
            '9wVHYW1tYQcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbWVzBgoFBGFya'
            'WQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgUGanVuZ2xlBQ'
            'pncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQHBwJpZAUFZ2FtbWEEbmF'
            'tZQUMR2FtbWEgU2VjdG9yCnNlY3RvclNlZWQEs4nM4e9uDHNlY3RvclN5bWJvbAUX'
            'L2NlbGVzdGlhbC9zZWN0b3IvMy5wbmcIaHVlU2hpZnQEPAZwcmVmaXgFBUdhbW1hD'
            '3dvcmxkUGFyYW1ldGVycwcCC3RocmVhdExldmVsBgIEBgQGDnVubG9ja2VkQmlvbW'
            'VzBgoFBGFyaWQFBmRlc2VydAUIc2F2YW5uYWgFBmZvcmVzdAUEc25vdwUEbW9vbgU'
            'GanVuZ2xlBQpncmFzc2xhbmRzBQZiYXJyZW4FDWFzdGVyb2lkZmllbGQFZGVsdGEM'
            'RGVsdGEgU2VjdG9yAAAA1Ooj2GcFRGVsdGEHAgt0aHJlYXRMZXZlbAYCBAgECA51b'
            'mxvY2tlZEJpb21lcwYOBQRhcmlkBQZkZXNlcnQFCHNhdmFubmFoBQZmb3Jlc3QFBH'
            'Nub3cFBG1vb24FBmp1bmdsZQUKZ3Jhc3NsYW5kcwUFbWFnbWEFCXRlbnRhY2xlcwU'
            'GdHVuZHJhBQh2b2xjYW5pYwUGYmFycmVuBQ1hc3Rlcm9pZGZpZWxkBwcCaWQFBWRl'
            'bHRhBG5hbWUFDERlbHRhIFNlY3RvcgpzZWN0b3JTZWVkBLWdop7hTgxzZWN0b3JTe'
            'W1ib2wFFy9jZWxlc3RpYWwvc2VjdG9yLzQucG5nCGh1ZVNoaWZ0BHgGcHJlZml4BQ'
            'VEZWx0YQ93b3JsZFBhcmFtZXRlcnMHAgt0aHJlYXRMZXZlbAYCBAgECA51bmxvY2t'
            '==')
        unlocked_sector_magic = base64.decodestring(
            magic_sector.encode('ascii')
        )
        rejection = build_packet(
            packets.Packets.CONNECT_FAILURE,
            packets.connect_failure().build(
                Container(
                    reject_reason=reason
                )
            ) + unlocked_sector_magic
        )
        self.protocol.transport.write(rejection)
        self.protocol.transport.loseConnection()

    def on_connect_failure(self, data):
        self.protocol.transport.loseConnection()

    def on_connect_success(self, data):
        try:
            connection_parameters = connect_success().parse(data.data)

            self.protocol.player.client_id = connection_parameters.client_id
            self.protocol.player.logged_in = True
            self.protocol.player.party_id = ''
            self.logger.info(
                'Player %s (UUID: %s, IP: %s) logged in',
                self.protocol.player.name,
                self.protocol.player.uuid,
                self.protocol.transport.getPeer().host
            )
        except:
            self.logger.exception(
                'Exception in on_connect_success, '
                'player info may not have been logged.'
            )
        finally:
            return True

    def after_world_start(self, data):
        world_start = packets.world_start().parse(data.data)
        if 'ship.maxFuel' in world_start['world_properties']:
            self.logger.info(
                'Player %s is now on a ship.', self.protocol.player.name
            )
            self.protocol.player.on_ship = True
            self.protocol.player.planet = 'On ship'
        elif world_start.planet['celestialParameters'] is None:
            self.protocol.player.on_ship = False
            self.protocol.player.planet = 'On Outpost'
        else:
            coords = world_start.planet['celestialParameters']['coordinate']
            parent_system = coords
            l = parent_system['location']
            self.protocol.player.on_ship = False
            planet = Planet(l[0], l[1], l[2],
                            coords['planet'], coords['satellite'])
            self.protocol.player.planet = str(planet)

    def on_client_disconnect_request(self, player):
        if self.protocol.player is not None and self.protocol.player.logged_in:
            self.logger.info(
                'Player disconnected: %s', self.protocol.player.name
            )
            self.protocol.player.logged_in = False
            self.protocol.player.admin_logged_in = False
        return True

    @permissions(UserLevels.REGISTERED)
    def nick(self, data):
        """
        Changes your nickname.
        Syntax: /nick (new name)
        """
        if not data:
            self.protocol.send_chat_message(self.nick.__doc__)
            return
        name = ' '.join(data)
        org_name = self.protocol.player.org_name

        # Replace problematic chars in client name
        for regex in self.regexes:
            name = re.sub(regex, '', name)
        if (
                self.player_manager.get_by_name(name) or
                (
                    self.player_manager.get_by_org_name(name) and
                    org_name != name
                )
        ):
            self.protocol.send_chat_message(
                'There\'s already a player by that name.'
            )
        else:
            old_name = self.protocol.player.colored_name(self.config.colors)
            self.protocol.player.name = name
            self.factory.broadcast(
                '{}^green;\'s name has been changed to {}'.format(
                    old_name,
                    self.protocol.player.colored_name(self.config.colors)
                )
            )

    @permissions(UserLevels.ADMIN)
    def nick_set(self, data):
        """
        Changes player nickname.
        Syntax: /nick_set (name) (new name)
        """
        if not data:
            self.protocol.send_chat_message(self.nick_set.__doc__)
            return

        try:
            first_name, rest = extract_name(data)

            # Replace problematic chars in client name
            for regex in self.regexes:
                first_name = re.sub(regex, '', first_name)
        except ValueError:
            self.protocol.send_chat_message(
                'Name not recognized. If it has spaces, '
                'please surround it by quotes!'
            )
            return

        if not rest:
            self.protocol.send_chat_message(self.nick_set.__doc__)
            return
        else:
            try:
                second_name = extract_name(rest)[0]

                # Replace problematic chars in client name
                for regex in self.regexes:
                    second_name = re.sub(regex, '', second_name)
            except ValueError:
                self.protocol.send_chat_message(
                    'New name not recognized. If it has spaces, '
                    'please surround it by quotes!'
                )
                return

        player = self.player_manager.get_by_name(str(first_name))
        player2 = self.player_manager.get_by_name(str(second_name))
        org_player = self.player_manager.get_by_org_name(str(first_name))
        org_player2 = self.player_manager.get_by_org_name(str(second_name))

        if player:
            first_uuid = player.uuid
        elif org_player:
            first_uuid = org_player.uuid
        if player2:
            second_uuid = player2.uuid
        elif org_player2:
            second_uuid = org_player2.uuid
        if player or org_player:
            if (player2 or org_player2) and first_uuid != second_uuid:
                self.protocol.send_chat_message(
                    'There\'s already a player by that name.'
                )
            else:
                old_name = player.colored_name(self.config.colors)
                player.name = second_name
                self.factory.broadcast(
                    '{}^green;\'s name has been changed to {}'.format(
                        old_name, player.colored_name(self.config.colors)
                    )
                )

    @permissions(UserLevels.ADMIN)
    def player_delete(self, data):
        """
        Delete a player from database.
        Syntax: /player_del (player)
        """
        if not data:
            self.protocol.send_chat_message(self.player_del.__doc__)
            return
        name = ' '.join(data)
        if self.player_manager.get_logged_in_by_name(name) is not None:
            self.protocol.send_chat_message(
                'That player is currently logged in. '
                'Refusing to delete logged in character.'
            )
            return False
        else:
            player = self.player_manager.get_by_name(name)
            if player is None:
                self.protocol.send_chat_message(
                    'Couldn\'t find a player named {}. '
                    'Please check the spelling and try again.'.format(name)
                )
                return False
            self.player_manager.delete(player)
            self.protocol.send_chat_message(
                'Deleted player with name {}.'.format(name)
            )

    @permissions(UserLevels.ADMIN)
    def player_list(self, data):
        """
        List registered players on the server.
        Syntax: /player_list [search term]
        """
        if not data:
            self.format_player_response(self.player_manager.all())
        else:
            rx = re.sub(r'[\*]', '%', ' '.join(data))
            self.format_player_response(self.player_manager.all_like(rx))

    def format_player_response(self, players):
        if len(players) <= 25:
            self.protocol.send_chat_message(
                'Results:\n%s'.format(
                    '\n'.join(
                        [
                            PLAYER_PATTER.format(
                                player.uuid,
                                player.colored_name(self.config.colors),
                                player.org_name
                            )
                            for player in players
                        ]
                    )
                )
            )
        else:
            self.protocol.send_chat_message(
                'Results:\n{}'.format(
                    '\n'.join(
                        [
                            PLAYER_PATTER.format(
                                player.uuid,
                                player.colored_name(self.config.colors),
                                player.org_name
                            )
                            for player in players[:25]
                        ]
                    )
                )
            )
            self.protocol.send_chat_message(
                'And {} more. Narrow it down with SQL like syntax. Feel free '
                'to use a *, it will be replaced appropriately.'.format(
                    len(players) - 25
                )
            )