18 Commits

Author SHA1 Message Date
mayx
2036ee2c4f Update 5 files
- /_tools/blogquine.py
- /_data/proxylist.yml
- /_layouts/default.html
- /deploy.sh
- /.readthedocs.yaml
2026-09-07 09:23:41 +00:00
mayx
a89e95869e Update 2 files
- /_data/ai-cache.json
- /_data/proxylist.yml
2026-09-03 02:35:45 +00:00
mayx
c217a52c70 Update 3 files
- /_posts/2026-09-01-vibe-coding2.md
- /_data/links.csv
- /_data/other_repo_list.csv
2026-08-31 16:00:07 +00:00
mayx
4b94d48330 Update 3 files
- /assets/js/blog-console.js
- /_data/proxylist.yml
- /_tools/envs_post-receive
2026-08-06 10:50:42 +00:00
mayx
2ec9345113 Update 3 files
- /assets/js/blog-console.js
- /_data/other_repo_list.csv
- /_data/proxylist.yml
2026-08-06 09:47:54 +00:00
mayx
987c604dea Update 3 files
- /assets/js/blog-console.js
- /BlogCard.svg
- /_layouts/default.html
2026-08-04 13:49:00 +00:00
mayx
8e0b6e11b3 Update 2 files
- /_data/other_repo_list.csv
- /games.md
2026-08-02 08:32:36 +00:00
mayx
317f5bdce7 Update 2 files
- /games.md
- /_data/ai-cache.json
2026-07-31 16:32:56 +00:00
mayx
89a0af5632 Update 5 files
- /_data/other_repo_list.csv
- /_posts/2026-08-01-terminal.md
- /index.html
- /_tools/envs_post-receive
- /games.md
2026-07-31 16:00:40 +00:00
Mayx
798f65eb97 Merge pull request #206 from Jingyuan-Zheng/codex/add-jingyuan-link
Add Jingyuan's blog
2026-07-27 19:50:32 +08:00
Jingyuan Zheng
05998cdc3f Use Chinese friend link details 2026-07-27 13:47:43 +02:00
Jingyuan Zheng
5d87b2c9d4 Add Jingyuan friend link 2026-07-27 13:42:42 +02:00
mayx
b8b29f86d5 Update 4 files
- /_data/other_repo_list.csv
- /_data/links.csv
- /nilaila-verify.txt
- /index.html
2026-07-18 09:39:55 +00:00
mayx
0e4e4d2fb7 Update 4 files
- /_data/other_repo_list.csv
- /_data/ai-cache.json
- /bo-ke-verify-24f0040157c07cc424b28b7b52ea734d.txt
- /_posts/2026-07-01-vibe-coding.md
2026-07-14 12:07:34 +00:00
mayx
7943cc7d6a Update 5 files
- /_data/other_repo_list.csv
- /index.html
- /_posts/2026-07-01-vibe-coding.md
- /assets/js/main_new.js
- /assets/js/main.js
2026-06-30 16:00:55 +00:00
Mayx
772e3ed0b7 Merge pull request #204 from exyone-js/master
添加友链 - Add exyone's blog links to links.csv
2026-06-25 15:50:29 +08:00
exyone
ee4c9acfde Update EXYONE blog URL in links.csv 2026-06-25 15:37:06 +08:00
exyone
2acc1f6fd7 Add exyone's blog links to links.csv 2026-06-25 14:41:12 +08:00
20 changed files with 2216 additions and 430 deletions

View File

@@ -12,5 +12,5 @@ build:
- mkdir Mabbs
- curl -L -o Mabbs/README.md https://github.com/Mabbs/Mabbs/raw/main/README.md
- bundle exec jekyll build --destination $READTHEDOCS_OUTPUT/html
- tar czvf MayxBlog.tgz -C $READTHEDOCS_OUTPUT html
- mv MayxBlog.tgz $READTHEDOCS_OUTPUT/html
- python3 _tools/blogquine.py $READTHEDOCS_OUTPUT/html MayxBlog.7z
- mv MayxBlog.7z $READTHEDOCS_OUTPUT/html

View File

@@ -77,7 +77,7 @@
y="0"
class="header"
data-testid="header"
>Mayx's Blog Article</text>
>Mayx's Blog Posts</text>
</g>
</g>

View File

@@ -178,5 +178,8 @@
"/2026/03/01/llm3.html": "这篇文章介绍了作者近期在LLM部署和应用方面的经历主要包括以下几个方面\n\n首先作者升级硬件从单张RTX4090 48GiB升级到双路RTX4090 48GiB并购买了TRX40+TR 3960X的主板套装用于运行GPT-OSS模型。随后作者尝试使用vLLM框架替换Ollama并成功配置了GPT-OSS模型达到了接近190Tps的性能。\n\n其次作者体验了DeepSeek 1M上下文模型发现其在处理长上下文任务时表现出色能够展现摘要无法捕捉的细节并成功生成简历、分析人格等。\n\n此外作者还尝试使用DeepSeek重构Mabbs并发现DeepSeek能够识别作者的博客信息这表明训练样本中包含了作者的信息。\n\n最后作者在8GiB内存的MacBook Pro上运行了LFM2.5-1.2B-Thinking模型并使用了Apollo软件体验了其快速的推理速度和良好的思考能力。作者总结认为AI的发展令人惊叹软件优化使其在有限硬件环境下也能运行。",
"/2026/04/14/ai-agent.html": "这篇文章介绍了“AI个人助理”Agent的发展现状和各种尝试。作者体验了OpenClaw、QClaw、WorkBuddy、Cline、LuckClaw和ApkClaw等不同的Agent项目发现它们在功能、易用性和性能上各有优劣。OpenClaw安装和使用存在困难国内大厂的QClaw和WorkBuddy则更易于上手但免费额度有限。作者认为开发任务更适合在编辑器集成AI中进行如GitHub Copilot。LuckClaw在微型开发板上运行表现出色ApkClaw则利用手机的优势操作移动应用。尽管Agent技术仍存在诸多问题但其应用场景不断拓展有望吸引更多人参与其中推动AI应用化进程。",
"/2026/05/01/virtual-net.html": "这篇文章介绍了作者在尝试异地组网搭建虚拟局域网时对多种组网工具的探索和体验。作者首先尝试了n2n但由于其项目停止更新且在NAT后的机器间存在掉线问题最终选择了WireGuard作为主要方案。文章详细描述了WireGuard的配置过程包括在Linux、OpenWrt和openEuler系统上的安装和配置并遇到了各种各样的挑战例如在红米AX3000路由器上找不到内核模块以及在openEuler上缺少WireGuard相关包。此外文章还提到了Netmaker和Headscale等WireGuard的控制平面以及VNT和EasyTier等其他组网工具并总结了最终选择WireGuard的原因简单、够用、可靠性不错且已经投入了大量配置。",
"/2026/06/01/dedupe.html": "这篇文章介绍了如何通过优化游戏资源文件来节约游戏占用的硬盘空间。作者由于Mac只有256GiB的硬盘存储空间在下载了几十部游戏后空间不足于是寻找解决方法。文章主要介绍了以下几点\n\n1. 使用jdupes工具去除重复素材作者发现许多游戏使用相同的引擎和素材导致硬盘空间浪费。通过使用jdupes工具进行硬链接可以有效去除重复文件节约空间。\n\n2. 不同引擎的处理方式:\n - 对于RPG制作大师MV/MZ作者使用RPG Maker Decrypter工具解密资源文件并将图片转换为WebP格式以压缩空间。\n - 对于RPG制作大师XP/VX/VA作者使用mkxp-z工具跨平台运行游戏并通过RPG Maker Decrypter解包资源文件与RTP素材合并后进行去重。\n - 对于Ren'Py游戏作者使用unrpa工具解包rpa文件但由于公共资源不多仅在系列游戏情况下进行解包。\n\n3. 最终效果通过以上优化作者成功将游戏文件夹大小从47G降至33G节约了大量硬盘空间。"
"/2026/06/01/dedupe.html": "这篇文章介绍了如何通过优化游戏资源文件来节约游戏占用的硬盘空间。作者由于Mac只有256GiB的硬盘存储空间在下载了几十部游戏后空间不足于是寻找解决方法。文章主要介绍了以下几点\n\n1. 使用jdupes工具去除重复素材作者发现许多游戏使用相同的引擎和素材导致硬盘空间浪费。通过使用jdupes工具进行硬链接可以有效去除重复文件节约空间。\n\n2. 不同引擎的处理方式:\n - 对于RPG制作大师MV/MZ作者使用RPG Maker Decrypter工具解密资源文件并将图片转换为WebP格式以压缩空间。\n - 对于RPG制作大师XP/VX/VA作者使用mkxp-z工具跨平台运行游戏并通过RPG Maker Decrypter解包资源文件与RTP素材合并后进行去重。\n - 对于Ren'Py游戏作者使用unrpa工具解包rpa文件但由于公共资源不多仅在系列游戏情况下进行解包。\n\n3. 最终效果通过以上优化作者成功将游戏文件夹大小从47G降至33G节约了大量硬盘空间。",
"/2026/07/01/vibe-coding.html": "这篇文章介绍了作者使用AI Agent进行Vibe Coding的体验。作者通过AI Agent生成代码实现了博客的PJAX功能和一个立直麻将Wordle小游戏。在使用AI Agent的过程中作者发现它能够理解整个项目的代码并且能够根据需求进行修改和优化。然而作者也遇到了一些问题例如生成的代码质量不高需要手动优化和调试。\n\n作者首先使用AI Agent为博客添加了PJAX功能实现了无刷新加载页面。虽然生成的代码质量不高但作者还是成功地实现了该功能。接着作者使用AI Agent生成了一个立直麻将Wordle小游戏并对其进行了优化和修改。作者还遇到了一些技术问题例如字体兼容性和役种计算问题但最终都通过AI Agent解决了。\n\n通过这次体验作者认为Vibe Coding的体验相当不错但也存在一些问题。完全由AI生成的代码可能会出现问题需要手动优化和调试。然而如果能够正确地使用AI Agent也可以实现高质量的代码。作者还提到有时候自己调查和研究比问AI更有效可以避免浪费时间和精力。",
"/2026/08/01/terminal.html": "这篇文章介绍了作者利用AI助手制作终端版博客的经历。起初作者想在博客上添加一个终端功能允许用户在浏览器中使用真正的Linux访问博客。作者选择了基于WASM Linux的方案并让AI助手开发了一个可以在浏览器中执行JS的设备文件以实现与外界的通信。在此基础上作者实现了列出文章、查看文章、打开文章和查看评论等功能。然而该系统存在一些限制如不能使用管道符和异步操作。作者还尝试了另一种方案即基于JSNix的版本虽然不是真正的Linux但模拟得非常到位且具有更好的兼容性和加载速度。最终作者成功制作了两个版本的终端版博客并表示对AI助手的强大功能感到满意。",
"/2026/09/01/vibe-coding2.html": "这篇文章介绍了作者使用AI进行Vibe Coding的体验。两个月前作者首次体验了Vibe Coding但当时对AI的能力持怀疑态度。然而在使用AI进行终端版博客开发后作者意识到AI的能力可能超过了自己的想象。作者开始使用国内的免费AI模型腾讯混元Hy3进行各种项目开发并取得了令人惊讶的成果。\n\n作者使用AI开发了 REPL 终端、WebMCP 项目、博客 API并将 WebMCP 应用于 AI让 AI 调用函数。作者还使用 AI 重放了一个即将关服的游戏的离散快照让游戏在浏览器中运行。AI 分析了游戏的 WebSocket+Protobuf 协议,并用 Python 和 JavaScript 实现了一个服务端,让游戏在浏览器中运行。\n\n此外作者还使用 AI 制作了一个完整的麻将对局引擎,包括人机对战功能。作者让 AI 录制了几把实际对局的包,并理解了数据包的时序,最终 AI 成功地制作出了完整的对局引擎。\n\n作者还探索了其他功能如挂载本地文件夹、基于 WebRTC 的局域网内组网和使用 VLESS 协议的网关。"
}

View File

@@ -2,7 +2,7 @@ title,link,feed_url,description
花火学园,https://www.sayhanabi.net/,,和谐融洽的ACG交流以及资源聚集地
资源统筹局,https://gkdworld.com/,,统筹保管用户分享的资源
贫困的蚊子,https://mozz.ie/,https://mozz.ie/index.xml,
极客兔兔,https://geektutu.com/,https://geektutu.com/atom.xml,致力于分享有趣的技术实践
极客兔兔,https://geektutu.com/,https://geektutu.com/feed.xml,致力于分享有趣的技术实践
维基萌,https://www.wikimoe.com/,https://www.wikimoe.com/rss,萌即是正义一名热爱acg的前端设计师的小站
7gugu's blog,https://www.7gugu.com/,https://7gugu.com/index.php/feed/,"一个用来存放我爱好的地方,编程,摄影之类的空间"
Kingfish404,https://blog.kingfish404.cn/,https://blog.kingfish404.cn/index.xml,"Stay curious,stay naive. WUT. Jin Yu's Blog"
@@ -23,3 +23,6 @@ Restent's Notebook,https://blog.gxres.net/,https://blog.gxres.net/atom.xml,不
RavelloH's Blog,https://ravelloh.com,https://ravelloh.com/feed.xml,Beginning of meditation.
初然忆,https://www.imcry.vip,https://www.imcry.vip/index.xml,初心如初见,然忆似流年。
姓王者,https://xingwangzhe.fun/,https://xingwangzhe.fun/rss.xml,探索、学习、进步、创造无限可能!
EXYONE@BLOG:~$,https://exyon.ee,https://exyon.ee/feed.xml,一隅藏天地,流水遇知音。
小景,https://jingyuan-zheng.github.io/zh/,https://jingyuan-zheng.github.io/zh/index.xml,随心分享有趣的技术、开源项目与生活记录。
热汤茶馆,https://blog.hotsouprealm.top/,https://blog.hotsouprealm.top/atom.xml,茶凉了可以续话断了可以接这里是hahahotsoup的茶馆。
1 title link feed_url description
2 花火学园 https://www.sayhanabi.net/ 和谐融洽的ACG交流以及资源聚集地
3 资源统筹局 https://gkdworld.com/ 统筹保管用户分享的资源
4 贫困的蚊子 https://mozz.ie/ https://mozz.ie/index.xml
5 极客兔兔 https://geektutu.com/ https://geektutu.com/atom.xml https://geektutu.com/feed.xml 致力于分享有趣的技术实践
6 维基萌 https://www.wikimoe.com/ https://www.wikimoe.com/rss 萌即是正义!一名热爱acg的前端设计师的小站!
7 7gugu's blog https://www.7gugu.com/ https://7gugu.com/index.php/feed/ 一个用来存放我爱好的地方,编程,摄影之类的空间
8 Kingfish404 https://blog.kingfish404.cn/ https://blog.kingfish404.cn/index.xml Stay curious,stay naive. WUT. Jin Yu's Blog
23 RavelloH's Blog https://ravelloh.com https://ravelloh.com/feed.xml Beginning of meditation.
24 初然忆 https://www.imcry.vip https://www.imcry.vip/index.xml 初心如初见,然忆似流年。
25 姓王者 https://xingwangzhe.fun/ https://xingwangzhe.fun/rss.xml 探索、学习、进步、创造无限可能!
26 EXYONE@BLOG:~$ https://exyon.ee https://exyon.ee/feed.xml 一隅藏天地,流水遇知音。
27 小景 https://jingyuan-zheng.github.io/zh/ https://jingyuan-zheng.github.io/zh/index.xml 随心分享有趣的技术、开源项目与生活记录。
28 热汤茶馆 https://blog.hotsouprealm.top/ https://blog.hotsouprealm.top/atom.xml 茶凉了可以续,话断了可以接,这里是hahahotsoup的茶馆。

View File

