Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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))
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
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")
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
              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 '')
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0

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))
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
 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()
Ejemplo n.º 13
0
 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()
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
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()
Ejemplo n.º 16
0
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)