import os import hashlib import requests import urllib.parse from urllib.request import urlretrieve import sys def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+ """https://stackoverflow.com/questions/3160699/python-progress-bar""" count = len(it) if count == 0: return def show(j): x = int(size*j/count) print("{}[{}{}] {}/{}".format(prefix, "#"*x, "."*(size-x), j, count), end='\r', file=out, flush=True) show(0) for i, item in enumerate(it): yield item show(i+1) print("\n", flush=True, file=out) def get_file_list(url): url = "https://apidgp-gameplayer.games.dmm.com" + url print("Retrieving file list from " + url) result = requests.get(url) result.raise_for_status() data = result.json()["data"] return data["domain"], data["file_list"] def get_file_hash(file_path): if not os.path.exists(file_path): return None with open(file_path, "rb") as f: file_hash = hashlib.md5() while chunk := f.read(8192): file_hash.update(chunk) return file_hash.hexdigest() def update_game(game_path, files_url, files_param): print("Updating game") server_url, server_files = get_file_list(files_url) server_file_dict = {file["local_path"]: file for file in server_files} local_files = [os.path.join(dp, f).replace("\\", "/") for dp, dn, filenames in os.walk(game_path) for f in filenames] local_file_dict = {"/" + os.path.relpath(r, game_path).replace("\\", "/"): {"abs_path":r, "hash":""} for r in local_files} files_to_download = [] files_to_delete = [] for server_file_key in server_file_dict.keys(): server_file = server_file_dict[server_file_key] if server_file_key in local_file_dict: local_file = local_file_dict[server_file_key] if server_file["force_delete_flg"]: files_to_delete.append(local_file["abs_path"]) else: local_file["hash"] = get_file_hash(local_file["abs_path"]) if server_file["check_hash_flg"] and local_file["hash"] == server_file["hash"]: continue download_url = urllib.parse.urljoin(server_url, server_file["path"]) + files_param download_path = game_path.replace("\\", "/") + server_file_key files_to_download.append({"url":download_url, "path":download_path}) else: download_url = urllib.parse.urljoin(server_url, server_file["path"]) + files_param download_path = game_path.replace("\\", "/") + server_file_key files_to_download.append({"url":download_url, "path":download_path}) print("Files to download:", len(files_to_download)) for file in progressbar(files_to_download, "Downloading: ", 40): url, path = file["url"], file["path"] os.makedirs(os.path.dirname(path), exist_ok=True) urlretrieve(url, path) # #files_to_delete is unused until fully tested # for file in files_to_delete: # os.remove(file) return True