Beispiel #1
0
def main():
    print('Running on Python %s' % sys.version)

    try:
        udp_proxy_proc1 = sp.Popen('udpproxy.exe %d' % GAME_PORT1)
        udp_proxy_proc2 = sp.Popen('udpproxy.exe %d' % GAME_PORT2)

    except OSError as e:
        print(
            'Failed to run udpproxy.exe. Run download_udpproxy.py to download it\n'
            'or build it yourself using the Visual Studio solution in the udpproxy\n'
            'subdirectory and place it in the taserver directory.\n',
            file=sys.stderr)
        return

    server_queue = gevent.queue.Queue()
    firewall = Firewall()
    gevent_spawn('firewall.run', firewall.run, server_queue)

    def handle_client(socket, address):
        msg = TcpMessageReader(socket).receive()
        command = json.loads(msg.decode('utf8'))
        server_queue.put(command)

    server = StreamServer(('127.0.0.1', 9801), handle_client)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        firewall.remove_all_rules()

    udp_proxy_proc1.terminate()
    udp_proxy_proc2.terminate()
Beispiel #2
0
def main():
    set_up_logging('authbot.log')
    logger = logging.getLogger(__name__)
    config = configparser.ConfigParser()
    with open(INI_PATH) as f:
        config.read_file(f)

    restart = True
    restart_delay = 10
    tasks = []
    try:
        while restart:
            incoming_queue = gevent.queue.Queue()

            tasks = [
                gevent_spawn("authbot's handle_authbot", handle_authbot,
                             config['authbot'], incoming_queue),
                gevent_spawn("authbot's handle_hirez_login_server",
                             handle_hirez_login_server, config['authbot'],
                             incoming_queue),
            ]

            # Wait for any of the tasks to terminate
            finished_greenlets = gevent.joinall(tasks, count=1)

            logger.warning('The following greenlets terminated: %s' %
                           ','.join([g.name for g in finished_greenlets]))

            fatal_errors = [
                '  %s' % g.exception for g in finished_greenlets
                if isinstance(g.exception, FatalError)
            ]
            if fatal_errors:
                logger.critical(
                    '\n' + '\n-------------------------------------------\n' +
                    'The following fatal errors occurred:\n' +
                    '\n'.join(fatal_errors) +
                    '\n-------------------------------------------\n')
                restart = False

            logger.info('Killing all tasks...')
            gevent.killall(tasks)
            logger.info('Waiting %s seconds before %s...' %
                        (restart_delay,
                         ('restarting' if restart else 'exiting')))
            gevent.sleep(restart_delay)

    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Exiting...')
        gevent.killall(tasks)
    except Exception:
        logger.exception('Main authbot thread exited with an exception')