@@ -2,527 +2,244 @@ repo_url
http://gdatura24gtdy23lxd7ht3xzx6mi7mdlkabpvuefhrjn4t5jduviw5ad.onion/Mayx/mayx
http://git.dkforestseeaaq2dqz2uflmlsybvnq2irzn4ygyvu53oazyorednviid.onion/mayx/blog
http://giteabolfdejtdzblkooalqei6jr67imiugmhtsh6ocw4hlj5a4q.b32.i2p/mayx/blog
https://lavaforge.org/mayx/blog
https://sij.ai/mayx/blog
https://repobase.net/mayx/blog
https://gitlab.lain.la/mayx/mayx.pages.lain.la
https://gitplac.si/mayx/mayx.gitpage.si
https://gitnet.fr/mayx/blog
https://opencommit.eu/mayx/blog
https://forge.fedoraproject.org/mabbs/blog
https://tilde.club/~mayx/git/blog.git/
https://git.envs.net/Mayx/mayx
https://tildegit.org/Mayx/mayx
https://git.tilde.town/mayx/blog
https://gitlab.haskell.org/mayx/mayx
https://lavaforge.org/mayx/blog
https://repo2.serv00.com/git/pub/Mayx/mayx/
https://git.pixie.town/mayx/mayx
https://sij.ai/mayx/blog
https://git.projectnightcrawler.dev/mayx/blog
https://codefloe.com/mayx/blog
https://git.pixie.town/mayx/blog
https://git.minetest.land/Mayx/blog
http://1.6.141.109:3000/mayx/blog
http://52.28.156.42/mayx/blog
https://code.dsconce.space/mayx/blog
http://101.66.229.132:61088/mayx/blog
https://git.bp-web.app/mayx/blog
https://mygit.iexercice.com/mayx/blog
http://162.215.134.149:4000/mayx/blog
http://durfee.mycrestron.com:3000/mayx/blog
https://gitea.nongnghiepso.com/mayx/blog
https://codes.tools.asitavsen.com/mayx/blog
https://git.zeroplay.io/mayx/blog
http://45.33.87.87/mayx/blog
http://168.126.28.36:3000/mayx/blog
http://69.62.77.234:8888/mayx/blog
http://112.219.147.186:7000/mayx/blog
https://git.rootfinlay.co.uk/mayx/blog
https://gitea.belanjaparts.com/mayx/blog
http://185.208.225.190:3000/mayx/blog
http://116.204.34.35:12000/mayx/blog
https://git.Apture.io/mayx/blog
https://gitea.jasonstolle.com/mayx/blog
http://8.134.61.107:3000/mayx/blog
http://47.107.88.161:3000/mayx/blog
http://142.171.47.170:3000/mayx/blog
http://111.231.146.230:8418/mayx/blog
https://git.pwaapp.cc/mayx/blog
https://an360.top/mayx/blog
http://111.119.244.185:3000/mayx/blog
https://git.influxfin.com/mayx/blog
http://219.157.255.213:25311/mayx/blog
https://git.vekus.ru/mayx/blog
http://116.204.75.78:6180/mayx/blog
http://109.228.48.121:8000/mayx/blog
http://27.124.12.222:3000/mayx/blog
https://gitea.hintsight.com/mayx/blog
http://blackobelisk.xyz:3000/mayx/blog
https://git.the-kn.com/mayx/blog
https://git.wangxinlei.cn/mayx/blog
http://123.56.193.182:3000/mayx/blog
http://167.172.7.198:8081/mayx/blog
https://gitea.meetgu.ru/mayx/blog
http://116.236.50.103:8789/mayx/blog
https://git.paulll.cc/mayx/blog
http://94.224.160.69:7990/mayx/blog
https://gitea.ekjeong.synology.me/mayx/blog
https://git.daoyoucloud.com/mayx/blog
https://code.bitahub.com/mayx/blog
https://repo.gusdya.net/mayx/blog
https://gitea.synapsetec.cn/mayx/blog
http://gitea.yunshanghub.com:8081/mayx/blog
http://113.177.27.200:2033/mayx/blog
http://152.69.204.151:3000/mayx/blog
http://207.180.229.193:3001/mayx/blog
http://34.81.52.16/mayx/blog
http://123.57.16.111:3000/mayx/blog
https://lius.familyds.org:3000/mayx/blog
http://git.chaojing-film.com:3000/mayx/blog
https://git.nusaerp.com/mayx/blog
http://35.207.205.18:3000/mayx/blog
http://git.zjsciot.com:3000/mayx/blog
https://gitea.ontoast.uk/mayx/blog
http://121.36.37.70:15501/mayx/blog
http://187.216.152.151:9999/mayx/blog
http://116.63.173.179:8001/mayx/blog
http://114.116.79.196/mayx/blog
http://121.40.40.177:3000/mayx/blog
http://178.254.35.219:3000/mayx/blog
http://2.59.132.109:3001/mayx/blog
http://81.71.148.57:8080/mayx/blog
https://git.lmskaran.com/mayx/blog
http://154.86.0.30:3000/mayx/blog
http://52.23.128.62:3000/mayx/blog
http://120.46.222.128:10021/mayx/blog
http://120.26.108.239:9188/mayx/blog
http://47.111.17.177:3000/mayx/blog
https://k0ki-dev.com/mayx/blog
http://110.42.45.89:2052/mayx/blog
https://git.furcom.org/mayx/blog
http://34.102.70.200:3000/mayx/blog
https://gitea.oio.cat/mayx/blog
https://git.karma-riuk.com/mayx/blog
https://git.7o9o.net/mayx/blog
https://git.gupaoedu.cn/mayx/blog
https://git.7milch.com/mayx/blog
https://git.sitenevis.com/mayx/blog
https://dreamplacesai.de/mayx/blog
http://1.94.13.224:9080/mayx/blog
http://gitea.coderpath.com/mayx/blog
http://43.136.169.169:3000/mayx/blog
http://121.196.213.68:3000/mayx/blog
https://git.micahmoore.io/mayx/blog
https://git.anatid.net/mayx/blog
https://git.lekai.info/mayx/blog
http://135.235.225.198:3000/mayx/blog
http://117.72.114.197:3000/mayx/blog
https://git.ashcloud.com/mayx/blog
https://git.novaa.xyz/mayx/blog
http://101.46.208.93:3000/mayx/blog
http://23.94.57.60:3000/mayx/blog
https://gitea.sciotech.cn/mayx/blog
http://8.140.250.85:3000/mayx/blog
http://202.65.194.19:3000/mayx/blog
http://101.201.34.43:3000/mayx/blog
https://git.gloje-rinchen-dorjee-rinpoche-buddhist-monastery.org/mayx/blog
http://101.35.227.2:3000/mayx/blog
http://209.141.47.52:3000/mayx/blog
http://60.204.158.188:3000/mayx/blog
http://60.204.156.211:3000/mayx/blog
http://nas.bi1kbu.com:8418/mayx/blog
http://1.94.178.207:3000/mayx/blog
https://gitea.tsaida.synology.me/mayx/blog
https://git.teygaming.com/mayx/blog
http://osztromok.com:3164/mayx/blog
http://175.209.53.134:3030/mayx/blog
http://39.107.226.169:3000/mayx/blog
http://39.96.211.118:3000/mayx/blog
http://121.37.47.20:3000/mayx/blog
https://git.antropix.dev/mayx/blog
http://15.237.198.144/mayx/blog
http://183.6.120.101:30000/mayx/blog
http://57.129.94.190:3000/mayx/blog
https://gitea.micro-stack.org/mayx/blog
https://gitea.temp.brentgruber.com/mayx/blog
http://47.102.147.170:3050/mayx/blog
http://172.236.250.154:3000/mayx/blog
http://54.198.134.152:3000/mayx/blog
http://121.41.35.226:11011/mayx/blog
http://47.111.1.12:3000/mayx/blog
https://nelgit.nelpi.co.uk/mayx/blog
http://8.141.91.86:3000/mayx/blog
http://117.72.15.187:3000/mayx/blog
http://81.70.30.91:3000/mayx/blog
http://106.54.211.95:3000/mayx/blog
http://210.245.20.73:3333/mayx/blog
http://43.248.97.109:3000/mayx/blog
http://113.207.86.104:3080/mayx/blog
http://39.96.195.72:10082/mayx/blog
http://172.172.102.93:3000/mayx/blog
http://115.120.245.164:3000/mayx/blog
http://35.194.179.90:3000/mayx/blog
http://66.179.208.56:3001/mayx/blog
http://121.43.60.72:9015/mayx/blog
http://171.80.13.66:9112/mayx/blog
http://223.108.157.174:3000/mayx/blog
http://120.24.249.56/mayx/blog
http://54.179.203.2:3000/mayx/blog
http://14.103.246.124:16000/mayx/blog
http://152.42.207.183:3000/mayx/blog
http://47.99.60.81:10082/mayx/blog
http://120.211.66.170:8418/mayx/blog
https://gitea.vilcap.com/mayx/blog
http://121.196.245.62/mayx/blog
http://8.138.142.17:3000/mayx/blog
http://www.koelndom.cn:13030/mayx/blog
http://209.127.59.74:3000/mayx/blog
https://git.dotb.cloud/mayx/blog
https://gitea.augeo.dev/mayx/blog
http://120.46.23.215:3000/mayx/blog
http://121.41.2.71:3000/mayx/blog
http://110.41.177.80:5000/mayx/blog
https://gitea.dsmaster.myds.me/mayx/blog
http://www.scserverddns.top:13000/mayx/blog
https://git.lucas-michel.fr/mayx/blog
https://git.imvictor.tech:2/mayx/blog
http://47.112.137.193:3000/mayx/blog
http://58.38.123.148:3176/mayx/blog
http://docker.clhero.fun:3000/mayx/blog
https://bdgit.educoder.net/mayx/blog
http://e19510c831.iok.la/mayx/blog
http://119.45.49.212:3000/mayx/blog
https://code.antopie.org/mayx/blog
https://git.serenetia.com/mayx/blog
https://vcs.cozydsp.space/mayx/blog
http://115.190.107.87:3000/mayx/blog
http://106.12.50.144:8081/mayx/blog
https://code.wxk8.com/mayx/blog
http://8.155.58.218:9000/mayx/blog
http://fanlibo.i234.me:8418/mayx/blog
https://git.temporaryname.org/mayx/blog
https://Repo.gusdya.net/mayx/blog
https://git.m.ctf.arrobe.fr/mayx/blog
http://69.62.64.52:3333/mayx/blog
https://git.flymiracle.com/mayx/blog
http://106.14.138.181:3000/mayx/blog
https://git.yyuu.xyz/mayx/blog
http://39.107.70.124:3000/mayx/blog
https://git.stormrain.cn/mayx/blog
https://git.deuxfleurs.fr/mayx/blog
https://www.simpra.org:3000/mayx/blog
http://8.148.31.14:3000/mayx/blog
http://47.94.246.1:3000/mayx/blog
https://www.arcbyte.dev/mayx/blog
https://scm.bcorex.e3labs.net/mayx/blog
http://58.17.14.95:8001/mayx/blog
https://hero-cloud-stg-code.cnbita.com/mayx/blog
http://101.37.69.204:3000/mayx/blog
https://gitea.tecamino.com/mayx/blog
http://39.99.175.172:8000/mayx/blog
http://8.138.13.251:3000/mayx/blog
http://104.254.131.244:3000/mayx/blog
https://gitea.alacloud.de/mayx/blog
https://git.tobiasweise.dev/mayx/blog
https://code.cif.su/mayx/blog
https://git.cynic.moe/mayx/blog
https://git.muellers-software.org/mayx/blog
http://8.130.128.130:3000/mayx/blog
https://repos.fbpx.io/mayx/blog
https://git.cavemanon.xyz/mayx/blog
http://svn.rivastudio.cn/mayx/blog
http://39.98.126.115:8080/mayx/blog
http://46.202.189.66:3000/mayx/blog
http://82.26.157.11:3001/mayx/blog
http://123.60.146.54:3000/mayx/blog
http://8.140.248.67:3000/mayx/blog
http://118.178.172.49:3000/mayx/blog
https://gitea.lasallesaintdenis.com/mayx/blog
http://123.57.225.51:3000/mayx/blog
http://8.130.135.159:3000/mayx/blog
https://git.suo0.com/mayx/blog
http://103.228.160.127:3100/mayx/blog
https://git.dshkabatur.ru/mayx/blog
https://gitea.hoba.dedyn.io/mayx/blog
https://git.wegoo.ltd/mayx/blog
http://114.203.209.83:3000/mayx/blog
http://47.100.111.106:3000/mayx/blog
http://47.103.78.70:3000/mayx/blog
http://47.100.208.160:51300/mayx/blog
http://113.44.218.8:3000/mayx/blog
https://git.cenoq.com/mayx/blog
http://8.152.205.35:3000/mayx/blog
http://120.210.80.160:3000/mayx/blog
http://194.5.152.156:3000/mayx/blog
http://8.155.172.147:3001/mayx/blog
https://git.erfmann.dev/mayx/blog
https://git.weavefun.com:5443/mayx/blog
http://58.65.162.118:3000/mayx/blog
https://git.arkon.solutions/mayx/blog
http://8.131.93.145:54082/mayx/blog
http://111.9.31.174:10007/mayx/blog
https://forgejo.bridgetownrb.com/mayx/blog
http://54.199.96.217:3000/mayx/blog
http://20.219.0.85:3000/mayx/blog
https://gitea.doinlab.com/mayx/blog
https://git.7af.ru/mayx/blog
https://gitea.yimoyuyan.cn/mayx/blog
https://git.apextoaster.com/mayx/blog
https://hub.open-verse.ai/mayx/blog
http://221.203.14.217:3000/mayx/blog
https://git.sophiagwen.au/mayx/blog
http://139.196.96.28:13000/mayx/blog
https://dev.kiramtech.com/mayx/blog
https://git.123doit.com/mayx/blog
http://62.43.207.91:8889/mayx/blog
https://git.johntsai.online/mayx/blog
https://gitea.css-sistemas.com.br/mayx/blog
https://git.f4e.lol/mayx/blog
http://47.113.145.232:3000/mayx/blog
http://47.115.212.237:3000/mayx/blog
http://72.61.229.93:4000/mayx/blog
https://lishan148.synology.me:3014/mayx/blog_cn
http://1.95.221.174:3000/mayx/blog
https://git.huwhy.cn/mayx/blog_cn
http://119.91.35.154:3000/mayx/blog_cn
http://110.42.101.39:13000/mayx/blog_cn
http://39.101.74.135:5000/mayx/blog_cn
http://124.236.46.74:9103/mayx/blog_cn
http://123.57.130.140:3000/mayx/blog_cn
http://112.124.49.128:3000/mayx/blog_cn
http://118.24.46.223:3000/mayx/blog_cn
http://s3.v100.vip:31057/mayx/blog_cn
https://www.syq.im:2025/mayx/blog_cn
http://101.33.225.95:3000/mayx/blog_cn
http://45.55.138.82:3000/mayx/blog_cn
http://82.156.121.2:3000/mayx/blog_cn
http://118.24.129.148:3000/mayx/blog_cn
http://58.241.155.106:10140/mayx/blog_cn
http://120.48.141.82:3000/mayx/blog_cn
http://61.178.84.89:8998/mayx/blog_cn
http://82.156.111.58:3000/mayx/blog_cn
https://git.saike.fun:9755/mayx/blog_cn
https://git.cool2645.com/mayx/blog_cn
http://1.95.173.44:3000/mayx/blog_cn
http://58.221.157.122:3000/mayx/blog_cn
https://gitlab.liruwei.cn/mayx/blog_cn
http://61.190.74.90:9900/mayx/blog_cn
http://49.234.27.222:3000/mayx/blog_cn
http://8.153.70.81:30001/mayx/blog_cn
http://175.27.229.211:3000/mayx/blog_cn
http://106.55.174.214:3000/mayx/blog_cn
https://git.yidaimingjvn.xyz/mayx/blog_cn
http://39.105.67.143:3000/mayx/blog_cn
http://8.140.232.131:8100/mayx/blog_cn
http://82.156.89.21:3000/mayx/blog_cn
https://git.sskuaixiu.com/mayx/blog_cn
http://xujiesoft.vicp.net:3000/mayx/blog_cn
http://113.44.36.103:23000/mayx/blog_cn
https://git.mingliqiye.com/mayx/blog_cn
http://119.29.194.155:8894/mayx/blog_cn
http://58.213.60.6:19000/mayx/blog_cn
http://36.153.162.171:3000/mayx/blog_cn
http://47.92.113.131:3000/mayx/blog
http://gyc.myds.me:4000/mayx/blog
https://git.tablet.sh/mayx/blog
https://git.gnyra.com/mayx/blog
https://git.graveyard.sh/mayx/blog
https://git.nathanspackman.com/mayx/blog
https://git.rmarl.in/mayx/blog
http://git.mynas71.myds.me/mayx/blog
https://git.4lsa.com/mayx/blog
https://rlgit.pro/mayx/blog
https://git.veraskolivna.net/mayx/blog
https://git.lifetop.net/mayx/blog
https://gitea.jnyuxia.com/mayx/blog
http://git.liuhung.com/mayx/blog
https://gitea.adber.tech/mayx/blog
https://gitea.hello.faith/mayx/blog
https://tea.neuron.my/mayx/blog
https://git.violka-it.net/mayx/blog
https://git.adityagupta.dev/mayx/blog
https://git.danpeak.co.uk/mayx/blog
https://gitea.mynas-lechner.de/mayx/blog
https://git.automathon.org/mayx/blog
https://git.esen.gay/mayx/blog
https://git.webtims.ru/mayx/blog
https://gitea.personalsoftware.space/mayx/blog
https://gitlab.iplusus.com/mayx/blog
https://gitea.zachl.tech/mayx/blog
https://git.miasma-os.com/mayx/blog
https://gitea.nacsity.cn/mayx/blog
https://gitea.diputadosalta.gob.ar/mayx/blog
https://ttym.space/mayx/blog
https://getskill.work/mayx/blog
https://suprasage.com/mayx/blog
https://git.zakum.cn/mayx/blog
https://gitea.amazingcoders.com/mayx/blog
https://gitea.kamilklecha.dev/mayx/blog
http://47.109.103.110:9000/mayx/blog_cn
http://47.105.124.101:3000/mayx/blog_cn
http://49.232.183.190:3000/mayx/blog_cn
http://git.zxkedu.com:33769/mayx/blog_cn
https://code.wemediacn.com/mayx/blog_cn
http://51.159.198.233:3000/mayx/blog
https://gitea.adriangonzalezbarbosa.eu/mayx/blog
https://git.legatus.ru/mayx/blog
https://git.kayashov.keenetic.pro/mayx/blog
http://47.104.241.192:19999/mayx/blog_cn
http://47.98.148.146:1026/mayx/blog_cn
http://119.96.62.56:3000/mayx/blog_cn
http://101.42.28.156:3000/mayx/blog_cn
http://106.55.0.66:31807/mayx/blog_cn
https://gitea.gentronhealth.com/mayx/blog_cn
http://43.143.209.246:6300/mayx/blog_cn
http://152.136.158.133:36512/mayx/blog_cn
http://yidaima.cn:6008/mayx/blog_cn
http://47.113.101.80:3000/mayx/blog_cn
http://82.156.98.34:3000/mayx/blog_cn
http://zgd.synology.me:8418/mayx/blog_cn
https://git.zguiy.com/mayx/blog_cn
http://58.221.216.202:3000/mayx/blog_cn
http://39.100.183.95:88/mayx/blog_cn
http://www.xshideserver.com:3000/mayx/blog_cn
http://124.223.54.62:28/mayx/blog_cn
http://159.75.131.235:3001/mayx/blog_cn
http://1.117.67.95:3000/mayx/blog_cn
http://103.236.53.208:3000/mayx/blog_cn
http://118.195.135.194:3000/mayx/blog_cn
http://81.70.102.154/mayx/blog_cn
http://154.8.164.149:3000/mayx/blog_cn
http://111.228.34.40:3000/mayx/blog_cn
http://82.156.249.211:3000/mayx/blog_cn
http://36.133.248.69:3088/mayx/blog_cn
http://220.205.16.27:18081/mayx/blog_cn
http://81.69.221.216:3000/mayx/blog_cn
http://183.204.60.122:10081/mayx/blog_cn
http://43.139.240.37:17000/mayx/blog_cn
http://159.75.27.114:3000/mayx/blog_cn
http://arcreya.top/mayx/blog_cn
https://code.tczkiot.com/mayx/blog_cn
http://111.170.153.123:3000/mayx/blog_cn
http://xeroworld.team/mayx/blog_cn
https://gitea.wuyuank.com/mayx/blog_cn
http://47.117.245.9:17701/mayx/blog_cn
https://git.sunlix.one/mayx/blog_cn
http://47.106.222.181:20511/mayx/blog_cn
http://101.43.95.130:3001/mayx/blog_cn
https://gitea.myat4.com/mayx/blog_cn
http://118.24.161.24:3000/mayx/blog_cn
http://githanea.s.odn.cc/mayx/blog_cn
https://git.dev.chuweizi.com/mayx/blog
http://35.175.189.8/mayx/blog
http://meowug.com:8418/mayx/blog_cn
http://36.138.125.206:3000/mayx/blog_cn
https://git.4lcap.com/mayx/blog_cn
http://59.110.175.62:4322/mayx/blog_cn
https://www.luluvip.cn:8419/mayx/blog_cn
http://xianyuhome.cn:11013/mayx/blog_cn
https://git.chatumbrella.online/mayx/blog
https://silica.codes/mayx/blog
https://git.crystalyx.net/mayx/blog
https://gittea.dev/mayx/blog
https://git.newnaturalphilosophy.org/mayx/blog
https://code.infininov.com/mayx/blog
http://gitea.mcelwain.net/mayx/blog
https://chunkks.com/mayx/blog
https://gitea.earthmanrpg.me/mayx/blog
https://ndiuky.site/mayx/blog
https://src.enterpriselinux.social/mayx/blog
https://gitea.grxe.io/mayx/blog
https://git.mhworld.net/mayx/blog
https://blvckout.foo/mayx/blog
https://gitea.accept.dev.dbf.nl/mayx/blog
https://git.ke5.de/mayx/blog
https://git.jhossain.online/mayx/blog
http://gitea.xsec.fun/mayx/blog
https://barhoum-lab.fr/mayx/blog
https://git.fedaya.net/mayx/blog
http://gitea.nakile.fr/mayx/blog
https://redev.lol/mayx/blog
http://git.zfxfzb.com/mayx/blog
https://papi.tkpups.com/mayx/blog
https://git.beyond-a-i.org/mayx/blog
http://huanghomenas2.myqnapcloud.com:4000/mayx/blog_cn
http://43.142.166.108:10082/mayx/blog_cn
https://tm-jikayo.com/mayx/blog_cn
http://zzdgitea.stnav.com/mayx/blog_cn
http://1.117.66.197:3000/mayx/blog_cn
http://git.zhmight.com/mayx/blog_cn
https://intl-dev.gaia888.com/mayx/blog_cn
http://gitea.snailtrack.cn/mayx/blog_cn
http://ydds.cloud:3000/mayx/blog_cn
http://120.24.50.145:3000/mayx/blog_cn
https://code.draussenfunker.de/mayx/blog_cn
https://git.dinsor.co.th/mayx/blog
https://ofibohost.com/mayx/blog
https://lab.iishka.net/mayx/blog
http://www.arkproject.top/mayx/blog
http://www.bkandssp.cn:30/mayx/blog
https://gitea.spitaki.cloud/mayx/blog
https://git.codle.ru/mayx/blog
https://codeop.ru/mayx/blog
https://git.mirocom.org/mayx/blog
http://gitea.ydxtool.com/mayx/blog
http://18.167.251.121:10003/mayx/blog
http://39.98.171.121:53000/mayx/blog
https://gitea.malxte.de/mayx/blog
https://git.nizart.me/mayx/blog
https://git.ddns.net/mayx/blog
http://222.85.214.245:9776/mayx/blog
https://git.kraevsky.ru/mayx/blog
https://ruyiscx.cloud:3000/mayx/blog
https://git.0xee.eu/mayx/blog
https://gitea.deitglobal.com/mayx/blog
https://git.crwlr.ir/mayx/blog
https://git.nozora.top/mayx/blog
https://git.sortug.com/mayx/blog
https://aivyx-gitea.cloud/mayx/blog
https://git.edenit.co.kr/mayx/blog
https://git.catgirlsneed.homes/mayx/blog
https://git.eldev.netcraze.pro/mayx/blog
http://110.41.184.238:3000/mayx/blog
http://47.108.255.216:3000/mayx/blog_cn
https://gitea.molietech.com/mayx/blog_cn
http://58.87.88.234:3000/mayx/blog_cn
http://210.75.240.13:3000/mayx/blog_cn
https://git.xz-i.com:30443/mayx/blog_cn
https://git.fynn.vip/mayx/blog_cn
http://119.91.212.17:3000/mayx/blog_cn
http://git.hbg99.com:8080/mayx/blog_cn
https://git.eplg.services/mayx/blog
http://89.167.38.168:3001/mayx/blog
http://namonba.asuscomm.com:3001/mayx/blog
http://109.199.98.226:3001/mayx/blog
https://git.extra.eiffel.com/mayx/blog
https://gitea.digitanie.org/mayx/blog
https://git.xleed.com/mayx/blog
https://qlcodegitserver.online/mayx/blog
https://gitea.vvzvlad.xyz/mayx/blog
https://git.supernets.org/mayx/blog
https://git.digitaltelepresence.com/mayx/blog
https://git.hrfee.pw/mayx/blog
https://git.libregaming.org/mayx/blog
https://git.kaki87.net/mayx/blog
https://forgejo.vanten-s.com/mayx/blog
https://git.heartnn.com/mayx/blog
https://git.joinplu.me/mayx/blog
https://git.research.dezeeuw.ca/mayx/blog
http://149.104.29.239:8081/mayx/blog
http://ysx.myds.me:3005/mayx/blog
http://124.71.169.183:3000/mayx/blog
https://git.csi-kjsce.org/mayx/blog
https://hiwifi.denq.us:8418/mayx/blog
http://39.108.124.198:3000/mayx/blog
http://1090391-twk8saas.tmweb.ru/mayx/blog
https://git.msoucy.me/mayx/blog
https://git.niisse.net/mayx/blog
http://139.224.24.61:3000/mayx/blog
http://140.120.108.238:49308/mayx/blog
http://220.132.16.87:3000/mayx/blog
http://git.chilidoginteractive.com:3000/mayx/blog_cn
https://git.thunder-data.cn/mayx/blog_cn
https://git.cukak.com/mayx/blog_cn
https://git.ixu.me/mayx/blog_cn
http://git.uhfdemo.com/mayx/blog_cn
http://43.143.142.38:7001/mayx/blog_cn
http://111.230.243.127:3000/mayx/blog_cn
http://git.qniao.cn/mayx/blog_cn
https://gitea.smartechouse.com/mayx/blog_cn
http://git.feashow.cn/mayx/blog_cn
https://git.panda-number.one/mayx/blog
https://datacortex.pl/mayx/blog
https://gitea.keymantek.com:777/mayx/blog
https://git.tirtapakuan.co.id/mayx/blog
http://tian-you.top:7020/mayx/blog
http://34.17.182.140/mayx-gogs/blog
http://gitea.mikarsoft.com/mayx/blog
https://mcgit.place/mayx/blog
https://forgejo.rekallservices.com/mayx/blog
http://git.instal.org.cn/mayx/blog
https://git.smart-family.net/mayx/blog
https://git.chiasson.cloud/mayx/blog
https://git.everestlinux.org/mayx/blog
https://git.netzbyte.com/mayx/blog
https://ataymakhzan.com/mayx/blog
https://repo.qruize.com/mayx/blog
https://git.xneon.org/mayx/blog
https://git.lamby.gay/mayx/blog
https://lab.dutt.ch/mayx/blog
https://gitea.dabit.synology.me/mayx/blog
https://git.joinplu.me/mayx/blog
http://otter.top/mayx/blog
http://188.66.0.25:3000/mayx/blog
https://gitea.deliverables.io/mayx/blog
http://23.182.16.150:3000/mayx/blog
https://git.ritonquilol.fr/mayx/blog
https://bis127.vse.cz/mayx/blog
https://app.gitpasha.com/mayx/blog
https://shaman2025.site/mayx/blog
https://git.jhammah.com/mayx/blog
https://git.kemomimi.site/mayx/blog
https://gitea.kolesarhome.com/mayx/blog
https://gitbucket.aint-no.info/mayx/blog
https://git.wikeo.ovh/mayx/blog
https://devcraft-dot.tech/mayx/blog
https://a-t-g.ru/mayx/blog
http://qiubei-git.cn/mayx/blog_cn
http://wangbeibei.xyz:6002/mayx/blog
http://8.141.82.163:20000/mayx/blog_cn
http://81.70.30.91:3000/mayx/blog_cn
http://yidaima.cn:6008/mayx/blog_cn
http://8.148.31.14:3000/mayx/blog_cn
http://58.17.14.95:8001/mayx/blog_cn
http://39.99.175.172:8000/mayx/blog_cn
https://git.newnaturalphilosophy.org/mayx/blog_cn
https://gitea.detr.top/mayx/blog_cn
http://175.178.193.35:3000/mayx/blog_cn
http://gitea.jb1000.com:88/mayx/blog_cn
http://www.22ai.vip/mayx/blog_cn
https://git.extra.eiffel.com/mayx/blog_cn
http://219.151.177.172:3000/mayx/blog_cn
http://62.234.20.54:3000/mayx/blog_cn
https://gitea.4gunn.cn:52443/mayx/blog_cn
http://jdunlap.com/mayx/blog
https://git.silica.codes/mayx/blog
https://www.vitelgrid.app/mayx/blog
https://gitruhub.ru/mayx/blog
https://git.linuxposting.xyz/mayx/blog
https://git.techworkshop42.ru/mayx/blog
http://speedyfox.app/mayx/blog
https://mjjtop.com/mayx/blog
https://forgejo.wanderingmonster.dev/mayx/blog
http://v.udvip.com/mayx/blog
https://git.edavmig.ru/mayx/blog
https://gitea.ns5001k.sigma2.no/mayx/blog
https://fzsimo.com/mayx/blog
https://git.hemangvyas.com/mayx/blog
https://gitav.ru/mayx/blog
https://git.sakuzyo.net/mayx/blog
http://www.365rise.top/mayx/blog
https://git.ifuntanhub.dev/mayx/blog
https://git.aptcloud.ru/mayx/blog
https://gitlab.dev.genai-team.ru/mayx/blog
https://d.roxyipt.com/mayx/blog
https://git.umervtilte.lol/mayx/blog
https://git.bitpak.ru/mayx/blog
https://git.amamedis.de/mayx/blog
https://git.kunstglass.de/mayx/blog
https://git.kry008.xyz/mayx/blog
https://gitea.onfing.ir/mayx/blog
https://gitea.augeo.dev/mayx/blog_cn
http://36.213.200.127:23000/mayx/blog_cn
http://20.219.0.85:3000/mayx/blog_cn
https://git.niisse.net/mayx/blog_cn
https://gitea.yfandxt.asia/mayx/blog_cn
http://81.69.57.215:3000/mayx/blog_cn
https://git.dglyoo.com/mayx/blog_cn
http://c8202.top:3000/mayx/blog_cn
http://nojava.fun/mayx/blog_cn
https://gitimn.com/mayx/blog
http://git.zapthisblog.com/mayx/blog
https://git.resacachile.cl/mayx/blog
https://git.vycsucre.gob.ve/mayx/blog
https://newtrafficworksgit.online/mayx/blog
https://git.uj-s.com/mayx/blog
https://git.albiobola.nl/mayx/blog
http://gitea.amm.ar/mayx/blog
https://git.83channel.net/mayx/blog
https://git.zeppone.com/mayx/blog
https://git.telecom.quest/mayx/blog
https://repo.paperless.rs/mayx/blog
https://urbal.dev/mayx/blog
https://git.pwarde.nl/mayx/blog
https://presko.info/mayx/blog
https://bolha.dev/mayx/blog
https://git.checkerwars.com/mayx/blog
1 repo_url
2 http://gdatura24gtdy23lxd7ht3xzx6mi7mdlkabpvuefhrjn4t5jduviw5ad.onion/Mayx/mayx
3 http://git.dkforestseeaaq2dqz2uflmlsybvnq2irzn4ygyvu53oazyorednviid.onion/mayx/blog
4 http://giteabolfdejtdzblkooalqei6jr67imiugmhtsh6ocw4hlj5a4q.b32.i2p/mayx/blog
https://lavaforge.org/mayx/blog
https://sij.ai/mayx/blog
https://repobase.net/mayx/blog
5 https://gitlab.lain.la/mayx/mayx.pages.lain.la
6 https://gitplac.si/mayx/mayx.gitpage.si
7 https://gitnet.fr/mayx/blog
8 https://opencommit.eu/mayx/blog
9 https://forge.fedoraproject.org/mabbs/blog
10 https://tilde.club/~mayx/git/blog.git/
11 https://git.envs.net/Mayx/mayx
12 https://tildegit.org/Mayx/mayx
13 https://git.tilde.town/mayx/blog
14 https://gitlab.haskell.org/mayx/mayx
15 https://lavaforge.org/mayx/blog
16 https://repo2.serv00.com/git/pub/Mayx/mayx/
17 https://git.pixie.town/mayx/mayx https://sij.ai/mayx/blog
18 https://git.projectnightcrawler.dev/mayx/blog
19 https://codefloe.com/mayx/blog
20 https://git.pixie.town/mayx/blog
21 https://git.minetest.land/Mayx/blog
22 http://1.6.141.109:3000/mayx/blog
http://52.28.156.42/mayx/blog
https://code.dsconce.space/mayx/blog
http://101.66.229.132:61088/mayx/blog
https://git.bp-web.app/mayx/blog
23 https://mygit.iexercice.com/mayx/blog
24 http://162.215.134.149:4000/mayx/blog
http://durfee.mycrestron.com:3000/mayx/blog
https://gitea.nongnghiepso.com/mayx/blog
https://codes.tools.asitavsen.com/mayx/blog
https://git.zeroplay.io/mayx/blog
25 http://45.33.87.87/mayx/blog
http://168.126.28.36:3000/mayx/blog
http://69.62.77.234:8888/mayx/blog
http://112.219.147.186:7000/mayx/blog
https://git.rootfinlay.co.uk/mayx/blog
https://gitea.belanjaparts.com/mayx/blog
26 http://185.208.225.190:3000/mayx/blog
http://116.204.34.35:12000/mayx/blog
27 https://git.Apture.io/mayx/blog
https://gitea.jasonstolle.com/mayx/blog
28 http://8.134.61.107:3000/mayx/blog
http://47.107.88.161:3000/mayx/blog
http://142.171.47.170:3000/mayx/blog
http://111.231.146.230:8418/mayx/blog
https://git.pwaapp.cc/mayx/blog
https://an360.top/mayx/blog
http://111.119.244.185:3000/mayx/blog
https://git.influxfin.com/mayx/blog
29 http://219.157.255.213:25311/mayx/blog
https://git.vekus.ru/mayx/blog
http://116.204.75.78:6180/mayx/blog
http://109.228.48.121:8000/mayx/blog
http://27.124.12.222:3000/mayx/blog
https://gitea.hintsight.com/mayx/blog
http://blackobelisk.xyz:3000/mayx/blog
https://git.the-kn.com/mayx/blog
https://git.wangxinlei.cn/mayx/blog
http://123.56.193.182:3000/mayx/blog
http://167.172.7.198:8081/mayx/blog
https://gitea.meetgu.ru/mayx/blog
30 http://116.236.50.103:8789/mayx/blog
https://git.paulll.cc/mayx/blog
http://94.224.160.69:7990/mayx/blog
https://gitea.ekjeong.synology.me/mayx/blog
https://git.daoyoucloud.com/mayx/blog
https://code.bitahub.com/mayx/blog
31 https://repo.gusdya.net/mayx/blog
32 https://gitea.synapsetec.cn/mayx/blog
33 http://gitea.yunshanghub.com:8081/mayx/blog
34 http://113.177.27.200:2033/mayx/blog
35 http://152.69.204.151:3000/mayx/blog
http://207.180.229.193:3001/mayx/blog
http://34.81.52.16/mayx/blog
http://123.57.16.111:3000/mayx/blog
https://lius.familyds.org:3000/mayx/blog
http://git.chaojing-film.com:3000/mayx/blog
https://git.nusaerp.com/mayx/blog
http://35.207.205.18:3000/mayx/blog
http://git.zjsciot.com:3000/mayx/blog
https://gitea.ontoast.uk/mayx/blog
http://121.36.37.70:15501/mayx/blog
36 http://187.216.152.151:9999/mayx/blog
37 http://116.63.173.179:8001/mayx/blog
http://114.116.79.196/mayx/blog
http://121.40.40.177:3000/mayx/blog
http://178.254.35.219:3000/mayx/blog
http://2.59.132.109:3001/mayx/blog
http://81.71.148.57:8080/mayx/blog
https://git.lmskaran.com/mayx/blog
http://154.86.0.30:3000/mayx/blog
http://52.23.128.62:3000/mayx/blog
http://120.46.222.128:10021/mayx/blog
http://120.26.108.239:9188/mayx/blog
http://47.111.17.177:3000/mayx/blog
https://k0ki-dev.com/mayx/blog
http://110.42.45.89:2052/mayx/blog
38 https://git.furcom.org/mayx/blog
http://34.102.70.200:3000/mayx/blog
https://gitea.oio.cat/mayx/blog
39 https://git.karma-riuk.com/mayx/blog
40 https://git.7o9o.net/mayx/blog
41 https://git.gupaoedu.cn/mayx/blog
42 https://git.7milch.com/mayx/blog
https://git.sitenevis.com/mayx/blog
https://dreamplacesai.de/mayx/blog
http://1.94.13.224:9080/mayx/blog
http://gitea.coderpath.com/mayx/blog
http://43.136.169.169:3000/mayx/blog
http://121.196.213.68:3000/mayx/blog
https://git.micahmoore.io/mayx/blog
https://git.anatid.net/mayx/blog
https://git.lekai.info/mayx/blog
http://135.235.225.198:3000/mayx/blog
http://117.72.114.197:3000/mayx/blog
https://git.ashcloud.com/mayx/blog
https://git.novaa.xyz/mayx/blog
http://101.46.208.93:3000/mayx/blog
http://23.94.57.60:3000/mayx/blog
43 https://gitea.sciotech.cn/mayx/blog
http://8.140.250.85:3000/mayx/blog
http://202.65.194.19:3000/mayx/blog
http://101.201.34.43:3000/mayx/blog
https://git.gloje-rinchen-dorjee-rinpoche-buddhist-monastery.org/mayx/blog
http://101.35.227.2:3000/mayx/blog
http://209.141.47.52:3000/mayx/blog
http://60.204.158.188:3000/mayx/blog
http://60.204.156.211:3000/mayx/blog
http://nas.bi1kbu.com:8418/mayx/blog
http://1.94.178.207:3000/mayx/blog
https://gitea.tsaida.synology.me/mayx/blog
https://git.teygaming.com/mayx/blog
http://osztromok.com:3164/mayx/blog
http://175.209.53.134:3030/mayx/blog
http://39.107.226.169:3000/mayx/blog
http://39.96.211.118:3000/mayx/blog
http://121.37.47.20:3000/mayx/blog
https://git.antropix.dev/mayx/blog
http://15.237.198.144/mayx/blog
http://183.6.120.101:30000/mayx/blog
http://57.129.94.190:3000/mayx/blog
44 https://gitea.micro-stack.org/mayx/blog
https://gitea.temp.brentgruber.com/mayx/blog
http://47.102.147.170:3050/mayx/blog
http://172.236.250.154:3000/mayx/blog
http://54.198.134.152:3000/mayx/blog
http://121.41.35.226:11011/mayx/blog
http://47.111.1.12:3000/mayx/blog
https://nelgit.nelpi.co.uk/mayx/blog
http://8.141.91.86:3000/mayx/blog
http://117.72.15.187:3000/mayx/blog
http://81.70.30.91:3000/mayx/blog
45 http://106.54.211.95:3000/mayx/blog
http://210.245.20.73:3333/mayx/blog
http://43.248.97.109:3000/mayx/blog
http://113.207.86.104:3080/mayx/blog
http://39.96.195.72:10082/mayx/blog
46 http://172.172.102.93:3000/mayx/blog
http://115.120.245.164:3000/mayx/blog
http://35.194.179.90:3000/mayx/blog
http://66.179.208.56:3001/mayx/blog
http://121.43.60.72:9015/mayx/blog
http://171.80.13.66:9112/mayx/blog
http://223.108.157.174:3000/mayx/blog
47 http://120.24.249.56/mayx/blog
http://54.179.203.2:3000/mayx/blog
http://14.103.246.124:16000/mayx/blog
http://152.42.207.183:3000/mayx/blog
http://47.99.60.81:10082/mayx/blog
48 http://120.211.66.170:8418/mayx/blog
https://gitea.vilcap.com/mayx/blog
http://121.196.245.62/mayx/blog
http://8.138.142.17:3000/mayx/blog
http://www.koelndom.cn:13030/mayx/blog
49 http://209.127.59.74:3000/mayx/blog
https://git.dotb.cloud/mayx/blog
https://gitea.augeo.dev/mayx/blog
http://120.46.23.215:3000/mayx/blog
50 http://121.41.2.71:3000/mayx/blog
http://110.41.177.80:5000/mayx/blog
https://gitea.dsmaster.myds.me/mayx/blog
http://www.scserverddns.top:13000/mayx/blog
https://git.lucas-michel.fr/mayx/blog
https://git.imvictor.tech:2/mayx/blog
http://47.112.137.193:3000/mayx/blog
http://58.38.123.148:3176/mayx/blog
http://docker.clhero.fun:3000/mayx/blog
https://bdgit.educoder.net/mayx/blog
51 http://e19510c831.iok.la/mayx/blog
52 http://119.45.49.212:3000/mayx/blog
53 https://code.antopie.org/mayx/blog
54 https://git.serenetia.com/mayx/blog
https://vcs.cozydsp.space/mayx/blog
http://115.190.107.87:3000/mayx/blog
http://106.12.50.144:8081/mayx/blog
https://code.wxk8.com/mayx/blog
http://8.155.58.218:9000/mayx/blog
http://fanlibo.i234.me:8418/mayx/blog
55 https://git.temporaryname.org/mayx/blog
56 https://Repo.gusdya.net/mayx/blog
https://git.m.ctf.arrobe.fr/mayx/blog
http://69.62.64.52:3333/mayx/blog
https://git.flymiracle.com/mayx/blog
http://106.14.138.181:3000/mayx/blog
https://git.yyuu.xyz/mayx/blog
http://39.107.70.124:3000/mayx/blog
57 https://git.stormrain.cn/mayx/blog
58 https://git.deuxfleurs.fr/mayx/blog
59 https://www.simpra.org:3000/mayx/blog
http://8.148.31.14:3000/mayx/blog
http://47.94.246.1:3000/mayx/blog
https://www.arcbyte.dev/mayx/blog
https://scm.bcorex.e3labs.net/mayx/blog
http://58.17.14.95:8001/mayx/blog
https://hero-cloud-stg-code.cnbita.com/mayx/blog
http://101.37.69.204:3000/mayx/blog
https://gitea.tecamino.com/mayx/blog
http://39.99.175.172:8000/mayx/blog
http://8.138.13.251:3000/mayx/blog
http://104.254.131.244:3000/mayx/blog
https://gitea.alacloud.de/mayx/blog
60 https://git.tobiasweise.dev/mayx/blog
https://code.cif.su/mayx/blog
https://git.cynic.moe/mayx/blog
https://git.muellers-software.org/mayx/blog
http://8.130.128.130:3000/mayx/blog
https://repos.fbpx.io/mayx/blog
61 https://git.cavemanon.xyz/mayx/blog
62 http://svn.rivastudio.cn/mayx/blog
http://39.98.126.115:8080/mayx/blog
http://46.202.189.66:3000/mayx/blog
http://82.26.157.11:3001/mayx/blog
http://123.60.146.54:3000/mayx/blog
http://8.140.248.67:3000/mayx/blog
63 http://118.178.172.49:3000/mayx/blog
https://gitea.lasallesaintdenis.com/mayx/blog
http://123.57.225.51:3000/mayx/blog
64 http://8.130.135.159:3000/mayx/blog
https://git.suo0.com/mayx/blog
http://103.228.160.127:3100/mayx/blog
65 https://git.dshkabatur.ru/mayx/blog
https://gitea.hoba.dedyn.io/mayx/blog
https://git.wegoo.ltd/mayx/blog
http://114.203.209.83:3000/mayx/blog
http://47.100.111.106:3000/mayx/blog
66 http://47.103.78.70:3000/mayx/blog
http://47.100.208.160:51300/mayx/blog
http://113.44.218.8:3000/mayx/blog
https://git.cenoq.com/mayx/blog
http://8.152.205.35:3000/mayx/blog
http://120.210.80.160:3000/mayx/blog
67 http://194.5.152.156:3000/mayx/blog
http://8.155.172.147:3001/mayx/blog
https://git.erfmann.dev/mayx/blog
https://git.weavefun.com:5443/mayx/blog
68 http://58.65.162.118:3000/mayx/blog
69 https://git.arkon.solutions/mayx/blog
http://8.131.93.145:54082/mayx/blog
http://111.9.31.174:10007/mayx/blog
https://forgejo.bridgetownrb.com/mayx/blog
http://54.199.96.217:3000/mayx/blog
http://20.219.0.85:3000/mayx/blog
https://gitea.doinlab.com/mayx/blog
https://git.7af.ru/mayx/blog
70 https://gitea.yimoyuyan.cn/mayx/blog
https://git.apextoaster.com/mayx/blog
https://hub.open-verse.ai/mayx/blog
71 http://221.203.14.217:3000/mayx/blog
https://git.sophiagwen.au/mayx/blog
http://139.196.96.28:13000/mayx/blog
72 https://dev.kiramtech.com/mayx/blog
https://git.123doit.com/mayx/blog
http://62.43.207.91:8889/mayx/blog
https://git.johntsai.online/mayx/blog
https://gitea.css-sistemas.com.br/mayx/blog
73 https://git.f4e.lol/mayx/blog
http://47.113.145.232:3000/mayx/blog
http://47.115.212.237:3000/mayx/blog
74 http://72.61.229.93:4000/mayx/blog
https://lishan148.synology.me:3014/mayx/blog_cn
http://1.95.221.174:3000/mayx/blog
https://git.huwhy.cn/mayx/blog_cn
http://119.91.35.154:3000/mayx/blog_cn
http://110.42.101.39:13000/mayx/blog_cn
75 http://39.101.74.135:5000/mayx/blog_cn
http://124.236.46.74:9103/mayx/blog_cn
76 http://123.57.130.140:3000/mayx/blog_cn
http://112.124.49.128:3000/mayx/blog_cn
77 http://118.24.46.223:3000/mayx/blog_cn
78 http://s3.v100.vip:31057/mayx/blog_cn
https://www.syq.im:2025/mayx/blog_cn
79 http://101.33.225.95:3000/mayx/blog_cn
80 http://45.55.138.82:3000/mayx/blog_cn
http://82.156.121.2:3000/mayx/blog_cn
81 http://118.24.129.148:3000/mayx/blog_cn
http://58.241.155.106:10140/mayx/blog_cn
82 http://120.48.141.82:3000/mayx/blog_cn
http://61.178.84.89:8998/mayx/blog_cn
http://82.156.111.58:3000/mayx/blog_cn
https://git.saike.fun:9755/mayx/blog_cn
https://git.cool2645.com/mayx/blog_cn
http://1.95.173.44:3000/mayx/blog_cn
http://58.221.157.122:3000/mayx/blog_cn
https://gitlab.liruwei.cn/mayx/blog_cn
http://61.190.74.90:9900/mayx/blog_cn
http://49.234.27.222:3000/mayx/blog_cn
http://8.153.70.81:30001/mayx/blog_cn
83 http://175.27.229.211:3000/mayx/blog_cn
http://106.55.174.214:3000/mayx/blog_cn
84 https://git.yidaimingjvn.xyz/mayx/blog_cn
85 http://39.105.67.143:3000/mayx/blog_cn
http://8.140.232.131:8100/mayx/blog_cn
86 http://82.156.89.21:3000/mayx/blog_cn
https://git.sskuaixiu.com/mayx/blog_cn
87 http://xujiesoft.vicp.net:3000/mayx/blog_cn
http://113.44.36.103:23000/mayx/blog_cn
88 https://git.mingliqiye.com/mayx/blog_cn
http://119.29.194.155:8894/mayx/blog_cn
89 http://58.213.60.6:19000/mayx/blog_cn
http://36.153.162.171:3000/mayx/blog_cn
90 http://47.92.113.131:3000/mayx/blog
91 http://gyc.myds.me:4000/mayx/blog
https://git.tablet.sh/mayx/blog
https://git.gnyra.com/mayx/blog
92 https://git.graveyard.sh/mayx/blog
https://git.nathanspackman.com/mayx/blog
https://git.rmarl.in/mayx/blog
http://git.mynas71.myds.me/mayx/blog
https://git.4lsa.com/mayx/blog
https://rlgit.pro/mayx/blog
https://git.veraskolivna.net/mayx/blog
https://git.lifetop.net/mayx/blog
93 https://gitea.jnyuxia.com/mayx/blog
http://git.liuhung.com/mayx/blog
https://gitea.adber.tech/mayx/blog
https://gitea.hello.faith/mayx/blog
https://tea.neuron.my/mayx/blog
https://git.violka-it.net/mayx/blog
https://git.adityagupta.dev/mayx/blog
https://git.danpeak.co.uk/mayx/blog
94 https://gitea.mynas-lechner.de/mayx/blog
https://git.automathon.org/mayx/blog
https://git.esen.gay/mayx/blog
https://git.webtims.ru/mayx/blog
https://gitea.personalsoftware.space/mayx/blog
95 https://gitlab.iplusus.com/mayx/blog
https://gitea.zachl.tech/mayx/blog
96 https://git.miasma-os.com/mayx/blog
https://gitea.nacsity.cn/mayx/blog
https://gitea.diputadosalta.gob.ar/mayx/blog
https://ttym.space/mayx/blog
https://getskill.work/mayx/blog
https://suprasage.com/mayx/blog
97 https://git.zakum.cn/mayx/blog
https://gitea.amazingcoders.com/mayx/blog
https://gitea.kamilklecha.dev/mayx/blog
98 http://47.109.103.110:9000/mayx/blog_cn
http://47.105.124.101:3000/mayx/blog_cn
http://49.232.183.190:3000/mayx/blog_cn
http://git.zxkedu.com:33769/mayx/blog_cn
https://code.wemediacn.com/mayx/blog_cn
http://51.159.198.233:3000/mayx/blog
https://gitea.adriangonzalezbarbosa.eu/mayx/blog
https://git.legatus.ru/mayx/blog
https://git.kayashov.keenetic.pro/mayx/blog
99 http://47.104.241.192:19999/mayx/blog_cn
100 http://47.98.148.146:1026/mayx/blog_cn
http://119.96.62.56:3000/mayx/blog_cn
http://101.42.28.156:3000/mayx/blog_cn
http://106.55.0.66:31807/mayx/blog_cn
https://gitea.gentronhealth.com/mayx/blog_cn
101 http://43.143.209.246:6300/mayx/blog_cn
http://152.136.158.133:36512/mayx/blog_cn
http://yidaima.cn:6008/mayx/blog_cn
http://47.113.101.80:3000/mayx/blog_cn
http://82.156.98.34:3000/mayx/blog_cn
http://zgd.synology.me:8418/mayx/blog_cn
https://git.zguiy.com/mayx/blog_cn
http://58.221.216.202:3000/mayx/blog_cn
102 http://39.100.183.95:88/mayx/blog_cn
http://www.xshideserver.com:3000/mayx/blog_cn
http://124.223.54.62:28/mayx/blog_cn
http://159.75.131.235:3001/mayx/blog_cn
http://1.117.67.95:3000/mayx/blog_cn
http://103.236.53.208:3000/mayx/blog_cn
http://118.195.135.194:3000/mayx/blog_cn
103 http://81.70.102.154/mayx/blog_cn
http://154.8.164.149:3000/mayx/blog_cn
http://111.228.34.40:3000/mayx/blog_cn
http://82.156.249.211:3000/mayx/blog_cn
104 http://36.133.248.69:3088/mayx/blog_cn
http://220.205.16.27:18081/mayx/blog_cn
http://81.69.221.216:3000/mayx/blog_cn
105 http://183.204.60.122:10081/mayx/blog_cn
http://43.139.240.37:17000/mayx/blog_cn
http://159.75.27.114:3000/mayx/blog_cn
http://arcreya.top/mayx/blog_cn
https://code.tczkiot.com/mayx/blog_cn
http://111.170.153.123:3000/mayx/blog_cn
http://xeroworld.team/mayx/blog_cn
https://gitea.wuyuank.com/mayx/blog_cn
http://47.117.245.9:17701/mayx/blog_cn
https://git.sunlix.one/mayx/blog_cn
106 http://47.106.222.181:20511/mayx/blog_cn
http://101.43.95.130:3001/mayx/blog_cn
https://gitea.myat4.com/mayx/blog_cn
107 http://118.24.161.24:3000/mayx/blog_cn
http://githanea.s.odn.cc/mayx/blog_cn
https://git.dev.chuweizi.com/mayx/blog
http://35.175.189.8/mayx/blog
http://meowug.com:8418/mayx/blog_cn
108 http://36.138.125.206:3000/mayx/blog_cn
https://git.4lcap.com/mayx/blog_cn
http://59.110.175.62:4322/mayx/blog_cn
https://www.luluvip.cn:8419/mayx/blog_cn
http://xianyuhome.cn:11013/mayx/blog_cn
https://git.chatumbrella.online/mayx/blog
https://silica.codes/mayx/blog
109 https://git.crystalyx.net/mayx/blog
https://gittea.dev/mayx/blog
https://git.newnaturalphilosophy.org/mayx/blog
https://code.infininov.com/mayx/blog
http://gitea.mcelwain.net/mayx/blog
https://chunkks.com/mayx/blog
https://gitea.earthmanrpg.me/mayx/blog
https://ndiuky.site/mayx/blog
https://src.enterpriselinux.social/mayx/blog
110 https://gitea.grxe.io/mayx/blog
https://git.mhworld.net/mayx/blog
https://blvckout.foo/mayx/blog
111 https://gitea.accept.dev.dbf.nl/mayx/blog
https://git.ke5.de/mayx/blog
112 https://git.jhossain.online/mayx/blog
http://gitea.xsec.fun/mayx/blog
113 https://barhoum-lab.fr/mayx/blog
https://git.fedaya.net/mayx/blog
http://gitea.nakile.fr/mayx/blog
https://redev.lol/mayx/blog
http://git.zfxfzb.com/mayx/blog
https://papi.tkpups.com/mayx/blog
https://git.beyond-a-i.org/mayx/blog
http://huanghomenas2.myqnapcloud.com:4000/mayx/blog_cn
http://43.142.166.108:10082/mayx/blog_cn
https://tm-jikayo.com/mayx/blog_cn
http://zzdgitea.stnav.com/mayx/blog_cn
http://1.117.66.197:3000/mayx/blog_cn
http://git.zhmight.com/mayx/blog_cn
https://intl-dev.gaia888.com/mayx/blog_cn
114 http://gitea.snailtrack.cn/mayx/blog_cn
http://ydds.cloud:3000/mayx/blog_cn
http://120.24.50.145:3000/mayx/blog_cn
115 https://code.draussenfunker.de/mayx/blog_cn
116 https://git.dinsor.co.th/mayx/blog
https://ofibohost.com/mayx/blog
https://lab.iishka.net/mayx/blog
http://www.arkproject.top/mayx/blog
117 http://www.bkandssp.cn:30/mayx/blog
https://gitea.spitaki.cloud/mayx/blog
https://git.codle.ru/mayx/blog
https://codeop.ru/mayx/blog
https://git.mirocom.org/mayx/blog
118 http://gitea.ydxtool.com/mayx/blog
http://18.167.251.121:10003/mayx/blog
http://39.98.171.121:53000/mayx/blog
119 https://gitea.malxte.de/mayx/blog
https://git.nizart.me/mayx/blog
https://git.ddns.net/mayx/blog
http://222.85.214.245:9776/mayx/blog
https://git.kraevsky.ru/mayx/blog
https://ruyiscx.cloud:3000/mayx/blog
https://git.0xee.eu/mayx/blog
https://gitea.deitglobal.com/mayx/blog
https://git.crwlr.ir/mayx/blog
120 https://git.nozora.top/mayx/blog
https://git.sortug.com/mayx/blog
https://aivyx-gitea.cloud/mayx/blog
121 https://git.edenit.co.kr/mayx/blog
122 https://git.catgirlsneed.homes/mayx/blog
https://git.eldev.netcraze.pro/mayx/blog
http://110.41.184.238:3000/mayx/blog
123 http://47.108.255.216:3000/mayx/blog_cn
https://gitea.molietech.com/mayx/blog_cn
http://58.87.88.234:3000/mayx/blog_cn
124 http://210.75.240.13:3000/mayx/blog_cn
https://git.xz-i.com:30443/mayx/blog_cn
https://git.fynn.vip/mayx/blog_cn
http://119.91.212.17:3000/mayx/blog_cn
125 http://git.hbg99.com:8080/mayx/blog_cn
126 https://git.eplg.services/mayx/blog
http://89.167.38.168:3001/mayx/blog
http://namonba.asuscomm.com:3001/mayx/blog
http://109.199.98.226:3001/mayx/blog
https://git.extra.eiffel.com/mayx/blog
https://gitea.digitanie.org/mayx/blog
127 https://git.xleed.com/mayx/blog
https://qlcodegitserver.online/mayx/blog
https://gitea.vvzvlad.xyz/mayx/blog
128 https://git.supernets.org/mayx/blog
129 https://git.digitaltelepresence.com/mayx/blog
130 https://git.hrfee.pw/mayx/blog
131 https://git.libregaming.org/mayx/blog
132 https://git.kaki87.net/mayx/blog
133 https://forgejo.vanten-s.com/mayx/blog
https://git.heartnn.com/mayx/blog
https://git.joinplu.me/mayx/blog
https://git.research.dezeeuw.ca/mayx/blog
http://149.104.29.239:8081/mayx/blog
http://ysx.myds.me:3005/mayx/blog
134 http://124.71.169.183:3000/mayx/blog
https://git.csi-kjsce.org/mayx/blog
https://hiwifi.denq.us:8418/mayx/blog
http://39.108.124.198:3000/mayx/blog
http://1090391-twk8saas.tmweb.ru/mayx/blog
135 https://git.msoucy.me/mayx/blog
https://git.niisse.net/mayx/blog
http://139.224.24.61:3000/mayx/blog
136 http://140.120.108.238:49308/mayx/blog
http://220.132.16.87:3000/mayx/blog
137 http://git.chilidoginteractive.com:3000/mayx/blog_cn
https://git.thunder-data.cn/mayx/blog_cn
https://git.cukak.com/mayx/blog_cn
https://git.ixu.me/mayx/blog_cn
138 http://git.uhfdemo.com/mayx/blog_cn
139 http://43.143.142.38:7001/mayx/blog_cn
140 http://111.230.243.127:3000/mayx/blog_cn https://git.panda-number.one/mayx/blog
141 http://git.qniao.cn/mayx/blog_cn https://datacortex.pl/mayx/blog
142 https://gitea.smartechouse.com/mayx/blog_cn https://gitea.keymantek.com:777/mayx/blog
143 http://git.feashow.cn/mayx/blog_cn https://git.tirtapakuan.co.id/mayx/blog
144 http://tian-you.top:7020/mayx/blog
145 http://34.17.182.140/mayx-gogs/blog
146 http://gitea.mikarsoft.com/mayx/blog
147 https://mcgit.place/mayx/blog
148 https://forgejo.rekallservices.com/mayx/blog
149 http://git.instal.org.cn/mayx/blog
150 https://git.smart-family.net/mayx/blog
151 https://git.chiasson.cloud/mayx/blog
152 https://git.everestlinux.org/mayx/blog
153 https://git.netzbyte.com/mayx/blog
154 https://ataymakhzan.com/mayx/blog
155 https://repo.qruize.com/mayx/blog
156 https://git.xneon.org/mayx/blog
157 https://git.lamby.gay/mayx/blog
158 https://lab.dutt.ch/mayx/blog
159 https://gitea.dabit.synology.me/mayx/blog
160 https://git.joinplu.me/mayx/blog
161 http://otter.top/mayx/blog
162 http://188.66.0.25:3000/mayx/blog
163 https://gitea.deliverables.io/mayx/blog
164 http://23.182.16.150:3000/mayx/blog
165 https://git.ritonquilol.fr/mayx/blog
166 https://bis127.vse.cz/mayx/blog
167 https://app.gitpasha.com/mayx/blog
168 https://shaman2025.site/mayx/blog
169 https://git.jhammah.com/mayx/blog
170 https://git.kemomimi.site/mayx/blog
171 https://gitea.kolesarhome.com/mayx/blog
172 https://gitbucket.aint-no.info/mayx/blog
173 https://git.wikeo.ovh/mayx/blog
174 https://devcraft-dot.tech/mayx/blog
175 https://a-t-g.ru/mayx/blog
176 http://qiubei-git.cn/mayx/blog_cn
177 http://wangbeibei.xyz:6002/mayx/blog
178 http://8.141.82.163:20000/mayx/blog_cn
179 http://81.70.30.91:3000/mayx/blog_cn
180 http://yidaima.cn:6008/mayx/blog_cn
181 http://8.148.31.14:3000/mayx/blog_cn
182 http://58.17.14.95:8001/mayx/blog_cn
183 http://39.99.175.172:8000/mayx/blog_cn
184 https://git.newnaturalphilosophy.org/mayx/blog_cn
185 https://gitea.detr.top/mayx/blog_cn
186 http://175.178.193.35:3000/mayx/blog_cn
187 http://gitea.jb1000.com:88/mayx/blog_cn
188 http://www.22ai.vip/mayx/blog_cn
189 https://git.extra.eiffel.com/mayx/blog_cn
190 http://219.151.177.172:3000/mayx/blog_cn
191 http://62.234.20.54:3000/mayx/blog_cn
192 https://gitea.4gunn.cn:52443/mayx/blog_cn
193 http://jdunlap.com/mayx/blog
194 https://git.silica.codes/mayx/blog
195 https://www.vitelgrid.app/mayx/blog
196 https://gitruhub.ru/mayx/blog
197 https://git.linuxposting.xyz/mayx/blog
198 https://git.techworkshop42.ru/mayx/blog
199 http://speedyfox.app/mayx/blog
200 https://mjjtop.com/mayx/blog
201 https://forgejo.wanderingmonster.dev/mayx/blog
202 http://v.udvip.com/mayx/blog
203 https://git.edavmig.ru/mayx/blog
204 https://gitea.ns5001k.sigma2.no/mayx/blog
205 https://fzsimo.com/mayx/blog
206 https://git.hemangvyas.com/mayx/blog
207 https://gitav.ru/mayx/blog
208 https://git.sakuzyo.net/mayx/blog
209 http://www.365rise.top/mayx/blog
210 https://git.ifuntanhub.dev/mayx/blog
211 https://git.aptcloud.ru/mayx/blog
212 https://gitlab.dev.genai-team.ru/mayx/blog
213 https://d.roxyipt.com/mayx/blog
214 https://git.umervtilte.lol/mayx/blog
215 https://git.bitpak.ru/mayx/blog
216 https://git.amamedis.de/mayx/blog
217 https://git.kunstglass.de/mayx/blog
218 https://git.kry008.xyz/mayx/blog
219 https://gitea.onfing.ir/mayx/blog
220 https://gitea.augeo.dev/mayx/blog_cn
221 http://36.213.200.127:23000/mayx/blog_cn
222 http://20.219.0.85:3000/mayx/blog_cn
223 https://git.niisse.net/mayx/blog_cn
224 https://gitea.yfandxt.asia/mayx/blog_cn
225 http://81.69.57.215:3000/mayx/blog_cn
226 https://git.dglyoo.com/mayx/blog_cn
227 http://c8202.top:3000/mayx/blog_cn
228 http://nojava.fun/mayx/blog_cn
229 https://gitimn.com/mayx/blog
230 http://git.zapthisblog.com/mayx/blog
231 https://git.resacachile.cl/mayx/blog
232 https://git.vycsucre.gob.ve/mayx/blog
233 https://newtrafficworksgit.online/mayx/blog
234 https://git.uj-s.com/mayx/blog
235 https://git.albiobola.nl/mayx/blog
236 http://gitea.amm.ar/mayx/blog
237 https://git.83channel.net/mayx/blog
238 https://git.zeppone.com/mayx/blog
239 https://git.telecom.quest/mayx/blog
240 https://repo.paperless.rs/mayx/blog
241 https://urbal.dev/mayx/blog
242 https://git.pwarde.nl/mayx/blog
243 https://presko.info/mayx/blog
244 https://bolha.dev/mayx/blog
245 https://git.checkerwars.com/mayx/blog

