/DepotManifestGen

steam仓库清单文件生成

Primary LanguageC

steam仓库清单文件生成

参数

  • -u, --username: 账号
  • -p, --password: 密码
  • -a, --app-id: 仅爬取指定appid
  • -l, --list-apps: 是否仅打印app信息
  • -s, --sentry-path, --ssfn: ssfn文件路径
  • -k, --login-key: 登录密钥
  • -f, --two-factor-code: 2fa验证码
  • -A, --auth-code: 邮箱验证码
  • -i, --login-id: 登录id
  • -c, --cli: 交互式登录
  • -L, --level: 日志,默认INFO
  • -C, --credential-location: 账户凭据存储路径,默认client
  • -r, --remove-old: 爬取到新的清单后是否删除旧的

清单文件简介

  • appid: 游戏id
  • depot: 用于存放游戏文件的仓库
  • depot_id: 仓库编号,通常是appid的递增编号,一个appid可以有多个depot_id,例如dlc语言等仓库
  • manifest: 记录每个仓库文件的清单
  • manifest_gid: 仓库清单的编号,类似于commit id
  • DecryptionKey: 仓库密钥,用于解密仓库清单文件
  • 具体可以查看https://steamdb.info/app/{app_id}/depots/

清单文件的位置

  • Steam\depotcache

清单文件的作用

清单文件生成

from steam.protobufs.content_manifest_pb2 import ContentManifestSignature

# 获取manifest_code
manifest_code = cdn.get_manifest_request_code(app_id, depot_id, manifest_gid)
# 通过manifest_code获取manifest对象
manifest = cdn.get_manifest(app_id, depot_id, manifest_gid, decrypt=False, manifest_request_code=manifest_code)
# 获取DecryptionKey
DecryptionKey = cdn.get_depot_key(manifest.app_id, manifest.depot_id)
# 通过DecryptionKey解密manifest
manifest.decrypt_filenames(DecryptionKey)
# 清空signature
manifest.signature = ContentManifestSignature()
for mapping in manifest.payload.mappings:
    # 删除文件名结尾特殊字符
    mapping.filename = mapping.filename.rstrip('\x00 \n\t')
    # 通过区块sha排序
    mapping.chunks.sort(key=lambda x: x.sha)
# 对文件名排序
manifest.payload.mappings.sort(key=lambda x: x.filename.lower())
# 通过payload计算crc_clear
manifest.metadata.crc_clear = calc_clear_crc(manifest.payload)
  • crc_clear计算
    • 通过对steam逆向分析后找到了计算crc_clear算法,具体代码在calc_crc_clear.c
    • 分析得出steam是对ContentManifestPayload部分进行了crc计算,具体过程没搞懂,只复制了汇编代码

steam导入清单文件后下载游戏

  • 把程序运行完后生成的.manifest文件复制到Steam\depotcache目录下
  • 把生成的config.vdf文件里的depots合并到Steam\config\config.vdf文件
  • 使用steamtools等工具解锁游戏后可以正常下载