Skip to content

Instantly share code, notes, and snippets.

@dominikandreas
Created May 29, 2020 20:52
Show Gist options
  • Save dominikandreas/b6401392e0b5d50d322946e582e23aa6 to your computer and use it in GitHub Desktop.
Save dominikandreas/b6401392e0b5d50d322946e582e23aa6 to your computer and use it in GitHub Desktop.
# run this with python3
import time
import os
import sys
import re
import json
try:
import psutil
except ImportError:
os.system(sys.executable + " -m pip install psutil")
import psutil
from subprocess import Popen
from urllib.request import urlopen
def get_astroneer_procs():
return [proc for proc in psutil.process_iter() if "Astro" in proc.name() and "AstroServer" in proc.exe()]
def stop_astroneer(astro_path, wait_for_save=True):
print("stopping astroneer")
procs = get_astroneer_procs()
if not procs:
return
if wait_for_save:
wait_for_game_save(astro_path)
t0, td = time.time(), 0
while procs:
td = time.time() - t0
for proc in procs:
proc.kill()
time.sleep(.3)
print_wait_message("waiting for astroneer to shut down", td)
procs = get_astroneer_procs()
print()
def start_astroneer(astro_path):
exe_path = f"{astro_path}/AstroServer.exe"
assert os.path.isfile(exe_path), f"unable to find astro server at {exe_path}"
return Popen([exe_path, "-log"], shell=False, cwd=astro_path)
def get_ip():
try:
ip = json.load(urlopen('http://api.ipify.org/?format=json'))['ip']
except:
try:
ip = json.load(urlopen('http://jsonip.com'))['ip']
except:
ip = json.load(urlopen('http://httpbin.org/ip'))['origin']
return ip.strip()
def check_valid_ip(ip):
# stackoverflow ftw: https://stackoverflow.com/questions/5284147/validating-ipv4-addresses-with-regexp
return ip is not None and re.match("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$", ip)
def get_current_ip_setting(astro_path):
config_path = astro_path + r"\Astro\Saved\Config\WindowsServer\AstroServerSettings.ini"
with open(config_path, "r") as f:
content = f.read()
return content.split("PublicIP=")[-1].split("\n")[0].strip()
def print_wait_message(message, td):
print("\r" + message + "." * int(td % 4), end=" ")
def update_astro_ip(astro_path, ip=None):
if not ip:
ip = get_ip()
if not ip or ip.count(".") != 3:
raise RuntimeError("Unable to get ip")
config_path = astro_path + r"\Astro\Saved\Config\WindowsServer\AstroServerSettings.ini"
with open(config_path) as f:
lines = [l.strip() for l in f.read().split("\n")]
ip_line_indices = [i for i, l in enumerate(lines) if "PublicIP" in l]
if not ip_line_indices:
lines.append("")
ip_line_idx = len(lines) -1
elif len(ip_line_indices) > 1: # this shouldn't really happen
for idx in ip_line_indices[1:]:
del lines[idx]
ip_line_idx = ip_line_indices[0]
else:
ip_line_idx = ip_line_indices[0]
ip_line = lines[ip_line_idx]
if ip_line.split("=")[-1] != ip:
print(f"updating ip setting in {config_path} to {ip}")
ip_line = "PublicIP=" + ip
with open(config_path, "w") as f:
lines[ip_line_idx] = ip_line
f.write(os.linesep.join(lines))
def wait_for_game_save(astro_path, secs_since_update=5):
t0 = time.time()
savegame_path = astro_path + r"\Astro\Saved\SaveGames"
latest_td = 0
while latest_td - t0 < secs_since_update:
savegames = [savegame_path + "/" + f for f in os.listdir(savegame_path) if f.startswith("SAVE")]
latest_td = max([os.stat(f).st_mtime for f in savegames])
td = time.time() - t0
time.sleep(.3)
print_wait_message("waiting for astroneer to save current game", td)
print()
def main(astro_path=r"D:\games\astroneer_server"):
actual_ip = get_ip()
if not check_valid_ip(actual_ip):
print("need a valid IP to continue but got " + actual_ip, file=sys.stderr)
sys.exit(1)
current_ip_setting = get_current_ip_setting(astro_path)
if actual_ip != current_ip_setting:
stop_astroneer(astro_path, wait_for_save=True)
update_astro_ip(astro_path)
if not get_astroneer_procs():
start_astroneer(astro_path)
else:
print("no action necessary")
if __name__ == "__main__":
astro_path = r"D:\games\astroneer_server"
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment