Compare commits

...

19 Commits

Author SHA1 Message Date
4c4436c6c6 New Diary: maid
All checks were successful
部署文档 / build (push) Successful in 1m41s
Signed-off-by: SilverAg.L <caclx@outlook.com>
2025-12-31 04:30:12 +08:00
3604b6e4c0 update
All checks were successful
部署文档 / build (push) Successful in 1m8s
- deps
- faster js cdn
- Diary: recents 2025
- Notes:
ArchInstall (archCN mirror, niri refs)
ArchUEFI (make `bootxxx.efi` questions more neutral)
SelfHosted (wont extend notes anymore)

Signed-off-by: SilverAg.L <caclx@outlook.com>
2025-12-26 00:40:16 +08:00
8eed3560c1 New Diary: recent maintains.
All checks were successful
部署文档 / build (push) Successful in 1m33s
2025-11-17 14:03:19 +08:00
c9b385dc0d deps: update
All checks were successful
部署文档 / build (push) Successful in 1m32s
- seems the font fetching needs optimization.
2025-11-17 11:48:38 +08:00
d04f252d68 Del Note: jellyfin repo organization
- as for now I admit the importance of maintaining medias into reasonable trees.
2025-11-17 11:47:32 +08:00
e423fa9b35 deps: update
All checks were successful
部署文档 / build (push) Successful in 1m35s
2025-11-06 19:29:44 +08:00
d0ba0f16ec Del Diaries: self blaming
All checks were successful
部署文档 / build (push) Successful in 1m29s
may move them into 'moments' in future templates or implements, or may not.

