Created
May 29, 2020 20:52
-
-
Save dominikandreas/b6401392e0b5d50d322946e582e23aa6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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