森罗幻想 - 博客
type: channel
link: https://blog.roysgensokyo.space/tag/Blog/
items: 网站更新日志 - 26/07/28
items: 2026春季学期总结
items: 网站更新日志 - 26/06/29
items: Typecho博客的折腾记录——Markdown扩展语法支持
items: Typecho博客的折腾记录——AI总结
items: 网站更新日志 - 26/06/16
items: 网站更新日志 - 26/06/12
items: CloudFlare Tunnel 使用手册（备忘）
items: 网站更新日志 - 26/05/30
items: Typecho博客的折腾记录——为Jasmine添加Meting播放器

网站更新日志 - 26/07/28
type: item
date: 2026-07-28T03:18:00+08:00
description: 服务器进入稳定运行阶段，近期改变如下： 7-17：使用Kimi K3完善主页，修复了跨站访问的问题，网站内集成了介绍内容。 7-28：恢复了被K3删除的友链内容。 更新了设备&宅物页面的物品，新增了两个娃娃一张专辑。 完成了域名的续费，保障服务稳定性。 将主页迁移到CloudFlare Pages托管，缓解主服务器宽带压力。 完成家里云搭建，基于FRP透传，可作为服务器的备份站点，亦或者作为MC服务器运行。

2026春季学期总结
type: item
date: 2026-07-13T00:23:00+08:00
description: 摘要大一下学期学业不佳，依赖AI致高数、物理挂科，建模比赛敷衍。爱好方面用Typecho重建博客，整合pjax等功能并借AI实现首页设计。生活作息紊乱，不吃早餐而依赖夜宵。宿舍关系和谐，线上社交有得有失，已退出学生会。学期结束虽有遗憾，亦收获个人项目成果，盼补考通过。正文 从3月10日拖着行李箱再次踏入校门，到7月10日放下笔走出期末考场，大一下的时光满打满算不过短短四个月。一百二十多天，说长不长，说短不短，刚好够一场从初春到盛夏的过渡，刚好够我从寒假里那个信誓旦旦要"这学期一定好好学习"的幻想中，慢慢滑回现实。 暑假眼看着就要来了，与其让它悄无声息地溜走，不如坐下来，对这磕磕绊绊的四个月做个简单总结吧。 学业方面 如果要用一个词概括，那只能是"马马虎虎"——甚至这个词本身都带着几分自我美化的成分。 这学期伊始，我并非没有立下过flag。然而现实是，三月的春风还没吹暖图书馆的座位，我的学习热情就已经先于气温降了下来。每天睁开眼，第一件事不是翻开课本，而是摸向手机，在各类消息和推送中消磨掉清晨最清醒的半小时。等到终于磨蹭着坐到书桌前，面对着高数课本上密密麻麻的公式，或是数据结构里那些让人头晕的指针和递归，动力就像沙漏里的细沙，无声无息地漏光了。 于是，"AI续命"成了这学期的主旋律。高数的课后作业？丢给AI，抄完答案，似懂非懂地点个头。数据结构的算法题？让AI写个框架，自己改改变量名交上去。Web前端的课程设计？直接让AI生成一套模板，修修补补就算完工。你说这些课程重要吗？当然重要——高数是理工科的地基，数据结构是编程的核心，Web前端是实打实的吃饭手艺。但你说我认没认真学呢？答案显然是否定的。那些用AI糊弄过去的知识点，在期末考场上全都变成了回旋镖，精准地扎了回来。 于是乎，我的数据结构和物理不出意外地挂掉了。看到成绩单的那一刻，不是意外，更像是迟到的审判——这学期偷的每一个懒，都在那张成绩单上找到了对应的位置。 至于跟队友参加的统计建模比赛，过程也是有气无力。赛前大家聚在一起，豪言壮语说要拿奖；赛中的无数个夜晚，群聊里充斥着"明天再搞吧"的相互安慰；最后截止日的前两天，全队进入经典抱佛脚模式，对着数据手忙脚乱地跑模型、凑论文。结果可想而知，投出去的作品像一颗小石子丢进大海，连点水花都未曾溅起。现在回想起来，那场比赛与其说是比赛，不如说是我们几个人集体拖延症发作的临床观察记录。 爱好方面 如果说学业是一潭死水，那爱好至少还泛着几圈涟漪——虽然这些涟漪很大程度上也是靠AI吹起来的。 这学期我做了一件酝酿已久的事：用Typecho取代了Astro，彻底重做了我的博客网站。迁移的过程比想象中折腾，数据导出、格式转换、主题适配，前后断断续续搞了两周。但当我终于在浏览器里输入新地址，看到熟悉的文章列表以全新的面貌呈现时，那种成就感是真实的。 紧接着，我开始借助AI对博客进行深度优化。最花心思的是pjax无刷新技术的整合——为了实现页面切换时的平滑过渡，我翻了不少文档，让AI帮我逐行调试代码，最终搞定了这套方案。后来又陆续整合了Live2d看板娘和在线音乐播放器，现在打开博客，能看到可爱的看板娘在角落晃悠，背景音乐缓缓流淌，至少视觉上算是有了点"个人站点"的样子，而不是千篇一律的模板站。 期间还心血来潮部署了一次邮件服务，想着以后可以给博客加上订阅功能，或者搞个联系方式。结果配置了半天SMTP、DKIM、SPF记录，好不容易能收信了，却因为服务器被阿里云制裁而无法发信，最后不了了之，成了又一个"烂尾工程"。 另外一件值得记录的事，是借助AI把自己手工设计的网站首页变成了现实。之前画了一堆草图，配色、布局、交互逻辑都在脑子里转了很久，但苦于前端能力有限，一直停留在纸上。这学期干脆把设计稿丢给AI，一边描述需求一边迭代，硬是把那个幻想中的首页做了出来。现在博客站和主页分开挂在两个域名下，一个负责内容输出，一个负责门面展示，管理起来清爽多了。 内容方面，这学期也没少往博客上灌水。翻出了高中时期写的一些旧文章，修修改改搬了上去；偶尔折腾了什么新东西，也习惯性地记上一笔。虽然更新频率飘忽不定，质量也参差不齐，但至少这个小小的自留地还在运转，没有彻底荒芜。 生活方面 作息方面，我倒是保持着一种诡异的"良好"——良好到几乎每天都能在凌晨两点准时躺下，早上七点准时被闹钟惊醒，然后以一个鲤鱼打挺的姿势冲向早八教室。听起来很健康对吧？但问题在于，这套作息的代价是几乎不吃早餐，以及顿顿不离夜宵。 早餐？不存在的。早八的课都踩点进教室了，哪还有时间光顾食堂。于是空腹撑到中午，午饭往往又因为各种事由草草了事。等到夜幕降临，肚子里的空虚感开始作祟，夜宵就成了唯一的救赎……凌晨的宿舍楼道里，我的外卖袋子和垃圾桶里的包装纸见证了太多罪恶的深夜。这两者形成了奇妙的强相关：…

