4 Commits

Author SHA1 Message Date
mayx 2a512a487d Update 3 files
- /_data/other_repo_list.csv
- /_data/links.csv
- /assets/js/jquery.min.js
2026-06-03 06:45:43 +00:00
mayx 556e27c9ad Update 2 files
- /index.html
- /assets/js/main_new.js
2026-06-01 05:36:14 +00:00
mayx 5a4baf5f4b Update 4 files
- /_data/ai-cache.json
- /_data/other_repo_list.csv
- /assets/js/pjax.js
- /_layouts/post.html
2026-06-01 01:09:42 +00:00
mayx 71d493c2a8 Update 4 files
- /_data/other_repo_list.csv
- /_posts/2026-06-01-dedupe.md
- /assets/js/pjax.js
- /index.html
2026-05-31 16:00:35 +00:00
9 changed files with 277 additions and 102 deletions
+2 -1
View File
@@ -177,5 +177,6 @@
"/2026/02/08/xslt.html": "这篇文章讲述了Google计划弃用XSLT技术,以及作者对这一决定的调查和应对方案。Google基于XSLT用户占比低、库存在漏洞等原因,建议将其从Web标准中删除。作者发现许多用户依赖XSLT进行博客订阅美化,甚至将其作为博客框架。为了对抗这一趋势,有人创建了网站https://xslt.rip,并开发了Polyfill库,通过WASM方式保持XSLT功能。虽然Polyfill库需要额外引用JS代码,但作者已将其提交至CDNJS。随后,作者探讨了替代方案,包括使用纯CSS美化订阅源(由AI生成feed.css),以及混合XHTML的方式,通过添加XHTML命名空间来实现链接等功能,但这种方法会产生“不纯粹”的警告。文章最后总结,技术可能会消失,但总有其他技术可以解决问题,并强调了适应浏览器厂商决策的重要性。",
"/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/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,节约了大量硬盘空间。"
}
+1 -2
View File
@@ -18,7 +18,6 @@ Lanke's blog,https://blog.blueke.top/,https://blog.blueke.top/rss.xml,请为一
寒士杰克,https://www.hansjack.com/,https://www.hansjack.com/feed/,喜欢捣鼓,不断进步!
Pinpe 的云端,https://pinpe.top/,https://pinpe.top/rss.xml,一个属于自己的云朵。
Chise Hachiroku,https://chise.hachiroku.com/zh/,https://chise.hachiroku.com/zh/feed/,向明日的辉迹,干杯!
映屿,https://www.glowisle.me/,https://www.glowisle.me/atom.xml,关于互联网、书籍、生活琐事以及那些一闪而过的念头
映屿,https://blog.verdant.ee/,https://blog.verdant.ee/atom.xml,关于互联网、书籍、生活琐事以及那些一闪而过的念头
Restent's Notebook,https://blog.gxres.net/,https://blog.gxres.net/atom.xml,不前沿技术分享
Coseroom,https://coseroom.com,,
RavelloH's Blog,https://ravelloh.com,https://ravelloh.com/feed.xml,Beginning of meditation.
1 title link feed_url description
18 寒士杰克 https://www.hansjack.com/ https://www.hansjack.com/feed/ 喜欢捣鼓,不断进步!
19 Pinpe 的云端 https://pinpe.top/ https://pinpe.top/rss.xml 一个属于自己的云朵。
20 Chise Hachiroku https://chise.hachiroku.com/zh/ https://chise.hachiroku.com/zh/feed/ 向明日的辉迹,干杯!
21 映屿 https://www.glowisle.me/ https://blog.verdant.ee/ https://www.glowisle.me/atom.xml https://blog.verdant.ee/atom.xml 关于互联网、书籍、生活琐事以及那些一闪而过的念头
22 Restent's Notebook https://blog.gxres.net/ https://blog.gxres.net/atom.xml 不前沿技术分享
Coseroom https://coseroom.com
23 RavelloH's Blog https://ravelloh.com https://ravelloh.com/feed.xml Beginning of meditation.
+32 -34
View File
@@ -18,7 +18,6 @@ https://repo2.serv00.com/git/pub/Mayx/mayx/
https://git.pixie.town/mayx/mayx
https://codefloe.com/mayx/blog
https://git.minetest.land/Mayx/blog
http://47.120.60.153:10880/mayx/blog
http://1.6.141.109:3000/mayx/blog
http://52.28.156.42/mayx/blog
https://code.dsconce.space/mayx/blog
@@ -29,7 +28,6 @@ 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
http://50.19.111.193:3000/mayx/blog
https://git.zeroplay.io/mayx/blog
http://45.33.87.87/mayx/blog
http://168.126.28.36:3000/mayx/blog
@@ -47,7 +45,6 @@ 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://106.15.78.64:3000/mayx/blog
http://111.119.244.185:3000/mayx/blog
https://git.influxfin.com/mayx/blog
http://219.157.255.213:25311/mayx/blog
@@ -58,7 +55,6 @@ 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://gitea.shirom.me/mayx/blog
https://git.wangxinlei.cn/mayx/blog
http://123.56.193.182:3000/mayx/blog
http://167.172.7.198:8081/mayx/blog
@@ -83,7 +79,6 @@ 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://112.124.40.88:5510/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
@@ -128,9 +123,6 @@ 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://175.126.123.163:3000/mayx/blog
http://git.uhfdemo.com/mayx/blog
https://git.jakubzabski.pl/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
@@ -163,7 +155,6 @@ 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
https://221.219.181.35:30000/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
@@ -188,7 +179,6 @@ 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
https://gitea.primecontrols-dev.com/mayx/blog
http://www.scserverddns.top:13000/mayx/blog
https://git.lucas-michel.fr/mayx/blog
https://git.imvictor.tech:2/mayx/blog
@@ -198,7 +188,6 @@ 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://gitea.kdlsvps.top/mayx/blog
https://code.antopie.org/mayx/blog
https://git.serenetia.com/mayx/blog
https://vcs.cozydsp.space/mayx/blog
@@ -212,7 +201,6 @@ 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
https://gitea.manekenbrand.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
@@ -229,7 +217,6 @@ 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://47.115.223.229:8888/mayx/blog
http://104.254.131.244:3000/mayx/blog
https://gitea.alacloud.de/mayx/blog
https://git.tobiasweise.dev/mayx/blog
@@ -240,7 +227,6 @@ 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
https://kamtk.ru:4000/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
@@ -263,12 +249,10 @@ 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://1.95.192.200:59300/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
https://git.vajdak.cz/mayx/blog
http://58.65.162.118:3000/mayx/blog
https://git.arkon.solutions/mayx/blog
http://8.131.93.145:54082/mayx/blog
@@ -276,7 +260,6 @@ 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://dev01.open-alt.com/mayx/blog
https://gitea.doinlab.com/mayx/blog
https://git.7af.ru/mayx/blog
https://gitea.yimoyuyan.cn/mayx/blog
@@ -286,17 +269,14 @@ 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.ihatemen.uk/mayx/blog
https://git.123doit.com/mayx/blog
http://62.43.207.91:8889/mayx/blog
https://rsas.de/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://git.yinbonet.cn/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
@@ -345,8 +325,6 @@ 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.qniao.cn/mayx/blog
https://git.fast-blast.uk/mayx/blog
http://git.mynas71.myds.me/mayx/blog
https://git.4lsa.com/mayx/blog
https://rlgit.pro/mayx/blog
@@ -365,9 +343,7 @@ https://git.automathon.org/mayx/blog
https://git.esen.gay/mayx/blog
https://git.webtims.ru/mayx/blog
https://gitea.personalsoftware.space/mayx/blog
http://gitea.yiban.com.tw:3030/mayx/blog
https://gitlab.iplusus.com/mayx/blog
https://git.cyberuk.me/mayx/blog
https://gitea.zachl.tech/mayx/blog
https://git.miasma-os.com/mayx/blog
https://gitea.nacsity.cn/mayx/blog
@@ -383,12 +359,10 @@ 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
https://gitea.shizuka.icu/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://43.138.83.20:3000/mayx/blog_cn
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
@@ -417,7 +391,6 @@ 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://115.159.194.75:4000/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
@@ -438,7 +411,6 @@ 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://101.43.238.71:3000/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
@@ -447,9 +419,7 @@ https://silica.codes/mayx/blog
https://git.crystalyx.net/mayx/blog
https://gittea.dev/mayx/blog
https://git.newnaturalphilosophy.org/mayx/blog
http://mrjinit.com:3000/mayx/blog
https://code.infininov.com/mayx/blog
https://git.apt142.ru/mayx/blog
http://gitea.mcelwain.net/mayx/blog
https://chunkks.com/mayx/blog
https://gitea.earthmanrpg.me/mayx/blog
@@ -476,7 +446,6 @@ 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
https://gitea.xinyuxi.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
@@ -488,7 +457,6 @@ 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://git.sao.ru/mayx/blog
https://codeop.ru/mayx/blog
https://git.mirocom.org/mayx/blog
http://gitea.ydxtool.com/mayx/blog
@@ -502,7 +470,6 @@ 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://www.mygitea.ru/mayx/blog
https://git.crwlr.ir/mayx/blog
https://git.nozora.top/mayx/blog
https://git.sortug.com/mayx/blog
@@ -525,6 +492,37 @@ 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
http://124.207.0.162:30000/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
1 repo_url
18 https://git.pixie.town/mayx/mayx
19 https://codefloe.com/mayx/blog
20 https://git.minetest.land/Mayx/blog
http://47.120.60.153:10880/mayx/blog
21 http://1.6.141.109:3000/mayx/blog
22 http://52.28.156.42/mayx/blog
23 https://code.dsconce.space/mayx/blog
28 http://durfee.mycrestron.com:3000/mayx/blog
29 https://gitea.nongnghiepso.com/mayx/blog
30 https://codes.tools.asitavsen.com/mayx/blog
http://50.19.111.193:3000/mayx/blog
31 https://git.zeroplay.io/mayx/blog
32 http://45.33.87.87/mayx/blog
33 http://168.126.28.36:3000/mayx/blog
45 http://111.231.146.230:8418/mayx/blog
46 https://git.pwaapp.cc/mayx/blog
47 https://an360.top/mayx/blog
http://106.15.78.64:3000/mayx/blog
48 http://111.119.244.185:3000/mayx/blog
49 https://git.influxfin.com/mayx/blog
50 http://219.157.255.213:25311/mayx/blog
55 https://gitea.hintsight.com/mayx/blog
56 http://blackobelisk.xyz:3000/mayx/blog
57 https://git.the-kn.com/mayx/blog
https://gitea.shirom.me/mayx/blog
58 https://git.wangxinlei.cn/mayx/blog
59 http://123.56.193.182:3000/mayx/blog
60 http://167.172.7.198:8081/mayx/blog
79 http://35.207.205.18:3000/mayx/blog
80 http://git.zjsciot.com:3000/mayx/blog
81 https://gitea.ontoast.uk/mayx/blog
http://112.124.40.88:5510/mayx/blog
82 http://121.36.37.70:15501/mayx/blog
83 http://187.216.152.151:9999/mayx/blog
84 http://116.63.173.179:8001/mayx/blog
123 http://101.201.34.43:3000/mayx/blog
124 https://git.gloje-rinchen-dorjee-rinpoche-buddhist-monastery.org/mayx/blog
125 http://101.35.227.2:3000/mayx/blog
http://175.126.123.163:3000/mayx/blog
http://git.uhfdemo.com/mayx/blog
https://git.jakubzabski.pl/mayx/blog
126 http://209.141.47.52:3000/mayx/blog
127 http://60.204.158.188:3000/mayx/blog
128 http://60.204.156.211:3000/mayx/blog
155 http://43.248.97.109:3000/mayx/blog
156 http://113.207.86.104:3080/mayx/blog
157 http://39.96.195.72:10082/mayx/blog
https://221.219.181.35:30000/mayx/blog
158 http://172.172.102.93:3000/mayx/blog
159 http://115.120.245.164:3000/mayx/blog
160 http://35.194.179.90:3000/mayx/blog
179 http://121.41.2.71:3000/mayx/blog
180 http://110.41.177.80:5000/mayx/blog
181 https://gitea.dsmaster.myds.me/mayx/blog
https://gitea.primecontrols-dev.com/mayx/blog
182 http://www.scserverddns.top:13000/mayx/blog
183 https://git.lucas-michel.fr/mayx/blog
184 https://git.imvictor.tech:2/mayx/blog
188 https://bdgit.educoder.net/mayx/blog
189 http://e19510c831.iok.la/mayx/blog
190 http://119.45.49.212:3000/mayx/blog
https://gitea.kdlsvps.top/mayx/blog
191 https://code.antopie.org/mayx/blog
192 https://git.serenetia.com/mayx/blog
193 https://vcs.cozydsp.space/mayx/blog
201 https://git.m.ctf.arrobe.fr/mayx/blog
202 http://69.62.64.52:3333/mayx/blog
203 https://git.flymiracle.com/mayx/blog
https://gitea.manekenbrand.com/mayx/blog
204 http://106.14.138.181:3000/mayx/blog
205 https://git.yyuu.xyz/mayx/blog
206 http://39.107.70.124:3000/mayx/blog
217 https://gitea.tecamino.com/mayx/blog
218 http://39.99.175.172:8000/mayx/blog
219 http://8.138.13.251:3000/mayx/blog
http://47.115.223.229:8888/mayx/blog
220 http://104.254.131.244:3000/mayx/blog
221 https://gitea.alacloud.de/mayx/blog
222 https://git.tobiasweise.dev/mayx/blog
227 https://repos.fbpx.io/mayx/blog
228 https://git.cavemanon.xyz/mayx/blog
229 http://svn.rivastudio.cn/mayx/blog
https://kamtk.ru:4000/mayx/blog
230 http://39.98.126.115:8080/mayx/blog
231 http://46.202.189.66:3000/mayx/blog
232 http://82.26.157.11:3001/mayx/blog
249 https://git.cenoq.com/mayx/blog
250 http://8.152.205.35:3000/mayx/blog
251 http://120.210.80.160:3000/mayx/blog
http://1.95.192.200:59300/mayx/blog
252 http://194.5.152.156:3000/mayx/blog
253 http://8.155.172.147:3001/mayx/blog
254 https://git.erfmann.dev/mayx/blog
255 https://git.weavefun.com:5443/mayx/blog
https://git.vajdak.cz/mayx/blog
256 http://58.65.162.118:3000/mayx/blog
257 https://git.arkon.solutions/mayx/blog
258 http://8.131.93.145:54082/mayx/blog
260 https://forgejo.bridgetownrb.com/mayx/blog
261 http://54.199.96.217:3000/mayx/blog
262 http://20.219.0.85:3000/mayx/blog
https://dev01.open-alt.com/mayx/blog
263 https://gitea.doinlab.com/mayx/blog
264 https://git.7af.ru/mayx/blog
265 https://gitea.yimoyuyan.cn/mayx/blog
269 https://git.sophiagwen.au/mayx/blog
270 http://139.196.96.28:13000/mayx/blog
271 https://dev.kiramtech.com/mayx/blog
https://git.ihatemen.uk/mayx/blog
272 https://git.123doit.com/mayx/blog
273 http://62.43.207.91:8889/mayx/blog
https://rsas.de/mayx/blog
274 https://git.johntsai.online/mayx/blog
275 https://gitea.css-sistemas.com.br/mayx/blog
276 https://git.f4e.lol/mayx/blog
277 http://47.113.145.232:3000/mayx/blog
278 http://47.115.212.237:3000/mayx/blog
279 http://72.61.229.93:4000/mayx/blog
https://git.yinbonet.cn/mayx/blog
280 https://lishan148.synology.me:3014/mayx/blog_cn
281 http://1.95.221.174:3000/mayx/blog
282 https://git.huwhy.cn/mayx/blog_cn
325 https://git.graveyard.sh/mayx/blog
326 https://git.nathanspackman.com/mayx/blog
327 https://git.rmarl.in/mayx/blog
http://git.qniao.cn/mayx/blog
https://git.fast-blast.uk/mayx/blog
328 http://git.mynas71.myds.me/mayx/blog
329 https://git.4lsa.com/mayx/blog
330 https://rlgit.pro/mayx/blog
343 https://git.esen.gay/mayx/blog
344 https://git.webtims.ru/mayx/blog
345 https://gitea.personalsoftware.space/mayx/blog
http://gitea.yiban.com.tw:3030/mayx/blog
346 https://gitlab.iplusus.com/mayx/blog
https://git.cyberuk.me/mayx/blog
347 https://gitea.zachl.tech/mayx/blog
348 https://git.miasma-os.com/mayx/blog
349 https://gitea.nacsity.cn/mayx/blog
359 http://49.232.183.190:3000/mayx/blog_cn
360 http://git.zxkedu.com:33769/mayx/blog_cn
361 https://code.wemediacn.com/mayx/blog_cn
https://gitea.shizuka.icu/mayx/blog_cn
362 http://51.159.198.233:3000/mayx/blog
363 https://gitea.adriangonzalezbarbosa.eu/mayx/blog
364 https://git.legatus.ru/mayx/blog
365 https://git.kayashov.keenetic.pro/mayx/blog
http://43.138.83.20:3000/mayx/blog_cn
366 http://47.104.241.192:19999/mayx/blog_cn
367 http://47.98.148.146:1026/mayx/blog_cn
368 http://119.96.62.56:3000/mayx/blog_cn
391 http://36.133.248.69:3088/mayx/blog_cn
392 http://220.205.16.27:18081/mayx/blog_cn
393 http://81.69.221.216:3000/mayx/blog_cn
http://115.159.194.75:4000/mayx/blog_cn
394 http://183.204.60.122:10081/mayx/blog_cn
395 http://43.139.240.37:17000/mayx/blog_cn
396 http://159.75.27.114:3000/mayx/blog_cn
411 http://meowug.com:8418/mayx/blog_cn
412 http://36.138.125.206:3000/mayx/blog_cn
413 https://git.4lcap.com/mayx/blog_cn
http://101.43.238.71:3000/mayx/blog_cn
414 http://59.110.175.62:4322/mayx/blog_cn
415 https://www.luluvip.cn:8419/mayx/blog_cn
416 http://xianyuhome.cn:11013/mayx/blog_cn
419 https://git.crystalyx.net/mayx/blog
420 https://gittea.dev/mayx/blog
421 https://git.newnaturalphilosophy.org/mayx/blog
http://mrjinit.com:3000/mayx/blog
422 https://code.infininov.com/mayx/blog
https://git.apt142.ru/mayx/blog
423 http://gitea.mcelwain.net/mayx/blog
424 https://chunkks.com/mayx/blog
425 https://gitea.earthmanrpg.me/mayx/blog
446 http://1.117.66.197:3000/mayx/blog_cn
447 http://git.zhmight.com/mayx/blog_cn
448 https://intl-dev.gaia888.com/mayx/blog_cn
https://gitea.xinyuxi.com/mayx/blog_cn
449 http://gitea.snailtrack.cn/mayx/blog_cn
450 http://ydds.cloud:3000/mayx/blog_cn
451 http://120.24.50.145:3000/mayx/blog_cn
457 http://www.bkandssp.cn:30/mayx/blog
458 https://gitea.spitaki.cloud/mayx/blog
459 https://git.codle.ru/mayx/blog
https://git.sao.ru/mayx/blog
460 https://codeop.ru/mayx/blog
461 https://git.mirocom.org/mayx/blog
462 http://gitea.ydxtool.com/mayx/blog
470 https://ruyiscx.cloud:3000/mayx/blog
471 https://git.0xee.eu/mayx/blog
472 https://gitea.deitglobal.com/mayx/blog
https://www.mygitea.ru/mayx/blog
473 https://git.crwlr.ir/mayx/blog
474 https://git.nozora.top/mayx/blog
475 https://git.sortug.com/mayx/blog
492 http://109.199.98.226:3001/mayx/blog
493 https://git.extra.eiffel.com/mayx/blog
494 https://gitea.digitanie.org/mayx/blog
http://124.207.0.162:30000/mayx/blog
495 https://git.xleed.com/mayx/blog
496 https://qlcodegitserver.online/mayx/blog
497 https://gitea.vvzvlad.xyz/mayx/blog
498 https://git.supernets.org/mayx/blog
499 https://git.digitaltelepresence.com/mayx/blog
500 https://git.hrfee.pw/mayx/blog
501 https://git.libregaming.org/mayx/blog
502 https://git.kaki87.net/mayx/blog
503 https://forgejo.vanten-s.com/mayx/blog
504 https://git.heartnn.com/mayx/blog
505 https://git.joinplu.me/mayx/blog
506 https://git.research.dezeeuw.ca/mayx/blog
507 http://149.104.29.239:8081/mayx/blog
508 http://ysx.myds.me:3005/mayx/blog
509 http://124.71.169.183:3000/mayx/blog
510 https://git.csi-kjsce.org/mayx/blog
511 https://hiwifi.denq.us:8418/mayx/blog
512 http://39.108.124.198:3000/mayx/blog
513 http://1090391-twk8saas.tmweb.ru/mayx/blog
514 https://git.msoucy.me/mayx/blog
515 https://git.niisse.net/mayx/blog
516 http://139.224.24.61:3000/mayx/blog
517 http://140.120.108.238:49308/mayx/blog
518 http://220.132.16.87:3000/mayx/blog
519 http://git.chilidoginteractive.com:3000/mayx/blog_cn
520 https://git.thunder-data.cn/mayx/blog_cn
521 https://git.cukak.com/mayx/blog_cn
522 https://git.ixu.me/mayx/blog_cn
523 http://git.uhfdemo.com/mayx/blog_cn
524 http://43.143.142.38:7001/mayx/blog_cn
525 http://111.230.243.127:3000/mayx/blog_cn
526 http://git.qniao.cn/mayx/blog_cn
527 https://gitea.smartechouse.com/mayx/blog_cn
528 http://git.feashow.cn/mayx/blog_cn
+2 -2
View File
@@ -162,7 +162,7 @@ $.get(BlogAPI + "/suggest?id={{ page.url }}&update=" + lastUpdated.valueOf(), fu
<div id="gitalk-container" data-page-id="{{ page.id }}"></div>
<script>
var gitalk = new Gitalk(Object.assign({ id: '{{ page.id }}' }, GitalkConfig))
gitalk.render('gitalk-container')
var gitalk = new Gitalk($.extend({ id: '{{ page.id }}' }, GitalkConfig));
gitalk.render('gitalk-container');
</script>
<!-- <![endif]-->
+210
View File
@@ -0,0 +1,210 @@
---
layout: post
title: 如何节约游戏占用的硬盘空间?
tags: [dedupe, RPG制作大师, 游戏]
---
浪费硬盘空间是可耻的!<!--more-->
# 起因
在几年前,我写过一篇在[MacBook上玩游戏](/2023/10/21/game.html)的文章,在那之后,我已经在我的Mac上下载了几十部游戏。只不过有个问题……我的Mac只有256GiB的硬盘存储空间,下载一堆游戏会让我的硬盘空间不够用,但是又不太想删,所以我该怎么尽可能让游戏占用更少的空间呢?
首先为了能在Mac上尽可能流畅地玩,我玩的游戏大多都是用跨平台能力很强的引擎编写的游戏,比如[Ren'Py](https://github.com/renpy/renpy)、RPG制作大师、Godot之类的,而像RPG制作大师这种引擎制作的游戏还有一个特点,开发者一般都会使用引擎自带的素材进行开发,有时候还会用不少第三方的罐头素材之类的(实际上甚至还有好多AVG为了蹭这些引擎的公用素材刻意用它们),所以这几十个游戏里应该有非常多的重复素材,如果能想办法把它们去个重,应该能节省相当多的空间吧……
# 去重的方法
如果想要对文件进行去重,我搜了一下,有个叫做[jdupes](https://codeberg.org/jbruchon/jdupes)的工具就很不错,它支持多种去重方式,比如使用硬链接,或者用一些文件系统的写时复制特性。不过如果用写时复制特性,jdupes在第二次执行的时候会认为去重后的文件还是单独的文件,就会重复去重了,而且最终也不好统计,反正对我玩的游戏来说,要去重的都是游戏素材,不存在后续修改的可能性,所以我打算全部用硬链接。
所以最终要执行的命令也非常简单,直接一句`jdupes -r -L Game`就可以了,这样以后每次下载了新的游戏之后重复执行这个操作,就可以将游戏中和其他游戏里有的素材去重了。
不过实际上很多游戏并不能直接用这种方式去重,因为它们的资源文件有些是打包成单个文件,有些进行了简单的加密,导致即使是相同的素材,文件也并不相同,所以我必须让所有的资源以单独原始的形态出现。对于不同的引擎也有不同的处理方式,所以接下来我需要对它们进行一些研究。
# 不同引擎的处理方式
## RPG制作大师MV/MZ
对于RPG制作大师MV/MZ开发的游戏来说,解密很简单,比较知名的是一个叫做[RPG-Maker-MV-Decrypter](https://gitlab.com/Petschko/RPG-Maker-MV-Decrypter)的工具,它可以在浏览器中进行解密,但一个游戏的资源文件非常多……要是全上传给浏览器实在是太麻烦了……后来我又搜了一下,有一个用C#写的叫[RPG Maker Decrypter](https://github.com/uuksu/RPGMakerDecrypter)工具也很不错,它作为命令行工具比在浏览器中执行简单多了,而且还能只把资源文件单独提出来,这样就可以剔除掉游戏自带的浏览器文件。不过他这个仓库的代码有个问题,它在选择文件的时候似乎会区分大小写,文件夹名中含有大写字母的似乎会被剔除……这样不太符合我的要求啊,当然我不会C#,于是我用AI改了一下,还给他提了个[PR](https://github.com/uuksu/RPGMakerDecrypter/pull/28),不过这家伙看起来似乎不太喜欢AI写的代码,看起来不打算合我的PR😅。不过无所谓了,反正我也是自用,他爱合不合吧。
这个工具的用法也非常简单,一句`RPGMakerDecrypter-cli [input] -p -o [output]`就处理好了,处理完之后只需要把`data/System.json`中的`hasEncryptedImages``hasEncryptedAudio`设置为false就可以正常识别,以后在Mac中只要在游戏路径下执行`python3 -m http.server`就可以在浏览器中游玩了。
在这个过程中,我还发现有一些游戏喜欢把原画文件直接放到游戏里面,一张图片好几M,但RPG制作大师的引擎在渲染的时候根本不会渲染出那么高的分辨率,结果毫无意义地浪费一大堆存储空间,而且因为图片是加密的,对大多数人来说也没有收藏价值。所以在解密完之后我就想干脆把这些图片全部有损压缩一遍,估计能节省不少存储空间,于是让AI写了个简单的压缩脚本处理了一下:
```python
#!/usr/bin/env python3
"""
图片压缩脚本(多进程版本)
将 pictures.orig 文件夹中的图片使用 WebP 格式进行高效压缩,
保持分辨率不变,肉眼看不出差异,压缩后的图片保存到 pictures 文件夹。
使用方法:
python3 compress_images.py
压缩策略:
- 保持原始分辨率不变
- 使用 WebP 格式(有损压缩,高质量)
- 质量设置为 85,在保持视觉质量的同时显著减小文件大小
- 文件名和后缀保持不变
- 多进程并行处理
- 处理失败时自动复制原文件
"""
import os
import shutil
from PIL import Image
from pathlib import Path
from multiprocessing import Pool, cpu_count
from functools import partial
# 配置路径
SOURCE_DIR = "pictures.orig"
OUTPUT_DIR = "pictures"
# WebP 质量设置 (0-100,数值越高质量越好,文件也越大)
# 85 是一个很好的平衡点,肉眼几乎看不出差异
WEBP_QUALITY = 85
# 对于带有透明通道的图片,可以设置不同的质量
WEBP_QUALITY_WITH_ALPHA = 80
# 并行进程数,默认为 CPU 核心数
NUM_WORKERS = cpu_count()
def compress_single_image(img_file: tuple[str, str, str]) -> tuple[str, bool, int, int]:
"""
压缩单个图片文件(用于多进程)
Args:
img_file: (源文件路径, 输出文件路径, 输出目录) 元组
Returns:
(文件名, 是否成功, 原始大小, 压缩后大小) 元组
"""
source_path, output_path_str, output_dir = img_file
source_path = Path(source_path)
output_path = Path(output_path_str)
original_size = source_path.stat().st_size
try:
img = Image.open(source_path)
# 检查是否有透明通道
has_alpha = img.mode in ('RGBA', 'LA', 'PA') or (img.mode == 'P' and 'transparency' in img.info)
# 确定使用的质量
quality = WEBP_QUALITY_WITH_ALPHA if has_alpha else WEBP_QUALITY
# 保存为 WebP 格式,但使用原始的文件扩展名
img.save(
str(output_path),
format='WEBP',
quality=quality,
method=6 # 压缩方法 0-6,6 是最慢但压缩率最高的
)
compressed_size = output_path.stat().st_size
return (source_path.name, True, original_size, compressed_size)
except Exception as e:
# 处理失败时,复制原文件到输出目录
try:
shutil.copy2(source_path, output_path)
compressed_size = output_path.stat().st_size
return (source_path.name, False, original_size, compressed_size)
except Exception as copy_error:
return (source_path.name, False, original_size, 0)
def main():
source_dir = Path(SOURCE_DIR)
output_dir = Path(OUTPUT_DIR)
# 检查源目录是否存在
if not source_dir.exists():
print(f"错误: 源目录 '{SOURCE_DIR}' 不存在")
return
# 创建输出目录
output_dir.mkdir(exist_ok=True)
# 获取所有图片文件(支持多种格式)
image_extensions = ('*.png', '*.jpg', '*.jpeg', '*.bmp', '*.gif', '*.tiff', '*.webp')
image_files = []
for ext in image_extensions:
image_files.extend(source_dir.glob(ext))
image_files = sorted(set(image_files)) # 去重并排序
if not image_files:
print(f"'{SOURCE_DIR}' 中没有找到图片文件")
return
# 构建任务列表
tasks = []
for img_file in image_files:
output_path = output_dir / img_file.name # 保持原文件名和后缀
tasks.append((str(img_file), str(output_path), str(output_dir)))
print(f"找到 {len(tasks)} 个图片文件")
print(f"源目录: {SOURCE_DIR}")
print(f"输出目录: {OUTPUT_DIR}")
print(f"WebP 质量设置: {WEBP_QUALITY}")
print(f"并行进程数: {NUM_WORKERS}")
print("-" * 70)
# 使用多进程池处理图片
success_count = 0
fail_count = 0
total_original = 0
total_compressed = 0
with Pool(processes=NUM_WORKERS) as pool:
for i, (filename, success, original_size, compressed_size) in enumerate(pool.imap(compress_single_image, tasks), 1):
total_original += original_size
total_compressed += compressed_size
if success:
success_count += 1
marker = ""
reduction = (1 - compressed_size / original_size) * 100 if original_size > 0 else 0
status_msg = f"{reduction:+.1f}%"
else:
fail_count += 1
marker = ""
status_msg = "复制原文件"
status = f"[{i}/{len(tasks)}] {filename}"
print(f"{marker} {status:50} {original_size/1024:>8.1f}KB -> {compressed_size/1024:>8.1f}KB ({status_msg})")
# 输出总结
print("-" * 70)
total_reduction = (1 - total_compressed / total_original) * 100 if total_original > 0 else 0
print(f"压缩完成!")
print(f" 成功处理: {success_count}/{len(tasks)} 个文件")
if fail_count > 0:
print(f" 失败(已复制原文件): {fail_count}/{len(tasks)} 个文件")
print(f" 原始总大小: {total_original / 1024 / 1024:.2f} MB ({total_original / 1024:.1f} KB)")
print(f" 压缩后大小: {total_compressed / 1024 / 1024:.2f} MB ({total_compressed / 1024:.1f} KB)")
print(f" 总压缩率: {total_reduction:.1f}%")
print(f" 节省空间: {(total_original - total_compressed) / 1024 / 1024:.2f} MB")
if __name__ == "__main__":
main()
```
最终压缩完之后我把原图上传到了[EH画廊](https://e-hentai.org/g/3901673/426a7a17ba/)中,本地只留压缩后的图片,大小从原来的2GiB多下降到了300多MiB,可以说效果相当显著了。
除此之外还有一些游戏使用了Ogg FLAC背景音乐,这种音乐不仅占用磁盘空间很大,而且我在Safari上玩的时候浏览器根本没法解析(Chrome应该可以)。虽然我听音乐是会考虑[HiFi](/2025/03/22/hifi.html),但玩游戏就没必要了吧……所以像这种音乐,就得用一句:
```bash
ffmpeg -i input.flac.ogg -c:a vorbis -strict -2 -q:a 10 output.ogg
```
转换为正常有损的Ogg音乐了。
## RPG制作大师XP/VX/VA
对于RPG制作大师XP/VX/VA引擎开发的游戏来说,它们都是基于用Ruby语言开发的RGSS编写的,作为脚本来说,倒是有跨平台的条件,但因为官方并没有做跨平台,所以不能直接在Mac上运行。不过有一款叫做[mkxp-z](https://github.com/mkxp-z/mkxp-z)的工具允许跨平台运行使用RPG制作大师XP/VX/VA制作的游戏,因此这类游戏我也收集了一些。
这些游戏的资源通常会进行简单的混淆加密,一般会打包成单个RGSSAD文件,这个解包也很简单,用刚刚的RPG Maker Decrypter就可以。不过这种游戏还有个特点,有些游戏需要使用[RTP](https://www.rpgmakerweb.com/run-time-package)才能运行,它这个RTP其实就是RPG制作大师自带的素材包,当时设计出来估计也是想着用来节约硬盘空间吧,就是不知道为什么到后来的MV/MZ却取消了这种方式……虽然mkxp-z是支持通过配置文件引入RTP的,但既然我已经选择了硬链接的方式,就没必要单独搞RTP了,我选择把RTP直接和游戏合并,然后让jdupes直接去重就好了,这样相比于RTP的方式还有一些好处就是XP/VX/VA可能有一些和MV/MZ使用相同的素材,这部分也可以不用占用重复的空间了。
## Ren'Py
对于Ren'Py来说,因为这个引擎并没有自带的公共资源,所以重复素材的问题并不是很大。不过在我之前对[Ren'Py的探索](/2024/01/20/renpy.html)中提到过,我玩的一些游戏是系列游戏,这种系列游戏有非常多的素材复用,但显然开发者并不会为了节约玩家硬盘空间而共享这部分资源,而且Ren'Py游戏也都是打包成单个文件的,所以接下来我们依然得要解包才能进行去重处理。
Ren'Py使用的rpa文件解包起来依然很简单,有一款现成的工具[unrpa](https://github.com/Lattyware/unrpa)可以直接解包,用pip就能安装。不知道为什么这些引擎总是喜欢把资源文件都打成一个包,明明很容易就能解包……难道是为了性能吗?
不过也正是因为Ren'Py的公共资源不多,如果玩的不是系列游戏,就没有解包的必要了,解包之后一堆小文件有可能会比整个rpa文件更大,毕竟文件系统存在“簇”,有可能会消耗没对齐的空间。
# 验证结果
最终进行完上述操作,可以通过执行`du -sh``du -shl`进行对比来验证节约的硬盘空间,我在这次游戏的瘦身中节约了:
```
~ % du -sh Game
33G Game
~ % du -shl Game
47G Game
```
看起来还是相当可观啊……尤其是在当下硬盘价格大涨的情况下,如果很多人能通过这些方式来节约硬盘空间,就能减少对硬盘容量的需求吧……不过说到底其实也都是网上能下到的资源,也许玩完之后就删掉才是最好的节约硬盘的方式吧😂。
<input name="live2dBGM" value="https://music.163.com/song/media/outer/url?id=1968116350.mp3" type="hidden" />
+5 -4
View File
File diff suppressed because one or more lines are too long
+14 -44
View File
@@ -1,51 +1,21 @@
/**
* 根据 URL ?kw= 参数高亮页面内匹配的关键词
* 提取为全局函数 pjax.js 在页面切换后复用避免重复实现
*/
function highlightKeyword() {
const urlParams = new URLSearchParams(window.location.search);
const keyword = urlParams.get('kw')?.trim();
var match = location.search.match(/[?&]kw=([^&]+)/);
var kw = match ? $.trim(decodeURIComponent(match[1].replace(/\+/g, ' '))) : '';
if (!kw) return;
if (!keyword) return;
var reg = new RegExp('(' + kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
var escapeMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
// 转义正则表达式特殊字符,避免安全问题
const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// 创建不区分大小写的正则表达式(全局匹配)
const regex = new RegExp(`(${escapedKeyword})`, 'gi');
// 递归遍历并高亮文本节点
const escapeHTML = str => str.replace(/[&<>"']/g,
tag => ({
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
}[tag] || tag));
function highlightTextNodes(element) {
$(element).contents().each(function () {
if (this.nodeType === Node.TEXT_NODE) {
const $this = $(this);
const text = escapeHTML($this.text());
// 使用正则替换并保留原始大小写
if (regex.test(text)) {
const replaced = text.replace(regex, '<mark>$1</mark>');
$this.replaceWith(replaced);
}
} else if (
this.nodeType === Node.ELEMENT_NODE &&
!$(this).is('script, style, noscript, textarea')
) {
highlightTextNodes(this);
}
});
}
$('section').each(function () {
highlightTextNodes(this);
$('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();
+2 -13
View File
@@ -10,19 +10,12 @@
var PJAX_OPTS = {
container: CONTAINER,
fragment: CONTAINER,
timeout: 8000,
timeout: 5000,
scrollTo: false
};
// ========== 各组件重初始化 ==========
/** AI 摘要(post.html 内联脚本,pjax 后由 executeScripts 触发) */
function reinitAISummary() {
if (typeof ai_gen === 'function' && $('#ai-output').length) {
try { ai_gen(); } catch (e) { /* ignore */ }
}
}
/** Google Analytics 页面浏览事件 */
function trackPageView() {
if (typeof gtag === 'function') {
@@ -87,7 +80,7 @@
/** 暴露给模板内 onclick/onchange 调用的导航函数 */
window.go = function (url) {
$.pjax({ url: url, ...PJAX_OPTS });
$.pjax($.extend({ url: url }, PJAX_OPTS));
};
// ========== 初始化 ==========
@@ -114,7 +107,6 @@
initVisitors();
initCopyButtons();
highlightKeyword();
reinitAISummary();
reinitLive2d();
trackPageView();
scrollToAnchor();
@@ -134,9 +126,6 @@
$('body').addClass('pjax-loading');
});
$(document).on('pjax:complete', doPjaxComplete);
$(document).on('pjax:error', function (xhr, textStatus, error) {
console.warn('[pjax] error, fallback:', error);
});
$(document).on('pjax:end', function (event, xhr, options) {
var $container = $(options.container || PJAX_OPTS.container);
+9 -2
View File
@@ -12,7 +12,7 @@ image: https://screenshot.mayx.eu.org/
<!-- 遍历分页后的文章 -->
<table class="entry-content h-feed">
{% for post in paginator.posts %}
<tr><td class="h-entry" onclick="if (!event.target.closest('a.p-category')) go('{{ post.url }}')">
<tr><td class="h-entry post-row" data-url="{{ post.url }}">
<h2 class="p-name"><a class="post-link u-url" href="{{ post.url }}">{{ post.title }}{% if post.layout == "encrypt" %} [加密] {% endif %}</a></h2>
<p>
<time class="date dt-published" datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date: "%-d %B %Y" }}</time>
@@ -77,4 +77,11 @@ image: https://screenshot.mayx.eu.org/
<small><a href="https://xn--sr8hvo.ws/previous"></a>
An <a href="https://xn--sr8hvo.ws">IndieWeb Webring</a> 🕸💍
<a href="https://xn--sr8hvo.ws/next"></a><br /><a href="https://icp.gov.moe/?keyword=20218888" target="_blank">萌ICP备 20218888号</a></small>
<input name="live2dBGM" value="https://music.163.com/song/media/outer/url?id=523658881.mp3" type="hidden" />
<input name="live2dBGM" value="https://music.163.com/song/media/outer/url?id=523658881.mp3" type="hidden" />
<script>
$(document).on('click', '.post-row', function(e) {
if ($(e.target).closest('.p-category').length === 0) {
go($(this).attr('data-url'));
}
});
</script>