View File

@@ -1,6 +1,5 @@
proxies:
- https://blog.mayx.workers.dev/
- https://mayx.deno.dev/
- https://mayx.val.run/
- https://mayx.azion.app/
- https://yuki.gear.host/
@@ -16,7 +15,6 @@ mirrors:
- https://mayx.gitpage.si/
- https://mayx.serv00.net/
- https://mayx.vercel.app/
- https://mayx-blog.pgs.sh/
- https://mayx.netlify.app/
- https://mayx.gitnet.page/
- https://mayx.stormkit.dev/
@@ -24,8 +22,6 @@ mirrors:
- https://mabbs.kinsta.page/
- https://mayx.codeberg.page/
- https://mayx.tildepages.org/
- https://mayx.pandastack.app/
- https://mayx.pages.lain.la/
- https://mayx.4everland.app/
- https://mayx.readthedocs.io/
- https://mayx.sourceforge.io/
@@ -42,7 +38,6 @@ repos:
- https://framagit.org/mayx/mayx.frama.io
- https://salsa.debian.org/mayx/mayx.pages.debian.net
- https://codeberg.org/mayx/blog
- https://pagure.io/mayx
- https://git.gay/mayx/mayx
- https://repo.or.cz/mayx.git
- https://gitea.com/mayx/mayx