网站更新日志 - 26/06/29
type: item
date: 2026-06-29T23:01:00+08:00
description: 借由 AI 辅助，近期进行了重大变更，细节如下： 新增 主页 站，与本博客站进行区分，本博客已迁移到 blog域； 图片来源：https://www.pixiv.net/artworks/91469670 新增一个简短版的个人介绍，请从 个人主页 访问； 将友链迁移到 个人主页 了； 贴合个人主页的主题颜色，对本站的主题色进行了变更。

Typecho博客的折腾记录——Markdown扩展语法支持
type: item
date: 2026-06-18T01:19:00+08:00
description: 摘要作者为优化Typecho博客的Markdown支持，尝试EditorMD插件遭遇PHP 8受保护方法调用错误及PJAX兼容性问题。经修复权限、尝试双插件并存后，因体验割裂最终决定整合EditorMD编辑器与EnhancedMarkdown的Parsedown解析器，开发新插件EnhancedMarkdownPlus，解决命名冲突实现前后端统一渲染，并总结AI辅助开发的经验教训。 前言 作为一个追求极致阅读和交互体验的独立博客站长，我使用了一款极简优雅的主题 Jasmine_Plus。在偶然跟别人的一次聊天，我就遇到了这个情况： 我：博客自带编辑器就是方便，走到哪写到哪（截图） 对面：没有语法着色吗（）我现在已经离不开语法着色了 我：这个没有，但是有预览（ 我：（说的也对，我好像可以弄一个了） …… 为了优化博客对 Markdown 语法的支持，我一开始上网搜索，选用了 EditorMD，但是装上插件以后很快就遇到了麻烦。借此又开启了这次折腾，以下是完整记录。 初遇 Bug 满怀期待部署完插件，上编辑器看看？一切正常，运行良好。 然后，刷新一下首页看看呢？ 报错了。进文章看看？也是空空如也。 初步定位 在AI的帮助下，我顺着追踪到了 Editor.MD 插件的主控文件 Plugin.php。在插件的 content 和 excerpt 过滤器中，代码试图去渲染文章内容： Php | 复制 \(text = \)conent->isMarkdown ? \(conent->markdown(\)text) : \(conent->autoP(\)text); 问题就出在这里：markdown() 和 autoP() 是 Widget\Base\Contents 内部的 protected（受保护）方法。 AI 给出如下解释： - 在旧版本 PHP 或老旧 Typecho 中，这种外部直接调用可能通过某些魔法方法或宽松的可见性规则被放行。 - 但在现代 PHP 8.x + Typecho 1.2+ 中，外部直接访问受保护方法会触发 Typecho\Widget 的 __call() 魔术方法。由于权限不足，该魔术方法最终返回了 null。 - 紧接着，这个 null 被传递给了 Typecho 核心的 Contents.php 进行后续处理（例如 explode() 等字符串操作），从而引发了 Passing null to parameter of type string is deprecated 的警告。 解法一：修复 Content 询问朋友资助的Opus4.6后，AI给出如下解法： 既然是受保护方法，我们只需要利用 PHP 的 Closure::bind，在运行时将闭包的作用域临时绑定到当前对象类中，就能合法地调用这些受保护方法。 同时，考虑到不同 Typecho 版本核心可能发生改变，我还增加了一层回退机制——如果类中不存在这两个方法，直接调用底层的 Utils\Markdown 和 Utils\AutoP 静态工具类。 修复后的 content 方法核心逻辑如下： Php | 复制 \(markdown = method_exists(\)conent, 'markdown') ? \Closure::bind(function(\(t) { return \)this->markdown(\(t); }, \)conent, get_class($conent)) : function(\(t) { return class_exists('\\Utils\\Markdown') ? \Utils\Markdown::convert(\)t) : $t; }; \(autoP = method_exists(\)conent, 'autoP') ? \Closure::bind(function(\(t) { return \)this->autoP(\(t); }, \)conent, get_class($conent)) : function($t) { if (class_exists('\\Utils\\AutoP')) { $parser = new \Utils\AutoP(); return \(parser->parse(\)t); } return $t; }; \(text = \)conent->isMarkdown ? \(markdown(\)text) : \(autoP(\)text); 经过此番修改，至少，首页的 Deprecated 报错消失了。 然而，还没高兴半分钟，当我从首页点击某篇文章的标题跳转进详情页时，傻眼了：文章内容区依然一片雪白，一个字都没有显示。 再战 Bug …

