def get_rcon_client(): if not get_rcon_client._client: with open(os.path.join(GAME_DATA, 'config/rconpw'), 'r') as fin: rconpw = fin.read().strip() get_rcon_client._client = factorio_rcon.RCONClient( "factorio", 27015, rconpw) return get_rcon_client._client
def tp(srcsrvid, srcconn): srchost = None srcport = None srcpass = None with open('server.list') as f: for line in f: if line.strip()[1] != '#': pieces = line.strip().split() if len(pieces) == 4: if pieces[0] == srcsrvid: srchost = pieces[1] srcport = pieces[2] srcpass = pieces[3] if not srchost or not srcport or not srcpass: exit(-1) cmd = '''/silent-command for k,v in pairs(game.surfaces[1].find_entities_filtered({name='character', area={{-66,-18},{-56,-8}}})) do v.player.connect_to_server({address='kilen.me:6011'}) end ''' if srcconn[0]: srcclient = srcconn[0] else: srcclient = factorio_rcon.RCONClient(srchost, int(srcport), srcpass, timeout=5) srcconn[0] = srcclient ret = srcclient.send_command(cmd)
async def factorio_spinup_server(ctx: FactorioContext) -> bool: savegame_name = os.path.abspath("Archipelago.zip") if not os.path.exists(savegame_name): logger.info(f"Creating savegame {savegame_name}") subprocess.run(( executable, "--create", savegame_name )) factorio_process = subprocess.Popen( (executable, "--start-server", savegame_name, *(str(elem) for elem in server_args)), stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, encoding="utf-8") factorio_server_logger.info("Started Information Exchange Factorio Server") factorio_queue = Queue() stream_factorio_output(factorio_process.stdout, factorio_queue, factorio_process) stream_factorio_output(factorio_process.stderr, factorio_queue, factorio_process) rcon_client = None try: while not ctx.auth: while not factorio_queue.empty(): msg = factorio_queue.get() factorio_server_logger.info(msg) if "Loading mod AP-" in msg and msg.endswith("(data.lua)"): parts = msg.split() ctx.mod_version = Utils.Version(*(int(number) for number in parts[-2].split("."))) elif "Write data path: " in msg: ctx.write_data_path = Utils.get_text_between(msg, "Write data path: ", " [") if "AppData" in ctx.write_data_path: logger.warning("It appears your mods are loaded from Appdata, " "this can lead to problems with multiple Factorio instances. " "If this is the case, you will get a file locked error running Factorio.") if not rcon_client and "Starting RCON interface at IP ADDR:" in msg: rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password) if ctx.mod_version == ctx.__class__.mod_version: raise Exception("No Archipelago mod was loaded. Aborting.") await get_info(ctx, rcon_client) await asyncio.sleep(0.01) except Exception as e: logger.exception(e, extra={"compact_gui": True}) msg = "Aborted Factorio Server Bridge" logger.error(msg) ctx.gui_error(msg, e) ctx.exit_event.set() else: logger.info( f"Got World Information from AP Mod {tuple(ctx.mod_version)} for seed {ctx.seed_name} in slot {ctx.auth}") return True finally: factorio_process.terminate() factorio_process.wait(5) return False
def main(): parser = argparse.ArgumentParser(description='arguments') parser.add_argument('--serverAddress', type=str) parser.add_argument('--serverPort', type=int) parser.add_argument('--game', type=str) parser.add_argument('--gameType', type=str) parser.add_argument('--name', type=str) parser.add_argument('--rconpw', type=str, default="None") args = parser.parse_args() ip = requests.get('http://169.254.169.254/latest/meta-data/public-ipv4').text while True: if args.game in ('soldat', 'gmod', 'valheim'): import valve.source.a2s from valve.source import NoResponseError try: SERVER_ADDRESS = (args.serverAddress, args.serverPort) with valve.source.a2s.ServerQuerier(SERVER_ADDRESS) as server: server.info() # need to genericize this documentStore(args.game, args.gameType, args.name, ip) break except NoResponseError: time.sleep(5) print('No response yet!') elif args.game == 'factorio': import factorio_rcon from factorio_rcon.factorio_rcon import RCONConnectError try: factorio_rcon.RCONClient(args.serverAddress, args.serverPort, args.rconpw, timeout=5) documentStore(args.game, args.gameType, args.name, ip) break except RCONConnectError: print('No response yet!') time.sleep(5) elif args.game == 'minecraft': from mcstatus import MinecraftServer try: SERVER_ADDRESS = [args.serverAddress, args.serverPort] server = MinecraftServer(SERVER_ADDRESS[0], SERVER_ADDRESS[1]) server.ping() documentStore(args.game, args.gameType, args.name, ip) break except Exception as e: time.sleep(5) print('No response yet! However, {}'.format(e))
async def connect(self): if self.connecting: return self.connecting = True while True: try: self.rcon = factorio_rcon.RCONClient(self.host, self.port, self.pwd) version = self.rcon.send_command('/version') except ConnectionError: #print('connection failed, retrying in 2 seconds') await asyncio.sleep(2) else: await self.onmsg({'type': 'connected', 'version': version}) self.connecting = False break
async def factorio_server_watcher(ctx: FactorioContext): import subprocess import factorio_rcon factorio_server_logger = logging.getLogger("FactorioServer") factorio_process = subprocess.Popen((executable, "--start-server", *(str(elem) for elem in server_args)), stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, encoding="utf-8") factorio_server_logger.info("Started Factorio Server") factorio_queue = Queue() stream_factorio_output(factorio_process.stdout, factorio_queue) stream_factorio_output(factorio_process.stderr, factorio_queue) try: while 1: while not factorio_queue.empty(): msg = factorio_queue.get() factorio_server_logger.info(msg) if not ctx.rcon_client and "Hosting game at IP ADDR:" in msg: ctx.rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password) # trigger lua interface confirmation ctx.rcon_client.send_command("/sc game.print('Starting Archipelago Bridge')") ctx.rcon_client.send_command("/sc game.print('Starting Archipelago Bridge')") if ctx.rcon_client: while ctx.send_index < len(ctx.items_received): transfer_item: NetworkItem = ctx.items_received[ctx.send_index] item_id = transfer_item.item player_name = ctx.player_names[transfer_item.player] if item_id not in lookup_id_to_name: logging.error(f"Cannot send unknown item ID: {item_id}") else: item_name = lookup_id_to_name[item_id] factorio_server_logger.info(f"Sending {item_name} to Nauvis from {player_name}.") ctx.rcon_client.send_command(f'/ap-get-technology {item_name} {player_name}') ctx.send_index += 1 await asyncio.sleep(1) except Exception as e: logging.exception(e) logging.error("Aborted Factorio Server Bridge")
def tp(srcsrvid, srcx, srcy, dstsrvid, dstx, dsty, srcconn, dstconn): try: srchost = None srcport = None srcpass = None with open('server.list') as f: for line in f: if line.strip()[1] != '#': pieces = line.strip().split() if len(pieces) == 4: if pieces[0] == srcsrvid: srchost = pieces[1] srcport = pieces[2] srcpass = pieces[3] if not srchost or not srcport or not srcpass: exit(-1) dsthost = None dstport = None dstpass = None with open('server.list') as f: for line in f: if line.strip()[1] != '#': pieces = line.strip().split() if len(pieces) == 4: if pieces[0] == dstsrvid: dsthost = pieces[1] dstport = pieces[2] dstpass = pieces[3] if not dsthost or not dstport or not dstpass: exit(-1) cmd='''/silent-command surface = game.get_surface(1) fef=surface.find_entity dst=fef('steel-chest', {''' + dstx + ''', ''' + dsty + '''}) local inv = dst.get_inventory(defines.inventory.chest) inv.sort_and_merge() slots = 0 for x=1,#inv do if inv[x].valid_for_read then slots = slots + 1 end end rcon.print(#inv-slots) ''' if dstconn[0]: dstclient = dstconn[0] else: dstclient = factorio_rcon.RCONClient(dsthost, int(dstport), dstpass, timeout=5) dstconn[0] = dstclient availableslots = dstclient.send_command(cmd) #print(availableslots) cmd='''/silent-command function serialize_table(t) s='{' for x,y in pairs(t) do s = s .. "['" .. x .. "']" .. '=' .. "'" .. y .. "'" .. ',' end if #s>1 then s=s:sub(1,-2) end s=s..'}' return(s) end surface = game.get_surface(1) fef=surface.find_entity src=fef('steel-chest', {''' + srcx + ''', ''' + srcy + '''}) local inv = src.get_inventory(defines.inventory.chest) contents = {} if inv.is_empty() then rcon.print('empty') else inv.sort_and_merge() types=0 for i=1,''' + availableslots + ''' do if inv[i].valid_for_read then name=inv[i].name qty = inv.find_item_stack(name).count contents = {name=name,count=qty} ser = serialize_table(contents) rcon.print(ser) end end end ''' rsp='' if srcconn[0]: srcclient = srcconn[0] else: srcclient = factorio_rcon.RCONClient(srchost, int(srcport), srcpass, timeout=5) srcconn[0] = srcclient rsp = srcclient.send_command(cmd) or '' #print(rsp) contents = '{' + ','.join(rsp.split('\n')) + '}' if contents != '[empty]': cmd='''/silent-command surface = game.get_surface(1) fef=surface.find_entity dst=fef('steel-chest', {''' + dstx + ''', ''' + dsty + '''}) contents = ''' + contents + ''' for k,v in pairs(contents) do if dst.can_insert(v) then dst.insert(v) rcon.print('{' .. k .. ',' .. "'ok'}") else rcon.print('{' .. k .. ',' .. "'nofit'}") end end ''' if dstconn[0]: dstclient = dstconn[0] else: dstclient = factorio_rcon.RCONClient(dsthost, int(dstport), dstpass, timeout=5) dstconn[0] = dstclient result = dstclient.send_command(cmd) or '' #print(result) transferstatus = '{' + ','.join(result.split('\n')) + '}' cmd='''/silent-command fef=surface.find_entity src=fef('steel-chest', {''' + srcx + ''', ''' + srcy + '''}) contents = ''' + contents + ''' transferstatus = ''' + transferstatus + ''' for k,v in pairs(transferstatus) do if v[2] == 'ok' then src.get_inventory(defines.inventory.chest).remove(contents[k]) end end ''' res = srcclient.send_command(cmd) #print(res) except Exception as e: print('EXCEPTION DURING TELEPORT') print(e) srcconn[0] = None dstconn[0] = None
cpos = spos elseif #wchest > 0 then cpos = wpos end if cpos then if s.signal.name == 'signal-R' then rcon.print('R'.. ' ' .. pos .. ' ' .. ival .. ' ' .. s.count .. ' ' .. cpos[1] .. ' ' .. cpos[2]) end if s.signal.name == 'signal-S' then rcon.print('S'.. ' ' .. pos .. ' ' .. ival .. ' ' .. s.count .. ' ' .. cpos[1] .. ' ' .. cpos[2]) end end end end end end end ''' srcclient = factorio_rcon.RCONClient(srchost, int(srcport), srcpass, timeout=5) contents = srcclient.send_command(cmd) print(str(srvid)) #print(contents) with open(srvid + '.combis', 'w') as f: f.write(contents or '')
import factorio_rcon client = factorio_rcon.RCONClient("127.0.0.1", 7777, "zzz") response = client.send_command("/sc rcon.print(game.tick) game.ticks_to_run = 12 rcon.print(game.tick)") print (response)
if __name__ == "__main__": # Parse arguments parser = argparse.ArgumentParser() parser.add_argument("--port", type=int, required=True, help="RCON port number") parser.add_argument("--password", type=str, required=True, help="RCON password") args = parser.parse_args() # Create RCON client client = factorio_rcon.RCONClient("localhost", args.port, args.password) # initialize latest alive time latest_alive_time_in_sec = time.time() # main loop while True: # get current time current_time_sec = time.time() # get online player count response = client.send_command("/players online count") m = re.match(r'Online players \((\d+)\)', response) if m is None: print("/players command response isn't matched") print("for safe, send /quit message") client.send_command("/quit") break player_count = int(m.group(1))
import factorio_rcon import sys print('Welcome to the script to make admin') if len(sys.argv)<3: print("Connection information are missing") print('Enter hostname as first parameter and port as second parameter') sys.exit() hostname = sys.argv[1] port = sys.argv[2] print('Connection to server ', hostname, ":", port) print('Enter password: '******'') pwd = input() client = factorio_rcon.RCONClient(hostname, int(port), pwd) print('Enter user to promote as admin: ', end = '') usr = input() cmd = "/promote " + usr response = client.send_command(cmd) print(response)
def game_time(self): rcon_client = factorio_rcon.RCONClient(self.ip, 27015, self.rcon_pw) try: return rcon_client.send_command("/time") finally: rcon_client.close()
def save(self): rcon_client = factorio_rcon.RCONClient(self.ip, 27015, self.rcon_pw) try: return rcon_client.send_command("/server-save") finally: rcon_client.close()
async def factorio_server_watcher(ctx: FactorioContext): savegame_name = os.path.abspath(ctx.savegame_name) if not os.path.exists(savegame_name): logger.info(f"Creating savegame {savegame_name}") subprocess.run(( executable, "--create", savegame_name, "--preset", "archipelago" )) factorio_process = subprocess.Popen((executable, "--start-server", ctx.savegame_name, *(str(elem) for elem in server_args)), stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, encoding="utf-8") factorio_server_logger.info("Started Factorio Server") factorio_queue = Queue() stream_factorio_output(factorio_process.stdout, factorio_queue, factorio_process) stream_factorio_output(factorio_process.stderr, factorio_queue, factorio_process) try: while not ctx.exit_event.is_set(): if factorio_process.poll(): factorio_server_logger.info("Factorio server has exited.") ctx.exit_event.set() while not factorio_queue.empty(): msg = factorio_queue.get() factorio_queue.task_done() if not ctx.rcon_client and "Starting RCON interface at IP ADDR:" in msg: ctx.rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password) if not ctx.server: logger.info("Established bridge to Factorio Server. " "Ready to connect to Archipelago via /connect") if not ctx.awaiting_bridge and "Archipelago Bridge Data available for game tick " in msg: ctx.awaiting_bridge = True factorio_server_logger.debug(msg) else: factorio_server_logger.info(msg) if ctx.rcon_client: commands = {} while ctx.send_index < len(ctx.items_received): transfer_item: NetworkItem = ctx.items_received[ctx.send_index] item_id = transfer_item.item player_name = ctx.player_names[transfer_item.player] if item_id not in Factorio.item_id_to_name: factorio_server_logger.error(f"Cannot send unknown item ID: {item_id}") else: item_name = Factorio.item_id_to_name[item_id] factorio_server_logger.info(f"Sending {item_name} to Nauvis from {player_name}.") commands[ctx.send_index] = f'/ap-get-technology {item_name}\t{ctx.send_index}\t{player_name}' ctx.send_index += 1 if commands: ctx.rcon_client.send_commands(commands) await asyncio.sleep(0.1) except Exception as e: logging.exception(e) logging.error("Aborted Factorio Server Bridge") ctx.rcon_client = None ctx.exit_event.set() finally: factorio_process.terminate() factorio_process.wait(5)
async def run_bot(server, logfile, connection_args, commands_config, factorio_username): twitch_channel, rcon_ip, rcon_port, rcon_password = connection_args logprint(logfile, "Processing commands...") twitch_channel = twitch_channel.lower() processed_commands = {} stats_help_dict = {} for command in commands_config: cmd_name = command["command_name"] if cmd_name not in processed_commands or command["overwrite"] == True: processed_commands[cmd_name] = [] stats_help_dict[cmd_name] = [] processed_commands[cmd_name].append(command["lua"]) stats_help_dict[cmd_name].append( f"!{cmd_name}" if command["args_description"] is None else f"!{cmd_name} {command['args_description']}") stats_help = " | ".join( sorted(set([desc for _, v in stats_help_dict.items() for desc in v]))) logprint(logfile, "Connecting to factorio server...") try: rcon_client = factorio_rcon.RCONClient(rcon_ip, rcon_port, rcon_password) except factorio_rcon.factorio_rcon.RCONConnectError: logprint( logfile, "Connection to factorio server failed.\nPerhaps change settings.txt." ) return logprint(logfile, "Connections successful. Bot started.") chat_buffer = "" while True: raw_irc_response = await chat_response(server) chat_buffer = chat_buffer + raw_irc_response messages = chat_buffer.split("\r\n") chat_buffer = messages.pop() for message in messages: if message == "PING :tmi.twitch.tv": await pong(server) elif len(message.split()) < 2: continue elif CHAT_MSG in message: try: await process_msg(logfile, rcon_client, server, twitch_channel, message, processed_commands, factorio_username, stats_help) except factorio_rcon.factorio_rcon.RCONClosed: logprint( logfile, "Lost connection to factorio server. Trying to reconnect..." ) while True: try: rcon_client = factorio_rcon.RCONClient( rcon_ip, rcon_port, rcon_password) logprint( logfile, "Connection to factorio server successful.") break except factorio_rcon.factorio_rcon.RCONConnectError: time.sleep(5) except Exception as e: msg = f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - Error: '{e}'" with open("error_log.txt", "a") as f: f.write(msg + "\n") print(msg) traceback.print_exc()
import factorio_rcon from influxdb import InfluxDBClient collection_interval = pytimeparse.parse( os.environ.get("COLLECTION_INTERVAL", "10s")) factorio_address = os.environ["FACTORIO_ADDRESS"] factorio_port = int(os.environ.get("FACTORIO_PORT", "27015")) factorio_password = os.environ["FACTORIO_PASSWORD"] influx_address = os.environ["INFLUX_ADDRESS"] influx_port = int(os.environ.get("INFLUX_PORT", "8086")) influx_username = os.environ.get("INFLUX_USERNAME", None) influx_password = os.environ.get("INFLUX_PASSWORD", None) influx_database = os.environ["INFLUX_DATABASE"] with open("gather-stats.lua", "r") as f: stats_code = f.read() rcon_command = "/silent-command " + stats_code rcon_client = factorio_rcon.RCONClient(factorio_address, factorio_port, factorio_password) influx_client = InfluxDBClient(influx_address, influx_port, influx_username, influx_password, influx_database) while True: raw_response = rcon_client.send_command(rcon_command) response = json.loads(raw_response) influx_client.write_points(response) time.sleep(collection_interval)