#!/usr/bin/env python3 """ 将 res/keys.json 生成为 src/utils/game_keys.h 头文件 KEY/IV 直接生成为字节数组,C++ 端无需 hex_to_bytes 转换 用法(在项目根目录运行): python res/gen_keys.py """ import json import sys from pathlib import Path JSON_PATH = Path("./res/keys.json") OUTPUT_PATH = Path("./src/utils/game_keys.h") def hex_to_c_array(hex_str): """将hex字符串转为C字节数组初始化列表,如 {0xA5, 0x37, ...}""" return "{" + ", ".join( "0x" + hex_str[i:i + 2].upper() for i in range(0, len(hex_str), 2) ) + "}" def main(): if not JSON_PATH.exists(): print("Error: " + str(JSON_PATH) + " not found", file=sys.stderr) sys.exit(1) with open(JSON_PATH, "r", encoding="utf-8") as f: entries = json.load(f) out = [] out.append("#pragma once") out.append("") out.append("#include ") out.append("") out.append("// 此文件由 gen_keys.py 从 res/keys.json 自动生成,请勿手动编辑") out.append("// 源文件: res/keys.json (" + str(len(entries)) + " 条记录)") out.append("") out.append("namespace game_keys {") out.append(" // 单个游戏的密钥条目(KEY/IV为16字节原始数组,无需运行时hex转换)") out.append(" struct Entry {") out.append(" const char *game_id;") out.append(" const uint8_t app_key[16];") out.append(" const uint8_t app_iv[16];") out.append(" const uint8_t opt_key[16];") out.append(" const uint8_t opt_iv[16];") out.append(" };") out.append("") out.append(" // 所有游戏的密钥表(编译期常量,无需运行时解析)") out.append(" inline constexpr Entry ENTRIES[] = {") for e in entries: line = ' {"' + e["GameID"] + '", ' + \ hex_to_c_array(e["AppKey"]) + ", " + \ hex_to_c_array(e["AppIV"]) + ", " + \ hex_to_c_array(e["OptKey"]) + ", " + \ hex_to_c_array(e["OptIV"]) + "}," out.append(line) out.append(" };") out.append("}") out.append("") content = "\n".join(out) OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True) with open(OUTPUT_PATH, "w", encoding="utf-8") as f: f.write(content) print("Generated " + str(OUTPUT_PATH) + " (" + str(len(entries)) + " entries)") if __name__ == "__main__": main()