View File

@@ -98,7 +98,7 @@ layout: xslt_container
<li><a href="{{ site.github.tar_url }}">Download <strong>TAR Ball</strong></a></li>
<li><a href="{{ site.github.repository_url }}">View On <strong>GitHub</strong></a></li>
{% else %}
<li style="width: 270px; border-right: none;"><a href="/MayxBlog.tgz">Download <strong>TGZ File</strong></a></li>
<li style="width: 270px; border-right: none;"><a href="/MayxBlog.7z">Download <strong>7-Zip File</strong></a></li>
{% endif %}
</ul>
</header>
@@ -117,6 +117,7 @@ layout: xslt_container
<script src="{{ "/assets/js/scale.fix.js" | relative_url }}"></script>
<!--[if !IE]> -->
<script src="/assets/js/main_new.js"></script>
<script src="/assets/js/blog-console.js"></script>
<script src="/Live2dHistoire/live2d/js/live2d.js"></script>
<script src="/Live2dHistoire/live2d/js/message.js"></script>
<script src="/assets/js/jquery.pjax.min.js"></script>

View File

@@ -0,0 +1,60 @@
---
layout: post
title: Vibe Coding新体验
tags: [Vibe Coding, AI, PJAX, 麻将]
---
All in AI!<!--more-->
# 起因
前段时间,我写了一篇关于[AI Agent](/2026/04/14/ai-agent.html)的文章,虽然当时我说这并没有什么创新之处,但在那之后用着用着感觉还是挺好用的,至少相比以前[在云端Vibe Coding](/2025/04/08/feed.html)来说又快又免费所以我打算分享一下最近我用AI Agent的经历。
不过大多数情况下我写代码都可以直接让各路AI在对话中给我生成那到底有什么样的场景才需要用AI Agent呢一般应该就是需要边改边测的东西吧。
# 关于PJAX的改造
虽然说AI生成的东西可靠性并不是很高但至少在网上已经有很多例子的代码应该不至于乱生成吧……其实我一直都想给我的博客增加全站无刷新的功能但是每次看到PJAX都要自己重新调用当前页面的各种函数就懒得动手了😂。不过其实这也不是什么复杂的事情主要是一个一个分析函数比较麻烦所以既然有AI了不如直接让AI帮我做吧。于是我让它克隆了我的仓库分析并写出PJAX的代码。
用AI Agent最大的好处就是能让它了解整个项目的所有代码如果是直接在对话里让AI修改的话就很难做到这一点。总之我告诉它之后等了一会它真的写出来了我试了一下确实能用虽然刚开始有不少问题主要是因为我用了[Live2D](/Live2dHistoire/),不少问题也是这个功能引起的。不过只要我告诉它问题在哪里,它总是能给我改好,先不论它实现的代码怎么样,但至少从效果来说还是相当不错的。
最终生成的代码我看了一下代码质量非常糟糕把我在别处的代码到处复制粘贴到PJAX用的代码里了但是体验效果不错……所以没办法虽然代码很糟糕但先用着吧。不过我觉得优化应该也能交给AI Agent只是它有时候改来改去还会把正常代码改坏所以优化看起来还是只能自己做……
最终的代码就是:[pjax.js](/assets/js/pjax.js),虽然我对这个代码质量不是很满意,但是毕竟能用,效果也不错,就先这样用吧~
# 生成一个小游戏
前段时间我在Bilibili上看视频的时候发现了一个有趣的微信小游戏叫做“雀谜”它把立直麻将和Wordle两个玩法结合到一起看起来挺有意思。不过它作为微信上的小游戏有些问题一是看提示要看广告二是换题也要看广告而且看广告就算能换题也有次数限制一天也就几次机会让我有点不爽。
不过从功能上来说看起来并不复杂感觉用AI直接Vibe Coding完全不是问题不过AI Agent从零开始写比较考验模型的水平所以我打算先让各路网页上的AI生成初版的Demo之后再考虑怎么改。于是我对它们说
> 帮我制作一款立直麻将Wordle网页小游戏规则为
> 1. 系统随机生成一个有役能和的14张牌必须按照万、筒、索、字的顺序排列同花色内数字从小到大但是第14张用来和的牌可以不遵守排列规则
> 2. 让玩家猜6次来猜到这个牌型每次猜的牌也必须是满足有役和牌的条件
> 3. 位置和内容正确的牌用绿色标注、只有内容正确但是位置不正确的用黄色标注,不在生成范围内的牌用灰色标注
> 4. 界面中所有的牌使用Unicode中的麻将字符并且提供一组输入按钮用于输入这些麻将字符
> 5. 输入按钮在游玩过程中也要标注颜色
> 6. 随机生成的牌需要标注场风、自风和是否自摸,如果是荣和需要额外的役,需要考虑平和之类的役种
> 7. 加一个提示键,可以查看答案牌型的役种
直接生成确实很考验水平有很多AI直接生成出来的完全用不了像DeepSeek生成出来的按钮按上去都没有反应😅最终只有Gemini生成出来的感觉还不错无论是界面还是输入的感觉都很好于是接下来的修改我就打算以Gemini生成出来的代码为主。
刚生成出来的代码虽然能玩但是每个AI直接生成都不想做完整的役种检测说什么一个对话不够😥明明各个都是几百k上下文的AI有什么不够的……总之想一口气就完美做出来显然是不现实的不过其实最开始我也不打算把所有役都做了毕竟条件是“有役和牌”而且没有副露所以好多可以叠加的役其实都不需要做尤其是役满那些大多都可以用其他役的条件满足。
在这期间“平和”算是实现起来最麻烦的主要是这个役需要根据和牌判定必须是顺子的两面听牌才可以……虽然AI理解这些知识但是写的时候经常出问题像边张之类的经常误判……但是不实现又不行毕竟这是可以nomi的牌型。
最终写的差不多了感觉还不错于是在GitHub Pages上[部署了一份](https://mabbs.github.io/riichi-mahjong-wordle/),起名叫[立直麻将 Wordle](https://github.com/Mabbs/riichi-mahjong-wordle)。
最开始我以为这个小游戏的玩法是他们原创的于是把生成的代码又丢给AI让它评价一下创新性结果AI说已经有开源了😂有个叫做[Mahjong Handle](https://github.com/xnuk/mahjong-handle)的才是最早做这个玩法的……还好这代码不是我写的,要是我写了半天结果发现有现成的那就很无语了😆。
当然我让AI写的版本也有一些特色Mahjong Handle那个和原版Wordle一样每天只有一道题而且这个题是从题库里抽的我让AI Agent看了一下它的代码似乎是用[phoenix-logs](https://github.com/MahjongRepository/phoenix-logs)这个脚本从天凤上下载的牌谱数据解析得到的题库所以它的题目数量是有限的而我的代码是完全随机生成的所以结果是无限的。但AI似乎认为作为Wordle来说一天一题才是它的特色无限就显得没意思了……既然如此那干脆让它给我把两个游戏合并了让它参考Mahjong Handle把一天一题的功能也给我加上另外Mahjong Handle还有一个MPSZ快速输入法也让AI给我合并进我的游戏里了。
这时候就体现了AI Agent的优势如果直接用线上的AI把Mahjong Handle中的功能移植到我的代码我还得完整描述要实现的功能但是AI Agent能自己看人家仓库的代码就知道要改什么东西了。
最终实现的效果也很不错虽然我的代码没有题库但是使用了当天日期作为随机种子用mulberry32算法搞出了一天一题的功能还挺有意思的。
另外在Mahjong Handle以及原版的Wordle中还有一个困难模式就是每次猜测必须使用之前的猜测条件不过我觉得如果原模原样把这个功能抄过来似乎有点无聊而且我发现玩这个东西一般直接一个国士+两个一气就基本上把要猜的牌找完了有点简单所以我想了一下要不然限制一下提交的条件提交的牌型必须包含目标的役种之类的……不过要是做这个功能就不能像之前那样只实现部分役种了得把所有能用到的都实现一遍还好这种事情肯定也不是我来做肯定还得是让AI来😋。
实现的时候还不能让AI直接一口气全加上还得一步一步的提示而且每个牌型还得手动测一遍……最终虽然做的看起来似乎已经很完善了不过逻辑的根本还是有点问题AI设计役种计算的时候是按拆解后役种数量最多的情况来算但事实上立直麻将算役种是按照高点法要最终点数最大才行。虽然按照目前的方法绝大多数情况下都能正常工作但偶尔也会遇到问题比如像这副牌
- 🀈🀈🀈🀉🀉🀉🀊🀊🀊🀞🀟🀗🀗 🀝
按照目前的方法计算的结果是:
- 断幺·平和·一杯口 = 3番30符
然而正确答案是:
- 断幺·三暗刻 = 3番50符
但是符数的计算又很麻烦……不过反正提示和验牌都是同一套程序题倒是也能做出来……所以就懒得修了🤣。当然说到底还是因为AI没有用现有的计算库像Mahjong Handle用的是现成的[Riichi](https://github.com/takayama-lily/riichi)库,制作起来比我这个就简单多了。
# 为游戏添加字体
在我制作“立直麻将 Wordle”这个小游戏的时候我让AI使用的是Unicode中的麻将字符毕竟有现成的字符总比去找牌的图片要方便而且实现起来感觉更简单一些。不过用字符确实也会遇到一些问题我不知道为什么在macOS和Android上其他牌都是黑白的唯有🀄是彩色的😅Windows上使用的Segoe UI Emoji倒都是彩色的但是牌很丑像是小学生设计的……虽然不影响玩但是看着很难受至少牌的颜色统一一下也好吧虽然也可以搞出黑白的🀄但如果用这个在Windows上又成了只有🀄是黑白的😅。虽然Mahjong Handle是直接用了SVG格式的牌图片但我觉得应该有现成的麻将字体像这种问题应该有现成的解决方法才对吧
于是我直接问AI有没有这样的字体AI搜了一下看起来还真有有个叫做[Mahjong Colored](https://github.com/kfarwell/Mahjong-Colored)就是基于那些SVG做的OpenType-SVG字体我本来以为问题就会这样解决然而当我应用了字体之后发现牌的位置变成了白色的方块貌似只有Firefox才支持这种字体……然而现在谁还用Firefox啊
那遇到这种问题怎么办当然还是让AI解决它说要在Safari和Chrome上使用彩色字体用COLR或者SBIX格式比较好COLR格式的兼容性最好三个浏览器都能用而SBIX的话Firefox没法用。不过Firefox既然基本上没人用了我倒是不太在乎它的兼容性但我肯定还是更希望能用兼容性更好的方案于是我把OpenType-SVG字体转换为COLR的工作交给了AI Agent。
结果它整了半天也没整出来貌似是因为SVG的特效太多没办法转换为COLR格式于是它选择了SBIX方案不过COLR存储的是矢量图而SBIX存储的是位图大小要大一些而且放大还会有锯齿。只是目前实在是没办法了只能用这种格式。
最终我把它转换后的字体存了一份到[仓库](https://github.com/Mabbs/Mahjong-Colored-SBIX)但是看着它1MiB多的大小以及不太好的浏览器兼容性再考虑到它还是位图实在是不太想在我的游戏里应用它……
结果后来我又搜了一下,原来是有现成的麻将字体啊,有个叫做[Mahjong Font](https://github.com/rutopio/mahjong-font)的项目用的就是COLR格式兼容性非常好而且大小只有80KiB算是最完美的解决方案了。垃圾AI给我推荐的Mahjong Colored真的是……浪费了不少时间看来有的时候自己调查要比问AI好一些吧。
# 感想
总的来看目前Vibe Coding的体验确实是相当不错只是问题也非常明显完全让AI生成的代码要么实现的不优雅要么就会出BUG如果完全不懂要写的东西纯粹由AI生成那出问题的概率就非常高了。不过要是看不出来错误完全被AI忽悠过去了也许这时候的Vibe Coding在另一方面算是完美吧😂至少对用的人来说也算是解决了问题呢。

View File

@@ -0,0 +1,31 @@
---
layout: post
title: 一次制作终端版博客的经历
tags: [WASM, 终端, Linux, 博客]
---
在浏览器上用真的Linux访问博客会是什么样的感觉<!--more-->
# 起因
在去年的时候我为了想在博客上加个终端,写过一篇关于[在浏览器中运行Linux](/2025/12/01/linux.html)的文章。不过那时候只是调查了有哪些可能的方法,并没有真的做出来,主要是自己做感觉太麻烦了😂。
但从上次进行了[Vibe Coding](/2026/07/01/vibe-coding.html)之后我意识到这可能不再是什么麻烦事也许只要和AI聊聊天就能轻松做出来了于是接着之前的方案我开始着手完成我的想法。
# 终端版博客的不同形式
## 基于WASM Linux的版本
在之前的文章里我其实更倾向于WASM Linux的方案尤其是[Thomas Stokes](https://github.com/tombl)制作的[WASM Linux](https://github.com/tombl/linux)因为它相比于虚拟机更轻量效率更高而且还能完美地在Safari中运行毕竟我用的是macOS😂因此接下来我计划用它为基础制作我的终端版博客。
不过之前我也说过目前这个WASM Linux还不能和外界通信不能和外界通信就不能读取我的文章。于是我打算先让AI解决这个问题。但如果我直接给它说想要和外界通信也许它会给我整一堆奇怪的实现所以我得自己先想一个实现起来最简单的方案。之前我记得Fabrice Bellard大神写的JSLinux中有一个剪贴板设备文件可以和外部通信那么干脆让AI写一个能在浏览器中执行JS的设备文件吧这样做出来只需要写简单的Shell脚本就可以和浏览器交互了也不需要考虑如何编译WASM程序于是就这样我开始让它实现这个功能。
最终经过几次调试和修改之后AI真的把这个设备文件给做出来了不过刚做出来的时候有些问题。因为在这个Linux中的进程都是在Web Worker中运行执行的JS也会在Web Worker中运行。但是Web Worker的局限性很大并不能和当前网页进行交互不过这种问题也都是小事发现了之后只要给AI一反馈也是轻轻松松就改好了……最终实现的效果我感觉相当不错既然如此那我就把AI做的这个驱动给上游[PR](https://github.com/tombl/linux/pull/24)一下吧,也算做个贡献。不过最终原作者不太喜欢这种实现方式,他好像更喜欢标准化的方式,说是已经做了一个[VsockDevice](https://github.com/tombl/linux/blob/b36416c7f266a465361ab7dde7622eb37239cd7e/tools/wasm/src/virtio.ts#L354)可以直接使用Linux自带的驱动和外界通信所以把我的PR拒了看来AI Slop还是入不了大佬的法眼😂~~不过我问了一下AI它说用这个设备的话可能需要`ioctl()`系统调用就没办法直接用Shell操作了只能用别的语言写的程序才能用它通信所以我只好自己用这种不标准的方式了。~~ 虽然VsockDevice确实是不太好操作但是大佬随后又新增了一个ethernetDevice可以用来上网考虑到维护自己的分支实在是太麻烦了所以我让AI写了一个虚拟的HTTP服务使其能够执行JS顺便还增加了连接互联网的功能。这样我就可以直接使用上游的代码不需要再维护之前写的驱动了其实以太网比Vsock复杂多了只是因为可以用wget之类的客户端请求所以才简单😋
在做好与外界通信的通道后我就开始让AI写能和我博客交互的脚本不过在这个过程中也遇到了不少问题最开始的时候发现这个Shell的管道有些问题执行的时候会忽略管道前的命令后面的命令就没法执行了……感觉有点奇怪所以我要求它在实现交互脚本时不要使用管道符。除此之外我还发现反引号和`$()`这些能把执行结果插入字符串的语法也不能用……总之就是局限相当多,但它还是克服了这些困难最终把脚本给写出来了,最终实现了列出文章、查看文章、打开文章和查看评论等功能,效果还是相当不错。 ~~唯一的缺陷就是它不能进行异步操作,只能同步请求,所以在进行请求的时候会把浏览器卡住,体验稍有打折。~~ 后来用了网络版的JS执行服务后就可以异步了避免出现把浏览器卡住的情况。
不过这个系统如果管道符不能用的话效果会差一大截这可是Shell的灵魂啊所以我提交了一个[Issue](https://github.com/tombl/linux/issues/25)希望作者能修一下。结果作者真的强得离谱提出问题之后第二天就修复了实在是太强了😨。但修好这个问题之后作者又整了一堆别的花活把内存限制给取消了结果我在Safari上一运行就报OOM的错误……于是我把这个问题又[反馈](https://github.com/tombl/linux/pull/26#issuecomment-5018155963)了一下顺便让AI看看这个问题怎么解决结果AI也不辜负我的期待轻轻松松就解决了🤣。最终我除了会提出问题之外什么也不会做只能看着大佬和AI完成我的想法了😝。
后来增加的以太网网关也挺折腾原理其实并不复杂但直接给AI说想用这个接口上网的时候它会自己想办法搓一套漏洞百出的TCP/IP协议栈所以后来我在GitHub找了个[tcpip.js](https://github.com/chipmk/tcpip.js)库让它集成BUG就比它自己手搓的少了不少。后来我又想加一个TLS终止功能因为在浏览器上没办法直接让系统里的程序发送原始的TLS数据包去请求网站但我又希望它能够请求带有https协议的网址所以要提前对TLS进行解密再转换成`fetch()`这时候我就没让AI自己手搓了在网上找了个[node-forge](https://github.com/digitalbazaar/forge)库让AI对接就可以避免出现一堆奇怪的BUG了。
做好网关之后我又突发奇想想做一个展示终端内状态的页面但是目前JS并不能主动和里面的系统直接通信所以又让AI搓了一个通过Service Worker访问系统内网络服务的功能然后用busybox的httpd执行sh写的cgi程序就可以被前端读取到了。随后我还给原作者发了个[Issue](https://github.com/tombl/linux/issues/34)展示这个Service Worker的效果结果人家已经做了这个功能我还是太Naive了😂。
最终做好的网站可以在[这里](https://mabbs.github.io/linux/)查看效果真的不是一般的好相比于其他模仿终端形式的博客简直是降维打击毕竟这是真的Linux啊虽然目前依然有些BUG但是原作者修BUG的速度还是挺快的相信等他发布正式版之后体验会更进一步。
## 基于JSNix的版本
虽然我觉得追求真实感很重要,但是我又回去看了一下为我提供想法的[JSNix](https://github.com/Erzbir/jsnix)。虽然这个项目并不是真的Linux但是我让AI看了一遍之后它对这个项目的评价也很高说是作者对Linux的了解非常深入很多细节模拟的也非常到位。而且为WASM Linux制作的那些脚本在这个JSNix上其实完全可以实现还更简单于是我直接让AI参考给WASM Linux写的脚本把那些功能全部移植到这个JSNix上。也许是因为AI更擅长编写网页很快它就完成了这些功能而且效果非常不错基本上和WASM Linux上面的效果一样表现也相当不错最终生成的结果可以在[这里](https://mabbs.github.io/jsnix/)查看。
不过假的毕竟还是假的和真的Linux差异还是有不少的像正经的Shell可以在终端中直接用if、for和while之类的语法写一些东西它这个就必须要编写成脚本才可以而且解析也有相当多的问题。各种命令的运行结果很多都是硬编码的只是编了一段对应命令的输出参数做得也不全。另外著名的Linux文本三剑客grep、sed和awk在这个系统里实现得也非常差只做了一些非常基础的功能基本上就是完全不可用。所以说这个系统还是不够真实只能做最基础的体验不能够深究。
但并不是说它没有优点它作为纯粹的JS不像WASM Linux那样容易出现兼容性问题比如很多手机浏览器不支持跨源隔离导致SharedArrayBuffer之类的API没法用所以手机上只能体验这个JSNix的版本另外WASM Linux的体积虽然说并不算很大但也有好几MiB不像这个JSNix连1MiB都不到还有这个系统没有启动过程相比于WASM Linux来说加载更快而且在编写和修改功能的时候比WASM Linux简单不少像给WASM Linux做的终端状态展示在JSNix上根本不需要折腾什么Service Worker以及请求网络之类的也非常简单直接`fetch()`就可以也正是如此JSNix的版本AI没一会儿就做完了……总之就是只要不涉及具体功能方面JSNix都比WASM Linux要强不少不过这样说有点“抛开事实不谈”的感觉了😂。
# 感想
最终做出来的这两个版本的终端版博客基本上所有的代码都不是我写的真的做到了仅仅是和AI聊聊天就把东西做出来了……只能说AI现在真的不是一般的强啊当然方案还是得自己考虑因为AI一旦走错了方向就很容易往一个方向不停地钻结果就是花了很长时间可能效果会很差尤其是现在的AI还特别喜欢自己造轮子所以这时候还是自己找找看已经有的方案然后告诉它会比较好。
从效果来说这次写的东西也让我非常满意,我想我这次做的这个博客界面估计是前所未有的,毕竟这可是在浏览器上用**真的**Linux访问博客啊其他人做的都是假的。至于虚拟机那些方案可能也是因为太重所以基本上没人用而WASM Linux只有Thomas Stokes做的效果最好但是又没有受到应有的关注……总之从我个人的角度来看这次做的东西还挺Cool就是不知道会不会吸引其他人来看呢……可能还是太小众了吧😂。

View File

@@ -0,0 +1,63 @@
---
layout: post
title: Vibe Coding 新体验2
tags: [Vibe Coding, AI, Agent]
---
AI is Everything!<!--more-->
# 起因
在两个月前,我[体验了现在的Vibe Coding](/2026/07/01/vibe-coding.html)不过那时候我其实还是没有完全信任AI认为它的能力可能还不够强大多数内容依然需要人来做。
但是自从上次做了[终端版博客](/2026/08/01/terminal.html)之后我意识到它的能力也许比我想象的更强可能真的能做到超越99%的开发者了因此在最近一段时间我一直使用AI做我想做的各种东西结果就是一次又一次地让我感到难以置信现在的AI真的实在是太强了😨。而且我做的这一切并不是用最先进的那批AI仅仅是国内被大家不怎么看好的免费模型——[腾讯混元Hy3](https://huggingface.co/tencent/Hy3)那么我很难想象如果我能用像GPT 5.6 Sol或者Fable 5那样当下最先进的AI我做的这些东西得有多完美啊……
# 最近Vibe Coding出来的各种项目
## Blog API + WebMCP
在上次做完[终端版博客](/2026/08/01/terminal.html)之后我就在想用Linux终端来呈现博客的形式真的是个好选择吗毕竟Linux在浏览器上并不是原生的尽管用了[WASM Linux](https://github.com/tombl/linux)可以做到WASM原生运行Linux但这还是额外添加的东西。于是我就想JavaScript应该也能作为终端吧就像Node.js一样REPL也可以作为终端使用正好那段时间DeepSeek-V4-Flash正式版出了就让它直接写了[一个Demo](https://github.com/Mabbs/jsnix/blob/main/repl.html)出来试试看,可以点开[这里](https://mabbs.github.io/jsnix/repl.html)体验。
写出来效果还挺不错的,和之前做的终端版博客的主要区别就是我写的是函数,而不是命令,不管怎么说也算是“真的”终端吧,唯一体验不太好的可能就是函数需要带个括号才能运行,稍微有点麻烦。
但后来我想了想明明开发者工具中就有个控制台根本没必要搞什么REPL终端啊直接把要用的功能提出来作为函数在控制台中运行效果比那个终端的效果要好得多啊而且这样就可以直接集成到我的博客中不需要单独搞个页面感觉体验更好一些。
既然有了函数,我觉得只给人类用就太浪费了,前段时间看到谷歌搞了个[WebMCP](https://webmachinelearning.github.io/webmcp/)那我完全可以把这些函数做成WebMCP让AI来调用啊相比于其他乱七八糟给AI的协议至少WebMCP是有谷歌和微软撑腰的所以加一个也不错。
最终我把WebMCP的文档以及之前实现的REPL代码直接发给AI让它帮我实现对应的函数以及应用WebMCP API没几分钟它就把所有功能实现好了最终代码就是[blog-console.js](/assets/js/blog-console.js)。在开发的过程中AI严格按照文档中的要求实现了结果我在实际测试的时候发现Chrome在实现`registerTool`方法的时候和文档的实现有差异文档说这个方法会返回Promise但Chrome实际并没有返回所以AI调用`.then()`时直接报错了😓……没办法就只能手动给它套一层Promise才算是能正常工作。毕竟这还是一个没有正式上线的API出点问题倒也能理解吧。
虽然东西已经实现了不过到底怎么才能让其他人知道我用了WebMCP的技术呢我发现网上有一个WebMCP Directory专门收录使用了WebMCP技术的网站于是我就随手提交了一下现在在[这里](https://webmcp.com/sites/mabbs.github.io)就能看到我博客的WebMCP信息了。
## 某个即将关服的游戏的离线快照
最近一段时间我在玩的一个使用Unity3D引擎制作的立直麻将游戏发了篇公告说是要关服了还给全服所有玩家送了一堆抽卡资源。我听到这个消息之后感觉还是挺遗憾的那个游戏总体来说做得还算不错吧而且画风也符合我的口味角色模型有点米哈游的那种感觉。我曾经遇到过几次游戏关服的事件但是每一次我都无能为力只能看着游戏消失然后逐渐被遗忘。然而现在我有了AI也许一切会变得不一样吧这次我要使用AI让即将消失的游戏不再消失。
### 重放大厅数据
最开始我其实想得很简单游戏登录之后其实没有和服务器有太多的通信像账号中有的角色以及各种材料等信息在登录的时候就已经发送了直到进入对局之前客户端都没有和服务器有什么有效的沟通而我主要需要的也就是能登进去看看角色听听语音就好了。那么接下来我只需要让AI把整个游戏资源下载下来然后抓个包让它给客户端重放就好了也不需要什么逆向操作。
AI分析了一下之后发现它用的是WebSocket+Protobuf协议正常来说如果要使用Protobuf协议得要有.proto接口定义文件才可以不过既然我的要求只是重放它就没去考虑逆向了只是简单分析了一下编码规则就用Python把服务端给写出来了。
不过如果这个快照必须本地启动一个服务器玩起来就有点麻烦了这样搞得我估计就没心思玩它了但是自从我做了终端版博客之后我觉得浏览器可能没有做不到的事情既然Python能运行服务器那JavaScript一样可以于是我就要求AI让游戏和服务端一起运行在浏览器中。
结果它还真折腾出来了在JavaScript中似乎一切都可以被覆盖于是AI就替换了浏览器的WebSocket对象让客户端以为它连接到了真实的服务器然后再按照之前录制的包发送就好了折腾了一段时间之后游戏真的能正常启动了真的是太离谱了😨。
### 制作对局引擎
其实这基本上已经满足我的要求了,但我还是有点好奇,这个客户端里真的没有.proto接口定义文件吗正常来说既然客户端知道怎么和服务端通信那么这个文件应该是必须要有的吧反正目的已经达到了接下来就让AI瞎折腾看看。
在我要求完之后它又折腾了好长时间,结果.proto也被它给搞出来了😨也许对于会逆向Unity3D游戏的人来说这不算什么但这已经让我很震惊了……既然有了这些也许完成一个完整的服务端将不再是难事。
于是我让它录制了几把我实际对局的包并理解整个对局中数据包的时序开始考虑如何做出完整的麻将对局。首先作为离线运行的游戏来说和人对局肯定是做不出来了那就得想办法搓个人机出来。我最先想到的是著名的麻将AI [Mortal](https://github.com/Equim-chan/Mortal)之前用它在雀魂上打了几把之后结果号没了😂不过我确实觉得和人打麻将没什么意思感觉麻将如果全按最优解打的话结果就全是靠运气……不过后来我想了一下还是不用Mortal了首先这个模型不小整个模型要好几百MiB而且三麻和四麻的模型还不一样还有三麻的模型还是收费的……另外真和Mortal打的话感觉难度也确实有点高除了运气因素外至少人机犯错的概率比人要低不少那打起来估计会很难受。所以我就对AI说做一个降低向听数为主的全攻型人机其他细节让它自己考虑另外我想到上次做的那个麻将Wordle它自己写的役种分析实在是有点烂所以这次就告诉它必须要使用现成的[Riichi](https://github.com/takayama-lily/riichi)库,免得出乱七八糟的问题。
在连续跑了好几个小时之后AI成功把完整的[对局引擎](https://github.com/Mabbs/mahjong-dream-snapshot/blob/main/mock/riichi.js)给搓出来了,真的是相当了不起,要知道这个东西正常来说人开发怎么说也得好几周吧?它就几个小时开发出来了,还理解了数据包的时序,用之前分析的.proto文件成功接入到了游戏中实在是太强了……当然因为我没有用大量真实牌谱去测试有BUG也是正常的比如目前的引擎还存在立直之后完全没法开杠这样的边缘问题就只能慢慢修了不过这都是小问题它能做到目前的水平已经不是一般人能做到的了。
最终做出来的项目可以在[这里](https://github.com/Mabbs/mahjong-dream-snapshot)看到,还可以通过[GitHub Pages](https://mabbs.github.io/mahjong-dream-snapshot/)上的部署直接游玩。
### 隐藏彩蛋
在AI做完整个服务端之后我闲得没事瞎改对战人机的角色和皮肤因为游戏中的皮肤ID有一定的规律所以可以根据角色ID来猜皮肤ID。在这个时候我发现其中有一个角色在游戏中没有对应的泳装皮肤但是我把人机的角色按照规律配置推测的泳装皮肤ID是能显示出来的……那也就是说这个游戏可能在配置中隐藏了这个皮肤但是并没有删掉美术资源所以接下来我就想着能不能让AI把这个隐藏的皮肤显示出来这样就能在游戏中直接使用了。
所以我根据自己推测的信息告诉AI在这个游戏中有一个皮肤编号3708002头像编号1018的资源被隐藏了其中关于这些资源的配置应该在commonconfigs中帮我解包并分析考虑如何将这个皮肤和头像恢复显示然后重新打包资源使其可以正常加载。就这么个需求它从Bundle的解包到分析FlatBuffers然后又处理XAsset的校验……最终花了3个小时就给我做出来了而且我试了一下非常完美简直就像这个皮肤本来就存在一样不过原本这就是被官方隐藏的嘛解除隐藏自然就和真的存在一样啊😂。
## 能在WASM Linux中运行的SSG
之前我做完终端版博客之后就在想让这个完整的Linux只用来展示博客似乎有点浪费感觉它还能做更多事但对我来说编译在这个系统中能运行的二进制程序还是有一点困难虽然我有用AI但是我的Agent是运行在macOS上的所以编译Linux二进制程序有点困难……不过单是BusyBox其实就能做相当多的事情了毕竟我当年可是在手机上用ash做出了论坛系统[Mabbs](https://github.com/Mabbs/Mabbs.project),那它能做的事情应该还有很多。
最近我在和群友聊天的时候发现有人用C#做了个静态网站生成器也是用AI做的看起来挺有意思。其实SSG的原理还是挺简单的说到底就是些文字转换罢了。于是我就想要不然我就让AI搓个能在WASM Linux中运行的SSG出来吧
当然直接搓我还是会有一点怀疑AI的能力所以又找了点素材之前在[体验Tilde社区](/2025/08/10/tilde.html)的时候发现了[bashblog](https://github.com/cfenollosa/bashblog)其实这就已经是一个现成的SSG了只不过它用的是Bash语法得让AI转换成POSIX风格的语法。另外它还依赖使用Perl语言编写的[Markdown库](https://daringfireball.net/projects/markdown/)我这个系统里可没有Perl啊也得想办法找个可以替代的东西。
我想了一下在BusyBox中最适合处理文本的大概就是awk了所以我首先应该找找有没有用awk编写的Markdown转换程序。结果搜了一下还真被我找到了有一个叫做[d.awk](https://github.com/wernsey/d.awk)的库里面包含一个完全用awk写的Markdown转换程序那么接下来我只需要把这两个项目丢给AI让它以bashblog为基础以d.awk为引擎制作一个兼容性极强的POSIX SSG吧。
这种问题果然还是太简单了,它只用了一两个小时的时间,就真的做出来了,最终它把这个项目起名叫做[possg](https://gist.github.com/Mabbs/3db745dc403d752a1d59d3e06938e310)并且我把这个程序粘贴到了我的终端版博客中运行了一下效果也是非常完美……如果哪一天我抛弃了Jekyll也许就会用这个possg吧😂。
## 终端版博客的各种新功能
最近一段时间我在我的[终端版博客](https://github.com/Mabbs/linux)又有一些新的想法于是就对着AI反复许愿结果AI还真的能让愿望成真。以下就是从上次做完之后又新增的一些功能
### Markdown高亮
最初博客在终端中显示文章时是直接打印的Markdown原文感觉不太好看所以我就想着如果能加个高亮功能体验应该会更好吧最开始我要求AI做这个功能的时候它选择使用Shell+sed来实现那时候我还没有做possg没考虑用awk来做所以性能非常差。因为Shell在处理这种任务的时候要不停地调用sed这个系统开进程的开销又很大所以处理一篇文章得好几秒后来才考虑用awk来做结果性能确实好了不少最终的代码可以在[这里](https://github.com/Mabbs/linux/blob/initramfs/bin/mdhl)查看。
### 挂载本地文件夹
前段时间我看到作者合并了一个关于[virtiofs的PR](https://github.com/tombl/linux/pull/40)当时我看到这个PR的时候就想记得Chrome浏览器有一个[showDirectoryPicker API](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showDirectoryPicker)可以允许网页对指定的文件夹进行读写。现在有了这个驱动的话让AI做个将本地文件夹挂载到Linux的功能应该是个很简单的事情于是我直接就闭着眼睛让AI做了。
做完之后虽然能用但是我又回想起上次让AI搓的通过Service Worker访问系统内网络服务的功能结果人家原作者已经做了一样的功能我还给作者发了[Issue](https://github.com/tombl/linux/issues/34)推荐😅所以这次我得吸取教训看看作者是不是已经做了这个功能毕竟作者实现virtiofs的时候估计就有这个打算吧结果看了一眼还真[做了](https://github.com/tombl/distro/blob/main/packages/linux-guest/src/browser.ts)😆我闭着眼睛让这个垃圾AI去做看来确实有点着急了虽然我不知道原来我的AI做得到底怎么样但是我对它还是没什么信心也许作者这个代码也是AI写的但很明显他的AI比我的AI水平强得多所以让它参考作者做的这个版本重新写了一版。总之最终都能用写出来的代码就是[hostfs.js](https://github.com/Mabbs/linux/blob/main/hostfs.js),再配合上[mount_host](https://github.com/Mabbs/linux/blob/initramfs/bin/mount_host)脚本就可以实现挂载本地文件夹的功能了。
### 基于WebRTC的局域网内组网
我在制作网络模块的时候一直在想有没有办法能在不依靠服务器的情况下让两个这样的Linux系统互联呢正常来说要想让两个浏览器内的服务互相访问就必须有一个中转服务器因为浏览器肯定是不允许网页监听端口而且就算能监听我的这个网页还是放在GitHub Pages上使用了HTTPS也没办法访问HTTP资源搞证书也是个麻烦事。
但其实浏览器是有P2P功能的那就是[WebRTC](https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API)只是我不太确定这个技术能不能做到无服务器于是我问了问AI这个功能能不能不要服务器结果AI说可以只要两个机器在同一个局域网就可以通过手动交换SDP信令来实现P2P连接而且考虑到我基本上完全没有锥形NAT网络可以用所以就不搞STUN服务器了反正也连不上。那既然理论上可以的话就让AI实现吧。
最终花了一点时间AI就写出来了使用[webrtc-p2p.js](https://github.com/Mabbs/linux/blob/main/webrtc-p2p.js)配合[connector](https://github.com/Mabbs/linux/blob/initramfs/bin/connector)就可以实现同一个局域网内两台电脑上的浏览器中的Linux互联了。
这个功能做出来之后直接就有了无限的想象空间比如想用A电脑的浏览器控制B电脑浏览器中的Linux就可以在B电脑中执行`tcpsvd -v 0.0.0.0 4444 /usr/bin/script -qc 'stty -echo; /bin/sh -i' /dev/null`然后在A电脑用`nc 10.0.2.x 4444`去连接就可以了效果就像SSH一样而且配合之前做的挂载本地文件夹功能甚至可以直接操作B电脑中的文件另外之前做的Service Worker访问系统内网络服务也能用得上假如B电脑有一个网页想要分享给A电脑可以在B电脑上用`mount_host`把本地文件夹挂载到Linux的`/mnt/host`目录中,然后在那个目录执行`httpd -p 8080`A电脑可以执行`tcpsvd -v 0.0.0.0 8080 /usr/bin/nc 10.0.2.x 8080`转发,接下来打开`http/8080/`就可以访问到B电脑上的网页了。
总之只要有了网络这个系统的功能就能被无限扩大了只是……说是这么说其实还是依赖浏览器的功能所以这些功能就算用JavaScript直接做也完全没问题但毕竟是作为Linux终端有了这些能力之后就显得更完整了。
最终我仔细确认了原作者确实没有做这个功能,所以就发了个[Issue](https://github.com/tombl/distro/issues/156)看看他有没有兴趣把这个功能加到他的库中,如果被接受了也算是做出贡献了吧。
### 使用VLESS协议的网关
虽然之前已经加了基于浏览器Fetch API的网关但这个网关的局限性还是挺大的基本上也就只能请求网站了。那其他能在浏览器上运行系统的项目是怎么做的呢看了一下像v86用的是一个基于L2 Over WS的公共网关relay.widgetry.org而WebVM用的则是Tailscale。这两种我都不喜欢主要是这些东西基本上专门服务于这类在浏览器中运行的系统普通人并不会特意去搭建而我既不想用某个特定的服务也不想自己搭……那么有什么样的网络服务既随处可见又能在浏览器中使用呢这时候我就想到了VLESS协议它天生就适合运行在WebSocket中而且搭建起来极其简单比如有人用Cloudflare Workers做了一个叫做[edgetunnel](https://github.com/zizifn/edgetunnel)的脚本可以轻松将Cloudflare作为代理使用因此我决定接下来让AI实现一个基于VLESS+WSS的网关这样除了请求网站之外还能做点别的事情比如用`telnet towel.blinkenlights.nl`命令看ASCII版的《星球大战》😆。
只不过相比于其他项目用的那些L2的服务来说VLESS承载的是L4的协议所以我还得让AI实现TCP/IP协议栈……其实我不太想这样做的因为AI做这种事情容易出错但是它看了一下我之前用的[tcpip.js](https://github.com/chipmk/tcpip.js)库说是里面的API不满足要求……那没办法AI既然自己想搓就让它搓吧。不过VLESS协议这个我觉得还是得给它个[文档](https://github.com/XTLS/Xray-docs-next/blob/main/docs/en/development/protocols/vless.md),免得它开始瞎编。
不管怎么说它还是搓出来了虽然质量我不是特别满意……但毕竟手头用的AI不是最先进的AI就先这样吧最终的代码就是[vless-gateway.js](https://github.com/Mabbs/linux/blob/main/vless-gateway.js),用法也很简单,首先要有一个**证书合法**的VLESS+WSS节点然后在我的博客终端中按F12打开控制台输入`switchToVless("wss://domain:port/path", "UUID")`就可以将原来基于Fetch的网络切换到VLESS节点的网络了考虑到避免被滥用的情况我就不内置节点了如果有人有兴趣可以用自己的节点进行连接。
# 感想
做到这里可以感受到最近的AI所做的一切真的是令人难以置信它不仅知道几乎所有知识还有不知疲倦的思考能力以及足够的动手能力而这也仅仅建立在一个很一般的免费模型上。再回想起前段时间用的Agent做的什么[订阅源预览](/2025/04/08/feed.html)简直就太简单了😂。目前据我所知其他人使用更先进的AI已经可以解决人类没能解决的数学难题、自主设计处理器指令集架构在上面运行Doom、[从零开发一个Classic Mac OS](https://github.com/Kelsidavis/System7)、制作直接在UEFI中运行的软件、以及完全逆向Unity3D游戏把几款游戏混合起来做成一个新游戏……至于网上总传的什么DeepSeek的所谓的灰测模型搞出来的[各种Demo](https://github.com/6WENHAO/DS-Games)就算了根本比不了过去各种难以想象的东西都被轻松做出来了而这一切就发生在最近几个月我已经很难想象未来AI能做到什么样的地步了也许AI真的会带领人类走向无法想象的高度吧

755
_tools/blogquine.py Normal file
View File

@@ -0,0 +1,755 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import binascii
import lzma
import os
import struct
import sys
# ============================================================
# Part 1: 最小 LZMA1 range coder只做编码
#
# 设计目标:只实现 quine 构造需要的 tokenliteral / match / rep0-match /
# end-marker编码字节与历史内容无关track=False 时不维护输出历史),
# 这是"先算结构、后填数据"两阶段装配的基础。
# 参考Igor Pavlov 的 LZMA SDK (LzmaEnc.c / LzmaDec.c)。
# ============================================================
kNumBitModelTotalBits = 11
kBitModelTotal = 1 << kNumBitModelTotalBits # 2048
kNumMoveBits = 5
kTopValue = 1 << 24 # 0x1000000
kNumStates = 12
kNumLitStates = 7
kNumPosBitsMax = 4
kNumLenToPosStates = 4
kNumAlignBits = 4
kEndPosModelIndex = 14
kNumFullDistances = 1 << (kEndPosModelIndex >> 1) # 128
kMatchMinLen = 2
kNumLowLenBits = 3
kNumMidLenBits = 3
kNumHighLenBits = 8
kNumLowLenSymbols = 1 << kNumLowLenBits # 8
kNumMidLenSymbols = 1 << kNumMidLenBits # 8
kNumPosSlotBits = 6
PROB_INIT = kBitModelTotal >> 1 # 1024
class RangeEncoder:
"""LZMA 的区间编码器。low 是 64 位要容纳进位range 是 32 位。"""
def __init__(self):
self.low = 0
self.range = 0xFFFFFFFF
self.cache = 0
self.cache_size = 1 # 初值 1 -> 第一个输出字节恒为 0x00
self.buf = bytearray()
def _shift_low(self):
if (self.low & 0xFFFFFFFF) < 0xFF000000 or (self.low >> 32) != 0:
temp = self.cache
while True:
self.buf.append((temp + (self.low >> 32)) & 0xFF)
temp = 0xFF
self.cache_size -= 1
if self.cache_size == 0:
break
self.cache = (self.low >> 24) & 0xFF
self.cache_size += 1
# 注意C 里 `(UInt32)low << 8` 会截断回 32 位,必须照做,
# 否则 low 的高位会一直累积,进位位 (low>>32) 就不止 0/1 了。
self.low = ((self.low & 0xFFFFFFFF) << 8) & 0xFFFFFFFF
def encode_bit(self, probs, idx, bit):
p = probs[idx]
bound = (self.range >> kNumBitModelTotalBits) * p
if bit == 0:
self.range = bound
probs[idx] = p + ((kBitModelTotal - p) >> kNumMoveBits)
else:
self.low += bound
self.range -= bound
probs[idx] = p - (p >> kNumMoveBits)
while self.range < kTopValue:
self.range = (self.range << 8) & 0xFFFFFFFF
self._shift_low()
def encode_direct_bits(self, value, num_bits):
for i in range(num_bits - 1, -1, -1):
self.range >>= 1
if (value >> i) & 1:
self.low += self.range
while self.range < kTopValue:
self.range = (self.range << 8) & 0xFFFFFFFF
self._shift_low()
def bittree_encode(self, probs, off, num_bits, symbol):
"""普通位树MSB 优先,节点下标从 1 开始。"""
m = 1
for i in range(num_bits - 1, -1, -1):
bit = (symbol >> i) & 1
self.encode_bit(probs, off + m, bit)
m = (m << 1) | bit
def bittree_reverse_encode(self, probs, off, num_bits, symbol):
"""反向位树LSB 优先,用于 SpecPos / Align。"""
m = 1
for i in range(num_bits):
bit = symbol & 1
symbol >>= 1
self.encode_bit(probs, off + m, bit)
m = (m << 1) | bit
def finish(self):
for _ in range(5):
self._shift_low()
return bytes(self.buf)
def _pos_slot_and_bits(d):
"""把 0 基距离 d (=真实距离-1) 拆成 (posSlot, 低位数, 低位值)。"""
if d < 4:
return d, 0, 0
# posSlot >= 4 时numDirectBits=(slot>>1)-1, base=(2|(slot&1))<<numDirectBits
for slot in range(4, 64):
n = (slot >> 1) - 1
base = (2 | (slot & 1)) << n
if d < base + (1 << n):
return slot, n, d - base
raise ValueError("distance too large: %d" % d)
class LzmaEncoder:
def __init__(self, lc=3, lp=0, pb=2, track=False):
"""
track=True 时维护输出假历史literal/match 复制内容),用于一般用途;
quine 构造用 track=Falsematch 的编码字节只取决于 (dist,len,pos)
与历史内容无关,可跳过 37MB 级假历史的逐字节复制。
"""
self.lc, self.lp, self.pb = lc, lp, pb
self.track = track
self.pos_mask = (1 << pb) - 1
self.lp_mask = (1 << lp) - 1
self.rc = RangeEncoder()
self.pos = 0 # 已输出字节数
self.state = 0
self.prev_byte = 0
self.reps = [0, 0, 0, 0] # rep0..rep3存的是 0 基距离
self.out = bytearray()
# 概率模型
n = PROB_INIT
self.p_is_match = [n] * (kNumStates << kNumPosBitsMax)
self.p_is_rep = [n] * kNumStates
self.p_is_rep_g0 = [n] * kNumStates
self.p_is_rep_g1 = [n] * kNumStates
self.p_is_rep_g2 = [n] * kNumStates
self.p_rep0_long = [n] * (kNumStates << kNumPosBitsMax)
self.p_pos_slot = [n] * (kNumLenToPosStates << kNumPosSlotBits)
self.p_spec_pos = [n] * (kNumFullDistances - kEndPosModelIndex) # 114
self.p_align = [n] * (1 << kNumAlignBits)
self.p_len_choice = [n] * 2
self.p_len_low = [n] * (16 * kNumLowLenSymbols)
self.p_len_mid = [n] * (16 * kNumMidLenSymbols)
self.p_len_high = [n] * (1 << kNumHighLenBits)
self.p_rep_len_choice = [n] * 2
self.p_rep_len_low = [n] * (16 * kNumLowLenSymbols)
self.p_rep_len_mid = [n] * (16 * kNumMidLenSymbols)
self.p_rep_len_high = [n] * (1 << kNumHighLenBits)
self.p_lit = [n] * (0x300 << (lc + lp))
# ---------- 内部 ----------
@property
def pos_state(self):
return self.pos & self.pos_mask
def _encode_len(self, choice, low, mid, high, length):
"""choice 是 2 元素数组choice[0]=choice 位choice[1]=choice2 位。"""
ps = self.pos_state
l = length - kMatchMinLen
if l < kNumLowLenSymbols:
self.rc.encode_bit(choice, 0, 0)
self.rc.bittree_encode(low, ps << kNumLowLenBits, kNumLowLenBits, l)
else:
self.rc.encode_bit(choice, 0, 1)
l -= kNumLowLenSymbols
if l < kNumMidLenSymbols:
self.rc.encode_bit(choice, 1, 0)
self.rc.bittree_encode(mid, ps << kNumMidLenBits, kNumMidLenBits, l)
else:
self.rc.encode_bit(choice, 1, 1)
self.rc.bittree_encode(high, 0, kNumHighLenBits, l - kNumMidLenSymbols)
def _copy_out(self, dist, length):
"""track=True 时把 match 的输出复制进假历史。"""
src = len(self.out) - dist
for i in range(length):
self.out.append(self.out[src + i])
self.prev_byte = self.out[-1]
# ---------- 对外 token ----------
def literal(self, b):
if self.state >= kNumLitStates:
raise NotImplementedError("matched-literal 未实现quine 构造不需要)")
# 每个符号先编 isMatch 位0 表示这是 literal
ps = self.pos_state
self.rc.encode_bit(self.p_is_match, (self.state << kNumPosBitsMax) + ps, 0)
lit_state = ((self.pos & self.lp_mask) << self.lc) + (self.prev_byte >> (8 - self.lc))
self.rc.bittree_encode(self.p_lit, lit_state * 0x300, 8, b)
self.out.append(b)
self.prev_byte = b
self.pos += 1
# UpdateState_Literal
if self.state <= 3:
self.state = 0
elif self.state <= 9:
self.state -= 3
else:
self.state -= 6
def _write_dist(self, dist, lts):
d = dist - 1
slot, n, low_bits = _pos_slot_and_bits(d)
self.rc.bittree_encode(self.p_pos_slot, lts << kNumPosSlotBits,
kNumPosSlotBits, slot)
if slot >= 4:
if slot < kEndPosModelIndex:
base = (2 | (slot & 1)) << n
off = base - slot - 1
self.rc.bittree_reverse_encode(self.p_spec_pos, off, n, low_bits)
else:
self.rc.encode_direct_bits(low_bits >> kNumAlignBits, n - kNumAlignBits)
self.rc.bittree_reverse_encode(self.p_align, 0, kNumAlignBits,
low_bits & ((1 << kNumAlignBits) - 1))
return d
def match(self, dist, length):
assert kMatchMinLen <= length <= 273, length
ps = self.pos_state
self.rc.encode_bit(self.p_is_match, (self.state << kNumPosBitsMax) + ps, 1)
self.rc.encode_bit(self.p_is_rep, self.state, 0) # 非 rep
lts = min(length - kMatchMinLen, kNumLenToPosStates - 1)
self._encode_len(self.p_len_choice,
self.p_len_low, self.p_len_mid, self.p_len_high, length)
d = self._write_dist(dist, lts)
# 状态与 rep 链更新
self.state = 7 if self.state < kNumLitStates else 10
self.reps[3], self.reps[2], self.reps[1], self.reps[0] = \
self.reps[2], self.reps[1], self.reps[0], d
if self.track:
self._copy_out(dist, length)
self.pos += length
def rep_match(self, length, rep_idx=0):
assert kMatchMinLen <= length <= 273, length
ps = self.pos_state
self.rc.encode_bit(self.p_is_match, (self.state << kNumPosBitsMax) + ps, 1)
self.rc.encode_bit(self.p_is_rep, self.state, 1)
if rep_idx == 0:
self.rc.encode_bit(self.p_is_rep_g0, self.state, 0)
self.rc.encode_bit(self.p_rep0_long, (self.state << kNumPosBitsMax) + ps, 1)
else:
self.rc.encode_bit(self.p_is_rep_g0, self.state, 1)
if rep_idx == 1:
self.rc.encode_bit(self.p_is_rep_g1, self.state, 0)
else:
self.rc.encode_bit(self.p_is_rep_g1, self.state, 1)
self.rc.encode_bit(self.p_is_rep_g2, self.state, 0 if rep_idx == 2 else 1)
if rep_idx == 3:
self.reps[3] = self.reps[2]
self.reps[2] = self.reps[1]
self.reps[1] = self.reps[0]
self.reps[0] = self.reps[rep_idx]
self._encode_len(self.p_rep_len_choice,
self.p_rep_len_low, self.p_rep_len_mid, self.p_rep_len_high, length)
dist = self.reps[0] + 1
self.state = 8 if self.state < kNumLitStates else 11
if self.track:
self._copy_out(dist, length)
self.pos += length
def end(self):
"""LZMA 结束标记:编码一个 0 基距离为 0xFFFFFFFF 的 match。"""
ps = self.pos_state
self.rc.encode_bit(self.p_is_match, (self.state << kNumPosBitsMax) + ps, 1)
self.rc.encode_bit(self.p_is_rep, self.state, 0)
self._encode_len(self.p_len_choice,
self.p_len_low, self.p_len_mid, self.p_len_high, kMatchMinLen)
self._write_dist(0x100000000, 0)
self.state = 7 if self.state < kNumLitStates else 10
def finish(self):
return self.rc.finish()
# ============================================================
# Part 2: 7z 格式原语
# ============================================================
SIG = b"7z\xbc\xaf'\x1c"
VER = b"\x00\x04"
MAX_MATCH = 273 # LZMA1 单个 match 长度上限
def crc32(b, v=0):
return binascii.crc32(b, v) & 0xFFFFFFFF
def varint(v):
"""7z UINT64 变长编码:首字节高位连续 n 个 1 + 值的 (7-n) 个高位,再跟 n 字节 LE。"""
if v < 0x80:
return bytes([v])
for n in range(1, 9):
if v < (1 << (8 * n + 7 - n)):
break
else:
raise ValueError("varint too big")
first = ((0xFF << (8 - n)) & 0xFF) | ((v >> (8 * n)) & ((1 << (7 - n)) - 1))
return bytes([first]) + (v & ((1 << (8 * n)) - 1)).to_bytes(n, "little")
def store_hdr(payload_len, first=False):
"""LZMA2 uncompressed chunk 头3 字节,大端 size-1"""
assert 1 <= payload_len <= 65536
return bytes([0x01 if first else 0x02]) + (payload_len - 1).to_bytes(2, "big")
def matches_for(dist, total):
"""dist 固定、总长 total 的 token 序列:首个 match + 后续 rep0。
长度按 273 上限切分,并避开"只剩 1 字节"rep0 最小长度为 2"""
assert total >= 2
toks = []
first = min(MAX_MATCH, total)
if total - first == 1:
first -= 1
toks.append(("m", dist, first))
total -= first
while total > 0:
l = min(MAX_MATCH, total)
if total - l == 1:
l -= 1
toks.append(("r0", l))
total -= l
return toks
# ============================================================
# Part 3: 多文件 7z quine 构造器
# ============================================================
PROPS_BYTE = 0x5D # lc=3, lp=0, pb=2
CHUNK = 65536 # LZMA2 单 chunk 解压上限
SEED_NOTE = ("\nMayx's Blog!").encode("utf-8")
def dict_prop_for(maxdist):
"""选最小的 LZMA2 dict prop 使字典 >= maxdist。"""
for p in range(41):
if (2 | (p & 1)) << (p // 2 + 11) >= maxdist:
return p, (2 | (p & 1)) << (p // 2 + 11)
raise ValueError("distance too large")
def lzma_chunk(tokens, out_pos):
"""编一个 LZMA chunk0xC0: state+props reset无 dict reset无 end marker
match token 的编码字节只取决于 (dist,len,pos)与历史内容无关track=False"""
enc = LzmaEncoder()
enc.pos = out_pos
total = 0
for t in tokens:
if t[0] == "m":
enc.match(t[1], t[2])
total += t[2]
else:
enc.rep_match(t[1], 0)
total += t[1]
data = enc.finish()
assert total - 1 < 65536 and len(data) - 1 < 65536
hdr = bytes([0xC0]) + (total - 1).to_bytes(2, "big") + \
(len(data) - 1).to_bytes(2, "big") + bytes([PROPS_BYTE])
return hdr + data, total
class BlogQuine:
def __init__(self, root, quine_name="MayxBlog.7z", seed_name="_quine_seed.bin"):
self.quine_name = quine_name
self.seed_name = seed_name
# walk_entries: walk 顺序(父先子后、同级 dirs 在前)的 (rel, is_dir)。
# 子流顺序 = 非空条目在此列表中的顺序,必须自始至终保持同一顺序。
self.walk_entries = []
self.files = [] # (relpath, data bytes),顺序 = walk_entries 中文件序
for dirpath, dirnames, filenames in os.walk(root):
dirnames.sort()
for dn in dirnames:
rel = os.path.relpath(os.path.join(dirpath, dn), root)
self.walk_entries.append((rel.replace(os.sep, "/"), True))
for fn in sorted(filenames):
p = os.path.join(dirpath, fn)
rel = os.path.relpath(p, root).replace(os.sep, "/")
with open(p, "rb") as fp:
data = fp.read()
self.walk_entries.append((rel.replace(os.sep, "/"), False))
self.files.append((rel.replace(os.sep, "/"), data))
self.dirs = [r for r, isd in self.walk_entries if isd]
self.content = b"".join(data for _, data in self.files)
def entries(self):
ent = [{"name": self.seed_name, "dir": False}]
ent += [{"name": r, "dir": isd} for r, isd in self.walk_entries]
ent.append({"name": self.quine_name, "dir": False})
return ent
# ---------- 7z header ----------
def build_header(self, n, total, d, entries, sub_sizes):
n_sub = len(sub_sizes)
N = len(entries)
h = bytearray()
h += b"\x01\x04" # kHeader, kMainStreamsInfo
h += b"\x06" + varint(0) + varint(1) + b"\x09" + varint(n) + b"\x00" # PackInfo
h += b"\x07" # UnpackInfo
h += b"\x0b" + varint(1) + b"\x00" # kFolder: 1, local
h += varint(1) + b"\x21\x21" + varint(1) + bytes([self.dict_prop])
h += b"\x0c" + varint(d + total) # kCodersUnpackSize
h += b"\x00" # end UnpackInfo
h += b"\x08" # SubStreamsInfo
h += b"\x0d" + varint(n_sub) # 子流数
h += b"\x09" + b"".join(varint(s) for s in sub_sizes[:-1]) # 前 n_sub-1 个大小
h += b"\x0a" + b"\x01" # kCRC: AllDefined
crc_base = len(h)
h += b"\x00" * (4 * n_sub) # CRC 槽quine 的待定点)
h += b"\x00\x00" # end SSI, end MainStreamsInfo
h += b"\x05" + varint(N) # FilesInfo
bits = bytearray((N + 7) // 8) # kEmptyStream 位域MSB 优先)
for i, e in enumerate(entries):
if e["dir"]:
bits[i // 8] |= 1 << (7 - i % 8)
h += b"\x0e" + varint(len(bits)) + bytes(bits)
names = bytearray(b"\x00") # kName: external=0
for e in entries:
names += e["name"].encode("utf-16-le") + b"\x00\x00"
h += b"\x11" + varint(len(names)) + bytes(names)
attrs = b"".join(struct.pack("<I", 0x10 if e["dir"] else 0x20)
for e in entries)
h += b"\x15" + varint(2 + len(attrs)) + b"\x01\x00" + attrs # kAttributes
h += b"\x00\x00" # end FilesInfo, end Header
return bytes(h), crc_base
# ---------- 结构计算 ----------
def layout(self, d_seed, maxdist_hint):
content_len = len(self.content)
d = d_seed + content_len
# C1 链k 个 uncompressed chunk载荷总长 d+35
Ls = []
rem = d + 35
while rem > CHUNK:
Ls.append(CHUNK)
rem -= CHUNK
Ls.append(rem)
assert Ls[-1] >= 2, "末 chunk 载荷 %d 太小,调整 d_seed" % Ls[-1]
k = len(Ls)
hdrA = store_hdr(CHUNK, first=False) # 0x02 FF FF
hdrB = store_hdr(Ls[-1], first=False) # 末 chunk 头(可能与 A 相同)
self.dict_prop, dict_size = dict_prop_for(maxdist_hint)
# 子流大小quine 的 total 在迭代后填seed, 各文件, quine
file_sizes = [len(data) for _, data in self.files]
T, h = 100, 100
for _ in range(30):
chunks = []
o, f = 0, 32
S = 0
for j, L in enumerate(Ls): # C1a..C1k
chunks.append({"kind": "store", "foff": f, "size": 3 + L,
"ooff": o, "olen": L, "first": j == 0,
"c1": True, "S": S})
o += L
f += 3 + L
S += L
assert o == d + 35
# repro复现 file[35 : 32+3k+d+35) = pay0 hdr1 pay1 ... hdr(k-1) pay(k-1)
S = 0
for j, L in enumerate(Ls):
if j > 0:
# chunk j 的 3 字节头:从 seed 开头样本复制
srcpos = 0 if (j < k - 1 or L == CHUNK) else 3
dist_h = (d + 35 + S + 3 * (j - 1)) - srcpos
hb, hu = lzma_chunk([("m", dist_h, 3)], o)
assert hu == 3
chunks.append({"kind": "lzma", "foff": f, "size": len(hb),
"ooff": o, "olen": hu, "bytes": hb})
o += hu
f += len(hb)
# chunk j 的载荷:从 W[S:S+L) 复制
cb, cu = lzma_chunk(matches_for(d + 35 + 3 * j, L), o)
assert cu == L
chunks.append({"kind": "lzma", "foff": f, "size": len(cb),
"ooff": o, "olen": cu, "bytes": cb})
o += cu
f += len(cb)
S += L
# gears: store(x)+copy(x) 把 slip 压到 <=16
while f - (o - d) > 16:
s = f - (o - d)
x = min(s + 3, CHUNK)
chunks.append({"kind": "store", "foff": f, "size": 3 + x,
"ooff": o, "olen": x})
o += x
f += 3 + x
cb, cu = lzma_chunk(matches_for(x, x), o)
chunks.append({"kind": "lzma", "foff": f, "size": len(cb),
"ooff": o, "olen": cu, "bytes": cb})
o += cu
f += len(cb)
# jump: 单 match 从 W[6:6+y)seed 里的种植串)复制,使 slip = -3
s = f - (o - d)
y = s + 17
for _ in range(10):
jb, ju = lzma_chunk([("m", o - 6, y)], o)
y2 = s + 3 + len(jb)
if y2 == y:
break
y = y2
assert ju == y and y2 == y, "jump 不动点失败"
assert y + 6 <= d_seed, "种植串 %d+6 超过 seed %d" % (y, d_seed)
chunks.append({"kind": "lzma", "foff": f, "size": len(jb),
"ooff": o, "olen": ju, "bytes": jb, "jump": True})
o += ju
f += len(jb)
# gadget: 真空 store(T) + match(T,T) + 结束标记
assert f == (o - d) - 3, "slip=%d 应为 -3" % (f - (o - d))
chunks.append({"kind": "store", "foff": f, "size": 3 + T,
"ooff": o, "olen": T, "vac": True})
f += 3 + T
o += T
gb, gu = lzma_chunk(matches_for(T, T), o)
assert gu == T
chunks.append({"kind": "lzma", "foff": f, "size": len(gb),
"ooff": o, "olen": gu, "bytes": gb, "gmatch": True})
f += len(gb)
o += gu
# LZMA2 流结束标记0x007z t 需要它确认流完整结束
chunks.append({"kind": "term", "foff": f, "size": 1,
"ooff": o, "olen": 0, "bytes": b"\x00"})
f += 1
n = f - 32
total = f + h
sub_sizes = [d_seed] + file_sizes + [total]
entries = self.entries()
hdr, crc_base = self.build_header(n, total, d, entries, sub_sizes)
h_new = len(hdr)
T_new = len(gb) + 1 + h_new
if T_new == T and h_new == h:
assert o == d + f + h, "输出终点 %d != d+total %d" % (o, d + f + h)
return {"d": d, "d_seed": d_seed, "k": k, "Ls": Ls,
"chunks": chunks, "header": hdr, "crc_base": crc_base,
"n": n, "total": f + h, "T": T, "h": h,
"hdrA": hdrA, "hdrB": hdrB, "jump_y": y,
"n_sub": len(sub_sizes), "sub_sizes": sub_sizes,
"entries": entries, "dict_size": dict_size}
T, h = T_new, h_new
raise RuntimeError("layout 不收敛")
# ---------- 装配 ----------
def assemble(self, lay):
F = bytearray(lay["total"])
d, T, h = lay["d"], lay["T"], lay["h"]
d_seed = lay["d_seed"]
hoff = lay["total"] - h
# pass A: sig + 所有非 payload 字节
F[0:6] = SIG
F[6:8] = VER
struct.pack_into("<Q", F, 12, lay["n"]) # NextHeaderOffset
struct.pack_into("<Q", F, 20, h) # NextHeaderSize
jump_c = vac_c = None
for c in lay["chunks"]:
if c["kind"] == "store":
F[c["foff"]:c["foff"] + 3] = store_hdr(c["olen"],
first=c.get("first", False))
if c.get("vac"):
vac_c = c
else:
F[c["foff"]:c["foff"] + c["size"]] = c["bytes"]
if c.get("jump"):
jump_c = c
F[hoff:hoff + h] = lay["header"]
assert jump_c and vac_c
# pass B: seed = hdrA ‖ hdrB ‖ 种植串 ‖ 填充
y = lay["jump_y"]
plant = bytes(F[jump_c["ooff"] - d: jump_c["ooff"] - d + y])
seed = bytearray(d_seed)
seed[0:3] = lay["hdrA"]
seed[3:6] = lay["hdrB"]
seed[6:6 + y] = plant
pad = (SEED_NOTE * (d_seed // len(SEED_NOTE) + 2))[:d_seed - 6 - y]
seed[6 + y:] = pad
# pass C: 各 store 的 payload
P = bytes(seed) + self.content + bytes(F[0:35]) # = W[0:d+35)
assert len(P) == d + 35
for c in lay["chunks"]:
if c["kind"] != "store":
continue
ooff, olen = c["ooff"], c["olen"]
if c.get("c1"):
F[c["foff"] + 3:c["foff"] + 3 + olen] = P[c["S"]:c["S"] + olen]
elif c.get("vac"):
fo = ooff - d
F[fo:fo + olen] = F[fo + olen:fo + 2 * olen]
else:
fo = ooff - d
F[c["foff"] + 3:c["foff"] + 3 + olen] = F[fo:fo + olen]
return F, bytes(seed)
# ---------- CRC 定点96x96 GF(2) ----------
def solve_crc(self, F, lay, seed):
T, h, d = lay["T"], lay["h"], lay["d"]
k, n_sub, crc_base = lay["k"], lay["n_sub"], lay["crc_base"]
hoff = lay["total"] - h
vout_f = lay["total"] - 2 * T
hcopy = vout_f + (T - h)
# 已知 CRCseed + 各文件quine 的是未知量 D
known = [crc32(seed)] + [crc32(data) for _, data in self.files]
assert len(known) == n_sub - 1
for i, e in enumerate(known):
struct.pack_into("<I", F, hoff + crc_base + 4 * i, e)
struct.pack_into("<I", F, hcopy + crc_base + 4 * i, e)
# 未知量 D N S各出现两处
dpos = crc_base + 4 * (n_sub - 1)
ncopy = 32 + 3 * k + d # C1k 载荷里 F[0:35) 副本起点
groups = [[hoff + dpos, hcopy + dpos],
[28, ncopy + 28],
[8, ncopy + 8]]
Fv = memoryview(F)
def targets():
return (crc32(Fv),
crc32(Fv[hoff:hoff + h]),
crc32(Fv[12:32]))
base = targets()
basevec = base[0] | (base[1] << 32) | (base[2] << 64)
cols = []
for g in range(3):
for kb in range(32):
poss = [p + kb // 8 for p in groups[g]]
bb = kb % 8
for p in poss:
F[p] ^= (1 << bb)
t = targets()
for p in poss:
F[p] ^= (1 << bb)
cols.append((t[0] ^ base[0]) | ((t[1] ^ base[1]) << 32)
| ((t[2] ^ base[2]) << 64))
# (I+A) x = basevec方程 i: x_i ^ sum_j A[i][j] x_j = base_i
eqs = []
for i in range(96):
coeff = 0
for j in range(96):
if (cols[j] >> i) & 1:
coeff |= 1 << j
coeff ^= 1 << i # 对角元 = 1 ^ A[i][i]
eqs.append([coeff, (basevec >> i) & 1])
for j in range(96):
p = next((i for i in range(j, 96) if (eqs[i][0] >> j) & 1), None)
if p is None:
raise RuntimeError("GF(2) 奇异 @bit%d" % j)
eqs[j], eqs[p] = eqs[p], eqs[j]
for i in range(96):
if i != j and ((eqs[i][0] >> j) & 1):
eqs[i][0] ^= eqs[j][0]
eqs[i][1] ^= eqs[j][1]
x = 0
for i in range(96):
assert eqs[i][0] == (1 << i)
if eqs[i][1]:
x |= 1 << i
vals = [x & 0xFFFFFFFF, (x >> 32) & 0xFFFFFFFF, (x >> 64) & 0xFFFFFFFF]
for g in range(3):
for p in groups[g]:
F[p:p + 4] = struct.pack("<I", vals[g])
t = targets()
assert t == tuple(vals), "CRC 定点失败: %s != %s" % (t, vals)
return vals, known
def build(self, maxdist_hint=None):
if maxdist_hint is None:
# 最大距离 ~ jump 的 dist ≈ 2d + repro/gear 余量
maxdist_hint = 2 * (len(self.content) + 128) + (1 << 21)
d_seed = 64
last_err = None
for _ in range(80):
d = d_seed + len(self.content)
if (d + 35) % CHUNK == 1: # L_k = 1 无法编 match
d_seed += 1
continue
try:
lay = self.layout(d_seed, maxdist_hint)
F, seed = self.assemble(lay)
crcs, known = self.solve_crc(F, lay, seed)
return bytes(F), lay, seed, (crcs, known)
except (RuntimeError, AssertionError) as e:
last_err = e
d_seed += 1
raise RuntimeError("build 多次失败: %s" % last_err)
def verify(F, lay, seed, files, quine_name):
"""解码 LZMA2 流并逐文件校验。"""
d, d_seed = lay["d"], lay["d_seed"]
dec = lzma.LZMADecompressor(
format=lzma.FORMAT_RAW,
filters=[{"id": lzma.FILTER_LZMA2, "dict_size": lay["dict_size"]}])
W = dec.decompress(F[32:32 + lay["n"]])
assert len(W) == d + len(F), "|W|=%d 期望 %d" % (len(W), d + len(F))
ok = True
if W[:d_seed] != seed:
print("[verify] seed 不匹配")
ok = False
pos = d_seed
for rel, data in files:
if W[pos:pos + len(data)] != data:
print("[verify] 文件不匹配:", rel)
ok = False
pos += len(data)
assert pos == d
if W[d:] != F:
print("[verify] quine 自复制不匹配")
ok = False
print("[verify] 自解码: |W|=%d, seed/文件/quine 全部匹配: %s" % (len(W), ok))
return ok
def main():
ap = argparse.ArgumentParser(description="多文件 7z quine 生成器")
ap.add_argument("srcdir")
ap.add_argument("output")
ap.add_argument("--quine-name", default=None,
help="归档内 quine 文件名(默认 = output 的文件名)")
ap.add_argument("--seed-name", default=".this_is_mayx_blog")
ap.add_argument("--quine-dir", default="",
help="quine 在归档内所在的目录(如 public默认根目录")
args = ap.parse_args()
quine_name = args.quine_name or os.path.basename(args.output)
if args.quine_dir:
# 归档内路径用 / 分隔(与 walk 收集的目录条目一致)
quine_dir = args.quine_dir.strip("/")
quine_name = quine_dir + "/" + quine_name
bq = BlogQuine(args.srcdir, quine_name=quine_name, seed_name=args.seed_name)
print("[blogquine] %d 个文件, %d 个目录, 内容 %d 字节"
% (len(bq.files), len(bq.dirs), len(bq.content)))
F, lay, seed, (crcs, known) = bq.build()
with open(args.output, "wb") as fp:
fp.write(F)
print("[blogquine] written %s: %d 字节 (d=%d, k=%d chunks, n=%d, h=%d, T=%d)"
% (args.output, len(F), lay["d"], lay["k"], lay["n"], lay["h"], lay["T"]))
print("[blogquine] CRC 定点: D(quine)=%08x N(hdr)=%08x S(sig)=%08x" % tuple(crcs))
ok = verify(F, lay, seed, bq.files, quine_name)
sys.exit(0 if ok else 1)
if __name__ == "__main__":
main()

View File

@@ -6,7 +6,6 @@ cd blog
mkdir Mabbs
curl -L -o Mabbs/README.md https://github.com/Mabbs/Mabbs/raw/main/README.md
bundle exec jekyll build -d ../public_html
rsync --delete -rv ../public_html/ mayx@pgs.sh:/blog
tar czvf MayxBlog.tgz --exclude-vcs ../public_html/
mv MayxBlog.tgz ../public_html/
cd ../public_html/

1147
assets/js/blog-console.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,25 @@ function initVisitors() {
}
}
function highlightKeyword() {
var match = location.search.match(/[?&]kw=([^&]+)/);
var kw = match ? $.trim(decodeURIComponent(match[1].replace(/\+/g, ' '))) : '';
if (!kw) return;
var reg = new RegExp('(' + kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
var escapeMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
$('section, section *').not('script, style, textarea').contents().filter(function () {
return this.nodeType === 3;
}).each(function () {
var escapedText = this.nodeValue.replace(/[&<>"']/g, function (m) { return escapeMap[m]; });
var highlighted = escapedText.replace(reg, '<mark>$1</mark>');
if (escapedText !== highlighted) {
$(this).replaceWith(highlighted);
}
});
}
$(function () {
(function () {
var $backToTopTxt = "返回顶部", $backToTopEle = $('<div class="backToTop"></div>').appendTo($("body"))
@@ -42,6 +61,7 @@ $(function () {
});
console.warn("Mayx may already be Dead");
}
highlightKeyword();
});
function getSearchJSON(callback) {

View File

@@ -1,22 +1,3 @@
function highlightKeyword() {
var match = location.search.match(/[?&]kw=([^&]+)/);
var kw = match ? $.trim(decodeURIComponent(match[1].replace(/\+/g, ' '))) : '';
if (!kw) return;
var reg = new RegExp('(' + kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
var escapeMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
$('section, section *').not('script, style, textarea').contents().filter(function() {
return this.nodeType === 3;
}).each(function() {
var escapedText = this.nodeValue.replace(/[&<>"']/g, function(m) { return escapeMap[m]; });
var highlighted = escapedText.replace(reg, '<mark>$1</mark>');
if (escapedText !== highlighted) {
$(this).replaceWith(highlighted);
}
});
}
function initCopyButtons() {
$('.copy').remove();
$('div.highlight').each(function () {
@@ -33,6 +14,5 @@ function initCopyButtons() {
}
$(function () {
highlightKeyword();
initCopyButtons();
});

View File

@@ -0,0 +1 @@
24f0040157c07cc424b28b7b52ea734d

View File

@@ -2,5 +2,5 @@
mkdir Mabbs
curl -L -o Mabbs/README.md https://github.com/Mabbs/Mabbs/raw/main/README.md
bundle exec jekyll build -d public
tar czvf MayxBlog.tgz public/
mv MayxBlog.tgz public/
python3 _tools/blogquine.py public MayxBlog.7z
mv MayxBlog.7z public/

10
games.md Normal file
View File

@@ -0,0 +1,10 @@
---
layout: default
title: Mayx的游戏列表
---
# Mayx的游戏列表
- 凯露&危险生存( [CHS]({% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/?cn) \| [JA]({% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/) \| [KO]({% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/?kr)
- [立直麻将 Wordle]({% unless site.github %}https://mabbs.github.io{% endunless %}/riichi-mahjong-wordle/)
- [Brainfuck可视化演示]({% unless site.github %}https://mabbs.github.io{% endunless %}/brainfuck-visualizer/)
- [《激情麻将》关服前快照]({% unless site.github %}https://mabbs.github.io{% endunless %}/mahjong-dream-snapshot/) [国际服]({% unless site.github %}https://mabbs.github.io{% endunless %}/mahjong-dream-snapshot/?intl)

View File

@@ -66,8 +66,8 @@ image: https://screenshot.mayx.eu.org/
<h2>其他页面</h2>
<p>
<a href="/service.html">Mayx的公开服务</a><br />
凯露&危险生存( <a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/?cn">CHS</a> | <a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/">JA</a> | <a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/karyl-yabaival/?kr">KO</a> <br />
<a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/brainfuck-visualizer/">Brainfuck可视化演示</a><br />
<a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/linux/">Mayx's Blog Terminal</a> (<a href="{% unless site.github %}https://mabbs.github.io{% endunless %}/jsnix/">Fake Version</a>)<br />
<a href="/games.html">Mayx的游戏列表</a><br />
<a href="/message.html">留言板</a><br />
<a href="/links.html">Links</a><br />
<a href="/proxylist.html">代理列表</a><br />

1
nilaila-verify.txt Normal file
View File

@@ -0,0 +1 @@
32691808d04b4e838d0c0610ec848ca2