Visual_Studio

Factorio Server Updater

Jan 12th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.56 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. from json import load
  4. from hashlib import sha1
  5. from os import mkdir, listdir
  6. from argparse import ArgumentParser
  7. from shutil import copyfile, rmtree
  8. from os.path import join, isfile, isdir
  9.  
  10. import requests
  11.  
  12. BLOCK_SIZE = 65535
  13.  
  14. MOD_DIR = "mods"
  15.  
  16. API_VERSION = 2
  17. MODS_URL = "https://mods.factorio.com"
  18. AUTH_URL = "https://auth.factorio.com"
  19.  
  20. USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
  21. TOKEN_FILE = "token.txt"
  22.  
  23. def download_file(url: str, filename: str) -> None:
  24.     r = session.get(url, stream=True, params={"username": username, "token": token})
  25.     with open(filename, 'wb') as f:
  26.         for chunk in r.iter_content(chunk_size=2048):
  27.             if chunk:
  28.                 f.write(chunk)
  29.  
  30. def hash_file(filename: str) -> str:
  31.     hasher = sha1()
  32.     with open(filename, "rb") as f:
  33.         buff = f.read(BLOCK_SIZE)
  34.         while len(buff) > 0:
  35.             hasher.update(buff)
  36.             buff = f.read(BLOCK_SIZE)
  37.     return hasher.hexdigest()
  38.  
  39. if __name__ == "__main__":
  40.     # setup arguments
  41.     parser = ArgumentParser(description="A script to download Factorio mods according to a mod list")
  42.     parser.add_argument("-i", "--in-file", type=str, default="mod-list.json", help="The mod list file to read from")
  43.     parser.add_argument("-u", "--username", type=str, help="The username you use to log into mods.factorio.com")
  44.     parser.add_argument("-p", "--password", type=str, help="The password you use to log into mods.factorio.com")
  45.     # parse arguments
  46.     args = parser.parse_args()
  47.  
  48.     # make sure the mod list file exists
  49.     assert isfile(args.in_file), "The specified mod list file doesn't exist"
  50.  
  51.     # clear the mod directory if anything exists in it
  52.     if len(listdir(MOD_DIR)) > 0:
  53.         print("Clearing mod directory...")
  54.         rmtree(MOD_DIR)
  55.  
  56.     # create the mod directory if it doesn't exist
  57.     if not isdir(MOD_DIR):
  58.         print("Creating mod directory...")
  59.         mkdir(MOD_DIR)
  60.  
  61.     # create a requests session
  62.     session = requests.session()
  63.     # make sure our session makes requests with a valid user agent
  64.     session.headers.update({"User-Agent": USER_AGENT})
  65.     # log in and generate the token file
  66.     token = None
  67.     if not isfile(TOKEN_FILE):
  68.         # set the username global
  69.         username = args.username
  70.         # send the login request
  71.         response = session.post(AUTH_URL + "/api-login", data={"username": username, "password": args.password, "require_game_ownership": "True"}, params={"api_version": API_VERSION})
  72.         # parse the JSON and grab the token
  73.         response_json = response.json()
  74.         # make sure the login was successful
  75.         assert "token" in response_json, "Invalid credentials"
  76.         # set the token global
  77.         token = response_json["token"]
  78.         # dump the token
  79.         with open(TOKEN_FILE, "w") as f:
  80.             f.write("%s:%s" % (username, token))
  81.     else:  # load the cookies from a cookie jar
  82.         # load the cookies from a file
  83.         with open(TOKEN_FILE, "r") as f:
  84.             (username, token) = f.read().split(":", 1)
  85.  
  86.     # grab the mod list from the mod-list.json file
  87.     client_mod_list = load(open(args.in_file, "r"))
  88.     # iterate through each mod in the list
  89.     for mod in client_mod_list["mods"]:
  90.         # make sure the mod isn't base and that it's enabled
  91.         if mod["name"] != "base" and mod["enabled"]:
  92.             # grab the info for the mod
  93.             mod_info = session.get(MODS_URL + "/api/mods/" + mod["name"]).json()
  94.             # get the latest release from the mod info
  95.             latest_release = mod_info["releases"][-1]  # last element is the newest
  96.             # the name of the mod's zip file
  97.             mod_file_name = latest_release["file_name"]
  98.             # the SHA-1 hash of the file
  99.             mod_hash = latest_release["sha1"]
  100.             # the URL to download the mod from
  101.             mod_download_url = MODS_URL + latest_release["download_url"]
  102.             # create the mod file path
  103.             mod_download_path = join(MOD_DIR, mod_file_name)
  104.             # print status
  105.             print("Downloading %s to \"%s\"..." % (mod["name"], mod_download_path))
  106.             # download the mod
  107.             download_file(mod_download_url, mod_download_path)
  108.             # verify the mod's hash
  109.             assert mod_hash == hash_file(mod_download_path), "Invalid hash on %s" % (mod["name"])
  110.     # copy the mod-list.json into the new mods folder
  111.     copyfile(args.in_file, join(MOD_DIR, args.in_file))
Advertisement
Add Comment
Please, Sign In to add comment