Beispiel #3
0
def main():
    print('Running on Python %s' % sys.version)
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--data-root',
        action='store',
        default='data',
        help='Location of the data dir containing all config files and logs.')
    args = parser.parse_args()
    data_root = args.data_root

    config = configparser.ConfigParser()
    with open(get_shared_ini_path(data_root)) as f:
        config.read_file(f)

    ports = Ports(int(config['shared']['port_offset']))

    try:
        udp_proxy_proc1 = sp.Popen('udpproxy.exe %d' % ports['gameserver1'])
        udp_proxy_proc2 = sp.Popen('udpproxy.exe %d' % ports['gameserver2'])

    except OSError as e:
        print(
            'Failed to run udpproxy.exe. Run download_udpproxy.py to download it\n'
            'or build it yourself using the Visual Studio solution in the udpproxy\n'
            'subdirectory and place it in the taserver directory.\n',
            file=sys.stderr)
        return

    server_queue = gevent.queue.Queue()
    firewall = Firewall(ports, data_root)
    gevent_spawn('firewall.run', firewall.run, server_queue)

    def handle_client(socket, address):
        msg = TcpMessageReader(socket).receive()
        command = json.loads(msg.decode('utf8'))
        server_queue.put(command)

    server = StreamServer(('127.0.0.1', ports['firewall']), handle_client)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        firewall.remove_all_rules()

    udp_proxy_proc1.terminate()
    udp_proxy_proc2.terminate()
    def _handle(self, sock, address):
        gevent.getcurrent().name = self.task_name
        task_id = id(gevent.getcurrent())
        self.logger.info('%s(%s): connected' % (self.task_name, task_id))

        reader, writer, peer = self.create_connection_instances(sock, address)

        if not isinstance(peer, Peer) or \
           not isinstance(reader, ConnectionReader) or \
           not isinstance(writer, ConnectionWriter):
            raise TypeError(
                'create_connection_instances should return a 3-tuple of instances of subclasses '
                'of ConnectionReader, ConnectionWriter and Peer respectively')

        if type(peer) is Peer:
            raise TypeError(
                'You should create an instance of a specific subclass of Peer in '
                'create_connection_instances not an instance of Peer itself, because '
                'the instance will be sent as part of Connected/Disconnected messages '
                'and the type is the only way to distinguish between messages from '
                'different ConnectionHandlers.')

        outgoing_queue = gevent.queue.Queue()

        peer.task_id = task_id
        peer.task_name = self.task_name
        peer.outgoing_queue = outgoing_queue

        reader.task_id = task_id
        reader.task_name = self.task_name
        reader.incoming_queue = self.incoming_queue
        reader.peer = peer

        writer.task_id = task_id
        writer.task_name = self.task_name
        writer.outgoing_queue = outgoing_queue

        tasks = [
            gevent_spawn("%s(%s)'s reader" % (self.task_name, task_id),
                         reader.run),
            gevent_spawn("%s(%s)'s writer" % (self.task_name, task_id),
                         writer.run)
        ]

        gevent.joinall(tasks)
    def start_server_process(self, server):
        external_port = self.ports[server]
        internal_port = self.ports[f'{server}proxy']
        log_filename = os.path.join(self.get_my_documents_folder(), 'My Games',
                                    'Tribes Ascend', 'TribesGame', 'Logs',
                                    'tagameserver%d.log' % external_port)

        try:
            self.logger.info(
                f'{server}: removing previous log file {log_filename}')
            os.remove(log_filename)
        except FileNotFoundError:
            pass

        self.logger.info(
            f'{server}: starting a new TribesAscend server on port {external_port}...'
        )
        # Add 100 to the port, because it's the udpproxy that's actually listening on the port itself
        # and it forwards traffic to port + 100
        args = [
            self.exe_path, 'server',
            '-Log=tagameserver%d.log' % external_port,
            '-port=%d' % internal_port, '-controlport',
            str(self.ports['game2launcher'])
        ]
        if self.dll_config_path is not None:
            args.extend(['-tamodsconfig', self.dll_config_path])
        process = sp.Popen(args, cwd=self.working_dir)
        self.servers[server] = process
        self.logger.info(f'{server}: started process with pid {process.pid}')

        # Check if it doesn't exit right away
        time.sleep(2)
        ret_code = process.poll()
        if ret_code:
            raise FatalError(
                'The game server process terminated almost immediately with exit code %08X'
                % ret_code)

        self.logger.info(
            f'{server}: waiting until game server has finished starting up...')
        if not self.wait_until_file_contains_string(
                log_filename, 'Log: Bringing up level for play took:',
                timeout=30):
            self.logger.warning(
                f'{server}: timeout waiting for log entry, continuing with injection...'
            )

        self.logger.info(
            f'{server}: injecting game controller DLL into game server...')
        inject(process.pid, self.dll_to_inject)
        self.logger.info(f'{server}: injection done.')

        self.watcher_task = gevent_spawn(
            'gameserver process watcher for server %s' % server,
            self.server_process_watcher, process, server)
