Ejemplo n.º 1
0
    def _listen(self):
        current_string = ''
        escape_level = 0
        is_escaped = False
        is_string = False

        while self.running:
            reqs = []
            output = []
            try:
                data = self.parent.connection.recv(4096).decode('UTF-8')

                if type(data) is not str:
                    print(data)

                #unpack the data - often will get multiple dictionaries
                for char in data:
                    if char == '{' and not is_escaped and not is_string:
                        escape_level += 1

                    elif char == '}' and not is_escaped and not is_string:
                        escape_level -= 1

                    elif char == '"' and not is_escaped:
                        is_string = not is_string

                    elif char == '\\':
                        is_escaped = not is_escaped

                    if not char == '\\':
                        is_escaped = False

                    current_string += char
                    if escape_level == 0 and not len(current_string) == 0:
                        output.append(current_string)
                        current_string = ''

                for json_data in output:
                    reqs.append(Request(json_data))

            except (ConnectionResetError, ConnectionAbortedError):
                reqs.append(
                    Request(command='disconnect', arguments={'clean': False})
                )  #argument 'clean' shows whether or not a message was sent to close the connection or the conenction was forcibly closed
                self.running = False

            except json.JSONDecodeError:
                pass

            for bind in self.binds:
                for req in reqs:
                    bind(req)

        self.parent.connection.close()
Ejemplo n.º 2
0
    def var_update(self, mode, category, to_write):
        if type(to_write) is not dict:
            to_write = {'value': to_write}

        if mode.lower().startswith('r'):
            self.send(Request(command='var update r', subcommand=category))

        elif mode.lower().startswith('w'):
            self.send(
                Request(command='var update w',
                        subcommand=category,
                        arguments=to_write))
Ejemplo n.º 3
0
 def tell_use_accurate_hitscan(self, use_accurate_hitscan):
     self.send(
         Request(command='set hit model',
                 subcommand={
                     True: 'accurate',
                     False: 'loose'
                 }[use_accurate_hitscan]))
Ejemplo n.º 4
0
 def use_item(self, item, rotation, position, slot):
     self.send(
         Request(command='use',
                 subcommand='client item',
                 arguments={
                     'item': item,
                     'rotation': rotation,
                     'position': position,
                     'slot': slot
                 }))
Ejemplo n.º 5
0
    def on_death(self, weapon, killer):
        self.metadata.health = 0

        #send death message to all connected clients
        s = random.choice(self.server.settingsdata['messages']['killfeed'])
        self.send_all(
            Request(command='event',
                    subcommand='death',
                    arguments={
                        'text':
                        s.format(weapon=weapon.lower(),
                                 killer=killer,
                                 victim=self.metadata.username),
                        'weapon':
                        weapon.lower()
                    }))
        self.output_console('Player {} died'.format(self.metadata.username))

        self.set_mode('spectator')

        if self.lobby.gamemode == 0:
            alive = self.lobby.num_alive()

            if alive[0] == 0:
                self.lobby.round_ended(winner=1)
            elif alive[1] == 0:
                self.lobby.round_ended(winner=0)

        elif self.lobby.gamemode == 1:
            self.respawn_after(self.server.settingsdata['player']['gamemodes']
                               ['deathmatch']['respawn time'])

        elif self.lobby.gamemode == 2:
            if self.metadata.team_id == 0:
                self.lobby.increment_scoreline(score0=1)
            elif self.metadata.team_id == 1:
                self.lobby.increment_scoreline(score1=1)

            self.respawn_after(self.server.settingsdata['player']['gamemodes']
                               ['team deathmatch']['respawn time'])

        elif self.lobby.gamemode == 3:
            self.respawn_after(self.server.settingsdata['player']['gamemodes']
                               ['pve surival']['respawn time'])
Ejemplo n.º 6
0
    def set_mode(self, mode):
        self.send(Request(command='set mode', subcommand=mode))

        self.metadata.mode = mode

        if self.metadata.mode == 'spectator':
            self.client_display_text(['chat', 'new mode', 'spectator'],
                                     [self.metadata.username])
            self.output_console('{} is now spectating'.format(
                self.metadata.username))
        elif self.metadata.mode == 'player':
            self.client_display_text(['chat', 'new mode', 'player'],
                                     [self.metadata.username])
            self.output_console('{} is now playing'.format(
                self.metadata.username))

            for client in self.server.clients:
                if client.metadata.active:
                    self.push_positions()
Ejemplo n.º 7
0
 def notify_map_load_finished(self):
     self.send(Request(command='map loaded'))
Ejemplo n.º 8
0
 def say(self, text):
     self.send(Request(command='say', arguments={'text': text}))
