Files

87 lines
2.8 KiB
Python

"""
将 manifest.json 中引用的 blockstates 和 models 文件分别打包成 zip
进一步减少 HTTP 请求
"""
import json
import re
import zipfile
from pathlib import Path
BASE_DIR = Path(r"d:\SMANAGE\TempLate\MC\minecraft")
BLOCKSTATES_DIR = BASE_DIR / "blockstates"
MODELS_DIR = BASE_DIR / "models"
MANIFEST_FILE = BASE_DIR / "manifest.json"
def ResolveModelPath(model_id):
"""模型ID → 文件路径"""
path = re.sub(r"^[^:]+:", "", model_id)
return MODELS_DIR / f"{path}.json"
def CollectModelChain(model_id, collected, visited=None):
"""递归收集模型链中所有引用的模型文件"""
if visited is None:
visited = set()
if model_id in visited:
return
visited.add(model_id)
model_file = ResolveModelPath(model_id)
if model_file.exists():
collected.add(model_id)
try:
with open(model_file, "r", encoding="utf-8") as f:
raw = json.load(f)
if "parent" in raw:
CollectModelChain(raw["parent"], collected, visited)
except:
pass
def Main():
with open(MANIFEST_FILE, "r", encoding="utf-8") as f:
manifest = json.load(f)
# 收集所有引用的 blockstate 文件
blockstate_refs = set()
for block in manifest["Blocks"]:
block_id = block["Blockstate"]
name = re.sub(r"^[^:]+:", "", block_id)
blockstate_refs.add(name)
# 收集所有引用的 model 文件(递归解析父模型链)
model_refs = set()
for block in manifest["Blocks"]:
CollectModelChain(block["DefaultModel"], model_refs)
print(f"Blockstates to pack: {len(blockstate_refs)}")
print(f"Models to pack: {len(model_refs)}")
# 打包 blockstates.zip
bs_zip = BASE_DIR / "blockstates.zip"
packed_bs = 0
with zipfile.ZipFile(bs_zip, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as zf:
for name in sorted(blockstate_refs):
bs_file = BLOCKSTATES_DIR / f"{name}.json"
if bs_file.exists():
zf.write(bs_file, f"{name}.json")
packed_bs += 1
bs_size = bs_zip.stat().st_size
print(f"blockstates.zip: {packed_bs} files, {bs_size / 1024:.1f} KB")
# 打包 models.zip
md_zip = BASE_DIR / "models.zip"
packed_md = 0
with zipfile.ZipFile(md_zip, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as zf:
for model_id in sorted(model_refs):
path = re.sub(r"^[^:]+:", "", model_id)
model_file = MODELS_DIR / f"{path}.json"
if model_file.exists():
zf.write(model_file, f"{path}.json")
packed_md += 1
md_size = md_zip.stat().st_size
print(f"models.zip: {packed_md} files, {md_size / 1024:.1f} KB")
print(f"\nTotal: {bs_size + md_size} bytes ({(bs_size + md_size) / 1024:.1f} KB)")
if __name__ == "__main__":
Main()