Files
simple-updater/generate_manifest.py
T
2026-09-08 09:24:35 +03:00

97 lines
2.9 KiB
Python

import os
import json
import hashlib
import argparse
# ============================================================
# CONFIGURATION - edit these values for your game/project
# ============================================================
MANIFEST_FILENAME = "manifest.json"
# Files the updater must never touch (launcher itself, local settings, etc.)
IGNORE_FILES = {
MANIFEST_FILENAME,
"updater.exe", # Your compiled updater executable
"Option.ini", # Example: graphics/sound settings
"WindowsInfo.ini", # Example: window layout settings
}
# Folders the updater must never scan or update
IGNORE_FOLDERS = {
"screenshots",
"logs",
"replays",
}
# File extensions to always skip (lowercase, without the dot doesn't matter, include the dot)
IGNORE_EXTENSIONS = {
".log",
}
# ============================================================
# END CONFIGURATION
# ============================================================
def get_md5(filepath):
"""Computes the MD5 hash of a file."""
hash_md5 = hashlib.md5()
try:
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
except IOError:
return None
def generate(client_dir):
if not os.path.exists(client_dir) or not os.path.isdir(client_dir):
print(f"Error: directory '{client_dir}' not found!")
return
manifest = {}
manifest_path = os.path.join(client_dir, MANIFEST_FILENAME)
print(f"Scanning client folder: {client_dir}")
for root, dirs, files in os.walk(client_dir):
# Filter out ignored folders (case-insensitive)
dirs[:] = [d for d in dirs if d.lower() not in IGNORE_FOLDERS]
for file in files:
if file in IGNORE_FILES:
continue
if any(file.lower().endswith(ext) for ext in IGNORE_EXTENSIONS):
continue
filepath = os.path.join(root, file)
# Path relative to the client folder (this is what the updater expects)
rel_path = os.path.relpath(filepath, client_dir)
# Convert Windows-style separators to web-style
rel_path_web = rel_path.replace("\\", "/")
file_hash = get_md5(filepath)
if file_hash:
manifest[rel_path_web] = file_hash
try:
with open(manifest_path, "w", encoding="utf-8") as f:
json.dump(manifest, f, indent=4)
print(f"Done! Manifest saved to: {manifest_path}")
print(f"Total files in manifest: {len(manifest)}")
except IOError as e:
print(f"Error saving manifest: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Universal manifest generator for game updaters.")
parser.add_argument("client_path", help="Path to the client files folder")
args = parser.parse_args()
generate(args.client_path)