in case even I am tired to look down myself now. lazy to write more stuffs.
2025-11-02 23:45:22 +08:00
f16d4f5649 Misc: rename groups
- maybe migrate to another theme later.
2025-11-01 06:27:22 +08:00
d43864e7e8 deps: update 2025-11-01 06:19:10 +08:00
09b7d88805 deps: update
All checks were successful
部署文档 / build (push) Successful in 1m35s
2025-10-22 09:06:55 +08:00
1024113c21 [Link] Asankilp (#11)
All checks were successful
部署文档 / build (push) Successful in 3m43s
Reviewed-on: #11
2025-10-11 10:01:31 +00:00
7e0c8aa896 [Link] Asankilp (#10)
Some checks failed
部署文档 / build (push) Failing after 11m10s
Reviewed-on: #10
2025-10-10 18:28:34 +00:00
5497b204fd [Link] SD7935的友链申请 (#9)
All checks were successful
部署文档 / build (push) Successful in 1m30s
[原文地址](https://github.com/AgxCOy/AgxCOy/issues/24)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Reviewed-on: https://git.liteyuki.org/AgxCOy/blogs/pulls/9
2025-10-03 19:42:27 +00:00
676783aa81 Edit Note: Arch UEFI
All checks were successful
部署文档 / build (push) Successful in 1m35s
- reword some repeats
2025-10-02 21:44:26 +08:00
0d1de50594 Edit Diaries - Appendix, Removal
All checks were successful
部署文档 / build (push) Successful in 1m31s
2025-10-02 21:25:21 +08:00
a111647c46 Edit Notes - Rearrange, Appendix, Bugfixes. 2025-10-02 17:23:43 +08:00
176b33ec18 Edit Category: diaries
All checks were successful
部署文档 / build (push) Successful in 1m28s
* btw Edit Diary: Cold Down.
2025-09-06 00:16:58 +08:00
c27bbe4fcf Rewrite Diary: Cold Down
All checks were successful
部署文档 / build (push) Successful in 1m31s
2025-09-06 00:04:38 +08:00
fdf210cdf1 Edit Note: Jellyfin File Organization 2025-09-05 21:53:02 +08:00
40 changed files with 2327 additions and 2387 deletions

View File

@@ -1,6 +1,7 @@
{
"files.exclude": {
"**/*.webp": true
"**/*.webp": true,
"**/*.avif": true
},
"editor.tabSize": 2
}

View File

@@ -1,12 +0,0 @@
---
title: 综述
index: false
article: false
timeline: false
comment: false
icon: folder-open
---
“综述”这边的博文通常比较正式一些,编排上会参考大学论文、实验报告,当然也经常会有迭代(综述嘛,追求严谨)。
<Catalog />

View File

@@ -0,0 +1,25 @@
---
article: false
---
# 年将尽,随几张女仆装
如题2025 也快结束了。今年我的精神状态感觉更糟了些。但万幸,女装——或者说穿上可爱的衣服——依旧是我内心想要去做的事之一,我也依旧愿意为此付出精力。
之前总说在减肥,目前看来 XXL 已经是我的极限了,再减似乎效果也不太明显的样子。但即便如此看着我的自拍也还是觉得怪怪的。也许我的身体条件本就不适合吧。
![黑巧-1 =300x](./maid-251231-1.avif)
![黑巧-2 =300x](./maid-251231-2.avif)
![黑巧-3 =300x](./maid-251231-3.avif)
![黑巧-4 =300x](./maid-251231-4.avif)
![白巧-1 =300x](./maid-251231-5.avif)
![白巧-2 =300x](./maid-251231-6.avif)
![白巧-3 =300x](./maid-251231-7.avif)
![白巧-4 =300x](./maid-251231-8.avif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

View File

@@ -1,5 +1,5 @@
---
title: 随想
title: 记忆的质料
index: false
article: false
timeline: false

View File

@@ -1,24 +0,0 @@
# 拖延症
> [!note]
> 事实上本文也鸽了。上面的看来是初次提交时间(真正动笔的时间),然鹅实际上 8.17 凌晨我就开这个坑了。
拖延症,后来又称“鸽”、“咕咕咕”,算是创作者的一种通病,毕竟创作者的精力终归有限。然鹅我的拖延属于是饱受诟病,以至于我自己都用“社会必要劳动时间”和“个别劳动时间”来自嘲。
君不见,我的《脑死 Remake》能做两年半给《星辰之光》做战役关卡能做个一年半载——而多数个人地图师可能只需一个月便可完工。无论是自己的企划还是给别人搬砖如若没有切实的代价比如延毕、被堵家门、信道被骚扰、扣工资我便对任务的时效性全无概念推进如龟速。或许这也是我做了诸多尝试却未曾成功的原因之一。
先前也是因为买了台并不合适的显示器[^sanc_screen],看到了 KDE 在屏幕缩放上的不足:只能**同时对所有显示器设置同一缩放率**,并不能针对性地让 1 屏 125% 缩放、2 屏 100% 缩放。6 月份重装 Arch Linux 之后我便吐槽这件事,这时有群友向我推荐 niri[^windows_mgr],当时我也表示愿意试试。结果呢?这都八月份了我**才开始**在 WSL 里测试。
[^sanc_screen]: 说来也是有些无语:在网购数码产品这方面,我似乎总缺少一些谨慎,又总是被我哥坑到。
我目前唯一能仰赖的轻薄本也是他推荐的——不过这也怪我需求不明,谁知道我不久之后就入坑《原神》了呢;而屏幕这边他推给我的选项看似也比较划算,但一是我没有仔细看品型参数、错买成 1080p二是并没有找多几家比价以至后来淘宝推了更便宜的 2K 24' 显示器之后只得捶胸顿足=。=
[^windows_mgr]: 一种平铺窗口管理器WM有别于 KDE Plasma 和 Windows 的活动窗口模式,这种平铺窗口切实遵循着网格般的布局,很少有窗口遮挡这种现象。
这种窗口管理器本身并不能形成完整的桌面 UI还需要显示管理器DM、资源管理器等诸多散装组件的协作就上手难度而言无疑是折磨级别。
![说是试试 niri却拖了好几个月 =420x](./niri.webp)
某种程度上这可比“三分钟热度”可怕多了。至少三分钟热度是当即就去做,然后没多久才被别的事物吸引注意力;而我这种咕咕咕则更像是“车大炮”(即吹牛)——空口无凭,只会耍嘴皮子,真办点事立马被别的东西吸引注意力,根本不靠谱。等我真“磨完洋工”,可能人早就走光了吧。
随着我自去年来精神状态每况愈下,在意识到这种咕咕咕可能还会加剧,以及我也确实没活去开坑之后,我终于还是放弃“做饭”、造轮子,专心当个读者、观众、工具的使用者,也就舍弃掉 Cl这套网名了。虽然很可惜但……这样就够了。有需求就先检索——早在 20 多年前互联网便无所不包了,轮子或许真不着急先造;实在不行再诉诸实践,用这双低效的双手一点点敲出来吧[^frg2089]。
[^frg2089]: 或者,并非是低效的我的实践。最近几次直播我看[岛风 @frg2089](https://github.com/frg2089) 也是非常之跃跃欲试,好几次请求开 Live Share 让他来搓。一方面挺感谢他的无偿劳动,另一方面又怪过意不去的。说到底还是我太菜了= =

View File

@@ -1,14 +0,0 @@
# 脑子一“热”?来点“冷却液”
最近也是无所事事(唉,无业),闲来无事刷视频。毕竟我是二游玩家,其中又以米游为甚,多少会刷到各种声音,令人难以分辨。张维为说得对啊:如今随着短视频的兴起,人保持理性变得越来越困难。
但上头了也不好。上头了容易“祸从口出”。虽然“巡猎”确实一定程度地维护了米游社区,但不可否认它也加剧群体极化,容易让人“杀红了眼”,对于个体而言不是什么好事。因此,我需要一样东西充当“冷却液”,让我保持“沉默是金”的风格。
上哪找呢……这倒是因人而异了。我自中学开始就和我爸争论,他很喜欢用《矛盾论》来指摘我过于主观——诚然如此。在这种氛围下,我很自然地理解马哲的观点,甚至去运用它分析自己的、亲友的一些症结(但遗憾的是,也只停留于分析层面)。于是,我便时不时拜读教员的《实践论》和《矛盾论》。不得不说,常看常新。
于是在用唯物辩证法洗了洗眼睛之后,忽然觉得这些难以分辨的声音也不再那么嘈杂,扰人清净。“没有调查就没有发言权”——我是始终相信这句话的。那么既然我的“调查”不够充分,我的发言自然会是片面,于我看来摆不上台面,干脆闭口不谈。……如此,便迫使自己冷静了下来。
另,我和所玩的游戏一定是有矛盾的(这或许与游戏公司之类的资本脱不开关系,但简单这么归结显然不对),只是缓和态与激化态之分罢了。既然如此,待到矛盾不可调和,那“分手”不就是了。
以上大抵就是我的一些消极的方法论,或许对社交平台乃至现实社交也同样适用。毕竟我吵架吵不过人嘛,索性就不吵,问就是“你说得对”。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

View File

@@ -7,6 +7,6 @@ comment: false
icon: message
---
小作文。自省?发泄?到什么什么。
小作文。自省?发泄?借用网友的一句话,梦到什么什么。
<Catalog />

View File

@@ -0,0 +1,37 @@
# 碎碎念25 年末版)
最近折腾了不少东西,心情也起起伏伏。《如我所书》取自崩铁的同名词条,个人也倾向于记录那些“能成篇的”专栏;咱这主题又没动态功能,思来想去还是写到这充当《记忆的质料》吧。
## 可爱一点的博客主题
既然说到博客主题,就顺便唠唠好了。我个人还是觉得`vuepress-theme-hope`偏向项目文档一些,当作博客虽然也可以 !!(甚至 MarkDown 扩展相对很齐全)!!,但……怎么说呢,可爱不起来(
我个人还挺宅的,主题这方面也想稍微萌系一点。不说非得特别可爱吧,至少想一眼给人那种二次元的印象。在 GitHub 上搜了一些二次元主题,要么是 Mizuki 二创(或者说 Fuwari 三创?),要么缺胳膊少腿。像有个 BA 主题只能塞推文,要动态和友链还得另搓;另有个 Miracle 主题虽然视觉上挺优雅的,但 MarkDown 扩展支持又一言难尽。
> 好友:自己搓个吧(
> 我:呜呜,补会(
所以还是接着套这个模板吧。
## 名为无所谓,实为破罐子破摔
前一阵发现“无病呻吟”这块连续塞了四篇负能量。事实证明,写小作文并不能解我的铃[^mentalIllness],充其量延缓我的症状。当然我的症状归根结底缘于内耗,解释起来又要去讨论我的“失败史”,不妨就这么总结吧:
- 咕咕咕的怠惰:只要没有 DDL !!(骗你的,没奖惩的 DDL 也照样)!!,就能以月、年为单位地拖。
- 懒汉做学问:要用什么学什么,主打一个经验主义。
- 自以为自知之明的无知:从来就没(能够)客观评价自己,要么眼高手低,要么把自己贬得一无是处(现在也一样)。
- 在失败的斜坡上短道速滑:独立创作遇上瓶颈滑坡成“毫无创见”,考研坠机滑坡成“这辈子也就这样了”,刚干活一个月犯了事(虽然并非小事)滑坡成“千古罪人”,……
于是一面写小作文痛批自己,一面发现自己仍然每况愈下,就这样磨洋工过了半年。最后与其说是释然、“无所谓”,更像是破罐子破摔、“随便怎么样吧”。说起来这“千古罪人”的帽子也不过是前同事跟我开玩笑说说的,只是我这人容易当真,我现在的确认为自己是个罪人,值得一呜呜伯爱死的那种。
[^mentalIllness]: 我个人觉得精神困境还是“解铃还需系铃人”的处理逻辑。不过最近也见证了一些无力处理这类困境、不得不求诊的例子,还是“说起来容易做起来难”啊。
## 硬件购置
今年说实话不太适合装机()双 11 前后内存涨、硬盘涨,现在甚至 CPU 也涨。不知道各位觉得 2T 固态理想情况得是多少米,我是借着我哥的天猫超市中秋礼券、红包、优惠叠起来,咬咬牙 680 买下铠侠的 SD10 2TB。!!说实话更希望再便宜点,最好是 648!!
另一边我去年的推流姬也摇身两变先是作为我上班的消遣RDP 远程),然后又拿来当 NAS当然也不单纯为了存储。NAS=Network Attached Storage没盘怎么组 Storage所以先是搞了块 500G 2.5 寸 CMR 薄盘,到这里为止说实话还称得上好活。
本年暑期,有群友出一台 4 盘位蜗牛 C 款小闷罐,我则用《原神·空月之歌》的两个版本代肝作为交换(当事人称作“灵活的支付方式”)。等实际接盘了我才发现所谓的扩展性在我这推流姬上困难重重:我这推流姬并没有那么多 IO 接口给他扩(也就 2.5 寸 SATA、m.2 SATA、NGFF WiFi那两 SATA 实测也不支持 PM 功能),随附的 miniPCIe 转 8654 也用布上(最开始甚至尝试用 mSATA 转接板连这个转接卡)。
最终只能考虑 USB3.0 去接 SATA PM 板,一拖五。结果又发现这机箱本就是残花败柳,四盘位坏了两。属于是“前景不错,但有前景不太可能”。推流姬的板 U 太垃圾导致的。
---
虽然还有很多话题想唠,但真要写起日记吧,记忆却蒙上一层薄雾,回忆不真切。以上是记得比较清楚 ~~(或者说耿耿于怀)~~ 的几件,姑且落笔一叙。

View File

@@ -1,41 +0,0 @@
# 需求与“死锁”
> 某种意义上,“死锁”也是我当前面临的心理困境。
## 首先,因为有了需求
我自认非常之“贪心算法”,我的行动也基本上为了“主观的当下”服务:我想要做什么?我想做的事需要什么条件?有没有可能设法达成?
这样通过需求推导,针对性地采取措施(比如学某项技能、做物质准备),在我看来算是一种“需求导向”。尽管“实用主义”并非真理,但马哲也好,各种方法论也罢,或许正因它们如同预期那般发挥了作用,人们才广泛运用它们的吧。
所以,在需求的驱使下,我认识了很多英语单词,折腾起 Windows 的配置,上手 AE 瞎摆弄着频谱特效,然后是 PECMD 脚本、C#、Python……虽然没人理解我为何钟情这些“有的没的”。
不得不承认,国人的一生非常地现实,客观的非生理需求(好比学生的学习应试需求)也是不得不直视的生活一部分。然鹅长期以来我都活得比较主观,社会的要求或者说“客观需求”并没有得到足够的重视,那么客观、社会现实层面上我无疑是比较失败的。
## 然后,需求催生动力
需求或许是学习最直接的原动力了吧,毕竟……是自己的欲求嘛。有人为了看懂番剧自学五十音,有人为了解放重复劳动学着写脚本写程序,也有人只是想上手玩玩什么——但那何尝不是一种需求,娱乐需求。
当然,正所谓“师者,传道受业解惑者也”,作为“徒”,学习或许也分两种途径:悟道与解惑。
但……我所接触的早年的“红警 diy”对新人谈不上友好有事没事“看教程”现实当中我也无从问起反倒更多地在为别人解惑——“你这么懂都不会那我们这些不懂的更帮不了你了啊”。所以面对如今热门的各种 AI社恐的我还真的无所适从——要怎么斟酌语言提问呢
如此,好像只剩下“我自己明悟”这一条路了。或许我应该庆幸,自己借此学会当一个调试器——是 200 OK 还是 417 Expectation Failed实地测测不就知道了。而除了各种课程、教程资源实地测试以外最重要的能力大抵就是信息检索能力吧毕竟“伸手党”亦为早期互联网所不齿。
## 但,假如需求链太长了呢?
这个问题在考研备考的后期逐渐暴露出来,并且随着就业压力愈发凸显。
我所谓的“需求导向”,成也需求,败也需求。人是有惰性的,对于一件工具,一样技艺,若只凭需求去学习运用,便容易浅尝辄止,“需要做什么我便学了什么为止”。想要搓一个好看的频谱视频,便只折腾频谱;想要方便地处理红警的 ini 和 csf便和键值对数据结构钻牛角尖。
这样的结果有二。其一,面对更高的需求时,一时间拿不出对等的“解”满足它。其一之后往往也是其二,一旦发现需求链过长,解决它需要付出很大的代价(尤其是时间),这时“需求导向”失灵,至今为了解决需求所做的一切全都归于虚无。
我 24 考研失利就在于此,哪怕最简单的数二,也难以理解“武神”如何省略的步骤,直接得出结果;然后发现是中学的芝士,却遗憾地发现连中学的知识点都不甚理解,就这样溯源到了初中。哪怕再给我一年,从初中重新学回来的收效也犹未可知。
此后忙前忙后终于还是没能“跨”去计专就那样毕业了。然鹅哪怕忽略掉各大单位“卡专业”的事实我也顿觉自己只学了个皮毛与人家的技术栈相去甚远。Native Programming不不不早就是 web 应用的时代了;什么?数据库都不认识?那还好意思去做程序员?
## 最终,形成了死锁
于是,我陷入了“虚无”,尽管我很清楚自己的状态并不正常、自己的思绪需要疏导,清楚自己“虚无”的症结——
::: center
有限的能力需要需求给养,然鹅莫得需求需要我解决,我也不再清楚“想做什么”;
更高的需求需要能力支持,然鹅莫得能力去搭这把手,我也茫然不知“要怎么做”。
:::
豪德,两边都等不到对方,死锁就这么成了。
尽管写这篇小作文的当下我已试着找些新的方向和需求,但漫无目的地学,也不过是学个乐呵。有没有用嘛……谁知道呢?哪天真有用了或许也已经淡忘了吧。

View File

@@ -1,36 +0,0 @@
# 醒“梦”
> [!note]
> 看到好友的说说,有感而发尔。原本是想 neta《崩坏3》7.6 版本标题的,但或许是厌弃自己、找不到可以被“曙”字修饰的契机吧,最终只 neta 了一半(
那么,先听听“阿雨”的告解吧:
> 希望我们都能早日醒来,也希望有一天,我们会让现实与梦境对我们而言同样美好,让离开梦境直面现实,不再是“敢于”,而只是从一朵开花的树下走到另一朵开花的树下。当然,在创造梦境般的现实之前,我们不得不或许有点痛苦的从梦境中醒来。
>
> ……
>
> 人如果在梦里梦外感觉都是痛苦的话,痛苦的感觉反而没有那么令人印象深刻,只是麻木罢了,就像我曾经经历的很多在刚醒来时印象深刻、过几天又忘的差不多了的噩梦。反而是某些带着甜味的片段,提醒我们梦里是什么样子、提醒我们曾经或者与曾经类似的东西是什么样子,又提醒着我们在现在的现实中那些曾经真实存在的东西从某种意义上来讲已经消失。无论是梦里的梦或者是梦外的梦。
回想我那连自己都厌倦于提及的,“来时的路”,或许如梦般光怪陆离而又易碎;又或者从现实的意义考量,寡淡如白开,平静如死水。但不可否认,再怎么毫无底线地否定自己,切实的经历始终是甜美的、难以割舍的“记忆”。否定了它,或许才是真正的“虚无”吧。
## 梦中
我的过去,概括地说来,不外乎四处求索,却求而不得的失意罢了。“看到了有意思的作品,想要像他们一样做点什么、做到什么”,基于这个动因,我做了许多次尝试,遗憾的是一次都没成功过。比起我“单纯”的过去,水友们,哪怕是大学四年熟识的舍友同学,其经历或许都“丰富”得多。换言之,“那很有生活了”。
都说人的本质属性是社会性,但当时我的交往十分畸形,有大量的输入:提问、征召、要求、期盼;但相对地,输出却被遏制:我的疑问找不到人求解,我的求索乃是踽踽独行,我没有资格谈什么条件,我的期盼“不过是玩物丧志”。加上 14 年初次开始尝试时接触的思潮:比起找人发问,不如多看教程——让我更加羞于开口。结果嘛也显而易见——**我沉浸在自己的求索里已然太久,连正常交流的能力都失去了**。如今连向 AI 提问都要斟酌半天。
既然错误地否定掉了“社会性”,我经历的单纯也就有了解释,毕竟我想象不到“有生活的人”缘何幸福。眼界的局限,让我逐渐把“求索的解”当成了唯一的支柱,那么支柱倒塌时的歇斯底里,也就不难想象了。
要说痛苦吗,在当时的我看来或许是吧。至少 2021 年末我的确因为“做不到”破防过。麻木……或许也沾点,现在的我的确再也提不起求索的兴致了。但比起麻木,在多次见识到自己的局限、与“大佬们”的差距之后,更多的是自我否定——什么都做不到的我,起不到任何作用的我,还有何面目留存于世呢?
虽然也有网友劝慰过我、肯定过我,但这种自我否定某种程度上已经根深蒂固,以至宁愿相信自己如前同事所说那般是个“千古罪人”。以上,便是我挥之不去的“噩梦”,如告解所谓的“梦外的梦”。
## 梦醒
“生命因何而沉睡?人们沉睡,是为了最终从梦中醒来。”
无论如何,日子终归是要过的,我的眼光也不得不更现实一些。相比起好友有潜力、有勇气、有意愿、积极向上的“直面现实”,我的“直面”或许更无可奈何一点,毕竟梦中的我不喜欢为自己留退路嘛。跨专业,虽然理想很美好,但失败了反倒是双输了。会计的本事我并不能称得上熟悉,何况性格使然我也不会考虑;搞开发吧我又心有余而力不足,何况莫得文凭、项目寥寥(或者说根本没有),在可见的未来里我应该是与这条道路无缘。
那么还能怎么办呢?保安?那是我做过的最糟糕的决定。送外卖?服务员?……
只能说,“找到工作”和“找到理想的工作”毕竟是两码事。低水平 fw 奢求不了太多。

View File

@@ -1,197 +0,0 @@
---
category: 折腾流程
tag:
- Jellyfin
- 影音服务器
- 媒体库
- 刮削
- 文件管理
---
# 影音服务器——有关 Jellyfin 的文件归集
> [!important]
> 本文仅探讨音、视、图、文在纳入 Jellyfin 媒体库时应该如何整理、刮削,**并不涉及工具本身的部署以及媒体库的建立**。如有需求还请另行查找教程,或翻阅[官方文档](https://jellyfin.org/docs/general/installation/)。
> ~~Emby 支持文件夹Jellyfin 不支持Emby 赢一半!(~~
Plex 怎样我不清楚,但 Emby 对文件摆放的要求的确是比 Jellyfin 宽松得多的。但在好友的撺掇下,我还是换用 Jellyfin 了。~~……然后,就被 Jellyfin 的刮削和文件结构要求气晕。~~
::: note 我个人的大致分类
- 电子书Books
- 漫画Comics
- 小说Novels
- 音频
- 音乐CloudMusic
- 音声DLsite、ASMR 虚拟主播的录播转码)
- 视频、图片
- 音声(实写录播)
- 画师的差分图Fanbox、Patreon等等
- MMD
- 可爱的女装照(不是我的,我的[都发出来惹](../diaries/dress/readme.md)
虽然上述一些内容的说法已经比较直白,但真的点出来是什么东西就还是有点超过了哈。
:::
有人可能会问,为什么音声会分音、视频呢?呐就要讨论下 Jellyfin 的媒体库了。
## 媒体库的类型
无论 Emby 还是 Jellyfin我想 Plex 也一样),对于媒体内容的界定通常比较分明。这当然可称得上一件好事,但视频不仅仅是影片,音频也不仅仅是歌曲。对于没办法归类成“剧集”的,尚有“家庭视频和照片”这种分类,这也就能够解释为何我把视频和图片归为一大类;然鹅对于没办法归类成“专辑”的,私密马赛,我莫得选择。
![Jellyfin 媒体库类型 =180x](./jellyfin_content_type.webp)
然后……接下来就讲讲音乐、书籍、家庭视频和照片怎么整理文件夹结构吧。电影和节目这块网上应该也有不少教程。“混合电影和电视”这一项据官网称**已经弃用,不推荐选**。
::: tip 或者参考这些博客
毕竟我是死宅嘛。!!死宅真恶心。!!
- [《利用 Jellyfin+Bangumi 打造更舒适的动画媒体库》(初之音)](https://www.himiku.com/archives/deploy-a-more-comfortable-animation-library-with-jellyfin-and-bangumi.html)
- [《打造你的同人音声媒体库》Hinata Rin](https://blog.hinatarin.com/2021/09/27/build-your-own-doujin-voice-media-library/index.html)
:::
## 书籍
::: details 官方给出的电子书摆放
```
Books
├── Audiobooks
│ ├── Author
│ │ ├── Book1
│ │ │ └── Book1.flac
│ │ └── Book2
│ │ └── Book2.mp3
│ └── Book3
│ ├── Book3.aac
│ ├── content.opf
│ └── cover.jpg
├── Books
│ └── Author
│ ├── Book4
│ │ └── Book4.epub
│ ├── Book5
│ │ └── Book5.epub
│ ├── Book6
│ │ ├── Book6.epub
│ │ ├── cover.png
│ │ └── metadata.opf
│ └── Book7
│ └── Book7.pdf
└── Comics
├── Plastic Man (1944)
│ └── Plastic Man #002 (1944).cbz
├── Attack on Titan (2012)
│ └── Attack on Titan #001 (2012).pdf
└── Comic (2008)
├── ComicInfo.xml
└── Comic #001 (2008).cbr
```
:::
简而言之,对于每一“本”书,最好**单独开辟一个文件夹**,然后文件夹里**只摆放该书的单文件“合订本”**(比如`Books/王道24寄网/王道24寄网.pdf`)。
但这么分在我看来十分甚至九分的抽象,因为我手里的大多数小说和漫画都莫得有效的标签,甚至绝大多数是由纯文本导出 PDF 而来。因此,比起官版墨迹的组织方式,不妨就按各人的阅读习惯组织起来,不支持的格式导出成 PDF就可以了。
## 家庭视频与照片
这一分类也是差不多的随性。官方也莫得文档来强制约束应当是什么样的文件组织。以《绝区零》铃妹的一组差分图为例:
![《家庭视频和照片》 =180x](./jellyfin_home_visual.webp)
## 音乐
然后就是重头戏了,音乐。开篇我提过,我借助音乐媒体库还托管一些同人音声,那么对于音声的管理也是同样的。
::: details 官方给出的音乐摆放
```
Music
├── Some Artist
│ ├── Album A
│ │ ├── Song 1.flac
│ │ ├── Song 2.flac
│ │ └── Song 3.flac
│ └── Album B
│ ├── Track 1.m4a
│ ├── Track 2.m4a
│ └── Track 3.m4a
└── Album X
├── Whatever You.mp3
├── Like To.mp3
├── Name Your.mp3
└── Music Files.mp3
```
:::
### 歌曲的刮削与组织
::: info 媒体刮削
刮削——或者我更愿意称之为“打标”或者“tagging”——指的是从特定渠道一定是互联网吗未必获取到这份音/视频的元数据信息(作者、标题、流派、专辑、发行年份,等等),并且填充进媒体文件的附加信息位(通常位于文件尾部),又或者单独整理成`.nfo`之类的数据库的行为。
这一词不仅限于音频,视频也是有元数据信息的,比如内嵌字幕(不同于剪辑、特效软件直接打在视频流上的文本框字幕)。
非要说的话,我更倾向于:“刮削”一词不过是老烧们捏出来唬人的,所谓的专有术语罢了。
:::
我的歌曲大多下载自网易云,通常来说都是刮削好的`mp3``flac`文件,但也有些许例外,比如 VIP 歌曲复制链接跑去在线工具抓取下载得来的音频文件,呐怎么办呢?
之前看到的[《基于 Jellyfin 和音流的 nas 影音库搭建及踩坑》(少数派)](https://sspai.com/post/90896)一文推荐了“音乐标签”这么个工具支持从网易云、QQ 等多个国内源抓取、刮削音频。此外Mp3tag[官网下载](https://www.mp3tag.de/en/download.html)、[官方文档](https://docs.mp3tag.de/))也可以从 MusicBrainz 等国外源抓取、刮削。
个人建议刮削阶段还是用国内源比较好,因为接下来我要讲一个“洛天依作品集”的故事:
![洛 天 依 作 品 集 =420x](./luotianyi_question_mark.webp)
![《洛天依》 =150x](./im_luotianyi.webp)
但刮削工具也并非万能。比如《紫罗兰永恒花园 OST》的很多歌就被“音乐标签”那软件霍霍了个遍
![《凹凸世界五周年》 =420x](./musictag_misfetch.webp)
---
刮削完了需要按上面的官方要求组织这些歌曲,毕竟 Jellyfin 不支持读取音乐标签自动聚合(这点在上面援引的博客中也吐槽了)。我个人用 Mp3tag 做批量重命名。相比起音乐标签Mp3tag 重命名时允许字符串格式化,比如`$replace``$num`,方便一点。
Jellyfin 的音频搜集**仅以专辑为依据**。官方文档自己也说“as long as each album is contained within one folder”翻译过来就是“只需确保一个文件夹子树均为同一张专”。所以文件结构自然也以专辑为准。
::: details 分碟
事实上,根据我对音声的组织实践来看,需要确保的是**一张专一个文件夹子树**。比如下列情形会被拆分:
```
Author
\AlbumA Vol.X
\AlbumA Vol.Y
\AlbumB Vol.X
```
这种情形会在媒体库里拆出两个 AlbumA分别为盘号 X 和盘号 Y正确的组织方式应为
```
Author
\AlbumA
\Vol.X
\Vol.Y
\AlbumB
```
当然,若是盘号没有显式标明,很有可能仍然会拆。~~所以就不能直接读音乐标签做自动聚合马?~~
:::
### 音频音声的刮削与组织
不同于歌曲的刮削,音声**通常是没有标签**的。所以首先需要人为对这些音声进行分类DLsite 贩售的?主包的订阅限定?还是说有什么特征,是剧情音声?催眠音声?普通的奥数魔刃?
如果有些音声实在没有头猪,至少也用“散装”之类的文件夹包起来,**尽量确保所有的“文件”都被文件夹收纳好,避免裸放在媒体库文件夹下,也避免文件夹和音声文件混着存放**[^mixed_album]。
[^mixed_album]: 避免音声文件和文件夹混在一起,是因为:
- 假若该文件并没有任何标签,那么你只能在 Jellyfin 音乐媒体库的(全部)歌曲那一页翻来覆去才找得到;
- 假如该文件有打标签,那么所有和它混在一起的文件夹,里面的音声分类(哪怕自身有打标)均会被覆盖为该文件的标签。
::: tip 理想的文件树(简化版本,但仍可能加载较慢)
```mermaid
flowchart LR
A(["音声"]) --> B(["DLsite"]) & D(["订阅限定"]) & E(["音声录播"])
B --> B1(["RJ416817"]) --> n1(("\*.mp3"))
D --> D1(["希丝奈cisne"]) --> D11(["24-11"]) --> n21(("\*.mp3"))
D1 --> D12(["八月舰长音声"]) --> n22(("\*.mp3"))
E --> E1(["mahoulelys"]) --> n3(("\*.mp4.mp3"))
```
或者说,尽可能保证所有的**文件**均在树形图的末端(末梢、叶子节点)处。
:::
分类完毕之后,再对这些音声做批量的打标。
DLsite 上贩售的音声可用 Python 第三方库`dvtag`打标(从 DLsite 获取元数据可能需要代理),具体可参见开篇的参考博客;像音声录播通常就以主播为单位收纳好;至于可能存在子文件夹的订阅限定,可以用 Mp3tag 批量为这些音声的作者、年份字段打上标注,或是在专辑字段打上“谁谁的限定音声”,都行。

View File

@@ -33,42 +33,43 @@ star: true
## 参考链接
本文有参考以下两篇安装教程:
本文有参考以下安装教程:
1. [律回彼境Arch Linux 折腾指南&记录](https://www.glowmem.com/archives/archlinux-note)(以下简称“律回指南”)
2. [Nakano MikuArch 简明指南](https://arch.icekylin.online/guide/)以下简称“Miku 指南”)
3. [Arch WikiInstallation Guide](https://wiki.archlinux.org/title/Installation_guide)
## I. 前期准备
- 下载安装镜像:[清华镜像 (25.06.01)](https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/archlinux-2025.06.01-x86_64.iso)、[官方下载](https://archlinux.org/download/)。
- 下载安装镜像:[清华镜像 (最新版本)](https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest)、[官方下载](https://archlinux.org/download/)。
> 烧录过程不再赘述,推荐用 Ventoy 统一管理安装镜像。[参见 Ventoy 中文主页](https://www.ventoy.net/cn/)
- 固件^1^:启用 UEFI、禁用安全启动Secure Boot
> 近十几年的主板大都支持 UEFI我也懒得花篇幅去讲传统 BIOS 引导。对于 Arch Linux 的 UEFI 引导方式,我[另有一篇笔记](./ArchUEFI.md)讨论,可供安装阶段参考。
> 至于 Secure Boot不用想了`.efi`启动文件签名着实是件麻烦事。我爱折腾,但不爱做没意义、意义不大的折腾。
> 近十几年的主板大都支持 UEFI我也懒得花篇幅去讲传统 BIOS 引导。对于 Arch Linux 的 UEFI 引导方式,我[另有一篇笔记](./ArchUEFI.md)讨论,可供部署阶段参考。
> 至于 Secure Boot不用想了`.efi`启动文件签名着实是件麻烦事。~~对我而言折腾这个没有意义。~~
- 网络^2^:如需连接 WiFi提前把 WiFi 名字SSID改成英文。
> 安装全程在命令行CLI环境进行并且 LiveCD维护环境下同的终端字体**不支持中文**。除非附近没有别的 WiFi 起中文名字,否则还是改你自己的 WiFi 比较妥
> 安装全程在命令行CLI环境进行并且 LiveCD维护环境下同**显示不出中文,也打不出中文**
> [!tip]
> 如果只是迁移系统,那么进入维护环境之后只需`rsync`做全盘搬运即可(当然前提是目标**盘**要比原**系统**的实际占用空间要大)。可参见 [lin.moe](https://lin.moe/tutorial/2020/04/arch_migrate/)。
## II. LiveCD 基础配置
与[律回指南 Ch.1](https://glowmem.com/archives/archlinux-note#%E4%B8%80%E8%BF%9E%E6%8E%A5%E7%BD%91%E7%BB%9C%E5%92%8C%E6%97%B6%E5%8C%BA%E9%85%8D%E7%BD%AE) 相同,但省略了分配固定 IP 的一步(我完全可以进路由器里猹询)。
与[律回指南 Ch.1](https://glowmem.com/archives/archlinux-note#%E4%B8%80%E8%BF%9E%E6%8E%A5%E7%BD%91%E7%BB%9C%E5%92%8C%E6%97%B6%E5%8C%BA%E9%85%8D%E7%BD%AE) 相同,但省略了分配固定 IP 的一步(我完全可以`ip addr`猹询)。
## III. 分区
对于固态硬盘,**不提倡建立过多的分区**。那么在 UEFI 启动的系统盘上,至少可以这么分:
对于固态硬盘,**不提倡建立过多的分区**。那么在 UEFI 启动、GPT 分区表的系统盘上,至少可以这么分:
- EFI 启动分区[^esp]:挂载`/efi``/boot`[^esp_mountpoint]
- 系统分区:挂载根目录`/`
我个人在此基础上,倾向于*在硬盘(逻辑扇区的)末端*开多一个交换分区。
[^esp]: 对于 GPT 分区表有专门的“EFI System”即 ESP分区类型,当然新款的主板也会*连带扫描 FAT 分区*;对于 MBR 分区表,则扫描**活动**的 FAT 分区。参见 [UEFI 启动的实际工作原理](https://www.cnblogs.com/mahocon/p/5691348.html)。
[^esp]: GPT 分区表有专门的“EFI System”分区类型(即 ESP当然新款的主板也会*连带扫描 FAT 分区*;对于 MBR 分区表,则扫描**活动**的 FAT 分区。参见 [(译)UEFI 启动的实际工作原理](https://www.cnblogs.com/mahocon/p/5691348.html)。
[^esp_mountpoint]: ESP 装载`/boot`系经典分区法。后来有说法称“直接暴露 Linux 内核并不安全”,所以又有将 ESP 装入`/boot/efi`的分法Ubuntu Server 24.04.2 即如此)。现在(至少在 Arch 里)则推荐直接挂载到`/efi`
@@ -77,13 +78,15 @@ star: true
- :new: [全新安装](https://arch.icekylin.online/guide/rookie/basic-install-detail#%F0%9F%86%95-%E5%85%A8%E6%96%B0%E5%AE%89%E8%A3%85)
- [7. 分区和格式化(使用 Btrfs 文件系统)](https://arch.icekylin.online/guide/rookie/basic-install.html#_7-%E5%88%86%E5%8C%BA%E5%92%8C%E6%A0%BC%E5%BC%8F%E5%8C%96-%E4%BD%BF%E7%94%A8-btrfs-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F)
然后是挂载。挂载**务必先挂载`/`**,务必先挂载`/`,务必先挂载`/`!除此之外,别忘了挂载交换分区(如果有的话)
然后是挂载。务必注意**先挂载`/`**!此外,**不要把不同分区、子卷挂到同一个挂载点上****有分交换分区的话记得`swapon`**
## IV. pacman 配置
### i. 换源
Linux 的包管理器默认用国外的软件源,`pacman`也一样。因此,非常建议先换用国内镜像,加快包下载速度。
Linux 的包管理器默认用国外的软件源,`pacman`也一样。因此,非常建议先换用国内镜像,加快包下载速度。
然鹅在更换之前可能需要等待片刻:一经联网,`reflector`会自动筛选**最新**的 20 个镜像站,然后才从快到慢排序^3^。如果换源过早,很可能会被`reflector`摘桃子。
编辑`/etc/pacman.d/mirrorlist``vim`还是`nano`请自便):
```ini
@@ -118,37 +121,70 @@ ParallelDownloads = 5 # 最大并行下载数(根据你的网速自行斟酌
> 很遗憾,经实测 pacman 配置并不会复制过去。在安装完系统`arch-chroot`进去进一步配置时,你需要重复做一遍上述操作。
## V. 正式部署
参见 [Miku 指南—基础安装—9. 安装系统](https://arch.icekylin.online/guide/rookie/basic-install.html#_9-%E5%AE%89%E8%A3%85%E7%B3%BB%E7%BB%9F)。当然我偏向于律回指南,除此之外还会提前装些工具:
- CPU 微码:`intel-ucode``amd-ucode`
- 基础命令行工具:`vi` `nano` `git` `wget` `tmux` `openssh` `htop`
- Windows 文件系统NTFS支持`ntfs-3g`
参见 [Miku 指南—基础安装—9. 安装系统](https://arch.icekylin.online/guide/rookie/basic-install.html#_9-%E5%AE%89%E8%A3%85%E7%B3%BB%E7%BB%9F)。或者像律回指南那样顺手装一些工具也无何不可:
不过……不知道以后好不好使就是了。之前律回指南还提前装了`yay``neofetch`,但现在不行了。
```sh
pacstrap -K /mnt base linux linux-firmware base-devel linux-headers \
vi vim nano git wget tmux openssh networkmanager htop ntfs-3g \
intel-ucode # or `amd-ucode`
```
然后`genfstab -U /mnt > /mnt/etc/fstab`生成挂载表,`arch-chroot /mnt`切换进新系统里,继续配置吧。
::: warning “密钥环不可写”报错
之前出现过`pacman-init.service`意外暴死,导致找不到密钥环的情况:
```log
(126/126) checking keys in keyring
warning: Public keyring not found; have you run `pacman-key --init`?
downloading required keys...
error: keyring is not writable
...
error: failed to commit transaction (unexpected error)
```
对此,[这篇讨论贴](https://bbs.archlinux.org/viewtopic.php?id=283075)中有人提供了个取巧的方案:
```sh
pacman-key --init
pacman-key --populate
```
实测可用。至于成因,贴中有人指出是系统时钟未校准导致,但我当时是来不及`timedatectl`就已经暴死了,具体原因不明。
:::
接下来的配置我参考了[律回指南 Ch.4](https://glowmem.com/archives/archlinux-note#%E5%9B%9B%E7%B3%BB%E7%BB%9F%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE),不过在`visudo`处我没有取消“免密`sudo`”的注释。**免密`sudo`还不如直接`su`,干脆也不用创建非 root 用户了**。
然后`genfstab -U /mnt > /mnt/etc/fstab`生成挂载表;
`arch-chroot /mnt`切换进新系统里,继续配置吧。
---
接下来在`chroot`环境里的配置我参考了[律回指南 Ch.4](https://glowmem.com/archives/archlinux-note#%E5%9B%9B%E7%B3%BB%E7%BB%9F%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE)大体也符合官方文档的流程调整时区、系统编码、设置主机名、root 密码、新建用户、配置 EFI 引导。
不过在`visudo`那一步我没有启用“免密`sudo`”(如下),律回本人也意识到免密`sudo`并不安全。
```
## Same thing without a password
#%wheel ALL=(ALL:ALL) NOPASSWD: ALL
```
> [!note]
> 除了上述标准流程之外,后续有些步骤也可以提前在`chroot`里完成。但**如果你是初次上手,还是一步一步慢慢来吧**。
## VI. 新系统的配置
跟着律回指南的三、四章装好系统之后,重启登入新系统的终端。
首先通过`nmtui`连上 WiFi。
### i. CN 源和 AUR 助手
在**联好网的新系统**里配置`archlinuxcn`源:`sudo nano /etc/pacman.conf`
在**联好网的新系统**里配置`archlinuxcn`源:再次打开`/etc/pacman.conf`,末尾添加如下小节
```ini
# 末行添加
[archlinuxcn]
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
Server = https://mirrors.cernet.edu.cn/archlinuxcn/$arch
```
并安装 CN 源的签名密钥和 AUR 助手:
```bash
sudo pacman-key --lsign-key "farseerfc@archlinux.org" # 为密钥环添加本地信任
sudo pacman -S archlinuxcn-keyring # 安装密钥环
sudo pacman -S yay paru # 安装 AUR 助手
```
::: info 关于本地信任 Key
简单来说就是给 CN 源密钥环签名的`farseerfc`他的 Key 掉信任了,包管理器“不敢”安装这个密钥环^2^。
::: warning 密钥环缺少信任
若 CN 源的包安装失败,遭遇`signature ... is marginal trust`报错,可本地信任那个人的 Key。之前`farseerfc`掉过一次,以他为例:
```sh
sudo pacman-key --lsign-key "farseerfc@archlinux.org"
```
然后重试即可。不过截至 25 年国庆为止,`farseerfc`的信任已经恢复,我安装时并未遭遇类似情况。
:::
### ii. 硬件(一)音频安装
@@ -160,7 +196,7 @@ sudo pacman -S sof-firmware alsa-firmware alsa-ucm-conf
# pipewire 及其音频管理套件
sudo pacman -S pipewire gst-plugin-pipewire pipewire-alsa pipewire-jack pipewire-pulse wireplumber
```
::: tip pulseaudio
::: details pulseaudio
除了 pipewire 音频方案之外另有`pulseaudio`可供选择。但务必注意:音频管理套件**只能二选一,不可以混装**。
另外,由于 pipewire 本身不单只负责音频管理的工作,如需装 pulseaudio 仍需安装`pipewire` `gst-plugin-pipewire`两个包。
@@ -175,14 +211,14 @@ sudo pacman -S pipewire gst-plugin-pipewire pipewire-alsa pipewire-jack pipewire
> 但 pulseaudio 仍需要这个包。
:::
显卡、蓝牙等其他硬件设施需要装好桌面环境再考虑。至少**到本小节为止你的系统里并没有蓝牙服务**,无法启用
显卡驱动等其他硬件设施需要装好桌面环境再考虑,在只有字符色块滚过的纯终端环境里也没有折腾显卡驱动的必要
### iii. KDE 桌面环境
跟完前面的内容之后,你便拥有了一个无 GUI 的终端 Arch 系统。但作为日常使用的话,图形桌面肯定必不可少。
本文与那两篇参考外链一样**采用 KDE 桌面环境**。当然除了 KDE 之外,你也可以考虑 GNOME 桌面环境 ~~(只是我用腻了)~~
也可以考虑散装方案(比如`hyprland`~~,只是我没折腾成功~~)。
也可以考虑散装方案(比如`niri`,部分配置可参见 [aglab.dotfiles](https://git.liteyuki.org/AgxCOy/aglab.dotfiles))。
```bash
# 分别安装 xorg 套件、sddm 登录管理器、KDE 桌面环境,以及配套软件
@@ -190,7 +226,7 @@ sudo pacman -S xorg
sudo pacman -S plasma sddm konsole dolphin kate okular spectacle partitionmanager ark filelight gwenview
# 启用 sddm 服务,重启进 SDDM 用户登录
sudo systemctl enable sddm
sudo reboot
sudo reboot now
```
::: info KDE 6 vs KDE 5
@@ -216,7 +252,7 @@ KDE 的图形实现默认已经是 Wayland 了。在开机后输入用户密码
AMD 或 NVIDIA 显卡可参见[律回指南 &sect;6.4](https://glowmem.com/archives/archlinux-note#4%E6%98%BE%E5%8D%A1%E9%A9%B1%E5%8A%A8%E5%AE%89%E8%A3%85)
和 [Miku 指南—进阶安装—显卡驱动](https://arch.icekylin.online/guide/rookie/graphic-driver.html)篇。
但我是锐炬核显捏,只需要在 Konsole 终端里`sudo pacman -S`安装图形 API
但我是锐炬核显捏,只需要在 Konsole 终端里`sudo pacman -S`安装英特尔的驱动
- `mesa` `lib32-mesa`OpenGL
- `vulkan-intel` `lib32-vulkan-intel`Vulkan
@@ -226,7 +262,7 @@ AMD 或 NVIDIA 显卡可参见[律回指南 &sect;6.4](https://glowmem.com/archi
```bash
sudo systemctl enable --now bluetooth
```
> 之前误以为`bluetooth`是 Arch 本身就有的服务,结果发现是桌面环境依赖了蓝牙组件包。
> 之前误以为`bluetooth`是 Arch 本身就有的服务,结果发现是桌面环境依赖了蓝牙组件包`bluez`
### v. 额外中文字体和输入法
@@ -310,14 +346,23 @@ VSCode 的主侧栏“源代码管理”页提交时并不会走终端,也就
所以我选择编辑`~/.gnupg/gpg-agent.conf`
```properties
default-cache-ttl 28800
default-cache-ttl 21600
pinentry-program /usr/bin/pinentry-qt
```
保存后重启`gpg-agent``gpg-connect-agent reloadagent /bye`
::: info 其他端 pinentry
理论上`pinentry`自身可以根据 XDG 后端选择适用的版本:
```sh
ls /usr/bin | grep 'pinentry'
echo GETPIN | pinentry
```
你可以用这两条命令看看都支持什么后端,以及它会自动选择哪个。像 niri 通常会装 gnome 后端,测试结果也的确会出`pinentry-gnome3`的密码框。
:::
除此之外,`pinentry`需要指定 tty否则找不到 IO 设备也会炸。解法:`export GPG_TTY=$(tty)`
经测试,大部分终端均能在 SSH 连接中调出 CUIVSCode Remote-SSH 打开的终端可能比较特殊,仍然无法签名。个人还是建议单独开个终端作为 workaround
经测试,大部分终端均能在 SSH 连接中调出 CUI。若 VSCode Remote-SSH 打开的终端签不了名,检查一下是不是终端分割得太小了
### II. GPG 密钥备份(导出导入)
之前并没有意识到备份 key 的重要性,结果重装 Arch 重新配置提交签名时,

View File

@@ -24,7 +24,7 @@ tag:
## UEFI 启动简述:启动项管理
> UEFI 规范定义了名为“UEFI 启动管理器”的一项功能 …… 是一种固件策略引擎,可通过修改固件架构中定义的全局 NVRAM 变量来进行配置。启动管理器将尝试按全局 NVRAM 变量定义的顺序依次加载 UEFI 驱动和 UEFI 应用程序(包括 UEFI 操作系统启动装载程序)。……
> UEFI 规范定义了名为“UEFI 启动管理器”的一项功能……(它)是一种固件策略引擎,可通过修改固件架构中定义的全局 NVRAM 变量来进行配置。启动管理器将尝试按全局 NVRAM 变量定义的顺序依次加载 UEFI 驱动和 UEFI 应用程序(包括 UEFI 操作系统启动装载程序)。……
> ::: right
> ——[UEFI 启动:实际工作原理](https://www.cnblogs.com/mahocon/p/5691348.html)
> :::
@@ -36,15 +36,15 @@ tag:
事实上Windows Boot Manager 是系统安装完成后,初次加载系统时为其创建的**原生启动项**。它明确指出需要启动**指定设备中**的**指定引导文件**(即`bootmgfw.efi`)。
即便 WinToGo 也是如此——在初次以 U 盘身份进入 WTG 系统时Windows 也会为该设备作配置——所谓“正在准备设备”。在此过程中,顺带把原生启动项建立好。然后重启之后再按快捷键进入启动菜单,你**可能**会在**部分主板上**发现有两个启动项,指向同一个设备:
即便 WinToGo 也是如此——在以 U 盘身份进入 WTG 系统时Windows 也会悄悄地把原生启动项建立好。然后重启之后再按快捷键进入启动菜单,你**可能**会在**部分主板上**发现有两个启动项,指向同一个设备:
```
Windows Boot Manager ( Koi Series Pro ...)
USB HDD: Koi Series Pro ...
```
需要注意的是,原生启动项是**存储在主板里的**(更准确的说,是全局 NVRAM 变量)。这多少可以解释为什么 Grub 引导那么脆弱(
需要注意的是,原生启动项是**存储在主板里的**(更准确的说,是全局 NVRAM 变量)。有些主板在检测到原生启动项失效(找不到指定引导文件)后,会自行删除该启动项。比如安装 Grub 后更换过硬盘,后来又把原盘插回去,可能仍然找不到 Grub 启动项。
### ii. 回退路径启动项
对于 WinPE、Windows 安装镜像而言,它们并非用于长线运行,往往没有“准备设备”的步骤,那么 UEFI 如何认出它们捏?
对于 WinPE、Windows 安装镜像而言,它们并非用于长线运行,不可能到处添加原生启动项,那么 UEFI 如何认出它们捏?
还记得上面提到的同一设备双启动项吗UEFI 固件是能够找到可启动设备,并且尝试启动的。但它是依据什么去找的捏?
UEFI 固件首先会**遍历各硬盘的 ESP 分区**,并在其中查找`\EFI\BOOT\boot{cpu_arch}.efi`。前面的这一固定路径就称为**回退路径**,通过查找回退路径建立的启动项就称作**回退路径启动项**。其中,`cpu_arch`即 CPU 架构,已知的有:
@@ -64,16 +64,20 @@ UEFI 固件首先会**遍历各硬盘的 ESP 分区**,并在其中查找`\EFI\
也就是说,哪怕原生启动项意外被固件扬了,只要还有回退启动项,便仍可从同一个硬盘启动系统。
> [!info]
> 实际上`bcdboot`工具会在 ESP 分区里同时写入`bootx64.efi``bootmgfw.efi`,这两个 EFI 除了文件名以外并无区别
> 前者即回退路径启动项,作为启动 Windows 的后备方案。
::: info
实际上`bcdboot`工具会在 ESP 分区里同时写入`bootx64.efi``bootmgfw.efi`。前者即回退路径启动项
有关`bootx64.efi``bootmgr(.efi)``bootmgfw.efi`的关系可能有些复杂,谷歌了一圈各种观点都有。本着实事求是的原则,我不会糅合这些观点提出假设,只附上几个问题:
- `bootx64.efi``bootmgfw.efi`(或`bootmgr`)分别在本机 Windows、WinToGo 和 WinPE 中起到什么作用?三者之间是否存在等价(即功能上可以替代,乃至文件哈希相同)?
- fwbootmgr`bootmgfw.efi`)与 bootmgr是谁“悄悄地”为 UEFI NVRAM 添加原生启动项?
:::
## 启动加载器(以 Grub 为主)
这也是最广泛使用的启动方式 ~~Windows 也干了~~。在 Linux 当中,最常用的加载器是 Grub。当然也有使用 rEFInd 的。
启动加载器bootloader本身作为跳板被 UEFI 固件加载后,需要根据配置找到真正的 Linux 内核,并经由内核引导用户硬盘上的 Arch 系统。而在 Windows 中,`bootmgfw.efi`会根据`BCD`配置文件,执行硬盘其中一个 Windows 副本中的`winload.exe`,并将该副本的其余加载流程交给它完成。
启动加载器bootloader本身作为跳板被 UEFI 固件加载后,需要根据配置找到真正的 Linux 内核,并经由内核引导用户硬盘上的 Arch 系统。而在 Windows 中,`boot[a-z]{3,4}.efi`会根据`BCD`配置文件,执行硬盘其中一个 Windows 副本中的`winload.efi`,并将该副本的其余加载流程交给它完成。
正常使用 Windows 单系统的用户可能对启动过程并无察觉,因为 Windows 为了确保能够启动,会时不时刷新启动项。但一旦与 Linux 混用,你就需要**留意 Linux 的加载器会不会被 Windows 刷下去(甚至被覆盖)**。除此之外,尽管因“机”而异,但 UEFI 固件**有可能会自动清理不再可用的启动项**。比如重新插拔固态,有可能会出现掉引导的情况。因此就个人来说,我不会再考虑 bootloader 了。
正常使用 Windows 单系统的用户可能对启动过程并无察觉,但一旦与 Linux 混用,你就需要**留意 Linux 的加载器会不会被 Windows 刷下去(甚至被覆盖)**。除此之外,固件和内核之间隔着加载器这么一块跳板,势必会拖慢引导流程。因此就个人来说,我不会再考虑 Grub 这类方案了。
### i. 修复 Grub 引导
Windows 启不动我们会尝试修复引导Arch 亦然。修复 Grub 引导实际上就是**重走 Grub 安装流程**
@@ -83,17 +87,21 @@ Windows 启不动我们会尝试修复引导Arch 亦然。修复 Grub 引导
> 个人建议无论如何都重建一遍`fstab`。反正刷完绝对是最新的。
- `arch-chroot`切换进硬盘上的系统;
- `grub-install`重建 grub 引导。
- `grub-mkconfig`重建 grub 配置(可能不需要……?)。
### ii. 补充回退启动项
### ii. 改用回退启动项
事实上,需要反复重建 Grub 引导的一大原因就在于Grub 只会写入它自己的`grubx64.efi`,以及原生启动项:
![群友的 ESP 分区目录树 =200x](./esp_without_bootARCH.webp)
那么办法也很简单:像 Windows 那样也建一个回退路径启动项。具体来说,在 ESP 分区里建立`EFI\BOOT`目录,复制`grubx64.efi`重命名成`bootx64.efi`嘛。~~Windows 不也干了(~~
那么办法也很简单:像 Windows 那样也建一个回退路径启动项。最简单的做法当然是复制改名,若求稳妥可以考虑用`grub-install`刷:
```sh
grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --removable
```
当然如果是像图中那样不止一个 Grub甚至同盘 Windows 和 Arch 双系统,那我不推荐你这么做。
> [!warning]
> 不要在这试图软链接节省空间!
> 不要在这试图软链接节省空间!
## 固件直接引导EFIStub
Grub 本身写入 ESP 的内容不多配置啊、Linux 内核啊都在`/boot`。有人便主张把`/boot`还给`/`ESP 分区实际挂载`/efi`
@@ -166,12 +174,12 @@ sudo efibootmgr --create --disk /dev/nvme0n1 --part 1 \
只要集成了 EFI 执行代码和 Linux 内核,就可以称作统一内核映像了。
:::
接下来以`mkinitcpio`为例,但是不走寻常路
接下来以`mkinitcpio`为例。
### i. 内核参数
Wiki 中介绍了两种方法:
- `/etc/cmdline.d/``.conf`配置。像`root.conf`决定`/`如何挂载,等等。
- 直接把所有参数搓成一行 echo 给`/etc/kernel/cmdline`文件。
- `/etc/cmdline.d/`投喂`.conf`配置(文件名随意)。比如`root.conf`决定`/`如何挂载,等等。
- 直接把所有参数搓成一行 echo `/etc/kernel/cmdline`文件。
于我而言,显然第二种更方便。
```bash
@@ -183,47 +191,24 @@ echo 'root=UUID=... resume=UUID=... rw loglevel=3 quiet' > /etc/kernel/cmdline
> [!warning]
> 若启用“安全启动”,且 UKI 封装了内核参数,则 UEFI 固件会无视外部传入的其余参数。
::: info [GPT 分区自动挂载](https://wiki.archlinuxcn.org/wiki/Systemd#GPT%E5%88%86%E5%8C%BA%E8%87%AA%E5%8A%A8%E6%8C%82%E8%BD%BD)
跟 [@Vescrity](https://github.com/Vescrity)讨论的时候我俩都觉得分区 UUID 太长了,于是他尝试省略掉`root=`参数。
就结果来看还真可行,顺带附上他的折腾记录:[《从统一内核镜像启动》](https://vescrity.github.io/post/UKI/)。
:::
### ii. 预设文件
编辑`/etc/mkinitcpio.d/linux.preset`我们前面说过“不走寻常路”,关键就在这里。
下面是我自用的`linux.preset`。~~想走寻常路的话还是抄别人的预设吧。~~
编辑`/etc/mkinitcpio.d/linux.preset`
```properties
# mkinitcpio preset file for the 'linux' package
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default' 'fallback')
#PRESETS=('default' 'fallback')
PRESETS=('default')
#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/BOOT/bootx64.efi"
#default_uki="/efi/EFI/Linux/arch-linux.efi"
#default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/boot/arch-linux-fallback.efi"
#fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"
default_uki="/efi/EFI/BOOT/bootx64.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"
```
> [!warning]
> 有的教程会出现`ALL_microcode=(/boot/*-ucode.img)`这一句。
> 这种指定微码的方法已经废弃,`/etc/mkinitcpio.conf`已经有针对微码的 Hook 了,无需手动指定。
正常来说 UKI 均会输出到`/efi/EFI/Linux/arch-linux*.efi`,据称`systemd-boot`可以扫到并引导 UKI。
但生成`bootx64.efi`让固件去加载不更直接?所以我选择直接导出到回退路径,如此连`efibootmgr`都不需要了。
另一方面,`fallback`也会生成 UKI`bootx64.efi`只有一个。注意到之前 EFIStub 一节我只给`initramfs-linux`构建了原生启动项,那么`fallback`自然丢回`/boot`里不管它。
> [!note]
> 把`fallback`移回`/boot`还有一重原因:尽量缩减 ESP 分区体积——本来`/efi`设计上也有减小 ESP 分区大小的意图。
> 我试跑完发现`fallback.efi`高达 140+MB`arch-linux.efi`不过 30MB。
>
> 当然,保险起见,我并没有尝试`default`生成 UKI、`fallback`仍生成内存盘的做法,也没有试图把`fallback`预设直接干掉。
> 如有勇士试验过一切正常,欢迎 Issues 反馈(
本身 UKI 默认是丢到`esp\EFI\Linux\arch-linux*.efi`里的相对来说已经比较通用Grub 可以直接读,也可以用作原生启动项)。但我尝试 UKI 本就是为了摒弃前面两种方案,殊途同归反倒不值得这么整了。所以我个人选择让 UEFI 固件直接加载回退路径启动项。
### iii. 创建映像
按需建立路径,并跑一遍生成:
@@ -231,7 +216,7 @@ fallback_options="-S autodetect"
mkdir -p /efi/EFI/BOOT/
mkinitcpio -p linux
```
还是那句话,想循规蹈矩的不要学我
如有必要,清理系统中废旧的启动文件(`grubx64.efi``refind_x64.efi`等),并用`efibootmgr`手动清理遗留的原生启动项
---

View File

@@ -24,8 +24,6 @@ tag:
首先当然得有那么个内网。在 [Zerotier](https://my.zerotier.com/login) 上注册/登录账号(可能比较卡,毕竟国外平台),`Create A Network`创建虚拟内网。免费版(截至目前)至多允许同一网络 25 个设备,但对于我来说足够了。
接下来图省事的朋友点进新建的网络,记一下`Network ID`就可以直接安装 Zerotier 客户端了。
Windows 有挂在任务栏里的 GUI 客户端,右键图标直接`Join Network`,粘贴刚刚的`Network ID`回车,进账号里同意加入、给它分配固定 IP 即可;
Linux 可以通过 Docker、官网提供的命令行、部分包管理器等方式安装 Zerotier One。
::: details 或者,进一步配置虚拟内网
主要关注以下项:
@@ -43,7 +41,16 @@ Linux 可以通过 Docker、官网提供的命令行、部分包管理器等方
然后在设备加入虚拟内网之后,可以在`Members`里找到这个设备,手工给它分配个静态 IP。
:::
安装之后记得确认一下 Zerotier 服务是否开启,若是 Docker 容器还请额外注意端口映射。
::: tabs#zerotierInstall
@tab Windows
Windows 安装之后在开始菜单找到 ZeroTier然后可以看到任务栏里出现了 ZeroTier 的图标。右键图标,在菜单里直接`Join Network`,粘贴刚刚的`Network ID`,回车即可。
顺带一提,记得在右键菜单里勾上`Start UI at Login`,也就是开机启动。
@tab Linux systemd
可以通过官网提供的[命令行](https://www.zerotier.com/download/#linux)、部分包管理器等方式安装 Zerotier One。
安装之后记得确认一下 Zerotier 服务是否开启:
```bash
sudo systemctl status zerotier-one.service
```
@@ -51,7 +58,33 @@ sudo systemctl status zerotier-one.service
```bash
sudo systemctl enable --now zerotier-one.service
```
于是就可以使用 Zerotier CLI 了。我的场景比较简单,不考虑自建 moon 的情况下直接`sudo zerotier-cli join Network_ID`,然后也是在账号上给它放行、分配固定 IP 就可以了。
于是就可以使用 Zerotier CLI 了。
我的场景比较简单,不考虑自建 moon 的情况下直接加入虚拟内网:
```sh
sudo zerotier-cli join Network_ID
sudo zerotier-cli listnetworks
```
@tab Docker
[官方文档](https://docs.zerotier.com/docker/)的做法是拉一个 centos 在里面用 systemd 方式安装,属于是脱裤子放屁。
网上有一些现成的镜像,像`zerotier``zerotier-synology`(群晖用的),这里摘录一下用`zerotier/zerotier`的流程:
> [!warning]
> **此方案尚未测试,谨慎复制**!建议在其他**有测试结果的**博客、专栏中获取适合的方案!
```sh
docker pull zerotier/zerotier
# 务必注意网络通信方式!
docker run -d --name zt --network host zerotier/zerotier
docker exec -it zerotier bash
zerotier-cli join Network_ID
zerotier-cli listnetworks
```
:::
在设备加入虚拟内网之后,需要再次登上账号同意设备加入(默认建立的是私有内网,需要号主同意加入),并且给它分配固定 IP。
::::
> [!warning]
@@ -174,11 +207,11 @@ geox-url:
:::
::: details 应用层
这块不是重点,各种服务有各种服务的参考文档。
这块不是重点,各种服务有它自己的参考文档。
- `webmin`:提供 WebUI 对服务器做些运维
- `webmin`:提供 WebUI 以配置服务器的系统,以及监测服务器的性能占用
- `aria2``AriaNg`提供直链、BT、PT 下载支持。参见[《手把手教你使用 Docker 搭建 aria2+AriaNg打造自己的离线下载服务器》博客园](https://www.cnblogs.com/wqp001/p/14709997.html) [^ariang_baidupan]。
- `jellyfin` `emby`:影音服务器。有关 Jellyfin 的媒体聚合和刮削会专门另开一篇讨论
- `jellyfin` `emby`:影音服务器。个人觉得就*资源管理的便利性*而言Jellyfin 并不算好;但 Emby 白嫖着用也不见得操作有多舒服
- `vscode-server`:控制端可利用 VSCode 配合 Remote-SSH 插件连上服务器,做些跨平台开发……或者 Linux Native 开发。~~真有人在 Linux 编译 MSVC x86-64 吗?有的话浇我。~~
- `ssh`Xshell 做些命令行活计Xftp 做些文件交换活计。
- `nfs`:和前面 Windows 一样,可以挂共享文件系统。

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -39,7 +39,7 @@ Bottles 是由 [bottlesdevs](https://github.com/bottlesdevs) 开发的可视化
[^lazy_loading]: 经实测发现,单文件 exe 才可以在这种情况下直接在 Bottles 里启动。但凡需要读同级文件、子文件夹的,都需要在 Bottle 里添加快捷方式,并在快捷方式的设置里手动指明工作目录。
首先需要引入`archlinuxcn`源。具体步骤参见[《Arch 安装流程》](../OS/ArchInstall.md#i-cn-源和-aur-助手),这里不再重复。
首先需要引入`archlinuxcn`源。具体步骤参见[《Arch 安装流程》](../Maintenance/ArchInstall.md#i-cn-源和-aur-助手),这里不再重复。
接着`sudo pacman -Sy bottles`安装。等待进度跑完,就可以从“应用程序菜单栏”运行了。
初次运行 Bottles 会弹出一个向导跟你 blabla无脑下一步即可。

View File

@@ -14,7 +14,7 @@ star: true
# 浅谈红警 2 触发组件的运行逻辑
::: warning 观前注意
由于涉及一些编程知识点,本综述可能存在亿些阅读困难。
由于涉及一些编程知识点,本可能存在亿些阅读困难。
虽然经过与 Zero Fanker 等人的讨论后决定做些~~修缮~~重写,但难免仍有需要改进之处。
:::

View File

@@ -92,13 +92,14 @@ int example() {
又假设`example()`被 main 函数调用,那么栈帧可能会是这种分布:
|地址|...|备注|
|-|:--:|-|
|0x524|...||
|0x520|`main()`的 EBP|`example()`栈帧从这里开始|
|0x51C|int a = 10|
|0x518|int b|
|0x514|(空余 8B|`gcc`编译器要求栈帧大小为 16B 的整数倍|
|0x510|(空余 8B|`gcc`要求栈帧大小为 16B 的整数倍|
|0x50C|1024|参数 y|
|0x508|10|参数 x即复制 a 的值|
|0x504|调用`eg_sub()`时 EIP 指向的下一指令地址|亦即被`call`压栈、`ret`返回的地址<br>`example()`栈帧到此结束|
|0x504|调用`eg_sub()`时 EIP 指向的下一指令地址|亦即被`call`压栈、`ret`返回的地址<br>`example()`栈帧到此结束|
|0x500|`example()`函数的 EBP|这里是`eg_sub()`的栈帧了|
|...|...||

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -1,5 +1,5 @@
---
title: 笔记
title: 如我所书
index: false
article: false
timeline: false
@@ -7,6 +7,4 @@ comment: false
icon: book
---
笔记这边类似 B 站、知乎的“专栏”,有能成篇的发现就会考虑写写。
<Catalog />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

View File

@@ -10,15 +10,15 @@
"up-deps": "pnpm dlx vp-update"
},
"devDependencies": {
"@vuepress/bundler-vite": "2.0.0-rc.23",
"@vuepress/plugin-docsearch": "2.0.0-rc.110",
"@vuepress/plugin-remove-pwa": "2.0.0-rc.109",
"katex": "^0.16.22",
"mermaid": "^11.7.0",
"sass-embedded": "^1.89.2",
"vue": "^3.5.17",
"vuepress": "2.0.0-rc.23",
"vuepress-theme-hope": "2.0.0-rc.93"
"@vuepress/bundler-vite": "2.0.0-rc.26",
"@vuepress/plugin-docsearch": "2.0.0-rc.121",
"@vuepress/plugin-remove-pwa": "2.0.0-rc.118",
"katex": "^0.16.27",
"mermaid": "^11.12.2",
"sass-embedded": "^1.97.1",
"vue": "^3.5.26",
"vuepress": "2.0.0-rc.26",
"vuepress-theme-hope": "2.0.0-rc.101"
},
"packageManager": "pnpm@9.15.3+sha512.1f79bc245a66eb0b07c5d4d83131240774642caaa86ef7d0434ab47c0d16f66b04e21e0c086eb61e62c77efc4d7f7ec071afad3796af64892fae66509173893a"
}

4022
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -22,5 +22,17 @@
"icon": "https://q.qlogo.cn/g?b=qq&nk=1574260633&s=640",
"desc": "可爱的 Python Dev 和音乐人律姐姐~",
"link": "https://glowmem.com/"
},
"#24:0": {
"name": "SD7935",
"icon": "https://q1.qlogo.cn/g?b=qq&s=640&nk=2691681405",
"desc": "一个CTFer、红警牢玩家、死宅、蟒蛇使用者、hentai",
"link": "https://www.sd7935.link/"
},
"#26:0": {
"name": "Asankilp",
"icon": "https://blog.erroro.moe/assets/avatar.jpg",
"desc": "半吊子写代码的,瞎折腾的。",
"link": "https://blog.erroro.moe/"
}
}

View File

@@ -2,7 +2,6 @@ import { navbar } from "vuepress-theme-hope";
export default navbar([
"/",
"/archives/",
"/notes/",
"/diaries/",
{

View File

@@ -4,19 +4,13 @@ export default sidebar({
"/": [
// "",
{
text: "综述",
icon: "folder-open",
prefix: "archives/",
children: "structure",
},
{
text: "笔记",
text: "如我所书",
icon: "book",
prefix: "notes/",
children: "structure",
},
{
text: "随想",
text: "记忆的质料",
icon: "paper-plane",
prefix: "diaries/",
children: [

View File

@@ -25,7 +25,7 @@ export default defineUserConfig({
[
"link",
{
href: "https://unpkg.com/",
href: "https://npm.onmicrosoft.cn/",
rel: "preconnect",
crossorigin: "",
},
@@ -33,7 +33,7 @@ export default defineUserConfig({
[
"link",
{
href: "https://unpkg.com/@agxcoy/lxgw-wenkai-vp-hope@latest/style.css",
href: "https://npm.onmicrosoft.cn/@agxcoy/lxgw-wenkai-vp-hope@latest/style.css",
rel: "stylesheet",
},
],