updateMojang.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import json
  2. import os
  3. import zipfile
  4. import requests
  5. from cachecontrol import CacheControl
  6. from cachecontrol.caches import FileCache
  7. from meta.common import upstream_path, ensure_upstream_dir, static_path
  8. from meta.common.http import download_binary_file
  9. from meta.common.mojang import BASE_DIR, VERSION_MANIFEST_FILE, VERSIONS_DIR, ASSETS_DIR, STATIC_EXPERIMENTS_FILE
  10. from meta.model.mojang import MojangIndexWrap, MojangIndex, ExperimentIndex, ExperimentIndexWrap
  11. UPSTREAM_DIR = upstream_path()
  12. STATIC_DIR = static_path()
  13. ensure_upstream_dir(BASE_DIR)
  14. ensure_upstream_dir(VERSIONS_DIR)
  15. ensure_upstream_dir(ASSETS_DIR)
  16. forever_cache = FileCache('caches/http_cache', forever=True)
  17. sess = CacheControl(requests.Session(), forever_cache)
  18. def fetch_zipped_version(path, url):
  19. zip_path = f"{path}.zip"
  20. download_binary_file(sess, zip_path, url)
  21. with zipfile.ZipFile(zip_path) as z:
  22. for info in z.infolist():
  23. if info.filename.endswith(".json"):
  24. print(f"Found {info.filename} as version json")
  25. version_json = json.load(z.open(info))
  26. break
  27. assert version_json
  28. with open(path, 'w', encoding='utf-8') as f:
  29. json.dump(version_json, f, sort_keys=True, indent=4)
  30. return version_json
  31. def fetch_version(path, url):
  32. r = sess.get(url)
  33. r.raise_for_status()
  34. version_json = r.json()
  35. with open(path, 'w', encoding='utf-8') as f:
  36. json.dump(version_json, f, sort_keys=True, indent=4)
  37. return version_json
  38. def main():
  39. # get the remote version list
  40. r = sess.get('https://piston-meta.mojang.com/mc/game/version_manifest_v2.json')
  41. r.raise_for_status()
  42. remote_versions = MojangIndexWrap(MojangIndex(**r.json()))
  43. remote_ids = set(remote_versions.versions.keys())
  44. version_manifest_path = os.path.join(UPSTREAM_DIR, VERSION_MANIFEST_FILE)
  45. if os.path.exists(version_manifest_path):
  46. # get the local version list
  47. current_versions = MojangIndexWrap(MojangIndex.parse_file(version_manifest_path))
  48. local_ids = set(current_versions.versions.keys())
  49. # versions not present locally but present remotely are new
  50. pending_ids = remote_ids.difference(local_ids)
  51. for x in local_ids:
  52. remote_version = remote_versions.versions[x]
  53. local_version = current_versions.versions[x]
  54. if remote_version.time > local_version.time:
  55. pending_ids.add(x)
  56. else:
  57. pending_ids = remote_ids
  58. for x in pending_ids:
  59. version = remote_versions.versions[x]
  60. print("Updating " + version.id + " to timestamp " + version.release_time.strftime('%s'))
  61. fetch_version(os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json"), version.url)
  62. # deal with experimental snapshots separately
  63. static_experiments_path = os.path.join(STATIC_DIR, STATIC_EXPERIMENTS_FILE)
  64. if os.path.exists(static_experiments_path):
  65. experiments = ExperimentIndexWrap(ExperimentIndex.parse_file(static_experiments_path))
  66. experiment_ids = set(experiments.versions.keys())
  67. for x in experiment_ids:
  68. version = experiments.versions[x]
  69. experiment_path = os.path.join(UPSTREAM_DIR, VERSIONS_DIR, f"{x}.json")
  70. print("Updating experiment " + version.id)
  71. if not os.path.isfile(experiment_path):
  72. fetch_zipped_version(experiment_path, version.url)
  73. else:
  74. print("Already have experiment " + version.id)
  75. remote_versions.index.write(version_manifest_path)
  76. if __name__ == '__main__':
  77. main()