Beispiel #6
0
def main():
    print('Running on Python %s' % sys.version)

    config = configparser.ConfigParser()
    with open(INI_PATH) as f:
        config.read_file(f)

    ports = Ports(int(config['shared']['port_offset']))

    try:
        wine64env = os.environ.copy()
        wine64env['WINEPREFIX'] = '/home/tribes/.wine64'
        udp_proxy_proc1 = sp.Popen('udpproxy.exe %d' % ports['gameserver1'],
                                   env=wine64env)
        udp_proxy_proc2 = sp.Popen('udpproxy.exe %d' % ports['gameserver2'],
                                   env=wine64env)

    except OSError as e:
        print(
            'Failed to run udpproxy.exe. Run download_udpproxy.py to download it\n'
            'or build it yourself using the Visual Studio solution in the udpproxy\n'
            'subdirectory and place it in the taserver directory.\n',
            file=sys.stderr)
        return

    server_queue = gevent.queue.Queue()
    firewall = Firewall(ports)
    gevent_spawn('firewall.run', firewall.run, server_queue)

    def handle_client(socket, address):
        msg = TcpMessageReader(socket).receive()
        command = json.loads(msg.decode('utf8'))
        server_queue.put(command)

    server = StreamServer(('127.0.0.1', ports['firewall']), handle_client)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        firewall.remove_all_rules()

    udp_proxy_proc1.terminate()
    udp_proxy_proc2.terminate()
Beispiel #7
0
def main():
    set_up_logging('login_server.log')
    logger = logging.getLogger(__name__)
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--dump', action='store_true',
                        help='Dump all traffic to %s in a format suitable '
                             'for parsing with the parse.py utility.' %
                             dumpfilename)
    args = parser.parse_args()

    # Perform data migrations on startup
    try:
        run_migrations('data')
    except ValueError as e:
        # If a migration failed, it will raise a ValueError
        logger.fatal('Failed to run data migrations with format error: %s' % str(e))
        sys.exit(2)
    except OSError as e:
        # If a migration failed, it will raise a ValueError
        logger.fatal('Failed to run data migrations with OS error: %s' % str(e))
        sys.exit(2)
    
    client_queues = {}
    server_queue = gevent.queue.Queue()
    server_stats_queue = gevent.queue.Queue()
    dump_queue = gevent.queue.Queue() if args.dump else None

    accounts = Accounts('data/accountdatabase.json')
    config = configparser.ConfigParser()
    with open(INI_PATH) as f:
        config.read_file(f)
    with open(SHARED_INI_PATH) as f:
        config.read_file(f)

    ports = Ports(int(config['shared']['port_offset']))

    tasks = [
        gevent_spawn("login server's handle_server",
                     handle_server,
                     server_queue,
                     client_queues,
                     server_stats_queue,
                     ports,
                     accounts),
        gevent_spawn("login server's handle_authcodes",
                     handle_authcodes,
                     server_queue),
        gevent_spawn("login server's handle_webhook",
                     handle_webhook,
                     server_stats_queue,
                     config['loginserver']),
        gevent_spawn("login server's handle_http",
                     handle_http,
                     server_queue,
                     ports),
        gevent_spawn("login server's handle_game_client",
                     handle_game_client,
                     server_queue, dump_queue),
        gevent_spawn("login server's handle_game_server_launcher",
                     handle_game_server_launcher,
                     server_queue,
                     ports)
    ]
    # Give the greenlets enough time to start up, otherwise killall can block
    gevent.sleep(1)

    if dump_queue:
        tasks.append(gevent_spawn("login server's handle_dump", handle_dump, dump_queue))

    try:
        # Wait for any of the tasks to terminate
        finished_greenlets = gevent.joinall(tasks, count=1)

        logger.error('The following greenlets terminated: %s' % ','.join([g.name for g in finished_greenlets]))

        exceptions = ['  %s' % g.exception for g in finished_greenlets
                                if isinstance(g.exception, Exception)]
        if exceptions:
            logger.critical('\n' +
                            '\n-------------------------------------------\n' +
                            'The following exceptions occurred:\n' +
                            '\n'.join(exceptions) +
                            '\n-------------------------------------------\n'
                            )

        if dump_queue:
            logger.info('Giving the dump greenlet some time to finish writing to disk...')
            gevent.sleep(2)

        logger.info('Killing everything and waiting 10 seconds before exiting...')
        gevent.killall(tasks)
        gevent.sleep(5)

    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Exiting...')
        gevent.killall(tasks)
        accounts.save()
    except Exception:
        logger.exception('Main login server thread exited with an exception')
Beispiel #8
0
def main():
    set_up_logging('game_server_launcher.log')
    logger = logging.getLogger(__name__)
    config = configparser.ConfigParser()
    with open(LAUNCHER_INI_PATH) as f:
        config.read_file(f)
    with open(SHARED_INI_PATH) as f:
        config.read_file(f)

    ports = Ports(int(config['shared']['port_offset']))

    restart = True
    restart_delay = 10
    tasks = []
    try:
        while restart:
            incoming_queue = gevent.queue.Queue()
            server_handler_queue = gevent.queue.Queue()

            tasks = [
                gevent_spawn("game server launcher's handle_ping", handle_ping,
                             ports),
                gevent_spawn("game server launcher's handle_game_server",
                             handle_game_server, config['gameserver'], ports,
                             server_handler_queue, incoming_queue),
                gevent_spawn("game server launcher's handle_login_server",
                             handle_login_server, config['loginserver'],
                             incoming_queue),
                gevent_spawn("game server launcher's handle_game_controller",
                             handle_game_controller, ports, incoming_queue),
                gevent_spawn("game server launcher's handle_launcher",
                             handle_launcher, config['gameserver'], ports,
                             incoming_queue, server_handler_queue)
            ]
            # Give the greenlets enough time to start up, otherwise killall can block
            gevent.sleep(1)

            # Wait for any of the tasks to terminate
            finished_greenlets = gevent.joinall(tasks, count=1)

            logger.warning('The following greenlets terminated: %s' %
                           ','.join([g.name for g in finished_greenlets]))

            fatal_errors = [
                '  %s' % g.exception for g in finished_greenlets
                if isinstance(g.exception, FatalError)
            ]
            if fatal_errors:
                logger.critical(
                    '\n' + '\n-------------------------------------------\n' +
                    'The following fatal errors occurred:\n' +
                    '\n'.join(fatal_errors) +
                    '\n-------------------------------------------\n')
                restart = False

            logger.info('Killing all tasks...')
            gevent.killall(tasks)
            logger.info('Waiting %s seconds before %s...' %
                        (restart_delay,
                         ('restarting' if restart else 'exiting')))
            gevent.sleep(restart_delay)

    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Exiting...')
        gevent.killall(tasks)
    except Exception:
        logger.exception(
            'Main game server launcher thread exited with an exception')
Beispiel #9
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--data-root',
        action='store',
        default='data',
        help='Location of the data dir containing all config files and logs.')
    args = parser.parse_args()
    data_root = args.data_root
    set_up_logging(data_root, 'authbot.log')
    logger = logging.getLogger(__name__)
    config = configparser.ConfigParser()
    with open(os.path.join(data_root, INI_FILE)) as f:
        config.read_file(f)

    # We're only gonna use fixed ports, so no need to read port offset from the config
    ports = Ports(0)

    restart = True
    tasks = []
    try:
        while restart:
            incoming_queue = gevent.queue.Queue()

            tasks = [
                gevent_spawn("authbot's handle_authbot", handle_authbot,
                             config['authbot'], incoming_queue),
                gevent_spawn("authbot's handle_hirez_login_server",
                             handle_hirez_login_server, config['authbot'],
                             ports, incoming_queue),
                gevent_spawn("authbot's handle_community_login_server",
                             handle_community_login_server, ports,
                             incoming_queue),
            ]

            # Wait for any of the tasks to terminate
            finished_greenlets = gevent.joinall(tasks, count=1)

            logger.warning('The following greenlets terminated: %s' %
                           ','.join([g.name for g in finished_greenlets]))

            restart_delay = 10

            fatal_errors = [
                '  %s' % g.exception for g in finished_greenlets
                if isinstance(g.exception, FatalError)
            ]
            if fatal_errors:
                logger.critical(
                    '\n' + '\n-------------------------------------------\n' +
                    'The following fatal errors occurred:\n' +
                    '\n'.join(fatal_errors) +
                    '\n-------------------------------------------\n')
                restart = False

            major_errors = [
                '  %s' % g.exception for g in finished_greenlets
                if isinstance(g.exception, MajorError)
            ]
            if major_errors:
                logger.critical(
                    '\n' + '\n-------------------------------------------\n' +
                    'The following major errors occurred:\n' +
                    '\n'.join(major_errors) +
                    '\n-------------------------------------------\n')
                restart_delay = 15 * 60

            logger.info('Killing all tasks...')
            gevent.killall(tasks)
            logger.info('Waiting %s seconds before %s...' %
                        (restart_delay,
                         ('restarting' if restart else 'exiting')))
            gevent.sleep(restart_delay)

    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Exiting...')
        gevent.killall(tasks)
    except Exception:
        logger.exception('Main authbot thread exited with an exception')