Typecho博客的折腾记录——AI总结
type: item
date: 2026-06-16T21:10:00+08:00
description: 摘要作者记录为 Typecho 博客配置 AI 摘要插件 AIContentSummary 的踩坑与重构过程。发现插件存在时序冲突（finishPublish 钩子执行时机导致无法生成摘要）、同步请求卡死及温度参数硬编码与 KIMI API 不兼容等问题。通过改用 write 钩子拦截内容变更、增加温度设置与单篇文章控制开关等方式改良插件，最终成果已开源至 GitHub。 前言 在独立博客的排版与呈现中，一篇精炼的摘要能极大提升读者的阅读体验。但是鉴于本人比较懒，所以就让打算让AI代劳。最近我尝试为 Typecho 博客配置一款名为 AIContentSummary的 AI 摘要插件，本以为填个 API Key 就能用了，结果在 AI 的帮助下还是折腾了好久，过程中踩了不少坑。 这里把这次 debug 和重构的完整过程记录下来。 一、初遇 Bug 配置好 API 地址和密钥后，我满怀期待地点击“发布”，却只看见一个Server Error，回到文章列表，发现文章发布了，但 AI 摘要字段依然是空的。即使我去修改已经存在的文章并重新发布，摘要也没有任何变化。 为了找出原因，我借助 AI，扒开了插件的源码 Plugin.php，顺着文章保存与发布的生命周期理了一遍逻辑： 时序冲突 在 Plugin.php 中，生成逻辑挂载在 finishPublish 钩子上，通过 ensureSummary() 方法来实现。而该方法内部有一行安全检查： Php | 复制 if (\(exists && trim((string) \)exists['str_value']) !== '') { return null; } 看似合情合理──如果文章已经有了摘要，就不重复生成。 然而，在 Typecho 写入文章的事务中，自定义字段的保存方法 applyFields() 在 finishPublish 钩子被触发之前就已经执行了。当用户点击“发布”时，表单提交了空的（或旧的）自定义字段，并写入了数据库。到了执行 finishPublish 时，数据库里其实已经存在了这个字段，导致上述检查永远返回 null，自动更新和生成机制直接失效！ 同步请求 由于 API 请求是同步发起的，如果接口响应缓慢或网络超时，整个发布文章的页面就会卡死；更严重的是，原代码中没有任何 try-catch 保护，一旦 API 服务异常或者鉴权失败抛出错误，会导致整个 Typecho 页面崩掉，这就是之前“Server Error”的根源所在。 二、排查诊断 为了在不崩掉页面的前提下定位错误，AI辅助我做了两件事： 在 finishPublish 中包裹了 try-catch，并使用 Typecho 自带的 Notice 机制，如果生成失败，就在页面重定向后以红条警告展示具体报错，而不是直接白屏。 在博客根目录下输出了一个临时的 debug.log，打印钩子触发的参数状态。 这一测，一下子就发现了问题： 模型参数限制 在开启了配置后，重新发布，日志里爆出了真正的接口报错： Text | 复制 async ensureSummary failed. Error: invalid temperature: only 1 is allowed for this model 原来插件在调用大模型接口时，将温度值（temperature）硬编码成了 0。而我配置的 KIMI 的 API 为了输出稳定性，强制要求温度值必须为 1。 三、AI 辅助下的插件改良 既然定位到了所有的痛点，那就开始解决！我给这个插件做了一次改良升级： 生成逻辑 拦截 write 钩子 ── 精准判定是否需要重绘 我注册了 Widget\Contents\Post\Edit 下的 write 过滤器。在文章真正写入数据库前： 比对旧正文与新正文，确认文章内容是否真的改变了。 比对旧摘要与表单提交的摘要。如果两者相同，说明作者并没有手动编辑过摘要，此时如果正文变了，就可以安全地将 $shouldRegenerate 状态标记为 true。 如果用户手动修改了摘要输入框，则主动放弃自动生成。 参数调优 增加温度（Temperature）设置：在插件配置后台中，新增了 temperature 字段，并将其默认值设定为 1.0，从而避免因为某些模型 API 参数限制报错。 按需独立控制：在文章编辑页新增了一个专门的 “自动 AI 总结” (启用/禁用) 单选按钮，让写作者在撰写单篇文章时，能根据需要灵活决定是否启用 AI 摘要生成。 保留日志输出：所有的调试日志全部在同级目录的 log/debug.log 下，方便用户检查错误原因。 总结 经过以上折腾，AI 总结已经能完美地运行在我的博客上，文章发布与更新流畅自如，A…

