参考资料 & 测试
- 前端渲染及 SSR:card.js「GitHub Repo」「Demo」「卡图」
- 鼠标悬浮提示框参考:Steam Info「出处:其乐论坛」「Greasy Fork」「源码」
- Hugo:自定义 shortcode「Shortcode 文档」「基本语法」「函数」
一个小 bug
这是一个 bug:`<div class="ygo-card" />` **首次**出现的时候 _前面的文本_ 会被视为一个段落 `<p/>` 进而导致自动换行,考虑使用双层 `<span/>` 嵌套尝试修复{{< ygo-card 禁忌的一滴 24299458 spell sg >}}测试文本测试文本测试文本测试文本{{< ygo-card name="青眼白龙" id="89631139" type="light" >}}测试文本测试文本测试文本测试文本测试文本测试文本测试文本{{< ygo-card name="红色重启" id="23002292" type="trap" icon="fj" >}}测试文本测试文本测试文本测试文本测试文本{{< ygo-card >}}测试文本测试文本测试文本测试测试文本
这是一个 bug:<div class="ygo-card" /> 首次出现的时候 前面的文本 会被视为一个段落 <p/> 进而导致自动换行,考虑使用双层 <span/> 嵌套尝试修复
需求
考虑做成一个前端网站。这里临时用 JS 做可行性验证,到时候还是用 TS 写。
Todo List
- 卡组格式转换 ydk ygm 等,类似「YGO-Engine 的 ydk 和 ygm 转换」
- 从录像文件
.yrp中提取卡组信息,类似「OURYGO 的」和「YGO-Engine 的」 - 展现卡图,类似「OURYGO 的」和「Koishi 的」
- 点击卡组中的单卡跳转卡查页面
-
不用 jq(我不想)实现鼠标浮(hover)在单卡上弹出悬浮对话框显示卡片详情 -
在线编辑卡组,类似 YGOPro 编辑卡组功能(或许可以用 godot 写成桌面端?) - 原来做 DLM 的现在做 MD 了(MDM):「Master Duel Meta - Deck Builder」
完美实现我想要的所有需求(从录像提取卡组除外,待实现) -
获取 MDM 的卡组,当然可以做爬虫,但有现成的可以抄,试着抄现成:- 逆向目标:拓王神 组卡器 2.2 - 对应 MD 1.02 里的
masterduelmeta导出卡组.exe - pyinstxtractor 把
.exe反编译成.pyc - 由于每个
.pyc文件都有 magic head,pyinstaller 生成 exe 的时候会把 pyc 的 magic 部分去掉,所以在反编译的时候需要自己补齐 - 通过
struct文件获取前 4 个字节(Python 编译的版本),加上00 00 00 004 个字节(本来应该是时间戳,不重要)组成 magic head - 通过 WinHex 或者 hexed.it 等工具把 magic head 重新写入
.pyc文件开头 - 发现 pyinstxtractor 生成
.pyc的已经是还原了 magic head 后的版本了,我就是过期资料的受害者 - 在线反编译 pyc 或者 uncompyle6(不支持 Python 3.9 及以上,之前重装过电脑上只有 3.10,我还专门去装了个 3.8.6)把
.pyc/.pyo反编译成.py源文件 - 失败,原因不明。到目前为止沉没的时间成本已经够多了,该及时止损了,打住打住
- 逆向目标:拓王神 组卡器 2.2 - 对应 MD 1.02 里的
- 自己写爬虫
- 本来应该用异步请求库 aiohttp,但没有大规模用途,临时用 requests 就够了
- DLM 的反爬做得可以啊,赞叹(你以前不是爬过吗
什么记忆只有 7 秒的弱智金鱼),静态网页只有<a class="image-wrapper svelte-152ds40 card-image-loading" /a>的占位符,具体内容后续动态加载,进一步使用 Selenium + PhantomJS 模拟浏览器加载 JS - 获得的 HTML 用 Beautiful Soup 4(以及 lxml 提高效率)解析
- 还原卡名,
from urllib.parse import unquote解码 url 编码 - 卡片数据以前我是去 YGOPro 偷的根目录下的
card.cdb(sqlite3),现在正好手上一堆 MD 相关工具,基本人手一个转换好的cards.json,直接用现成的了 - 妈的优化做多了有点入脑了,老是满脑子效率,魔怔了属于是。随便写个脚本难道还能有百万吞吐?真的怪。直接
json.loads(file.read())读成字典暴力遍历就完事了 - 搞定,输入 MDM 网址,输出 ydk 格式卡组代码
- 顺手把批量转换卡名写了,支持将整个卡组切换为中文名、日文名、英文名
可部分选中,也提供一键复制按钮用脚本写的不考虑人机交互 - 爽到,从现在开始可以一行命令把
masterduelmeta.com的卡组抄到博客来了
最后还是重复造轮子了?
没有哦,masterduelmeta导出卡组.exe这个工具只能导出卡组,对其他格式毫无办法
而我有导出任何卡组的需求,比如《「NR 杯」卡组构筑》里用到的 NR 杯禁限卡表
ydk 卡组代码
众所周知,广为流传的 .ydk 格式简单易懂:
#main后面 - 主卡组#extra后面 - 额外卡组!side后面 - 副卡组
每行一个卡密,每个卡密代表一张卡。
#备注 随便写什么
#main
71039903
71039903
71039903
45467446
89631139
89631139
89631139
38517737
22804410
55410871
24094653
21082832
#extra
2129638
56532353
59822133
59822133
40908371
40908371
!side
20654247
43228023
感谢 Hugo 强大的 shortcode 功能 支持高度客制化玩法,允许我轻松实现下面的呈现效果。
卡查用的 百鸽;卡图来自momobako.com这个域名的 CDN(由知乎用户 Nanahira 提供)。
2022.5 更新:
- 重构:解析方式使用 Markdown 代码块代替之前的 Hugo shortcode
(混合 Go 的 HTML → JavaScript)- 样式:改进边框,利用 CSS 实现 3D 悬浮卡片特效
- 样式:改进排版,换用 SVG 强制规定尺寸和位置,支持无极缩放 & 动态自适应容器大小
- 优化:现在真的有检测图片,如果不存在则自动回退(fallback)的机制了(红色占位图)
- 优化:辅助排版时的占位图现在使用的是本地图片了(蓝色占位图),之前是第三方接口生成的
- 优化:占位图没有点击跳转的超链接,鼠标指针 hover 也不会变
- 优化:卡组信息不再解析所谓的「评论」,卡组就是卡组,就你话多,要评自己另外找地方 BB
- TODO:生成按钮,支持一键复制
ydk代码- TODO:自动生成外链,允许新窗口打开卡组(类似这样)
处理 ydk
这个格式真的蛮好,
| |
ygm 格式 卡组分享码
解析成功之后像「ygo-sem.cn 的 ydk / ygm 分享码互相转换」这样的工具做起来也很简单了。
| |
所谓 ygm 就是早年间安卓端 YGOMobile 的卡组分享码格式,现在已经被淘汰了。
(最新版的 YGOMobile 用的是下面提到的 DA 协议。)
而 ydk 被包括 YGOPro 在内的各种桌面端广泛支持和使用,并允许以.ydk格式的文件保存。
DA 协议分析
闭门造车不可取,有现成的可用没必要标新立异非要自己重新设计。
参考现有的《YGO 决斗助手协议》(简称 DA 协议)的设计完成长度压缩算法。这兄弟文档写得有点乱,费了点劲才看明白。
base64 编码「文本」是 3 字节 → 4 字节,平白多出 33% 的冗余,显然跟压缩沾不上边。
但这里记录的是「纯数值」,用 base64 旨在压缩长度——把一长串卡组信息压成一行字符。
不要挑我字眼。
单卡
每一种类不同的卡,为一个「29 位的二进制数」,具体组成为「
| |
卡组
按照 主卡组 + 额外卡组 + 副卡组 的顺序把单卡依次拼接起来即可。
还要注意记录各个卡组的单卡种类数量,并将数量也转换为固定长度的二进制数放在开头。
| 主卡组种类数量 | 额外卡组种类数量 | 副卡组种类数量 | 主卡组构成 | 额外卡组构成 | 副卡组构成 |
|---|---|---|---|---|---|
| 8 位 | 4 位 | 4 位 | 29 位 × n 种 | 29 位 × m 种 | 29 位 × p 种 |
| |
得到下面生成的链接:
http://deck.ourygo.top/ydk/show.html?ygotype=deck&v=1&d=B0Lh39z6rXHNuq9TRqS7vpSt-90tNgLdKDZaCCB-5lr07AzkNA1k4Gymk7KKdUnNu4A
打开链接 验证效果,完美。