import json
import os
import subprocess
import shutil
from concurrent.futures import ThreadPoolExecutor, as_completed
CDN_PREFIX = "https://dik52o19344s2.cloudfront.net/king/prod/66b9705e-297a-4c5f-8dbf-fdd19e0f17db/"
VALID_SUFFIXES = ('.basis', '.json', '.atlas.txt')
JSON_PATH = r"C:\Users\username\Downloads\config.json"
DOWNLOAD_DIR = "resdownload/zzmw"
TEMP_DIR = os.path.join(DOWNLOAD_DIR, "temp")
BASISU_EXE = "basisu.exe"
os.makedirs(DOWNLOAD_DIR, exist_ok=True)
os.makedirs(TEMP_DIR, exist_ok=True)
file_map = {}
def basis_to_png_threadsafe(basis_path):
basename = os.path.splitext(os.path.basename(basis_path))[0]
work_dir = os.path.join(TEMP_DIR, basename)
try:
os.makedirs(work_dir, exist_ok=True)
temp_basis_path = os.path.join(work_dir, os.path.basename(basis_path))
shutil.copy(basis_path, temp_basis_path)
result = subprocess.run(
[os.path.abspath(BASISU_EXE), "-file", os.path.basename(temp_basis_path)],
cwd=work_dir
)
if result.returncode != 0:
print(f"[!] basisu解码失败: {basis_path}")
return False
candidates = [
f"{basename}_unpacked_rgba_PVRTC1_4_RGBA_0000.png",
f"{basename}_still1_unpacked_rgb_PVRTC1_4_RGBA_0000.png",
f"{basename}_unpacked_rgb_PVRTC1_4_RGB_0000.png"
]
for png_file in candidates:
temp_png_path = os.path.join(work_dir, png_file)
if os.path.exists(temp_png_path):
final_png_path = os.path.join(DOWNLOAD_DIR, f"{basename}.png")
shutil.move(temp_png_path, final_png_path)
print(f"[+] 转换成功: {basis_path} → {final_png_path}")
return True
print(f"[!] 没找到有效PNG: {basis_path}")
return False
finally:
shutil.rmtree(work_dir, ignore_errors=True)
def clean_temp():
if os.path.exists(TEMP_DIR):
shutil.rmtree(TEMP_DIR)
print("[*] 已清理临时目录")
def getpngmain():
basis_files = [
os.path.join(DOWNLOAD_DIR, f)
for f in os.listdir(DOWNLOAD_DIR)
if f.endswith(".basis")
]
with ThreadPoolExecutor(max_workers=10) as executor:
future_to_path = {executor.submit(basis_to_png_threadsafe, path): path for path in basis_files}
for future in as_completed(future_to_path):
path = future_to_path[future]
try:
if future.result():
os.remove(path)
print(f"[+] 删除原文件: {path}")
except Exception as e:
print(f"[!] 处理失败 {path}: {e}")
clean_temp()
def organize_files_by_prefix(spine_prefixes):
for prefix in spine_prefixes:
folder_path = os.path.join(DOWNLOAD_DIR, prefix)
os.makedirs(folder_path, exist_ok=True)
for f in os.listdir(DOWNLOAD_DIR):
if f == prefix:
continue
if f.startswith(prefix) and os.path.isfile(os.path.join(DOWNLOAD_DIR, f)):
src = os.path.join(DOWNLOAD_DIR, f)
dst = os.path.join(folder_path, f)
shutil.move(src, dst)
print(f"[+] 移动: {f} → {folder_path}")
def rename_atlas_txt():
for f in os.listdir(DOWNLOAD_DIR):
if f.endswith(".atlas.txt"):
old_path = os.path.join(DOWNLOAD_DIR, f)
new_name = f[:-4]
new_path = os.path.join(DOWNLOAD_DIR, new_name)
os.rename(old_path, new_path)
print(f"[+] 重命名: {f} → {new_name}")
with open(JSON_PATH, "r", encoding="utf-8") as f:
data = json.load(f)
assets = data.get("assets", {})
for asset_id, asset_info in assets.items():
file_info = asset_info.get("file")
if not file_info:
continue
url = None
filename = None
basis_variant = file_info.get("variants", {}).get("basis")
if basis_variant:
filename = basis_variant.get("filename")
url = basis_variant.get("url")
if not url or not filename:
filename = file_info.get("filename")
url = file_info.get("url")
if not filename or not url:
continue
if not filename.endswith(VALID_SUFFIXES):
continue
full_url = CDN_PREFIX + url
file_map[filename] = full_url
with open("zzmw.txt", "w", encoding="utf-8") as out_file:
for fname, url in file_map.items():
if fname.endswith(".json"):
out_file.write(f"{url}\n out={fname}\n\n")
os.system(f"aria2c -i zzmw.txt -j 16 -s 16 -x 16 --check-certificate=false --dir={DOWNLOAD_DIR}")
spine_prefixes = set()
for fname in os.listdir(DOWNLOAD_DIR):
if fname.endswith(".json"):
fpath = os.path.join(DOWNLOAD_DIR, fname)
try:
with open(fpath, "r", encoding="utf-8") as f:
j = json.load(f)
if "skeleton" in j and isinstance(j["skeleton"], dict) and "spine" in j["skeleton"]:
name_prefix = os.path.splitext(fname)[0]
spine_prefixes.add(name_prefix)
else:
os.remove(fpath)
except Exception:
os.remove(fpath)
with open("zzmw.txt", "w", encoding="utf-8") as out_file:
for fname, url in file_map.items():
if fname.endswith(".json"):
continue
for prefix in spine_prefixes:
if fname.startswith(prefix):
out_file.write(f"{url}\n out={fname}\n\n")
break
os.system(f"aria2c -i zzmw.txt -j 32 -s 16 -x 16 --check-certificate=false --dir={DOWNLOAD_DIR}")
getpngmain()
rename_atlas_txt()
organize_files_by_prefix(spine_prefixes)
就这样先吧…由于是dmm他的资源清单获取逻辑一路追踪上去要jwt会话令牌就不管了先等erolab版吧(好歹e服没码)
注意这个脚本只会下载spine文件(似乎只有hcg是spine?)当然全下也行自己改函数都写好了就去掉个过滤就行完整资源大约2200个文件
config.json
config.zip (4.8 MB)