网站更新日志 - 26/06/16
type: item
date: 2026-06-16T13:49:00+08:00
description: 借助AI，近期更新极大的优化了网站的功能和稳定性，具体如下： 优化了PJAX的加载逻辑，极大的减少了控制台报错的概率，相应的提升了网站稳定性； 网站现在可以记忆阅读位置了，点击上一页会自动回到上一次浏览的位置； 更换Markdowm解析引擎，使用自己修改的，基于插件 EnhancedMarkdown 和 EditorMD 的二次修改的 EnhancedMarkdownPlus 插件作为网站的MD支持； 网站基于AIContentSummary二次修改了插件，为博客增加AI摘要功能。

网站更新日志 - 26/06/12
type: item
date: 2026-06-12T21:58:00+08:00
description: 友链新增七辰和诺雅狐； 网站新增了对PJAX的支持，以节省流量开支； 友链界面排版优化； 新增“罗伊的技能点”页面，展示我的技能； 删除单独的“罗伊在哪里”页面； 使用了新的网站logo； 优化“关于罗伊”： 新增“个人档案”； 补充“我的游戏人生”，整理了玩过的许多游戏； 爱好与兴趣合并为“兴趣关键词”； 新增已删除单独的“罗伊在哪里”页面，作为介绍的一部分内容展示。

