引言
前几日 Steam 仙剑奇侠传系列大包 打折,四、五、六、五前传四部仙剑只要 ¥12.2,加之大促挂卡掉了张闪卡小赚五块,不到七块喜加四,畅玩了一番。
仙剑系列之前只玩过 137:
- 7 虽然剧本不堪,系统和九泉世界观的构建确实不错,而且前不久加入了 XGP,试错成本很低
- 3 年代久远,当时玩的因为这是上海软星的第一部作品,不久之后还出了电视剧
- 1 玩的版本比较多,DOS 版、95 版、98 柔情版、SS 版,顺带一提 SS 版仙剑也是土星上唯一的官方国产游戏
打完五前传弃坑六(开场 CG 世界观搞得那么大,结果操作人物初次战斗是打小混混)适逢 Switch 版「轩辕剑叁:云和山的彼端」发售,于是搞了一个,然后被各种恶性 bug 折磨直到死档删游 :)
终于要进入正题了,印象中轩辕剑我只玩过初代和 3 外传「天之痕」,结果昨天晚上突然想到鬼谷工作室做的天之痕 Flash 同人「上古神器」,这才想到,当年玩的压根就不是天之痕。
轩辕剑传说:鬼谷之泪™
又想到之前下过 在线 DOS 游戏 的全站 ROM(chinese-dos-games),顺藤摸瓜果然搜到了 Flash 保存计划,于是看到个网站就想爬的爬虫瘾犯了,一番操作写了一个 Bash 全站下载脚本。
当然,因为这个量比较大,统计数据页面 显示有 165,670 个 Flash,文件总大小 430.22 GiB,全部下下来还是有点费劲,所以只是写了,没有真的抓取。如果只需要单个 Flash,在游戏界面即可下载。
此外注意原项目采用 CC BY-SA 4.0 DEED 许可证,使用请保证遵守开源协议。
前置信息
- Flash 保存计划项目地址: flash-archive-project
- 需要的
flash.json
:https://raw.githubusercontent.com/rwv/flash-archive-project/main/flash.json
- 获取 SWF 文件:
https://flash-swf.zczc.cz/{sha256}.swf
- jq
jq
jq 用来处理 JSON 数据相当方便,我在 Awesome One-liner 中也多次使用,随便举个🌰️,获取 Citra 最新的 nightly build 下载 URL:
# Get Citra Nightly Download URL
GITHUB_URL=$(curl --silent --location https://api.github.com/repos/citra-emu/citra-nightly/releases/latest | jq --raw-output ".assets[].browser_download_url" | grep --extended-regexp "citra-linux-.*?.tar.xz")
完整的 flash.json
有 8M,这里只贴个简化版简单说一下数据清洗:
{
"0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc": {
"sha256": "0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc",
"size": 233234,
"original": "http://www.flashempire.com/theater/flash/2001-06/725.swf",
"ref": {
"flashempire": {
"author": "ZOLLIS",
"id": 737,
"name": "北京的梦想",
"popularity": 7288,
"url": "http://www.flashempire.com/theater/play.php?id=737"
}
}
},
"000becacfecf648c39d547da798b5527b6fba89f48bb44f3708be88920ea823c": {
"sha256": "000becacfecf648c39d547da798b5527b6fba89f48bb44f3708be88920ea823c",
"size": 4031690,
"original": "http://www.flash8.net/uploadflash/16/flash8net_15491.swf",
"ref": {
"flash8": {
"author": "vincent",
"description": "这个片子是偶然做起来的\n和此前完全不同的感觉\n基本没做剧本\n想哪做哪\n就算一个小尝实验了:)\n以后继续实验新的东西",
"email": "dayong7645@163.com",
"id": 15491,
"name": "迷墙(the wall)",
"original": false,
"uploader": "大大大苹果",
"url": "http://www.flash8.net/flash/15491.shtml"
}
}
}
}
可以看到 JSON 包括了几乎全部的元数据,不过下载全站需要用到的只有 sha256
和 name
。文档是不可能看的,用法是不可能会的,但是可以塞文档问 GPT。
由于 JSON 文件中的 sha256 是作为对象的属性,我们需要使用 keys
函数来获取属性名,然后再提取对应的 sha256 值:
jq 'keys[] as $key | .[$key].sha256' file.json
这个表达式首先使用 keys[]
函数获取所有的属性名,然后使用 as $key
将每个属性名存储在变量 $key
中,最后使用 .[$key].sha256
来提取对应的 sha256 值。
同理,提取 ref 下面的 name(注意中间字段不一定是 flashempire
,也可能是 flash8
或者其他内容):
jq 'keys[] as $key | .[$key].ref | .[] | .name' file.json
以及构造输出为 {sha256} name
的格式,比如这样:
0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc 北京的梦想
000becacfecf648c39d547da798b5527b6fba89f48bb44f3708be88920ea823c 迷墙(the wall)
需要将两个字段拼接在一起时,可以使用字符串插值来实现:
jq 'keys[] as $key | "\(.[$key].sha256) \(.[$key].ref[].name)"' file.json
sed
sed 也是老生常谈,我在 富婆妹 FD 机翻汉化补丁润色笔记 中曾经提到过,BTW 这篇文章至今都有不小的访问量,实在是匪夷所思, 甚至怀疑被(Artemis 引擎)机翻教程引用了,不过只要保留原文链接,想用就用吧,我对机翻并没有抵触情绪,不然也不会写 VNR 了。
#jq 最后拼接出的字符串带双引号,不符合 hash 的格式,但正好利用这个双引号来构造下载 URL。
"0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc 北京的梦想"
"000becacfecf648c39d547da798b5527b6fba89f48bb44f3708be88920ea823c 迷墙(the wall)"
#前置信息 中已经给出 SWF 的下载地址,只需要根据 jq 中提取的 sha256 加上前缀和后缀即可:
# Before
0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc
# After
https://flash-swf.zczc.cz/0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc.swf
实际命令也没什么难的,注意转义 https://
中的 /
即可:
# 构建 URL
cat sha256.txt | sed 's/"/https:\/\/flash-swf.zczc.cz\//' | sed 's/"/.swf/' > wget-list.txt
这里本来想用变量,方便后续下载全站截图,然而 sed 单双引号混用有点麻烦,遂作罢。
SWF_PREFIX="https://flash-swf.zczc.cz/"
SWF_SUFFIX=".swf"
还有一个问题,直接下载下来的 SWF 都是 0000633ee403f443cffbfc9ee16d919a91954eb8e7e9d7dd72af3f59abe202cc.swf
这种名字,鬼才知道哪个是哪个,下载后手动重命名为 北京的梦想.swf
才便于搜索。而 jq 中插值生成的 hash 除了用来校验下载文件,还可以用作批量重命名。
这一步的 sed 看着复杂,其实只需要注意先后顺序即可,随便一个文本编辑器打开正则替换,或者直接另存为 CSV 和 UTF-8 BOM 编码,用 Excel 操作也不成问题:
# 构建文件名替换脚本
cat file.txt | sed 's/ /.swf / ; s/"/mv /' | sed 's/"/.swf/' | sed 's/ / "/'2 | sed 's/.swf/.swf"/'2 | sed -E '1s/^/#!\/bin\/bash\n/' > file-rename.sh
注意替换完成后,需要手动打开脚本检查一下,有很多 edge case 没有考虑,懒得优化,比如 L1654 癫当 神奇玫瑰花(第一集).swf
有错位,导致直到 L4875 的三千多行无法正常处理。处理也很简单,找个有代码高亮的编辑器花几分钟改改就能用,总好过手动重命名这一万多个文件。
脚本
最后附上完整脚本,还是那句话,遵守原项目协议,请勿滥用。
#!/bin/bash
# Flash Archive Project Downloader
# Author: Vinfall
# License: GPL
# 这里只下载 SWF,没有下载对应截图
wget https://raw.githubusercontent.com/rwv/flash-archive-project/main/flash.json
# 提取有关信息
cat flash.json | jq 'keys[] as $key | .[$key].sha256' | sort | uniq > sha256.txt
#cat flash.json | jq 'keys[] as $key | .[$key].ref | .[] | .name' | sort | uniq > name.txt
cat flash.json | jq 'keys[] as $key | "\(.[$key].sha256) \(.[$key].ref[].name)"' | sort | uniq > file.txt
# 构建 sha256sum
cat file.txt | sed 's/"//' | sed 's/"/.swf/' > hash.txt
# 构建 URL
#SWF_PREFIX=https://flash-swf.zczc.cz/
#SWF_SUFFIX=.swf
cat sha256.txt | sed 's/"/https:\/\/flash-swf.zczc.cz\//' | sed 's/"/.swf/' > wget-list.txt
# 构建文件名替换脚本
cat file.txt | sed 's/ /.swf / ; s/"/mv /' | sed 's/"/.swf/' | sed 's/ / "/'2 | sed 's/.swf/.swf"/'2 | sed -E '1s/^/#!\/bin\/bash\n/' > file-rename.sh
# 批量下载并重命名
wget --continue -i wget-list.txt
sha256sum -c --ignore-missing hash.txt
#bash file-rename.sh
# Garbage clean
rm sha256.txt name.txt file.txt
echo 'Done'
#rm wget-list.txt file-rename.sh file.txt