Beispiel #10
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--data-root',
        action='store',
        default='data',
        help='Location of the data dir containing all config files and logs.')
    parser.add_argument('--port-offset',
                        action='store',
                        default=None,
                        help='Override port offset in the config')
    args = parser.parse_args()
    data_root = args.data_root
    set_up_logging(data_root, 'game_server_launcher.log')
    logger = logging.getLogger(__name__)
    config = configparser.ConfigParser()
    with open(os.path.join(data_root, 'gameserverlauncher.ini')) as f:
        config.read_file(f)
    with open(get_shared_ini_path(data_root)) as f:
        config.read_file(f)

    if args.port_offset is not None:
        print(f"Using port offset flag: {int(args.port_offset)}")
        ports = Ports(int(args.port_offset))
    else:
        ports = Ports(int(config['shared']['port_offset']))

    restart = True
    restart_delay = 10
    tasks = []
    try:
        while restart:
            incoming_queue = gevent.queue.Queue()
            server_handler_queue = gevent.queue.Queue()

            tasks = [
                gevent_spawn("game server launcher's handle_ping", handle_ping,
                             ports),
                gevent_spawn("game server launcher's handle_game_server",
                             handle_game_server, config['gameserver'], ports,
                             server_handler_queue, incoming_queue, data_root),
                gevent_spawn("game server launcher's handle_login_server",
                             handle_login_server, config['loginserver'],
                             incoming_queue),
                gevent_spawn("game server launcher's handle_game_controller",
                             handle_game_controller, ports, incoming_queue),
                gevent_spawn("game server launcher's handle_launcher",
                             handle_launcher, config['gameserver'], ports,
                             incoming_queue, server_handler_queue, data_root)
            ]
            # Give the greenlets enough time to start up, otherwise killall can block
            gevent.sleep(1)

            # Wait for any of the tasks to terminate
            finished_greenlets = gevent.joinall(tasks, count=1)

            logger.warning('The following greenlets terminated: %s' %
                           ','.join([g.name for g in finished_greenlets]))

            fatal_errors = [
                '  %s' % g.exception for g in finished_greenlets
                if isinstance(g.exception, FatalError)
            ]
            if fatal_errors:
                logger.critical(
                    '\n' + '\n-------------------------------------------\n' +
                    'The following fatal errors occurred:\n' +
                    '\n'.join(fatal_errors) +
                    '\n-------------------------------------------\n')
                restart = False

            logger.info('Killing all tasks...')
            gevent.killall(tasks)
            logger.info('Waiting %s seconds before %s...' %
                        (restart_delay,
                         ('restarting' if restart else 'exiting')))
            gevent.sleep(restart_delay)

    except KeyboardInterrupt:
        logger.info('Keyboard interrupt received. Exiting...')
        gevent.killall(tasks)
    except Exception:
        logger.exception(
            'Main game server launcher thread exited with an exception')