CloudFlare Tunnel 使用手册（备忘）
type: item
date: 2026-05-31T23:58:00+08:00
description: 摘要Cloudflare Tunnel 技术指南详解通过 cloudflared 建立加密隧道暴露本地服务的两种管理模式（本地配置与远程 Token）、跨平台安装、核心命令与配置语法、部署流程及安全实践，支持 HTTP/SSH/TCP 等多协议代理与故障排查。一、概述 Cloudflare Tunnel（原 Argo Tunnel）通过 cloudflared 守护进程在你的本地服务器与 Cloudflare 边缘网络之间建立出站加密连接，无需公网 IP、无需开放防火墙端口，即可将本地服务安全暴露到互联网。 两种管理模式 模式 特点 适用场景 本地管理（Local Management） 配置存储在本地 config.yml，使用 cert.pem 和 JSON 凭证 需要版本控制、基础设施即代码 远程管理（Remote Management） 配置存储在 Cloudflare Dashboard，本地仅使用 Token 快速部署、多副本 HA、团队共享 二、安装 macOS Bash | 复制 brew install cloudflared Linux（Debian/Ubuntu） Bash | 复制 curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb sudo dpkg -i cloudflared.deb Windows Powershell | 复制 winget install --id Cloudflare.cloudflared # 或 choco install cloudflared Docker Bash | 复制 docker run -d --name cloudflared --restart unless-stopped \ cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <YOUR_TOKEN> 三、核心命令详解 3.1 认证与账户 命令 功能 cloudflared tunnel login 打开浏览器授权，将本地 cloudflared 与 Cloudflare 账户关联，生成 ~/.cloudflared/cert.pem cloudflared tunnel token <NAME/UUID> 获取指定隧道的 Token（用于远程管理或 Docker 部署） 3.2 Tunnel 生命周期管理 命令 功能 cloudflared tunnel create <NAME> 创建命名隧道，输出 Tunnel ID（UUID）和凭证文件路径 cloudflared tunnel list 列出所有活跃隧道（加 -d 可包含已删除隧道） cloudflared tunnel info <NAME/UUID> 查看隧道详情，包括活跃连接器（replicas）状态 cloudflared tunnel delete <NAME/UUID> 删除隧道（活跃连接时拒绝，加 -f 强制删除） cloudflared tunnel cleanup <NAME/UUID> 清理隧道的残留连接（用于非优雅退出后的修复） cloudflared tunnel cleanup --connector-id <ID> <NAME/UUID> 断开并删除指定 replica 连接器 3.3 路由配置 命令 功能 cloudflared tunnel route dns <NAME/UUID> <hostname> 自动在 Cloudflare DNS 创建 CNAME 记录，将子域名指向隧道 cloudflared tunnel route lb <NAME/UUID> <hostname> <pool> 将隧道添加为负载均衡池端点（自动创建 LB 和 Pool） 3.4 运行与调试 命令 功能 cloudflared tunnel run <NAME/UUID> 运行指定隧道（前台运行，Ctrl+C 退出） cloudflared tunnel --config <path> run <NAME/UUID> 使用自定义配置文件运行隧道 cloudflared tunnel --url http://localhost:PORT 启动 Quick Tunnel（临时隧道，无需账户，生成 *.trycloudflare.com 域名） cloudflared tunnel diag 运行连通性预检查（2026.5.2+ 版本内置） cloudflare…

