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()
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')
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)
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()
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')
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')
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')
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')