Ejemplo n.º 9
0
    def handle(self, req):
        if req.command == 'disconnect':  #client wants to cleanly end it's connection with the server
            self.output_console('User {} disconnected'.format(
                self.interface.address[0]))
            if 'clean' in req.arguments and not req.arguments['clean']:
                self.output_console('Disconnect was not clean')

        elif req.command == 'lobby':
            if req.subcommand == 'join':
                self.server.join_lobby(self, req.arguments['index'])

            elif req.subcommand == 'list':
                self.send(
                    Request(command='lobby response',
                            subcommand='list',
                            arguments={
                                'lobbies':
                                self.server.list_lobbies(show_inactive=False)
                            }))

        if self.lobby is None:  #player is in the menu, not a lobby
            if req.command == 'say':
                self.send_all(Request(command='say',
                                      arguments={
                                          'text':
                                          '{}: {}'.format(
                                              self.metadata.username,
                                              req.arguments['text'])
                                      }),
                              only_lobby=False)

            elif req.command == 'db read':
                if req.subcommand == 'leaderboard':
                    self.send(
                        Request(command='db read response',
                                subcommand='leaderboard',
                                arguments={
                                    'data':
                                    self.server.database.get_leaderboard(
                                        req.arguments['num'])
                                }))

            elif req.command == 'db write':
                pass

        else:  #player is in a lobby
            if req.command == 'var update r':  #client wants the server to send it a value
                if req.subcommand == 'map':  #client wants the server to send the name of the current map
                    self.write_var('map', {'map name': self.lobby.map.name})

                elif req.subcommand == 'player model':  #client wants to know it's own player model
                    if self.lobby.map.name is not None:
                        self.write_var('player model', self.metadata.model)

                elif req.subcommand == 'health':
                    self.write_var('health', self.metadata.health)

                elif req.subcommand == 'all player positions':  #client wants to see all player positions (players marked as "active")
                    self.push_positions()

                elif req.subcommand == 'round time':
                    self.write_var('round time', self.lobby.get_timeleft())

            elif req.command == 'var update w':  #client wants to update a variable on the server
                if req.subcommand == 'position':  #client wants to update it's own position
                    self.metadata.pos.x = req.arguments['x']
                    self.metadata.pos.y = req.arguments['y']
                    self.metadata.pos.rotation = req.arguments['rotation']

                elif req.subcommand == 'health':  #client wants to update it's own health
                    self.update_health(req.arguments['value'],
                                       weapon='environment',
                                       killer='world')

                elif req.subcommand == 'username':
                    self.output_console('{} changed name to {}'.format(
                        self.metadata.username, req.arguments['value']))
                    self.metadata.username = req.arguments['value']
                    self.server.database.user_connected(self.metadata.username)
                    self.client_display_text(['chat', 'client changed name'],
                                             [self.metadata.username])

            elif req.command == 'map loaded':  #client has loaded the map and wants to be given the starting items and other information
                self.give(self.lobby.map.data['player']['starting items'][
                    self.metadata.team_id])
                print(self.lobby.map.data['player']['starting items'][
                    self.metadata.team_id])
                self.write_var('team', self.metadata.team_id)
                self.read_var('username')
                self.set_mode('player')

                spawnpoint = self.generate_spawn()
                self.setpos(spawnpoint[0], spawnpoint[1], 0)

                self.tell_use_accurate_hitscan(
                    self.server.settingsdata['network']
                    ['accurate hit detection'])

                self.client_display_text(['fullscreen', 'welcome'],
                                         None,
                                         category='welcome')

            elif req.command == 'use' and req.arguments[
                    'item'] in self.lobby.items.dicts:
                if self.metadata.item_use_timestamp is None or (time.time(
                ) - self.metadata.item_use_timestamp) > self.lobby.items.dicts[
                        req.arguments['item']]['use cooldown']:
                    obj = self.lobby.items.scripts[self.lobby.items.dicts[
                        req.arguments['item']]['control script']](
                            req.arguments['item'], self.lobby)

                    obj.attributes.creator = self
                    obj.attributes.pos.x = req.arguments['position'][0]
                    obj.attributes.pos.y = req.arguments['position'][1]
                    obj.attributes.rotation = req.arguments['rotation']
                    obj.attributes.ticket = self.lobby.items.ticket
                    obj.set_velocity(
                        self.lobby.items.dicts[req.arguments['item']]['speed'])

                    self.lobby.items.objects.append(obj)

                    self.lobby.items.ticket += 1
                    self.metadata.item_use_timestamp = time.time()

                    self.send(
                        Request(command='increment inventory slot',
                                arguments={
                                    'index': req.arguments['slot'],
                                    'increment': -1
                                }))

            elif req.command == 'say':
                self.send_all(
                    Request(command='say',
                            arguments={
                                'text':
                                '{}: {}'.format(self.metadata.username,
                                                req.arguments['text'])
                            }))
Ejemplo n.º 10
0
 def push_positions(self):
     self.send(
         Request(
             command='var update w',
             subcommand='player positions',
             arguments={'positions': self.lobby.get_all_positions([self])}))
Ejemplo n.º 11
0
 def join_lobby(self, index):
     self.send(
         Request(command='lobby',
                 subcommand='join',
                 arguments={'index': index}))
Ejemplo n.º 12
0
 def clear_inventory(self):
     self.send(Request(command='clear inventory'))
Ejemplo n.º 13
0
 def give(self, items):
     self.send(Request(command='give', arguments={'items': items}))
Ejemplo n.º 14
0
 def read_db(self, read_from, arguments={}):
     self.send(
         Request(command='db read',
                 subcommand=read_from,
                 arguments=arguments))
Ejemplo n.º 15
0
 def push_item_states(self, states):
     self.send(
         Request(command='update items',
                 subcommand='server tick',
                 arguments={'pushed': states}))
Ejemplo n.º 16
0
    def write_db(self, write_to, data):
        if type(data) is not dict:
            data = {'data': data}

        self.send(
            Request(command='db write', subcommand=write_to, arguments=data))
Ejemplo n.º 17
0
 def list_lobbies(self):
     self.send(Request(command='lobby', subcommand='list'))