# 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