<commit_before>from . import network, packer, builtin_tables
import bge
import logging


class ServerHost:

    server = True

    def __init__(self, interface='', port=54303, version=0, maxclients=10):
        builtin_tables.define()

        # Handy for server lists
        self.port = port
        self.version = version
        self.maxclients = maxclients

        # Client ID == enet peer ID
        self.clients = [None] * maxclients
        self.components = [None] * 65535
        self.last_component = 0 # Saves some iteration while looping

        if network is None:
            # No compatible network library was supplied
            self.network = None
            logging.warning('Enet not found.  Network play is disabled.')
        else:
            self.network = network.ENetWrapper(
                server=True, interface=interface, port=port,
                maxclients=maxclients)

            logging.info('Server started')

    def assignComponentID(self, component):
        i = 0
        for comp in self.components:
            if comp is None:
                self.components[i] = component
                component.net_id = i
                self.last_component = i
                return

            i += 1

    def onConnect(self, peer_id):
        """
        Override this
        """
        return

    def onDisconnect(self, peer_id):
        """
        Override this
        """
        return

    def _addClient(self, peer):
        peerID = peer.incomingPeerID
        if self.clients[peerID] is not None:
            logging.error('Client ID in use: {}'.format(peerID))
            peer.reset()
            return

        client = _Client(peer)
        self.clients[peerID] = client

        # Send everything!
        i = 0
        for comp in self.components:
            if i > self.last_component:
                break

            i += 1

            if comp is None:
                continue

            client.send_reliable(comp.serialize())

        # User-defined
        self.onConnect(peerID)

    def _removeClient(self, peerID):
        # Assumes peer was already disconnected
        if self.clients[peerID] is None:
            logging.error('Client was already removed')
            return

        self.clients[peerID] = None

        # User-defined
        self.onDisconnect(peerID)

    def _update_components(self):
        i = 0
        last = self.last_component
        for comp in self.components:
            if i > last:
                return

            i += 1

            if comp is None:
                continue

            comp.update()
            comp.update_server()

    def update(self):
        self._update_components()

        if self.network is None:
            # Flush queued data
            return

        event_backlog = []
        if self.network.threaded:
            event_backlog = self.network.disableThreading()

        while True:
            if len(event_backlog):
                event = event_backlog.popleft()
            else:
                event = self.network._host.service(0)

            if event.type == 0:
                break

            elif event.type == network.EVENT_TYPE_CONNECT:
                logging.info("{} connecting".format(event.peer.address))
                ## TODO - check version
                self._addClient(event.peer)

            elif event.type == network.EVENT_TYPE_DISCONNECT:
                logging.info("{} disconnecting".format(event.peer.address))
                self._removeClient(event.peer)

            elif event.type == network.EVENT_TYPE_RECEIVE:
                peerID = event.peer.incomingPeerID
                bufflist = packer.unjoin_buffers(event.packet.data)

                for buff in bufflist:
                    table = packer.to_table(buff)
                    # Find the component by ID
                    component = self.components[table.get('id')]

                    if component is None:
                        logging.info('Received data for a non-existent component.  This is acceptable for unreliable data.')
                        continue

                    # Check for permissions
                    if peerID in component.permissions:
                        # Run the associated method
                        getattr(component, table.tableName())(table)
                    else:
                        logging.warning('Client does not have input permission')<commit_msg>Fix client disconnection<commit_after>from . import network, packer, builtin_tables
import bge
import logging


class ServerHost:

    server = True

    def __init__(self, interface='', port=54303, version=0, maxclients=10):
        builtin_tables.define()

        # Handy for server lists
        self.port = port
        self.version = version
        self.maxclients = maxclients

        # Client ID == enet peer ID
        self.clients = [None] * maxclients
        self.components = [None] * 65535
        self.last_component = 0 # Saves some iteration while looping

        if network is None:
            # No compatible network library was supplied
            self.network = None
            logging.warning('Enet not found.  Network play is disabled.')
        else:
            self.network = network.ENetWrapper(
                server=True, interface=interface, port=port,
                maxclients=maxclients)

            logging.info('Server started')

    def assignComponentID(self, component):
        i = 0
        for comp in self.components:
            if comp is None:
                self.components[i] = component
                component.net_id = i
                self.last_component = i
                return

            i += 1

    def onConnect(self, peer_id):
        """
        Override this
        """
        return

    def onDisconnect(self, peer_id):
        """
        Override this
        """
        return

    def _addClient(self, peer):
        peerID = peer.incomingPeerID
        if self.clients[peerID] is not None:
            logging.error('Client ID in use: {}'.format(peerID))
            peer.reset()
            return

        client = _Client(peer)
        self.clients[peerID] = client

        # Send everything!
        i = 0
        for comp in self.components:
            if i > self.last_component:
                break

            i += 1

            if comp is None:
                continue

            client.send_reliable(comp.serialize())

        # User-defined
        self.onConnect(peerID)

    def _removeClient(self, peerID):
        # Assumes peer was already disconnected
        if self.clients[peerID] is None:
            logging.error('Client was already removed')
            return

        self.clients[peerID] = None

        # User-defined
        self.onDisconnect(peerID)

    def _update_components(self):
        i = 0
        last = self.last_component
        for comp in self.components:
            if i > last:
                return

            i += 1

            if comp is None:
                continue

            comp.update()
            comp.update_server()

    def update(self):
        self._update_components()

        if self.network is None:
            # Flush queued data
            return

        event_backlog = []
        if self.network.threaded:
            event_backlog = self.network.disableThreading()

        while True:
            if len(event_backlog):
                event = event_backlog.popleft()
            else:
                event = self.network._host.service(0)

            if event.type == 0:
                break

            elif event.type == network.EVENT_TYPE_CONNECT:
                logging.info("{} connecting".format(event.peer.address))
                ## TODO - check version
                self._addClient(event.peer)

            elif event.type == network.EVENT_TYPE_DISCONNECT:
                logging.info("{} disconnecting".format(event.peer.address))
                peerID = event.peer.incomingPeerID
                self._removeClient(peerID)

            elif event.type == network.EVENT_TYPE_RECEIVE:
                peerID = event.peer.incomingPeerID
                bufflist = packer.unjoin_buffers(event.packet.data)

                for buff in bufflist:
                    table = packer.to_table(buff)
                    # Find the component by ID
                    component = self.components[table.get('id')]

                    if component is None:
                        logging.info('Received data for a non-existent component.  This is acceptable for unreliable data.')
                        continue

                    # Check for permissions
                    if peerID in component.permissions:
                        # Run the associated method
                        getattr(component, table.tableName())(table)
                    else:
                        logging.warning('Client does not have input permission')
{'fraction_non_alphanumeric': 0.07772596047079725, 'fraction_numerical': 0.004885631801021541, 'mean_word_length': 1.4629477713973202, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7342307', 'n_tokens_mistral': 2373, 'n_tokens_neox': 2189, 'n_words': 599}