网站更新日志 - 26/05/30
type: item
date: 2026-05-30T01:15:00+08:00
description: 新增了播放器支持，源项目Github； 添加了位于左下角的 Live2D 模型，源项目地址Github； 对网站进行测速，使用cf配置优化了网站加载速度。

Typecho博客的折腾记录——为Jasmine添加Meting播放器
type: item
date: 2026-05-26T18:29:00+08:00
description: 摘要本文详细讲解如何在 Typecho Jasmine 主题首页集成 Meting APlayer 音乐播放器，包括插件安装、模板修改、初始化脚本编写、侧边栏控制按钮添加及移动端适配等步骤，提供多种部署方案。 前言 Jasmine主题简约而又强大，配合Meting Aplayer 可以得到相当不错的体验，但是仅限于文章页面，我希望能在保留两者的强大功能的情况下，将播放器深度集成进网站，在查找源码询问ai以后一番折腾便有了如下教程，感谢ai 正文：在 Jasmine 主题首页集成 Meting APlayer 音乐播放器 前置说明 在实际部署中，三个项目的目录结构如下（并不在同一层级）： | 复制 Typecho 根目录/ ├── usr/ │ ├── plugins/ │ │ └── Meting/ ← Meting Aplayer 插件（重命名后放在这里） │ │ ├── Plugin.php │ │ ├── Action.php │ │ ├── assets/ │ │ ├── driver/ │ │ └── include/ │ └── themes/ │ └── Jasmine/ ← Jasmine 主题 │ ├── index.php │ ├── template-parts/ │ │ ├── header.php │ │ ├── footer.php │ │ └── ... │ └── assets/ └── index.php Meting-master/ 是 Meting-api 的 Node.js 源码仓库，仅用于参考或二次开发，不参与部署。实际运行时使用的是插件内 include/Meting.php（PHP 版本）。 第一步：安装 Meting Aplayer 插件 将 Meting Aplayer/ 文件夹上传至 Typecho 的 usr/plugins/ 目录 将文件夹重命名为 Meting（这是必须的，插件内部通过 pluginUrl.'/Meting/assets' 引用资源） 进入 Typecho 后台 → 控制台 → 插件，启用 "APlayer-Typecho | Meting" 确认服务器已安装 PHP 的 curl 和 openssl 扩展 插件关键配置项（后台可调） 配置项 默认值 说明 theme #ad7a86 播放器主题色 height 340px 播放列表最大高度 autoplay false 是否自动播放 order list 播放顺序（list / random） preload auto 音频预加载策略 bitrate 192 音质（128 / 192 / 320） api 自动生成 云解析地址，一般无需修改 salt 自动生成 API 接口保护盐值，一般无需修改 第二步：理解播放器的工作机制 插件激活后会自动注入以下前端资源到所有页面： header 钩子：注入 APlayer.min.css、APlayer.min.js，以及全局变量 meting_api footer 钩子：注入 Meting.min.js（负责发现 DOM 中的 .aplayer 元素并初始化播放器） content 钩子：解析文章/页面内容中的 短代码，将其渲染为 DOM 元素 因此，只要页面中存在带有正确 data-* 属性的 .aplayer 元素，Meting.min.js 就会自动将其初始化为播放器。 第三步：在 Jasmine 首页添加播放器 Jasmine 主题的首页模板是 index.php，它按顺序加载 header.php、left.php、navbar.php、文章列表、right.php、footer.php。 有两种方式将播放器嵌入首页： 方式 A：直接修改 index.php 模板（推荐） 编辑 Jasmine/index.php，在文章列表区域的上方或下方插入一个 .aplayer 容器。 注意：插入位置取决于那个区域是主题的哪个组件在负责，例如右边就查找包含right字段的文件，根据名称可定位具体位置，在对应的位置插入这一行即可 插入位置示例（在文章列表上方，导航栏下方）： Php | 复制 <?php $this->need('template-parts/navbar.php'); ?> <?php if ($this->have()): ?> 然后在 Jasmine/template-parts/footer.php 中（$this->footer() 之前），添加初始化脚本： Html | 复制 将 你的歌单ID 替换为实际的歌单 ID（如网易云歌单 436843836）。平台和类型也可改为 tencent、kugou 等。 不显示播放列表：如需保留播放器面…